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