of: MSI: Simplify irqdomain lookup
[linux/fpc-iii.git] / drivers / phy / phy-exynos5250-usb2.c
blob2ed1735a076a1f8a50898de3d3de28bc7dfa235d
1 /*
2 * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 5250 support
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * Author: Kamil Debski <k.debski@samsung.com>
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.
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"
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
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
31 /* Normal host */
32 #define EXYNOS_5250_HOSTPHYCTRL0 0x0
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)
56 /* HSIC0 & HSIC1 */
57 #define EXYNOS_5250_HSICPHYCTRL1 0x10
58 #define EXYNOS_5250_HSICPHYCTRL2 0x20
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)
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)
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)
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)
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)
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
133 enum exynos4x12_phy_id {
134 EXYNOS5250_DEVICE,
135 EXYNOS5250_HOST,
136 EXYNOS5250_HSIC0,
137 EXYNOS5250_HSIC1,
138 EXYNOS5250_NUM_PHYS,
142 * exynos5250_rate_to_clk() converts the supplied clock rate to the value that
143 * can be written to the phy register.
145 static int exynos5250_rate_to_clk(unsigned long rate, u32 *reg)
147 /* EXYNOS_5250_FSEL_MASK */
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;
175 return 0;
178 static void exynos5250_isol(struct samsung_usb2_phy_instance *inst, bool on)
180 struct samsung_usb2_phy_driver *drv = inst->drv;
181 u32 offset;
182 u32 mask;
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;
197 regmap_update_bits(drv->reg_pmu, offset, mask, on ? 0 : mask);
200 static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst)
202 struct samsung_usb2_phy_driver *drv = inst->drv;
203 u32 ctrl0;
204 u32 otg;
205 u32 ehci;
206 u32 ohci;
207 u32 hsic;
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);
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);
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;
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);
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);
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);
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);
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);
319 break;
321 exynos5250_isol(inst, 0);
323 return 0;
326 static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst)
328 struct samsung_usb2_phy_driver *drv = inst->drv;
329 u32 ctrl0;
330 u32 otg;
331 u32 hsic;
333 exynos5250_isol(inst, 1);
335 switch (inst->cfg->id) {
336 case EXYNOS5250_DEVICE:
337 otg = readl(drv->reg_phy + EXYNOS_5250_USBOTGSYS);
338 otg |= (EXYNOS_5250_USBOTGSYS_FORCE_SUSPEND |
339 EXYNOS_5250_USBOTGSYS_SIDDQ_UOTG |
340 EXYNOS_5250_USBOTGSYS_FORCE_SLEEP);
341 writel(otg, drv->reg_phy + EXYNOS_5250_USBOTGSYS);
342 break;
343 case EXYNOS5250_HOST:
344 ctrl0 = readl(drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
345 ctrl0 |= (EXYNOS_5250_HOSTPHYCTRL0_SIDDQ |
346 EXYNOS_5250_HOSTPHYCTRL0_FORCESUSPEND |
347 EXYNOS_5250_HOSTPHYCTRL0_FORCESLEEP |
348 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRST |
349 EXYNOS_5250_HOSTPHYCTRL0_PHYSWRSTALL);
350 writel(ctrl0, drv->reg_phy + EXYNOS_5250_HOSTPHYCTRL0);
351 break;
352 case EXYNOS5250_HSIC0:
353 case EXYNOS5250_HSIC1:
354 hsic = (EXYNOS_5250_HSICPHYCTRLX_REFCLKDIV_12 |
355 EXYNOS_5250_HSICPHYCTRLX_REFCLKSEL_DEFAULT |
356 EXYNOS_5250_HSICPHYCTRLX_SIDDQ |
357 EXYNOS_5250_HSICPHYCTRLX_FORCESLEEP |
358 EXYNOS_5250_HSICPHYCTRLX_FORCESUSPEND
360 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL1);
361 writel(hsic, drv->reg_phy + EXYNOS_5250_HSICPHYCTRL2);
362 break;
365 return 0;
369 static const struct samsung_usb2_common_phy exynos5250_phys[] = {
371 .label = "device",
372 .id = EXYNOS5250_DEVICE,
373 .power_on = exynos5250_power_on,
374 .power_off = exynos5250_power_off,
377 .label = "host",
378 .id = EXYNOS5250_HOST,
379 .power_on = exynos5250_power_on,
380 .power_off = exynos5250_power_off,
383 .label = "hsic0",
384 .id = EXYNOS5250_HSIC0,
385 .power_on = exynos5250_power_on,
386 .power_off = exynos5250_power_off,
389 .label = "hsic1",
390 .id = EXYNOS5250_HSIC1,
391 .power_on = exynos5250_power_on,
392 .power_off = exynos5250_power_off,
396 const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = {
397 .has_mode_switch = 1,
398 .num_phys = EXYNOS5250_NUM_PHYS,
399 .phys = exynos5250_phys,
400 .rate_to_clk = exynos5250_rate_to_clk,