2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
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.
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/err.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>
22 #include <plat/usb-phy.h>
23 #include <plat/regs-usb3-exynos-drd-phy.h>
27 #define EXYNOS4_USB_CFG (S3C_VA_SYS + 0x21C)
28 #define EXYNOS5_USB_CFG S5P_SYSREG(0x0230)
32 USB_PHY0 = (0x1 << 0),
33 USB_PHY1 = (0x1 << 1),
34 USB_PHY_HSIC0 = (0x1 << 1),
35 USB_PHY_HSIC1 = (0x1 << 2),
38 struct exynos_usb_phy {
46 static atomic_t host_usage;
47 static struct exynos_usb_phy usb_phy_control;
48 static DEFINE_SPINLOCK(phy_lock);
50 static int exynos4_usb_host_phy_is_on(void)
52 return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
55 static int exynos5_usb_host_phy20_is_on(void)
57 return (readl(EXYNOS5_PHY_HOST_CTRL0) & HOST_CTRL0_PHYSWRSTALL) ? 0 : 1;
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)
64 struct clk *phy_clk = NULL;
66 if (!soc_is_exynos5250())
69 phy_clk = clk_get(&pdev->dev, "usbhost");
71 if (IS_ERR(phy_clk)) {
72 dev_err(&pdev->dev, "Failed to get phy clock\n");
76 err = clk_enable(phy_clk);
78 dev_err(&pdev->dev, "Failed to enable phy clock\n");
86 static void exynos_usb_phy_clock_disable(struct clk *phy_clk)
92 static void exynos_usb_mux_change(struct platform_device *pdev, int val)
95 if (!soc_is_exynos5250())
98 is_host = readl(EXYNOS5_USB_CFG);
99 writel(val, EXYNOS5_USB_CFG);
101 dev_dbg(&pdev->dev, "Change USB MUX from %s to %s",
102 is_host ? "Host" : "Device", val ? "Host" : "Device");
105 static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on)
107 spin_lock(&phy_lock);
108 if (soc_is_exynos5250()) {
109 if (phy_type & USB_PHY0) {
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);
119 } else if (phy_type & USB_PHY1) {
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);
130 spin_unlock(&phy_lock);
133 static u32 exynos_usb_phy_set_clock(struct platform_device *pdev)
138 ref_clk = clk_get(&pdev->dev, "ext_xtal");
140 if (IS_ERR(ref_clk)) {
141 dev_err(&pdev->dev, "Failed to get reference clock\n");
142 return PTR_ERR(ref_clk);
144 if (soc_is_exynos5250()) {
145 switch (clk_get_rate(ref_clk)) {
147 refclk_freq = EXYNOS5_CLKSEL_9600K;
150 refclk_freq = EXYNOS5_CLKSEL_10M;
153 refclk_freq = EXYNOS5_CLKSEL_12M;
156 refclk_freq = EXYNOS5_CLKSEL_19200K;
159 refclk_freq = EXYNOS5_CLKSEL_20M;
162 refclk_freq = EXYNOS5_CLKSEL_50M;
166 /* default reference clock */
167 refclk_freq = EXYNOS5_CLKSEL_24M;
177 * Sets the phy clk as EXTREFCLK (XXTI) which is internal clock form clock core.
179 static u32 exynos_usb_phy30_set_clock_int(struct platform_device *pdev)
184 refclk = exynos_usb_phy_set_clock(pdev);
186 reg = EXYNOS_USB3_PHYCLKRST_REFCLKSEL_EXT_REF_CLK |
187 EXYNOS_USB3_PHYCLKRST_FSEL(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));
195 case EXYNOS5_CLKSEL_20M:
196 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF |
197 EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x00));
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));
204 case EXYNOS5_CLKSEL_24M:
206 reg |= (EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
207 EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x88));
215 * Sets the phy clk as ref_pad_clk (XusbXTI) which is clock from external PLL.
217 static u32 exynos_usb_phy30_set_clock_ext(struct platform_device *pdev)
221 reg = EXYNOS_USB3_PHYCLKRST_REFCLKSEL_PAD_REF_CLK |
222 EXYNOS_USB3_PHYCLKRST_FSEL_PAD_100MHZ |
223 EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF;
228 static int _exynos5_usb_phy30_init(struct platform_device *pdev,
233 exynos_usb_phy_control(USB_PHY0, PHY_ENABLE);
235 /* Reset USB 3.0 PHY */
236 writel(0x00000000, EXYNOS_USB3_PHYREG0);
241 writel(reg, EXYNOS_USB3_PHYPARAM0);
243 writel(0x03fff81c, EXYNOS_USB3_PHYPARAM1);
244 writel(0x00000000, EXYNOS_USB3_PHYRESUME);
246 /* Setting the Frame length Adj value[6:1] to default 0x20 */
247 writel(0x08000040, EXYNOS_USB3_LINKSYSTEM);
248 writel(0x00000004, EXYNOS_USB3_PHYBATCHG);
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);
256 /* UTMI Power Control */
257 writel(EXYNOS_USB3_PHYUTMI_OTGDISABLE, EXYNOS_USB3_PHYUTMI);
260 reg = exynos_usb_phy30_set_clock_ext(pdev);
262 reg = exynos_usb_phy30_set_clock_int(pdev);
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;
274 writel(reg, EXYNOS_USB3_PHYCLKRST);
278 reg &= ~(EXYNOS_USB3_PHYCLKRST_PORTRESET);
279 writel(reg, EXYNOS_USB3_PHYCLKRST);
284 int exynos5_dwc_phyclk_switch(struct platform_device *pdev, bool use_ext_clk)
286 return _exynos5_usb_phy30_init(pdev, use_ext_clk);
289 static int exynos5_usb_phy30_init(struct platform_device *pdev)
292 struct clk *host_clk = NULL;
294 host_clk = exynos_usb_phy_clock_enable(pdev);
296 dev_err(&pdev->dev, "Failed to enable USB3.0 host clock\n");
301 * We'll start out with the XusbXTI turned on
302 * for phy reference clock refclksel [3:2]
304 ret = _exynos5_usb_phy30_init(pdev, true);
306 exynos_usb_phy_clock_disable(host_clk);
311 static int exynos5_usb_phy30_exit(struct platform_device *pdev)
314 struct clk *host_clk = NULL;
316 host_clk = exynos_usb_phy_clock_enable(pdev);
318 dev_err(&pdev->dev, "Failed to enable USB3.0 host clock\n");
322 reg = EXYNOS_USB3_PHYUTMI_OTGDISABLE |
323 EXYNOS_USB3_PHYUTMI_FORCESUSPEND |
324 EXYNOS_USB3_PHYUTMI_FORCESLEEP;
325 writel(reg, EXYNOS_USB3_PHYUTMI);
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);
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);
340 exynos_usb_phy_control(USB_PHY0, PHY_DISABLE);
342 exynos_usb_phy_clock_disable(host_clk);
347 static int exynos5_usb_phy20_init(struct platform_device *pdev)
350 u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl, ehcictrl;
351 struct clk *host_clk = NULL;
353 atomic_inc(&host_usage);
355 host_clk = exynos_usb_phy_clock_enable(pdev);
357 dev_err(&pdev->dev, "Failed to get host_clk\n");
361 if (exynos5_usb_host_phy20_is_on()) {
362 dev_err(&pdev->dev, "Already power on PHY\n");
366 exynos_usb_mux_change(pdev, 1);
368 exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);
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);
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);
381 /* COMMON Block configuration during suspend */
382 hostphy_ctrl0 &= ~(HOST_CTRL0_COMMONON_N);
383 otgphy_sys |= (OTG_SYS_COMMON_ON);
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);
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);
398 hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL
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);
404 hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
405 writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
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);
413 hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
414 writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
415 writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
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);
424 exynos_usb_phy_clock_disable(host_clk);
429 static int exynos5_usb_phy20_exit(struct platform_device *pdev)
431 u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl;
432 struct clk *host_clk = NULL;
434 if (atomic_dec_return(&host_usage) > 0) {
435 dev_info(&pdev->dev, "still being used\n");
439 host_clk = exynos_usb_phy_clock_enable(pdev);
441 dev_err(&pdev->dev, "Failed to get host_clk\n");
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);
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);
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);
462 exynos_usb_phy_control(USB_PHY1, PHY_DISABLE);
464 exynos_usb_phy_clock_disable(host_clk);
470 static int exynos4_usb_phy1_init(struct platform_device *pdev)
473 struct clk *xusbxti_clk;
478 atomic_inc(&host_usage);
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);
486 err = clk_enable(otg_clk);
492 if (exynos4_usb_host_phy_is_on())
495 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
496 S5P_USBHOST_PHY_CONTROL);
498 /* set clock frequency for PLL */
499 phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
501 xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
502 if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
503 switch (clk_get_rate(xusbxti_clk)) {
505 phyclk |= CLKSEL_12M;
508 phyclk |= CLKSEL_24M;
512 /* default reference clock */
515 clk_put(xusbxti_clk);
518 writel(phyclk, EXYNOS4_PHYCLK);
520 /* floating prevention logic: disable */
521 writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
523 /* set to normal HSIC 0 and 1 of PHY1 */
524 writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
527 /* set to normal standard USB of PHY1 */
528 writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
530 /* reset all ports of both PHY and Link */
531 rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
533 writel(rstcon, EXYNOS4_RSTCON);
536 rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
537 writel(rstcon, EXYNOS4_RSTCON);
540 clk_disable(otg_clk);
546 static int exynos4_usb_phy1_exit(struct platform_device *pdev)
551 if (atomic_dec_return(&host_usage) > 0)
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);
560 err = clk_enable(otg_clk);
566 writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
569 writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
570 S5P_USBHOST_PHY_CONTROL);
572 clk_disable(otg_clk);
578 int s5p_usb_phy_init(struct platform_device *pdev, int type)
580 if (type == S5P_USB_PHY_HOST) {
581 if (soc_is_exynos5250())
582 return exynos5_usb_phy20_init(pdev);
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);
589 dev_err(&pdev->dev, "USB 3.0 DRD not present\n");
594 int s5p_usb_phy_exit(struct platform_device *pdev, int type)
596 if (type == S5P_USB_PHY_HOST) {
597 if (soc_is_exynos5250())
598 return exynos5_usb_phy20_exit(pdev);
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);
605 dev_err(&pdev->dev, "USB 3.0 DRD not present\n");