1 // SPDX-License-Identifier: GPL-2.0-only
3 * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support
5 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
6 * Author: Kamil Debski <k.debski@samsung.com>
9 #include <linux/delay.h>
11 #include <linux/phy/phy.h>
12 #include <linux/regmap.h>
13 #include "phy-samsung-usb2.h"
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
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
29 #define EXYNOS_5250_HOSTPHYCTRL0 0x0
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)
54 #define EXYNOS_5250_HSICPHYCTRL1 0x10
55 #define EXYNOS_5250_HSICPHYCTRL2 0x20
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)
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)
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)
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)
118 /* Isolation, configured in the power management unit */
119 #define EXYNOS_5250_USB_ISOL_OTG_OFFSET 0x704
120 #define EXYNOS_5250_USB_ISOL_HOST_OFFSET 0x708
121 #define EXYNOS_5420_USB_ISOL_HOST_OFFSET 0x70C
122 #define EXYNOS_5250_USB_ISOL_ENABLE BIT(0)
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
130 enum exynos4x12_phy_id
{
138 * exynos5250_rate_to_clk() converts the supplied clock rate to the value that
139 * can be written to the phy register.
141 static int exynos5250_rate_to_clk(unsigned long rate
, u32
*reg
)
143 /* EXYNOS_5250_FSEL_MASK */
147 *reg
= EXYNOS_5250_FSEL_9MHZ6
;
150 *reg
= EXYNOS_5250_FSEL_10MHZ
;
153 *reg
= EXYNOS_5250_FSEL_12MHZ
;
156 *reg
= EXYNOS_5250_FSEL_19MHZ2
;
159 *reg
= EXYNOS_5250_FSEL_20MHZ
;
162 *reg
= EXYNOS_5250_FSEL_24MHZ
;
165 *reg
= EXYNOS_5250_FSEL_50MHZ
;
174 static void exynos5250_isol(struct samsung_usb2_phy_instance
*inst
, bool on
)
176 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
178 u32 mask
= EXYNOS_5250_USB_ISOL_ENABLE
;
180 if (drv
->cfg
== &exynos5250_usb2_phy_config
&&
181 inst
->cfg
->id
== EXYNOS5250_DEVICE
)
182 offset
= EXYNOS_5250_USB_ISOL_OTG_OFFSET
;
183 else if (drv
->cfg
== &exynos5250_usb2_phy_config
&&
184 inst
->cfg
->id
== EXYNOS5250_HOST
)
185 offset
= EXYNOS_5250_USB_ISOL_HOST_OFFSET
;
186 else if (drv
->cfg
== &exynos5420_usb2_phy_config
&&
187 inst
->cfg
->id
== EXYNOS5250_HOST
)
188 offset
= EXYNOS_5420_USB_ISOL_HOST_OFFSET
;
192 regmap_update_bits(drv
->reg_pmu
, offset
, mask
, on
? 0 : mask
);
195 static int exynos5250_power_on(struct samsung_usb2_phy_instance
*inst
)
197 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
204 switch (inst
->cfg
->id
) {
205 case EXYNOS5250_DEVICE
:
206 regmap_update_bits(drv
->reg_sys
,
207 EXYNOS_5250_MODE_SWITCH_OFFSET
,
208 EXYNOS_5250_MODE_SWITCH_MASK
,
209 EXYNOS_5250_MODE_SWITCH_DEVICE
);
211 /* OTG configuration */
212 otg
= readl(drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
214 otg
&= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK
;
215 otg
|= drv
->ref_reg_val
<< EXYNOS_5250_USBOTGSYS_FSEL_SHIFT
;
217 otg
&= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND
|
218 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP
|
219 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG
);
220 otg
|= EXYNOS_5250_USBOTGSYS_PHY_SW_RST
|
221 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET
|
222 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG
|
223 EXYNOS_5250_USBOTGSYS_OTGDISABLE
;
225 otg
&= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK
;
226 otg
|= EXYNOS_5250_REFCLKSEL_CLKCORE
<<
227 EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT
;
228 writel(otg
, drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
230 otg
&= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST
|
231 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG
|
232 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET
|
233 EXYNOS_5250_USBOTGSYS_OTGDISABLE
);
234 writel(otg
, drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
238 case EXYNOS5250_HOST
:
239 case EXYNOS5250_HSIC0
:
240 case EXYNOS5250_HSIC1
:
241 /* Host registers configuration */
242 ctrl0
= readl(drv
->reg_phy
+ EXYNOS_5250_HOSTPHYCTRL0
);
244 ctrl0
&= ~EXYNOS_5250_HOSTPHYCTRL0_FSEL_MASK
;
245 ctrl0
|= drv
->ref_reg_val
<<
246 EXYNOS_5250_HOSTPHYCTRL0_FSEL_SHIFT
;
249 ctrl0
&= ~(EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST
|
250 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL
|
251 EXYNOS_5250_HOSTPHYCTRL0_SIDDQ
|
252 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND
|
253 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP
);
254 ctrl0
|= EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST
|
255 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST
|
256 EXYNOS_5250_HOSTPHYCTRL0_COMMON_ON_N
;
257 writel(ctrl0
, drv
->reg_phy
+ EXYNOS_5250_HOSTPHYCTRL0
);
259 ctrl0
&= ~(EXYNOS_5250_HOSTPHYCTRL0_LINKSWRST
|
260 EXYNOS_5250_HOSTPHYCTRL0_UTMISWRST
);
261 writel(ctrl0
, drv
->reg_phy
+ EXYNOS_5250_HOSTPHYCTRL0
);
263 /* OTG configuration */
264 otg
= readl(drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
266 otg
&= ~EXYNOS_5250_USBOTGSYS_FSEL_MASK
;
267 otg
|= drv
->ref_reg_val
<< EXYNOS_5250_USBOTGSYS_FSEL_SHIFT
;
269 otg
&= ~(EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND
|
270 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP
|
271 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG
);
272 otg
|= EXYNOS_5250_USBOTGSYS_PHY_SW_RST
|
273 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET
|
274 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG
|
275 EXYNOS_5250_USBOTGSYS_OTGDISABLE
;
277 otg
&= ~EXYNOS_5250_USBOTGSYS_REFCLKSEL_MASK
;
278 otg
|= EXYNOS_5250_REFCLKSEL_CLKCORE
<<
279 EXYNOS_5250_USBOTGSYS_REFCLKSEL_SHIFT
;
280 writel(otg
, drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
282 otg
&= ~(EXYNOS_5250_USBOTGSYS_PHY_SW_RST
|
283 EXYNOS_5250_USBOTGSYS_LINK_SW_RST_UOTG
|
284 EXYNOS_5250_USBOTGSYS_PHYLINK_SW_RESET
);
286 /* HSIC phy configuration */
287 hsic
= (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12
|
288 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT
|
289 EXYNOS_5250_HSICPHYCTRLX_PHYSWRST
);
290 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL1
);
291 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL2
);
293 hsic
&= ~EXYNOS_5250_HSICPHYCTRLX_PHYSWRST
;
294 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL1
);
295 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL2
);
296 /* The following delay is necessary for the reset sequence to be
300 /* Enable EHCI DMA burst */
301 ehci
= readl(drv
->reg_phy
+ EXYNOS_5250_HOSTEHCICTRL
);
302 ehci
|= EXYNOS_5250_HOSTEHCICTRL_ENAINCRXALIGN
|
303 EXYNOS_5250_HOSTEHCICTRL_ENAINCR4
|
304 EXYNOS_5250_HOSTEHCICTRL_ENAINCR8
|
305 EXYNOS_5250_HOSTEHCICTRL_ENAINCR16
;
306 writel(ehci
, drv
->reg_phy
+ EXYNOS_5250_HOSTEHCICTRL
);
309 ohci
= readl(drv
->reg_phy
+ EXYNOS_5250_HOSTOHCICTRL
);
310 /* Following code is based on the old driver */
312 writel(ohci
, drv
->reg_phy
+ EXYNOS_5250_HOSTOHCICTRL
);
316 exynos5250_isol(inst
, 0);
321 static int exynos5250_power_off(struct samsung_usb2_phy_instance
*inst
)
323 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
328 exynos5250_isol(inst
, 1);
330 switch (inst
->cfg
->id
) {
331 case EXYNOS5250_DEVICE
:
332 otg
= readl(drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
333 otg
|= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND
|
334 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG
|
335 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP
);
336 writel(otg
, drv
->reg_phy
+ EXYNOS_5250_USBOTGSYS
);
338 case EXYNOS5250_HOST
:
339 ctrl0
= readl(drv
->reg_phy
+ EXYNOS_5250_HOSTPHYCTRL0
);
340 ctrl0
|= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ
|
341 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND
|
342 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP
|
343 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST
|
344 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL
);
345 writel(ctrl0
, drv
->reg_phy
+ EXYNOS_5250_HOSTPHYCTRL0
);
347 case EXYNOS5250_HSIC0
:
348 case EXYNOS5250_HSIC1
:
349 hsic
= (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12
|
350 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT
|
351 EXYNOS_5250_HSICPHYCTRLX_SIDDQ
|
352 EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP
|
353 EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND
355 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL1
);
356 writel(hsic
, drv
->reg_phy
+ EXYNOS_5250_HSICPHYCTRL2
);
364 static const struct samsung_usb2_common_phy exynos5250_phys
[] = {
367 .id
= EXYNOS5250_DEVICE
,
368 .power_on
= exynos5250_power_on
,
369 .power_off
= exynos5250_power_off
,
373 .id
= EXYNOS5250_HOST
,
374 .power_on
= exynos5250_power_on
,
375 .power_off
= exynos5250_power_off
,
379 .id
= EXYNOS5250_HSIC0
,
380 .power_on
= exynos5250_power_on
,
381 .power_off
= exynos5250_power_off
,
385 .id
= EXYNOS5250_HSIC1
,
386 .power_on
= exynos5250_power_on
,
387 .power_off
= exynos5250_power_off
,
391 static const struct samsung_usb2_common_phy exynos5420_phys
[] = {
394 .id
= EXYNOS5250_HOST
,
395 .power_on
= exynos5250_power_on
,
396 .power_off
= exynos5250_power_off
,
400 .id
= EXYNOS5250_HSIC0
,
401 .power_on
= exynos5250_power_on
,
402 .power_off
= exynos5250_power_off
,
406 const struct samsung_usb2_phy_config exynos5250_usb2_phy_config
= {
407 .has_mode_switch
= 1,
408 .num_phys
= ARRAY_SIZE(exynos5250_phys
),
409 .phys
= exynos5250_phys
,
410 .rate_to_clk
= exynos5250_rate_to_clk
,
413 const struct samsung_usb2_phy_config exynos5420_usb2_phy_config
= {
414 .has_mode_switch
= 1,
415 .num_phys
= ARRAY_SIZE(exynos5420_phys
),
416 .phys
= exynos5420_phys
,
417 .rate_to_clk
= exynos5250_rate_to_clk
,