Merge tag 'arc-5.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
[linux-2.6-microblaze.git] / drivers / phy / samsung / phy-exynos5250-usb2.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support
4  *
5  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
6  * Author: Kamil Debski <k.debski@samsung.com>
7  */
8
9 #include <linux/delay.h>
10 #include <linux/io.h>
11 #include <linux/phy/phy.h>
12 #include <linux/regmap.h>
13 #include "phy-samsung-usb2.h"
14
15 /* Exynos USB PHY registers */
16 #define EXYNOS_5250_REFCLKSEL_CRYSTAL   0x0
17 #define EXYNOS_5250_REFCLKSEL_XO        0x1
18 #define EXYNOS_5250_REFCLKSEL_CLKCORE   0x2
19
20 #define EXYNOS_5250_FSEL_9MHZ6          0x0
21 #define EXYNOS_5250_FSEL_10MHZ          0x1
22 #define EXYNOS_5250_FSEL_12MHZ          0x2
23 #define EXYNOS_5250_FSEL_19MHZ2         0x3
24 #define EXYNOS_5250_FSEL_20MHZ          0x4
25 #define EXYNOS_5250_FSEL_24MHZ          0x5
26 #define EXYNOS_5250_FSEL_50MHZ          0x7
27
28 /* Normal host */
29 #define EXYNOS_5250_HOSTPHYCTRL0                        0x0
30
31 #define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL            BIT(31)
32 #define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT        19
33 #define EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_MASK \
34                 (0x3 << EXYNOS_5250_HOSTPHYCTRL0_REFCLKSEL_SHIFT)
35 #define EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT             16
36 #define EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK \
37                 (0x7 << EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT)
38 #define EXYNOS_5250_HOSTPHYCTRL0_TESTBURNIN             BIT(11)
39 #define EXYNOS_5250_HOSTPHYCTRL0_RETENABLE              BIT(10)
40 #define EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N            BIT(9)
41 #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_MASK         (0x3 << 7)
42 #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_DUAL         (0x0 << 7)
43 #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ID0          (0x1 << 7)
44 #define EXYNOS_5250_HOSTPHYCTRL0_VATESTENB_ANALOGTEST   (0x2 << 7)
45 #define EXYNOS_5250_HOSTPHYCTRL0_SIDDQ                  BIT(6)
46 #define EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP             BIT(5)
47 #define EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND           BIT(4)
48 #define EXYNOS_5250_HOSTPHYCTRL0_WORDINTERFACE          BIT(3)
49 #define EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST              BIT(2)
50 #define EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST              BIT(1)
51 #define EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST               BIT(0)
52
53 /* HSIC0 & HSIC1 */
54 #define EXYNOS_5250_HSICPHYCTRL1                        0x10
55 #define EXYNOS_5250_HSICPHYCTRL2                        0x20
56
57 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_MASK         (0x3 << 23)
58 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT      (0x2 << 23)
59 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_MASK         (0x7f << 16)
60 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12           (0x24 << 16)
61 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_15           (0x1c << 16)
62 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_16           (0x1a << 16)
63 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_19_2         (0x15 << 16)
64 #define EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_20           (0x14 << 16)
65 #define EXYNOS_5250_HSICPHYCTRLX_SIDDQ                  BIT(6)
66 #define EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP             BIT(5)
67 #define EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND           BIT(4)
68 #define EXYNOS_5250_HSICPHYCTRLX_WORDINTERFACE          BIT(3)
69 #define EXYNOS_5250_HSICPHYCTRLX_UTMISWRST              BIT(2)
70 #define EXYNOS_5250_HSICPHYCTRLX_PHYSWRST               BIT(0)
71
72 /* EHCI control */
73 #define EXYNOS_5250_HOSTEHCICTRL                        0x30
74 #define EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN          BIT(29)
75 #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR4               BIT(28)
76 #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR8               BIT(27)
77 #define EXYNOS_5250_HOSTEHCICTRL_ENAINCR16              BIT(26)
78 #define EXYNOS_5250_HOSTEHCICTRL_AUTOPPDONOVRCUREN      BIT(25)
79 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT        19
80 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \
81                 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT)
82 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT        13
83 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_MASK \
84                 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL1_SHIFT)
85 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL2_SHIFT        7
86 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_MASK \
87                 (0x3f << EXYNOS_5250_HOSTEHCICTRL_FLADJVAL0_SHIFT)
88 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT     1
89 #define EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_MASK \
90                 (0x1 << EXYNOS_5250_HOSTEHCICTRL_FLADJVALHOST_SHIFT)
91 #define EXYNOS_5250_HOSTEHCICTRL_SIMULATIONMODE         BIT(0)
92
93 /* OHCI control */
94 #define EXYNOS_5250_HOSTOHCICTRL                        0x34
95 #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT      1
96 #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_MASK \
97                 (0x3ff << EXYNOS_5250_HOSTOHCICTRL_FRAMELENVAL_SHIFT)
98 #define EXYNOS_5250_HOSTOHCICTRL_FRAMELENVALEN          BIT(0)
99
100 /* USBOTG */
101 #define EXYNOS_5250_USBOTGSYS                           0x38
102 #define EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET          BIT(14)
103 #define EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG          BIT(13)
104 #define EXYNOS_5250_USBOTGSYS_PHY_SW_RST                BIT(12)
105 #define EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT           9
106 #define EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK \
107                 (0x3 << EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT)
108 #define EXYNOS_5250_USBOTGSYS_ID_PULLUP                 BIT(8)
109 #define EXYNOS_5250_USBOTGSYS_COMMON_ON                 BIT(7)
110 #define EXYNOS_5250_USBOTGSYS_FSEL_SHIFT                4
111 #define EXYNOS_5250_USBOTGSYS_FSEL_MASK \
112                 (0x3 << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT)
113 #define EXYNOS_5250_USBOTGSYS_FORCE_SLEEP               BIT(3)
114 #define EXYNOS_5250_USBOTGSYS_OTGDISABLE                BIT(2)
115 #define EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG                BIT(1)
116 #define EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND             BIT(0)
117
118 /* Isolation, configured in the power management unit */
119 #define EXYNOS_5250_USB_ISOL_OTG_OFFSET         0x704
120 #define EXYNOS_5250_USB_ISOL_OTG                BIT(0)
121 #define EXYNOS_5250_USB_ISOL_HOST_OFFSET        0x708
122 #define EXYNOS_5250_USB_ISOL_HOST               BIT(0)
123
124 /* Mode swtich register */
125 #define EXYNOS_5250_MODE_SWITCH_OFFSET          0x230
126 #define EXYNOS_5250_MODE_SWITCH_MASK            1
127 #define EXYNOS_5250_MODE_SWITCH_DEVICE          0
128 #define EXYNOS_5250_MODE_SWITCH_HOST            1
129
130 enum exynos4x12_phy_id {
131         EXYNOS5250_DEVICE,
132         EXYNOS5250_HOST,
133         EXYNOS5250_HSIC0,
134         EXYNOS5250_HSIC1,
135         EXYNOS5250_NUM_PHYS,
136 };
137
138 /*
139  * exynos5250_rate_to_clk() converts the supplied clock rate to the value that
140  * can be written to the phy register.
141  */
142 static int exynos5250_rate_to_clk(unsigned long rate, u32 *reg)
143 {
144         /* EXYNOS_5250_FSEL_MASK */
145
146         switch (rate) {
147         case 9600 * KHZ:
148                 *reg = EXYNOS_5250_FSEL_9MHZ6;
149                 break;
150         case 10 * MHZ:
151                 *reg = EXYNOS_5250_FSEL_10MHZ;
152                 break;
153         case 12 * MHZ:
154                 *reg = EXYNOS_5250_FSEL_12MHZ;
155                 break;
156         case 19200 * KHZ:
157                 *reg = EXYNOS_5250_FSEL_19MHZ2;
158                 break;
159         case 20 * MHZ:
160                 *reg = EXYNOS_5250_FSEL_20MHZ;
161                 break;
162         case 24 * MHZ:
163                 *reg = EXYNOS_5250_FSEL_24MHZ;
164                 break;
165         case 50 * MHZ:
166                 *reg = EXYNOS_5250_FSEL_50MHZ;
167                 break;
168         default:
169                 return -EINVAL;
170         }
171
172         return 0;
173 }
174
175 static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on)
176 {
177         struct samsung_usb2_phy_driver *drv = inst->drv;
178         u32 offset;
179         u32 mask;
180
181         switch (inst->cfg->id) {
182         case EXYNOS5250_DEVICE:
183                 offset = EXYNOS_5250_USB_ISOL_OTG_OFFSET;
184                 mask = EXYNOS_5250_USB_ISOL_OTG;
185                 break;
186         case EXYNOS5250_HOST:
187                 offset = EXYNOS_5250_USB_ISOL_HOST_OFFSET;
188                 mask = EXYNOS_5250_USB_ISOL_HOST;
189                 break;
190         default:
191                 return;
192         }
193
194         regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask);
195 }
196
197 static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst)
198 {
199         struct samsung_usb2_phy_driver *drv = inst->drv;
200         u32 ctrl0;
201         u32 otg;
202         u32 ehci;
203         u32 ohci;
204         u32 hsic;
205
206         switch (inst->cfg->id) {
207         case EXYNOS5250_DEVICE:
208                 regmap_update_bits(drv->reg_sys,
209                                    EXYNOS_5250_MODE_SWITCH_OFFSET,
210                                    EXYNOS_5250_MODE_SWITCH_MASK,
211                                    EXYNOS_5250_MODE_SWITCH_DEVICE);
212
213                 /* OTG configuration */
214                 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS);
215                 /* The clock */
216                 otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK;
217                 otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT;
218                 /* Reset */
219                 otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND |
220                         EXYNOS_5250_USBOTGSYS_FORCE_SLEEP |
221                         EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG);
222                 otg |=  EXYNOS_5250_USBOTGSYS_PHY_SW_RST |
223                         EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET |
224                         EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG |
225                         EXYNOS_5250_USBOTGSYS_OTGDISABLE;
226                 /* Ref clock */
227                 otg &=  ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK;
228                 otg |=  EXYNOS_5250_REFCLKSEL_CLKCORE <<
229                                         EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT;
230                 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS);
231                 udelay(100);
232                 otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST |
233                         EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG |
234                         EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET |
235                         EXYNOS_5250_USBOTGSYS_OTGDISABLE);
236                 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS);
237
238
239                 break;
240         case EXYNOS5250_HOST:
241         case EXYNOS5250_HSIC0:
242         case EXYNOS5250_HSIC1:
243                 /* Host registers configuration */
244                 ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
245                 /* The clock */
246                 ctrl0 &= ~EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK;
247                 ctrl0 |= drv->ref_reg_val <<
248                                         EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT;
249
250                 /* Reset */
251                 ctrl0 &=        ~(EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST |
252                                 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL |
253                                 EXYNOS_5250_HOSTPHYCTRL0_SIDDQ |
254                                 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND |
255                                 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP);
256                 ctrl0 |=        EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST |
257                                 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST |
258                                 EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N;
259                 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
260                 udelay(10);
261                 ctrl0 &=        ~(EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST |
262                                 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST);
263                 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
264
265                 /* OTG configuration */
266                 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS);
267                 /* The clock */
268                 otg &= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK;
269                 otg |= drv->ref_reg_val << EXYNOS_5250_USBOTGSYS_FSEL_SHIFT;
270                 /* Reset */
271                 otg &= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND |
272                         EXYNOS_5250_USBOTGSYS_FORCE_SLEEP |
273                         EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG);
274                 otg |=  EXYNOS_5250_USBOTGSYS_PHY_SW_RST |
275                         EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET |
276                         EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG |
277                         EXYNOS_5250_USBOTGSYS_OTGDISABLE;
278                 /* Ref clock */
279                 otg &=  ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK;
280                 otg |=  EXYNOS_5250_REFCLKSEL_CLKCORE <<
281                                         EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT;
282                 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS);
283                 udelay(10);
284                 otg &= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST |
285                         EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG |
286                         EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET);
287
288                 /* HSIC phy configuration */
289                 hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 |
290                                 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT |
291                                 EXYNOS_5250_HSICPHYCTRLX_PHYSWRST);
292                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1);
293                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2);
294                 udelay(10);
295                 hsic &= ~EXYNOS_5250_HSICPHYCTRLX_PHYSWRST;
296                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1);
297                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2);
298                 /* The following delay is necessary for the reset sequence to be
299                  * completed */
300                 udelay(80);
301
302                 /* Enable EHCI DMA burst */
303                 ehci = readl(drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL);
304                 ehci |= EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN |
305                         EXYNOS_5250_HOSTEHCICTRL_ENAINCR4 |
306                         EXYNOS_5250_HOSTEHCICTRL_ENAINCR8 |
307                         EXYNOS_5250_HOSTEHCICTRL_ENAINCR16;
308                 writel(ehci, drv->reg_phy + EXYNOS_5250_HOSTEHCICTRL);
309
310                 /* OHCI settings */
311                 ohci = readl(drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL);
312                 /* Following code is based on the old driver */
313                 ohci |= 0x1 << 3;
314                 writel(ohci, drv->reg_phy + EXYNOS_5250_HOSTOHCICTRL);
315
316                 break;
317         }
318         exynos5250_isol(inst, 0);
319
320         return 0;
321 }
322
323 static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst)
324 {
325         struct samsung_usb2_phy_driver *drv = inst->drv;
326         u32 ctrl0;
327         u32 otg;
328         u32 hsic;
329
330         exynos5250_isol(inst, 1);
331
332         switch (inst->cfg->id) {
333         case EXYNOS5250_DEVICE:
334                 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS);
335                 otg |= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND |
336                         EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG |
337                         EXYNOS_5250_USBOTGSYS_FORCE_SLEEP);
338                 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS);
339                 break;
340         case EXYNOS5250_HOST:
341                 ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
342                 ctrl0 |= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ |
343                                 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND |
344                                 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP |
345                                 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST |
346                                 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL);
347                 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
348                 break;
349         case EXYNOS5250_HSIC0:
350         case EXYNOS5250_HSIC1:
351                 hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 |
352                                 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT |
353                                 EXYNOS_5250_HSICPHYCTRLX_SIDDQ |
354                                 EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP |
355                                 EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND
356                                 );
357                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1);
358                 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2);
359                 break;
360         }
361
362         return 0;
363 }
364
365
366 static const struct samsung_usb2_common_phy exynos5250_phys[] = {
367         {
368                 .label          = "device",
369                 .id             = EXYNOS5250_DEVICE,
370                 .power_on       = exynos5250_power_on,
371                 .power_off      = exynos5250_power_off,
372         },
373         {
374                 .label          = "host",
375                 .id             = EXYNOS5250_HOST,
376                 .power_on       = exynos5250_power_on,
377                 .power_off      = exynos5250_power_off,
378         },
379         {
380                 .label          = "hsic0",
381                 .id             = EXYNOS5250_HSIC0,
382                 .power_on       = exynos5250_power_on,
383                 .power_off      = exynos5250_power_off,
384         },
385         {
386                 .label          = "hsic1",
387                 .id             = EXYNOS5250_HSIC1,
388                 .power_on       = exynos5250_power_on,
389                 .power_off      = exynos5250_power_off,
390         },
391 };
392
393 const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = {
394         .has_mode_switch        = 1,
395         .num_phys               = EXYNOS5250_NUM_PHYS,
396         .phys                   = exynos5250_phys,
397         .rate_to_clk            = exynos5250_rate_to_clk,
398 };