]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00152915-1 mx6q-usb: refine usb phy usage
authorPeter Chen <peter.chen@freescale.com>
Mon, 11 Jul 2011 10:24:50 +0000 (18:24 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:32:57 +0000 (08:32 +0200)
(Fixed the bug that PLL7 lock failed after usb enters low power mode)
After confirming with IC guys, the phy clock should be used
like below:
- OTG phy clock
EN_USB_CLKS: should be also enabled
PLL3 power: Enable/Disable on the fly
- Host1 phy clock
EN_USB_CLKS and PLL7 power should be also enabled at the initialization
PLL7 power will be totally controller by IC

Signed-off-by: Peter Chen <peter.chen@freescale.com>
arch/arm/mach-mx6/board-mx6q_sabreauto.c
arch/arm/mach-mx6/clock.c
arch/arm/mach-mx6/usb_dr.c
arch/arm/mach-mx6/usb_h1.c
arch/arm/plat-mxc/usb_wakeup.c

index 23a5b07c38eb07a2fce27c34cf5e05361f768005..9791f676f7e0f3eec26adf016ef69c7f6a6a546b 100644 (file)
@@ -63,7 +63,6 @@
 
 #include "usb.h"
 #include "devices-imx6q.h"
-#include "regs-anadig.h"
 #include "crm_regs.h"
 
 #define MX6Q_SABREAUTO_ECSPI1_CS0      IMX_GPIO_NR(2, 30)
@@ -288,16 +287,9 @@ static void imx6q_sabreauto_usbotg_vbus(bool on)
 static void __init imx6q_sabreauto_init_usb(void)
 {
        int ret = 0;
-       void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
 
        imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
        /* disable external charger detect, or it will affect signal quality at dp */
-       __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B  \
-                       | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B,  \
-                       anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT);
-       __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B  \
-                       | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
-                       anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
 
        ret = gpio_request(MX6Q_SABREAUTO_USB_OTG_PWR, "usb-pwr");
        if (ret) {
index 394bf2bb414006873135c0137ab497ae096e03a5..3f20e453bbd7ade549d29f3e0b5a564db146c746 100644 (file)
@@ -328,20 +328,6 @@ static void _clk_pfd_disable(struct clk *clk)
                apbh_dma_clk.disable(&apbh_dma_clk);
 }
 
-static void _clk_usb_phy_enable(struct clk *clk)
-{
-       u32 usb_phy_reg;
-       usb_phy_reg = __raw_readl(clk->enable_reg);
-       __raw_writel(usb_phy_reg | clk->enable_shift, clk->enable_reg);
-}
-
-static void _clk_usb_phy_disable(struct clk *clk)
-{
-       u32 usb_phy_reg;
-       usb_phy_reg = __raw_readl(clk->enable_reg);
-       __raw_writel(usb_phy_reg & (~clk->enable_shift), clk->enable_reg);
-}
-
 static int _clk_pll_enable(struct clk *clk)
 {
        unsigned int reg;
@@ -383,7 +369,7 @@ static void _clk_pll_disable(struct clk *clk)
        reg &= ~ANADIG_PLL_ENABLE;
        reg |= ANADIG_PLL_BYPASS;
        reg |= ANADIG_PLL_POWER_DOWN;
-       if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk)
+       if (clk == &pll3_usb_otg_main_clk)
                reg &= ~ANADIG_PLL_POWER_DOWN;
        __raw_writel(reg, pllbase);
 }
@@ -610,13 +596,8 @@ static struct clk pll3_usb_otg_main_clk = {
 static struct clk usb_phy1_clk = {
        __INIT_CLK_DEBUG(usb_phy1_clk)
        .parent = &pll3_usb_otg_main_clk,
-       .enable = _clk_usb_phy_enable,
-       .disable = _clk_usb_phy_disable,
-       .enable_reg = (void *)PLL3_480_USB1_BASE_ADDR,
-       .enable_shift = ANADIG_PLL_480_EN_USB_CLKS,
        .set_rate = _clk_pll3_usb_otg_set_rate,
        .get_rate = _clk_pll3_usb_otg_get_rate,
-
 };
 
 static struct clk pll3_pfd_508M = {
@@ -777,18 +758,6 @@ static struct clk pll7_usb_host_main_clk = {
 
 };
 
-static struct clk usb_phy2_clk = {
-       __INIT_CLK_DEBUG(usb_phy2_clk)
-       .parent = &pll7_usb_host_main_clk,
-       .enable = _clk_usb_phy_enable,
-       .disable = _clk_usb_phy_disable,
-       .enable_reg = (void *)PLL7_480_USB2_BASE_ADDR,
-       .enable_shift = ANADIG_PLL_480_EN_USB_CLKS,
-       .set_rate = _clk_pll7_usb_otg_set_rate,
-       .get_rate = _clk_pll7_usb_otg_get_rate,
-
-};
-
 static struct clk pll8_enet_main_clk = {
        __INIT_CLK_DEBUG(pll8_enet_main_clk)
        .parent = &osc_clk,
@@ -3989,7 +3958,6 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "imx_sata_clk", sata_clk),
        _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
        _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy1_clk),
-       _REGISTER_CLOCK(NULL, "usb_phy2_clk", usb_phy2_clk),
        _REGISTER_CLOCK(NULL, "video_27M_clk", video_27M_clk),
 };
 
