usb: tegra: set sclk rate
authorPrashant Gaikwad <pgaikwad@nvidia.com>
Tue, 26 Apr 2011 05:34:48 +0000 (11:04 +0530)
committerVarun Colbert <vcolbert@nvidia.com>
Tue, 10 May 2011 23:05:30 +0000 (16:05 -0700)
sclk minimum rate is set to 40MHz which is less than required by usb.
set sclk rate to 80MHz when usb is connected and disable sclk when usb is
not connected so that sclk will get clocked at minimum rate.

Bug 819796

Reviewed-on: http://git-master/r/28766
(cherry picked from commit e705e6b448791ef938a0897755205cdde72fa361)

Change-Id: I180d044f788e153d0057355e22ed422f32552d5c
Reviewed-on: http://git-master/r/30818
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Prashant Gaikwad <pgaikwad@nvidia.com>
drivers/usb/gadget/fsl_tegra_udc.c
drivers/usb/host/ehci-tegra.c

index 14e62f40a50a50d0923c2e46220af98bdb0642cc..8589ef78103939250ee8d61991e0d151fccbc3a2 100644 (file)
@@ -16,6 +16,7 @@
 static struct tegra_usb_phy *phy;
 static struct clk *udc_clk;
 static struct clk *emc_clk;
+static struct clk *sclk_clk;
 static void *udc_base;
 
 int fsl_udc_clk_init(struct platform_device *pdev)
@@ -34,6 +35,16 @@ int fsl_udc_clk_init(struct platform_device *pdev)
 
        clk_enable(udc_clk);
 
+       sclk_clk = clk_get(&pdev->dev, "sclk");
+       if (IS_ERR(sclk_clk)) {
+               dev_err(&pdev->dev, "Can't get sclk clock\n");
+               err = PTR_ERR(sclk_clk);
+               goto err_sclk;
+       }
+
+       clk_set_rate(sclk_clk, 80000000);
+       clk_enable(sclk_clk);
+
        emc_clk = clk_get(&pdev->dev, "emc");
        if (IS_ERR(emc_clk)) {
                dev_err(&pdev->dev, "Can't get emc clock\n");
@@ -79,6 +90,9 @@ err0:
        clk_disable(emc_clk);
        clk_put(emc_clk);
 err_emc:
+       clk_disable(sclk_clk);
+       clk_put(sclk_clk);
+err_sclk:
        clk_disable(udc_clk);
        clk_put(udc_clk);
        return err;
@@ -97,6 +111,9 @@ void fsl_udc_clk_release(void)
        clk_disable(udc_clk);
        clk_put(udc_clk);
 
+       clk_disable(sclk_clk);
+       clk_put(sclk_clk);
+
        clk_disable(emc_clk);
        clk_put(emc_clk);
 }
@@ -105,12 +122,14 @@ void fsl_udc_clk_suspend(void)
 {
        tegra_usb_phy_power_off(phy);
        clk_disable(udc_clk);
+       clk_disable(sclk_clk);
        clk_disable(emc_clk);
 }
 
 void fsl_udc_clk_resume(void)
 {
        clk_enable(emc_clk);
+       clk_enable(sclk_clk);
        clk_enable(udc_clk);
        tegra_usb_phy_power_on(phy);
 }
index a81046b93af7552ce76849be006db0bdbdea2206..fab9edb4cc99adf5af1e4b4517d249b89485cc76 100644 (file)
@@ -43,6 +43,7 @@ struct tegra_ehci_hcd {
        struct tegra_usb_phy *phy;
        struct clk *clk;
        struct clk *emc_clk;
+       struct clk *sclk_clk;
        struct otg_transceiver *transceiver;
        int host_resumed;
        int bus_suspended;
@@ -57,6 +58,7 @@ static void tegra_ehci_power_up(struct usb_hcd *hcd)
        struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
 
        clk_enable(tegra->emc_clk);
+       clk_enable(tegra->sclk_clk);
        clk_enable(tegra->clk);
        tegra_usb_phy_power_on(tegra->phy);
        tegra->host_resumed = 1;
@@ -69,6 +71,7 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
        tegra->host_resumed = 0;
        tegra_usb_phy_power_off(tegra->phy);
        clk_disable(tegra->clk);
+       clk_disable(tegra->sclk_clk);
        clk_disable(tegra->emc_clk);
 }
 
@@ -836,6 +839,17 @@ static int tegra_ehci_probe(struct platform_device *pdev)
        if (err)
                goto fail_clken;
 
+
+       tegra->sclk_clk = clk_get(&pdev->dev, "sclk");
+       if (IS_ERR(tegra->sclk_clk)) {
+               dev_err(&pdev->dev, "Can't get sclk clock\n");
+               err = PTR_ERR(tegra->sclk_clk);
+               goto fail_sclk_clk;
+       }
+
+       clk_set_rate(tegra->sclk_clk, 80000000);
+       clk_enable(tegra->sclk_clk);
+
        tegra->emc_clk = clk_get(&pdev->dev, "emc");
        if (IS_ERR(tegra->emc_clk)) {
                dev_err(&pdev->dev, "Can't get emc clock\n");
@@ -930,6 +944,9 @@ fail_io:
        clk_disable(tegra->emc_clk);
        clk_put(tegra->emc_clk);
 fail_emc_clk:
+       clk_disable(tegra->sclk_clk);
+       clk_put(tegra->sclk_clk);
+fail_sclk_clk:
        clk_disable(tegra->clk);
 fail_clken:
        clk_put(tegra->clk);
@@ -1002,6 +1019,9 @@ static int tegra_ehci_remove(struct platform_device *pdev)
        clk_disable(tegra->clk);
        clk_put(tegra->clk);
 
+       clk_disable(tegra->sclk_clk);
+       clk_put(tegra->sclk_clk);
+
        clk_disable(tegra->emc_clk);
        clk_put(tegra->emc_clk);