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 */
exynos5250_rate_to_clk(unsigned long rate,u32 * reg)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
exynos5250_isol(struct samsung_usb2_phy_instance * inst,bool on)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
exynos5250_power_on(struct samsung_usb2_phy_instance * inst)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
exynos5250_power_off(struct samsung_usb2_phy_instance * inst)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 };
399