index c2441c7ad8e6745b571656d400ed6f9f15f70881..d9b16a1c1a285c198ade518a1a03965fcb60de59 100644 (file)
 #include <mach/arc_otg.h>
 #include <mach/hardware.h>
 #include "devices-imx6q.h"
+#include "regs-anadig.h"
 #include "usb.h"
 static int usbotg_init_ext(struct platform_device *pdev);
 static void usbotg_uninit_ext(struct platform_device *pdev);
 static void usbotg_clock_gate(bool on);
 
+/* The usb_phy1_clk do not have enable/disable function at clock.c
+ * and PLL output for usb1's phy should be always enabled.
+ * usb_phy1_clk only stands for usb uses pll3 as its parent.
+ */
 static struct clk *usb_phy1_clk;
 static struct clk *usb_oh3_clk;
 static void usbotg_wakeup_event_clear(void);
@@ -409,6 +414,7 @@ static void device_wakeup_handler(struct fsl_usb2_platform_data *pdata)
 void __init mx6_usb_dr_init(void)
 {
        struct platform_device *pdev;
+       static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
 #ifdef CONFIG_USB_OTG
        /* wake_up_enable is useless, just for usb_register_remote_wakeup execution*/
        dr_utmi_config.wake_up_enable = _device_wakeup_enable;
@@ -439,4 +445,16 @@ void __init mx6_usb_dr_init(void)
 #endif
        /* register wakeup device */
        imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config);
+       /* Some phy and power's special controls for otg
+        * 1. The external charger detector needs to be disabled
+        * or the signal at DP will be poor
+        * 2. The EN_USB_CLKS is always enabled.
+        * The PLL's power is controlled by usb and others who
+        * use pll3 too.
+        */
+       __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B  \
+                       | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B,  \
+                       anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT);
+       __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+                       anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
 }
index 2261235fe879e84041bdc92f3705b0c8f2ff64f2..353b79fd2051efa477e592696293ffca182b1349 100644 (file)
@@ -28,9 +28,9 @@
 #include <mach/arc_otg.h>
 #include <mach/hardware.h>
 #include "devices-imx6q.h"
+#include "regs-anadig.h"
 #include "usb.h"
 
-static struct clk *usb_phy2_clk;
 static struct clk *usb_oh3_clk;
 extern int clk_get_usecount(struct clk *clk);
 static struct fsl_usb2_platform_data usbh1_config;
@@ -89,10 +89,6 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev)
        clk_enable(usb_clk);
        usb_oh3_clk = usb_clk;
 
-       usb_clk = clk_get(NULL, "usb_phy2_clk");
-       clk_enable(usb_clk);
-       usb_phy2_clk = usb_clk;
-
        ret = fsl_usb_host_init(pdev);
        if (ret) {
                printk(KERN_ERR "host1 init fails......\n");
@@ -113,9 +109,6 @@ static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
        clk_disable(usb_oh3_clk);
        clk_put(usb_oh3_clk);
 
-       clk_disable(usb_phy2_clk);
-       clk_put(usb_phy2_clk);
-
 }
 
 static void usbh1_clock_gate(bool on)
@@ -123,9 +116,7 @@ static void usbh1_clock_gate(bool on)
        pr_debug("%s: on is %d\n", __func__, on);
        if (on) {
                clk_enable(usb_oh3_clk);
-               clk_enable(usb_phy2_clk);
        } else {
-               clk_disable(usb_phy2_clk);
                clk_disable(usb_oh3_clk);
        }
 }
@@ -260,8 +251,24 @@ static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = {
 
 void __init mx6_usb_h1_init(void)
 {
+       static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
        imx6q_add_fsl_ehci_hs(1, &usbh1_config);
        usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
        imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
+       /* Some phy and power's special controls for host1
+        * 1. The external charger detector needs to be disabled
+        * or the signal at DP will be poor
+        * 2. The PLL's power and output to usb for host 1
+        * is totally controlled by IC, so the Software only needs
+        * to enable them at initializtion.
+        */
+       __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B  \
+                       | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
+                       anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
+
+       __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE  \
+                       | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
+                       | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
+                       anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
 }
 
index d55abc47d10b5d6dadfd55c78359068e4b9d7d76..9afd479aaf191f59b54baab5de15badde76dd873 100755 (executable)
@@ -85,7 +85,7 @@ static irqreturn_t usb_wakeup_handler(int irq, void *_dev)
        struct wakeup_ctrl *ctrl = (struct wakeup_ctrl *)_dev;
        irqreturn_t ret = IRQ_NONE;
        if (usb2_is_in_lowpower(ctrl)) {
-               printk("usb wakeup is here\n");
+               pr_debug("usb wakeup is here\n");
                delay_process_wakeup(ctrl);
                ret = IRQ_HANDLED;
        }
@@ -109,7 +109,6 @@ static void wakeup_event_handler(struct wakeup_ctrl *ctrl)
 
        wakeup_clk_gate(ctrl->pdata, true);
 
-recheck:
        for (i = 0; i < 3; i++) {
                struct fsl_usb2_platform_data *usb_pdata = pdata->usb_pdata[i];
                if (usb_pdata) {