e944ff4e259e80aba4434c774254dcab8c2574da
[cascardo/linux.git] / arch / arm / mach-exynos / setup-usb-phy.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4  *
5  *  This program is free software; you can redistribute  it and/or modify it
6  *  under  the terms of  the GNU General  Public License as published by the
7  *  Free Software Foundation;  either version 2 of the  License, or (at your
8  *  option) any later version.
9  *
10  */
11
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/err.h>
15 #include <linux/io.h>
16 #include <linux/of.h>
17 #include <linux/of_gpio.h>
18 #include <linux/platform_device.h>
19 #include <mach/regs-pmu.h>
20 #include <mach/regs-usb-phy.h>
21 #include <plat/cpu.h>
22 #include <plat/usb-phy.h>
23 #include <plat/regs-usb3-exynos-drd-phy.h>
24
25 #define PHY_ENABLE      1
26 #define PHY_DISABLE     0
27 #define EXYNOS4_USB_CFG         (S3C_VA_SYS + 0x21C)
28 #define EXYNOS5_USB_CFG         S5P_SYSREG(0x0230)
29
30 enum usb_phy_type {
31         USB_PHY         = (0x1 << 0),
32         USB_PHY0        = (0x1 << 0),
33         USB_PHY1        = (0x1 << 1),
34         USB_PHY_HSIC0   = (0x1 << 1),
35         USB_PHY_HSIC1   = (0x1 << 2),
36 };
37
38 struct exynos_usb_phy {
39         u8 phy0_usage;
40         u8 phy1_usage;
41         u8 phy2_usage;
42         unsigned long flags;
43 };
44
45
46 static atomic_t host_usage;
47 static struct exynos_usb_phy usb_phy_control;
48 static DEFINE_SPINLOCK(phy_lock);
49
50 static int exynos4_usb_host_phy_is_on(void)
51 {
52         return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
53 }
54
55 static int exynos5_usb_host_phy20_is_on(void)
56 {
57         return (readl(EXYNOS5_PHY_HOST_CTRL0) & HOST_CTRL0_PHYSWRSTALL) ? 0 : 1;
58 }
59
60 /* Returning 'clk' here so as to disable clk in phy_init/exit functions */
61 static struct clk *exynos_usb_phy_clock_enable(struct platform_device *pdev)
62 {
63         int err;
64         struct clk *phy_clk = NULL;
65
66         if (!soc_is_exynos5250())
67                 return NULL;
68
69         phy_clk = clk_get(&pdev->dev, "usbhost");
70
71         if (IS_ERR(phy_clk)) {
72                 dev_err(&pdev->dev, "Failed to get phy clock\n");
73                 return NULL;
74         }
75
76         err = clk_enable(phy_clk);
77         if (err) {
78                 dev_err(&pdev->dev, "Failed to enable phy clock\n");
79                 clk_put(phy_clk);
80                 return NULL;
81         }
82
83         return phy_clk;
84 }
85
86 static void exynos_usb_phy_clock_disable(struct clk *phy_clk)
87 {
88         clk_disable(phy_clk);
89         clk_put(phy_clk);
90 }
91
92 static void exynos_usb_mux_change(struct platform_device *pdev, int val)
93 {
94         u32 is_host;
95         if (!soc_is_exynos5250())
96                 return;
97
98         is_host = readl(EXYNOS5_USB_CFG);
99         writel(val, EXYNOS5_USB_CFG);
100         if (is_host != val)
101                 dev_dbg(&pdev->dev, "Change USB MUX from %s to %s",
102                         is_host ? "Host" : "Device", val ? "Host" : "Device");
103 }
104
105 static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on)
106 {
107         spin_lock(&phy_lock);
108         if (soc_is_exynos5250()) {
109                 if (phy_type & USB_PHY0) {
110                         if (on == PHY_ENABLE
111                                 && (usb_phy_control.phy0_usage++) == 0)
112                                 writel(S5P_USBDRD_PHY_ENABLE,
113                                                 S5P_USBDRD_PHY_CONTROL);
114                         else if (on == PHY_DISABLE
115                                 && (--usb_phy_control.phy0_usage) == 0)
116                                 writel(~S5P_USBDRD_PHY_ENABLE,
117                                                 S5P_USBDRD_PHY_CONTROL);
118
119                 } else if (phy_type & USB_PHY1) {
120                         if (on == PHY_ENABLE
121                                 && (usb_phy_control.phy1_usage++) == 0)
122                                 writel(S5P_USBHOST_PHY_ENABLE,
123                                                 S5P_USBHOST_PHY_CONTROL);
124                         else if (on == PHY_DISABLE
125                                 && (--usb_phy_control.phy1_usage) == 0)
126                                 writel(~S5P_USBHOST_PHY_ENABLE,
127                                                 S5P_USBHOST_PHY_CONTROL);
128                 }
129         }
130         spin_unlock(&phy_lock);
131 }
132
133 static u32 exynos_usb_phy_set_clock(struct platform_device *pdev)
134 {
135         struct clk *ref_clk;
136         u32 refclk_freq = 0;
137
138         ref_clk = clk_get(&pdev->dev, "ext_xtal");
139
140         if (IS_ERR(ref_clk)) {
141                 dev_err(&pdev->dev, "Failed to get reference clock\n");
142                 return PTR_ERR(ref_clk);
143         }
144         if (soc_is_exynos5250()) {
145                 switch (clk_get_rate(ref_clk)) {
146                 case 96 * 100000:
147                         refclk_freq = EXYNOS5_CLKSEL_9600K;
148                         break;
149                 case 10 * MHZ:
150                         refclk_freq = EXYNOS5_CLKSEL_10M;
151                         break;
152                 case 12 * MHZ:
153                         refclk_freq = EXYNOS5_CLKSEL_12M;
154                         break;
155                 case 192 * 100000:
156                         refclk_freq = EXYNOS5_CLKSEL_19200K;
157                         break;
158                 case 20 * MHZ:
159                         refclk_freq = EXYNOS5_CLKSEL_20M;
160                         break;
161                 case 50 * MHZ:
162                         refclk_freq = EXYNOS5_CLKSEL_50M;
163                         break;
164                 case 24 * MHZ:
165                 default:
166                         /* default reference clock */
167                         refclk_freq = EXYNOS5_CLKSEL_24M;
168                         break;
169                 }
170         }
171         clk_put(ref_clk);
172
173         return refclk_freq;
174 }
175
176 /*
177  * Sets the phy clk as EXTREFCLK (XXTI) which is internal clock form clock core.
178  */
179 static u32 exynos_usb_phy30_set_clock_int(struct platform_device *pdev)
180 {
181         u32 reg;
182         u32 refclk;
183
184         refclk = exynos_usb_phy_set_clock(pdev);
185
186         reg = EXYNOS_USB3_PHYCLKRST_REFCLKSEL_EXT_REF_CLK |
187               EXYNOS_USB3_PHYCLKRST_FSEL(refclk);
188
189         switch (refclk) {
190         case EXYNOS5_CLKSEL_50M:
191                 /* TODO: multiplier seems wrong; others make ~2.5GHz */
192                 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(0x02) |
193                         EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x00));
194                 break;
195         case EXYNOS5_CLKSEL_20M:
196                 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF |
197                         EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x00));
198                 break;
199         case EXYNOS5_CLKSEL_19200K:
200                 /* TODO: multiplier seems wrong; others make ~2.5GHz */
201                 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(0x02) |
202                         EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x88));
203                 break;
204         case EXYNOS5_CLKSEL_24M:
205         default:
206                 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
207                         EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x88));
208                 break;
209         }
210
211         return reg;
212 }
213
214 /*
215  * Sets the phy clk as ref_pad_clk (XusbXTI) which is clock from external PLL.
216  */
217 static u32 exynos_usb_phy30_set_clock_ext(struct platform_device *pdev)
218 {
219         u32 reg;
220
221         reg = EXYNOS_USB3_PHYCLKRST_REFCLKSEL_PAD_REF_CLK |
222                 EXYNOS_USB3_PHYCLKRST_FSEL_PAD_100MHZ |
223                 EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF;
224
225         return reg;
226 }
227
228 static int _exynos5_usb_phy30_init(struct platform_device *pdev,
229                                                 bool use_ext_clk)
230 {
231         u32 reg;
232
233         exynos_usb_phy_control(USB_PHY0, PHY_ENABLE);
234
235         /* Reset USB 3.0 PHY */
236         writel(0x00000000, EXYNOS_USB3_PHYREG0);
237
238         reg = 0x24d4e6e4;
239         if (use_ext_clk)
240                 reg |= (0x1 << 31);
241         writel(reg, EXYNOS_USB3_PHYPARAM0);
242
243         writel(0x03fff81c, EXYNOS_USB3_PHYPARAM1);
244         writel(0x00000000, EXYNOS_USB3_PHYRESUME);
245
246         /* Setting the Frame length Adj value[6:1] to default 0x20 */
247         writel(0x08000040, EXYNOS_USB3_LINKSYSTEM);
248         writel(0x00000004, EXYNOS_USB3_PHYBATCHG);
249
250         /* PHYTEST POWERDOWN Control */
251         reg = readl(EXYNOS_USB3_PHYTEST);
252         reg &= ~(EXYNOS_USB3_PHYTEST_POWERDOWN_SSP |
253                 EXYNOS_USB3_PHYTEST_POWERDOWN_HSP);
254         writel(reg, EXYNOS_USB3_PHYTEST);
255
256         /* UTMI Power Control */
257         writel(EXYNOS_USB3_PHYUTMI_OTGDISABLE, EXYNOS_USB3_PHYUTMI);
258
259         if (use_ext_clk)
260                 reg = exynos_usb_phy30_set_clock_ext(pdev);
261         else
262                 reg = exynos_usb_phy30_set_clock_int(pdev);
263
264         reg |= EXYNOS_USB3_PHYCLKRST_PORTRESET |
265                 /* Digital power supply in normal operating mode */
266                 EXYNOS_USB3_PHYCLKRST_RETENABLEN |
267                 /* Enable ref clock for SS function */
268                 EXYNOS_USB3_PHYCLKRST_REF_SSP_EN |
269                 /* Enable spread spectrum */
270                 EXYNOS_USB3_PHYCLKRST_SSC_EN |
271                 /* Power down HS Bias and PLL blocks in suspend mode */
272                 EXYNOS_USB3_PHYCLKRST_COMMONONN;
273
274         writel(reg, EXYNOS_USB3_PHYCLKRST);
275
276         udelay(10);
277
278         reg &= ~(EXYNOS_USB3_PHYCLKRST_PORTRESET);
279         writel(reg, EXYNOS_USB3_PHYCLKRST);
280
281         return 0;
282 }
283
284 int exynos5_dwc_phyclk_switch(struct platform_device *pdev, bool use_ext_clk)
285 {
286         return _exynos5_usb_phy30_init(pdev, use_ext_clk);
287 }
288
289 static int exynos5_usb_phy30_init(struct platform_device *pdev)
290 {
291         int ret;
292         struct clk *host_clk = NULL;
293
294         host_clk = exynos_usb_phy_clock_enable(pdev);
295         if (!host_clk) {
296                 dev_err(&pdev->dev, "Failed to enable USB3.0 host clock\n");
297                 return -ENODEV;
298         }
299
300         /*
301          * We'll start out with the XusbXTI turned on
302          * for phy reference clock refclksel [3:2]
303          */
304         ret = _exynos5_usb_phy30_init(pdev, true);
305
306         exynos_usb_phy_clock_disable(host_clk);
307
308         return ret;
309 }
310
311 static int exynos5_usb_phy30_exit(struct platform_device *pdev)
312 {
313         u32 reg;
314         struct clk *host_clk = NULL;
315
316         host_clk = exynos_usb_phy_clock_enable(pdev);
317         if (!host_clk) {
318                 dev_err(&pdev->dev, "Failed to enable USB3.0 host clock\n");
319                 return -ENODEV;
320         }
321
322         reg = EXYNOS_USB3_PHYUTMI_OTGDISABLE |
323                 EXYNOS_USB3_PHYUTMI_FORCESUSPEND |
324                 EXYNOS_USB3_PHYUTMI_FORCESLEEP;
325         writel(reg, EXYNOS_USB3_PHYUTMI);
326
327         /* Resetting the PHYCLKRST enable bits to reduce leakage current */
328         reg = readl(EXYNOS_USB3_PHYCLKRST);
329         reg &= ~(EXYNOS_USB3_PHYCLKRST_REF_SSP_EN |
330                 EXYNOS_USB3_PHYCLKRST_SSC_EN |
331                 EXYNOS_USB3_PHYCLKRST_COMMONONN);
332         writel(reg, EXYNOS_USB3_PHYCLKRST);
333
334         /* Control PHYTEST to remove leakage current */
335         reg = readl(EXYNOS_USB3_PHYTEST);
336         reg |= (EXYNOS_USB3_PHYTEST_POWERDOWN_SSP |
337                 EXYNOS_USB3_PHYTEST_POWERDOWN_HSP);
338         writel(reg, EXYNOS_USB3_PHYTEST);
339
340         exynos_usb_phy_control(USB_PHY0, PHY_DISABLE);
341
342         exynos_usb_phy_clock_disable(host_clk);
343
344         return 0;
345 }
346
347 static int exynos5_usb_phy20_init(struct platform_device *pdev)
348 {
349         u32 refclk_freq;
350         u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl, ehcictrl;
351         struct clk *host_clk = NULL;
352
353         atomic_inc(&host_usage);
354
355         host_clk = exynos_usb_phy_clock_enable(pdev);
356         if (!host_clk) {
357                 dev_err(&pdev->dev, "Failed to get host_clk\n");
358                 return -ENODEV;
359         }
360
361         if (exynos5_usb_host_phy20_is_on()) {
362                 dev_err(&pdev->dev, "Already power on PHY\n");
363                 return 0;
364         }
365
366         exynos_usb_mux_change(pdev, 1);
367
368         exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);
369
370         /* Host and Device should be set at the same time */
371         hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
372         hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
373         otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
374         otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK);
375
376         /* 2.0 phy reference clock configuration */
377         refclk_freq = exynos_usb_phy_set_clock(pdev);
378         hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT);
379         otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT);
380
381         /* COMMON Block configuration during suspend */
382         hostphy_ctrl0 &= ~(HOST_CTRL0_COMMONON_N);
383         otgphy_sys |= (OTG_SYS_COMMON_ON);
384
385         /* otg phy reset */
386         otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG
387                                                 | OTG_SYS_FORCE_SLEEP);
388         otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK);
389         otgphy_sys |= (OTG_SYS_REF_CLK_SEL(0x2) | OTG_SYS_OTGDISABLE);
390         otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG
391                                                 | OTG_SYS_PHYLINK_SW_RESET);
392         writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
393         udelay(10);
394         otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG
395                                                 | OTG_SYS_PHYLINK_SW_RESET);
396         writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
397         /* host phy reset */
398         hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL
399                                                 | HOST_CTRL0_SIDDQ);
400         hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
401         hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
402         writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
403         udelay(10);
404         hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
405         writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
406
407         /* HSIC phy reset */
408         hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2)
409                                                 | HSIC_CTRL_PHYSWRST);
410         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
411         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
412         udelay(10);
413         hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
414         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
415         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
416
417         udelay(80);
418
419         ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL);
420         ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4
421                                 | EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
422         writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL);
423
424         exynos_usb_phy_clock_disable(host_clk);
425
426         return 0;
427 }
428
429 static int exynos5_usb_phy20_exit(struct platform_device *pdev)
430 {
431         u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl;
432         struct clk *host_clk = NULL;
433
434         if (atomic_dec_return(&host_usage) > 0) {
435                 dev_info(&pdev->dev, "still being used\n");
436                 return -EBUSY;
437         }
438
439         host_clk = exynos_usb_phy_clock_enable(pdev);
440         if (!host_clk) {
441                 dev_err(&pdev->dev, "Failed to get host_clk\n");
442                 return -ENODEV;
443         }
444
445         hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2)
446                                 | HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESLEEP
447                                 | HSIC_CTRL_FORCESUSPEND);
448         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
449         writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
450
451         hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
452         hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ);
453         hostphy_ctrl0 |= (HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
454         hostphy_ctrl0 |= (HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL);
455         writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
456
457         otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
458         otgphy_sys |= (OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG
459                                 | OTG_SYS_FORCE_SLEEP);
460         writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
461
462         exynos_usb_phy_control(USB_PHY1, PHY_DISABLE);
463
464         exynos_usb_phy_clock_disable(host_clk);
465
466         return 0;
467 }
468
469
470 static int exynos4_usb_phy1_init(struct platform_device *pdev)
471 {
472         struct clk *otg_clk;
473         struct clk *xusbxti_clk;
474         u32 phyclk;
475         u32 rstcon;
476         int err;
477
478         atomic_inc(&host_usage);
479
480         otg_clk = clk_get(&pdev->dev, "otg");
481         if (IS_ERR(otg_clk)) {
482                 dev_err(&pdev->dev, "Failed to get otg clock\n");
483                 return PTR_ERR(otg_clk);
484         }
485
486         err = clk_enable(otg_clk);
487         if (err) {
488                 clk_put(otg_clk);
489                 return err;
490         }
491
492         if (exynos4_usb_host_phy_is_on())
493                 return 0;
494
495         writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
496                         S5P_USBHOST_PHY_CONTROL);
497
498         /* set clock frequency for PLL */
499         phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
500
501         xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
502         if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
503                 switch (clk_get_rate(xusbxti_clk)) {
504                 case 12 * MHZ:
505                         phyclk |= CLKSEL_12M;
506                         break;
507                 case 24 * MHZ:
508                         phyclk |= CLKSEL_24M;
509                         break;
510                 default:
511                 case 48 * MHZ:
512                         /* default reference clock */
513                         break;
514                 }
515                 clk_put(xusbxti_clk);
516         }
517
518         writel(phyclk, EXYNOS4_PHYCLK);
519
520         /* floating prevention logic: disable */
521         writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
522
523         /* set to normal HSIC 0 and 1 of PHY1 */
524         writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
525                         EXYNOS4_PHYPWR);
526
527         /* set to normal standard USB of PHY1 */
528         writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
529
530         /* reset all ports of both PHY and Link */
531         rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
532                 PHY1_SWRST_MASK;
533         writel(rstcon, EXYNOS4_RSTCON);
534         udelay(10);
535
536         rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
537         writel(rstcon, EXYNOS4_RSTCON);
538         udelay(80);
539
540         clk_disable(otg_clk);
541         clk_put(otg_clk);
542
543         return 0;
544 }
545
546 static int exynos4_usb_phy1_exit(struct platform_device *pdev)
547 {
548         struct clk *otg_clk;
549         int err;
550
551         if (atomic_dec_return(&host_usage) > 0)
552                 return 0;
553
554         otg_clk = clk_get(&pdev->dev, "otg");
555         if (IS_ERR(otg_clk)) {
556                 dev_err(&pdev->dev, "Failed to get otg clock\n");
557                 return PTR_ERR(otg_clk);
558         }
559
560         err = clk_enable(otg_clk);
561         if (err) {
562                 clk_put(otg_clk);
563                 return err;
564         }
565
566         writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
567                         EXYNOS4_PHYPWR);
568
569         writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
570                         S5P_USBHOST_PHY_CONTROL);
571
572         clk_disable(otg_clk);
573         clk_put(otg_clk);
574
575         return 0;
576 }
577
578 int s5p_usb_phy_init(struct platform_device *pdev, int type)
579 {
580         if (type == S5P_USB_PHY_HOST) {
581                 if (soc_is_exynos5250())
582                         return exynos5_usb_phy20_init(pdev);
583                 else
584                         return exynos4_usb_phy1_init(pdev);
585         } else if (type == S5P_USB_PHY_DRD) {
586                 if (soc_is_exynos5250())
587                         return exynos5_usb_phy30_init(pdev);
588                 else
589                         dev_err(&pdev->dev, "USB 3.0 DRD not present\n");
590         }
591         return -EINVAL;
592 }
593
594 int s5p_usb_phy_exit(struct platform_device *pdev, int type)
595 {
596         if (type == S5P_USB_PHY_HOST) {
597                 if (soc_is_exynos5250())
598                         return exynos5_usb_phy20_exit(pdev);
599                 else
600                         return exynos4_usb_phy1_exit(pdev);
601         } else if (type == S5P_USB_PHY_DRD) {
602                 if (soc_is_exynos5250())
603                         return exynos5_usb_phy30_exit(pdev);
604                 else
605                         dev_err(&pdev->dev, "USB 3.0 DRD not present\n");
606         }
607         return -EINVAL;
608 }