CHROMIUM: usb: dwc3: allow to configure the XHCI to use the internal clock
authorVincent Palatin <vpalatin@chromium.org>
Tue, 27 Nov 2012 00:13:41 +0000 (16:13 -0800)
committerGerrit <chrome-bot@google.com>
Tue, 27 Nov 2012 19:24:23 +0000 (11:24 -0800)
Remove the hardcoded assumption that we have an external PLL for the USB3 clock.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:16351
TEST=on Spring, plug on usb key on USB3 port and browse the content.

Change-Id: I0bf2a3604b3009abbcdfe3b0daf9d7fcccf1438c
Reviewed-on: https://gerrit.chromium.org/gerrit/38684
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Todd Broch <tbroch@chromium.org>
Reviewed-by: Olof Johansson <olofj@chromium.org>
Commit-Ready: Vincent Palatin <vpalatin@chromium.org>

arch/arm/mach-exynos/setup-usb-phy.c
arch/arm/plat-samsung/include/plat/usb-phy.h
drivers/usb/dwc3/dwc3-exynos.c
include/linux/platform_data/dwc3-exynos.h

index e944ff4..635d90b 100644 (file)
@@ -286,7 +286,7 @@ int exynos5_dwc_phyclk_switch(struct platform_device *pdev, bool use_ext_clk)
        return _exynos5_usb_phy30_init(pdev, use_ext_clk);
 }
 
-static int exynos5_usb_phy30_init(struct platform_device *pdev)
+static int exynos5_usb_phy30_init(struct platform_device *pdev, bool ext_clk)
 {
        int ret;
        struct clk *host_clk = NULL;
@@ -297,11 +297,7 @@ static int exynos5_usb_phy30_init(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       /*
-        * We'll start out with the XusbXTI turned on
-        * for phy reference clock refclksel [3:2]
-        */
-       ret = _exynos5_usb_phy30_init(pdev, true);
+       ret = _exynos5_usb_phy30_init(pdev, ext_clk);
 
        exynos_usb_phy_clock_disable(host_clk);
 
@@ -575,7 +571,7 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev)
        return 0;
 }
 
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
+int s5p_usb_phy_init(struct platform_device *pdev, int type, bool ext_clk)
 {
        if (type == S5P_USB_PHY_HOST) {
                if (soc_is_exynos5250())
@@ -584,7 +580,7 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type)
                        return exynos4_usb_phy1_init(pdev);
        } else if (type == S5P_USB_PHY_DRD) {
                if (soc_is_exynos5250())
-                       return exynos5_usb_phy30_init(pdev);
+                       return exynos5_usb_phy30_init(pdev, ext_clk);
                else
                        dev_err(&pdev->dev, "USB 3.0 DRD not present\n");
        }
index 6836a5c..d6e781b 100644 (file)
@@ -17,7 +17,8 @@ enum s5p_usb_phy_type {
        S5P_USB_PHY_DRD,
 };
 
-extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_init(struct platform_device *pdev, int type,
+                                               bool use_ext_clk);
 extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
 extern int exynos5_dwc_phyclk_switch(struct platform_device *pdev,
                                                bool use_ext_clk);
index 3167710..f26a59f 100644 (file)
@@ -161,8 +161,13 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
        if (!pdata) {
                dev_dbg(&pdev->dev, "missing platform data\n");
        } else {
+               /*
+                * if we have no gpio to control external PLL, we are using
+                * the internal clock.
+                */
                if (pdata->phy_init)
-                       pdata->phy_init(pdev, pdata->phy_type);
+                       pdata->phy_init(pdev, pdata->phy_type,
+                                       gpio_is_valid(exynos->phyclk_gpio));
        }
 
        pm_runtime_set_active(&pdev->dev);
@@ -232,15 +237,16 @@ static int dwc3_exynos_runtime_suspend(struct device *dev)
 
        dev_dbg(dev, "entering runtime suspend\n");
 
-       if (!pdata) {
-               dev_dbg(&pdev->dev, "missing platform data\n");
-       } else {
-               if (pdata->phyclk_switch)
-                       pdata->phyclk_switch(pdev, false);
-       }
+       if (gpio_is_valid(exynos->phyclk_gpio)) {
+               if (!pdata) {
+                       dev_dbg(&pdev->dev, "missing platform data\n");
+               } else {
+                       if (pdata->phyclk_switch)
+                               pdata->phyclk_switch(pdev, false);
+               }
 
-       if (gpio_is_valid(exynos->phyclk_gpio))
                gpio_set_value(exynos->phyclk_gpio, 0);
+       }
 
        return 0;
 }
@@ -263,13 +269,13 @@ static int dwc3_exynos_runtime_resume(struct device *dev)
                 * and cross our fingers that it's enough.
                 */
                msleep(10);
-       }
 
-       if (!pdata) {
-               dev_dbg(&pdev->dev, "missing platform data\n");
-       } else {
-               if (pdata->phyclk_switch)
-                       pdata->phyclk_switch(pdev, true);
+               if (!pdata) {
+                       dev_dbg(&pdev->dev, "missing platform data\n");
+               } else {
+                       if (pdata->phyclk_switch)
+                               pdata->phyclk_switch(pdev, true);
+               }
        }
 
        return 0;
@@ -335,7 +341,8 @@ static int dwc3_exynos_resume(struct device *dev)
                dev_dbg(&pdev->dev, "missing platform data\n");
        } else {
                if (pdata->phy_init)
-                       pdata->phy_init(pdev, pdata->phy_type);
+                       pdata->phy_init(pdev, pdata->phy_type,
+                                       gpio_is_valid(exynos->phyclk_gpio));
        }
 
        /* runtime set active to reflect active state. */
index e2c6c86..e8b0f19 100644 (file)
@@ -17,7 +17,7 @@
 
 struct dwc3_exynos_data {
        int phy_type;
-       int (*phy_init)(struct platform_device *pdev, int type);
+       int (*phy_init)(struct platform_device *pdev, int type, bool ext_clk);
        int (*phy_exit)(struct platform_device *pdev, int type);
        int (*phyclk_switch)(struct platform_device *pdev, bool use_ext_clk);
 };