From be33652601b6dc6232338ea8da7638db05e96645 Mon Sep 17 00:00:00 2001 From: yangkai Date: Wed, 22 Dec 2010 17:05:03 +0800 Subject: [PATCH] usb clock gate update --- drivers/usb/dwc_otg/dwc_otg_driver.c | 152 ++++++++++++++++++--------- drivers/usb/dwc_otg/dwc_otg_driver.h | 4 +- drivers/usb/dwc_otg/dwc_otg_pcd.c | 6 +- 3 files changed, 108 insertions(+), 54 deletions(-) diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 9f1e31f6917d..f26074426bbe 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -825,8 +825,12 @@ static int dwc_otg_driver_remove(struct platform_device *pdev) { iounmap(otg_dev->base); } - clk_put(otg_dev->clk); - clk_disable(otg_dev->clk); + clk_put(otg_dev->phyclk); + clk_disable(otg_dev->phyclk); + clk_put(otg_dev->ahbclk); + clk_disable(otg_dev->ahbclk); + clk_put(otg_dev->busclk); + clk_disable(otg_dev->busclk); kfree(otg_dev); /* @@ -863,20 +867,11 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) int32_t snpsid; int irq; int32_t regval; + struct clk *ahbclk,*phyclk,*busclk; + unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); /* *Enable usb phy */ - unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - struct clk* clk; - - clk = clk_get(NULL, "otgphy0"); - if (IS_ERR(clk)) { - retval = PTR_ERR(clk); - DWC_ERROR("can't get USB clock of otgphy0\n"); - goto fail; - } - clk_enable(clk); - regval = * otg_phy_con1; regval |= (0x01<<2); regval |= (0x01<<3); // exit suspend. @@ -908,7 +903,34 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; - dwc_otg_device->clk = clk; + + busclk = clk_get(NULL, "usb"); + if (IS_ERR(busclk)) { + retval = PTR_ERR(busclk); + DWC_ERROR("can't get USB PERIPH AHB bus clock\n"); + goto fail; + } + clk_enable(busclk); + + phyclk = clk_get(NULL, "otgphy0"); + if (IS_ERR(phyclk)) { + retval = PTR_ERR(phyclk); + DWC_ERROR("can't get USBPHY0 clock\n"); + goto fail; + } + clk_enable(phyclk); + + ahbclk = clk_get(NULL, "usbotg0"); + if (IS_ERR(ahbclk)) { + retval = PTR_ERR(ahbclk); + DWC_ERROR("can't get USB otg0 ahb bus clock\n"); + goto fail; + } + clk_enable(ahbclk); + + dwc_otg_device->phyclk = phyclk; + dwc_otg_device->ahbclk = ahbclk; + dwc_otg_device->busclk = busclk; /* * Map the DWC_otg Core memory into virtual address space. */ @@ -1203,8 +1225,10 @@ static int host11_driver_remove(struct platform_device *pdev) { iounmap(otg_dev->base); } - clk_put(otg_dev->clk); - clk_disable(otg_dev->clk); + clk_put(otg_dev->phyclk); + clk_disable(otg_dev->phyclk); + clk_put(otg_dev->ahbclk); + clk_disable(otg_dev->ahbclk); kfree(otg_dev); /* @@ -1234,29 +1258,12 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) dwc_otg_device_t *dwc_otg_device; int32_t snpsid; int irq; + struct clk* ahbclk,*phyclk; /* *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - struct clk* clk; - - clk = clk_get(NULL, "uhost"); - if (IS_ERR(clk)) { - retval = PTR_ERR(clk); - DWC_ERROR("can't get USB clock of uhost\n"); - goto fail; - } - clk_enable(clk); - if (clk_get_rate(clk) != 48000000) { - DWC_PRINT("Bad USB clock (%d Hz), changing to 48000000 Hz\n", - (int)clk_get_rate(clk)); - if (clk_set_rate(clk, 48000000)) { - DWC_ERROR("Unable to set correct USB clock (48MHz)\n"); - retval = -EIO; - goto fail1; - } - } - + *otg_phy_con1 &= ~(0x01<<28); // exit suspend. #if 0 *otg_phy_con1 |= (0x01<<2); @@ -1279,7 +1286,35 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; - dwc_otg_device->clk = clk; + + phyclk = clk_get(NULL, "uhost"); + if (IS_ERR(phyclk)) { + retval = PTR_ERR(phyclk); + DWC_ERROR("can't get UHOST clock\n"); + goto fail; + } + clk_enable(phyclk); + + ahbclk = clk_get(NULL, "uhost_ahb"); + if (IS_ERR(ahbclk)) { + retval = PTR_ERR(ahbclk); + DWC_ERROR("can't get UHOST ahb bus clock\n"); + goto fail1; + } + clk_enable(ahbclk); + + if (clk_get_rate(phyclk) != 48000000) { + DWC_PRINT("Bad USB clock (%d Hz), changing to 48000000 Hz\n", + (int)clk_get_rate(phyclk)); + if (clk_set_rate(phyclk, 48000000)) { + DWC_ERROR("Unable to set correct USB clock (48MHz)\n"); + retval = -EIO; + goto fail2; + } + } + dwc_otg_device->ahbclk = ahbclk; + dwc_otg_device->phyclk = phyclk; + /* * Map the DWC_otg Core memory into virtual address space. */ @@ -1393,9 +1428,12 @@ static __devinit int host11_driver_probe(struct platform_device *pdev) DWC_PRINT("host11_driver_probe end, everest\n"); return 0; +fail2: + clk_put(ahbclk); + clk_disable(ahbclk); fail1: - clk_put(clk); - clk_disable(clk); + clk_put(phyclk); + clk_disable(phyclk); fail: devm_kfree(&pdev->dev, dwc_otg_device); @@ -1477,8 +1515,10 @@ static int host20_driver_remove(struct platform_device *pdev) { iounmap(otg_dev->base); } - clk_put(otg_dev->clk); - clk_disable(otg_dev->clk); + clk_put(otg_dev->phyclk); + clk_disable(otg_dev->phyclk); + clk_put(otg_dev->ahbclk); + clk_disable(otg_dev->ahbclk); kfree(otg_dev); /* @@ -1510,20 +1550,12 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) int32_t snpsid; int irq; uint32_t otgreg; + struct clk* ahbclk,*phyclk; /* *Enable usb phy */ unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); - struct clk* clk; - - clk = clk_get(NULL, "otgphy1"); - if (IS_ERR(clk)) { - retval = PTR_ERR(clk); - DWC_ERROR("can't get USB clock of otgphy1\n"); - goto fail; - } - clk_enable(clk); - + otgreg = * otg_phy_con1; otgreg |= (0x01<<13); // software control otgreg |= (0x01<<14); // exit suspend. @@ -1550,7 +1582,25 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) memset(dwc_otg_device, 0, sizeof(*dwc_otg_device)); dwc_otg_device->reg_offset = 0xFFFFFFFF; - dwc_otg_device->clk = clk; + + phyclk = clk_get(NULL, "otgphy1"); + if (IS_ERR(phyclk)) { + retval = PTR_ERR(phyclk); + DWC_ERROR("can't get USBPHY1 clock\n"); + goto fail; + } + clk_enable(phyclk); + + ahbclk = clk_get(NULL, "usbotg1"); + if (IS_ERR(ahbclk)) { + retval = PTR_ERR(ahbclk); + DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); + goto fail; + } + clk_enable(ahbclk); + dwc_otg_device->phyclk = phyclk; + dwc_otg_device->ahbclk = ahbclk; + /* * Map the DWC_otg Core memory into virtual address space. */ diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.h b/drivers/usb/dwc_otg/dwc_otg_driver.h index 702b9744b6ab..3e334d0201e9 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.h +++ b/drivers/usb/dwc_otg/dwc_otg_driver.h @@ -64,7 +64,9 @@ typedef struct dwc_otg_device /** Pointer to the HCD structure. */ struct dwc_otg_hcd *hcd; - struct clk* clk; + struct clk* phyclk; + struct clk* ahbclk; + struct clk* busclk; /** Flag to indicate whether the common IRQ handler is installed. */ uint8_t common_irq_installed; diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index cb0d81d46ab3..be70bd083b84 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -1542,7 +1542,8 @@ int rk28_usb_suspend( int exitsuspend ) unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); if(exitsuspend && (pcd->phy_suspend == 1)) { - clk_enable(pcd->otg_dev->clk); + clk_enable(pcd->otg_dev->ahbclk); + clk_enable(pcd->otg_dev->phyclk); pcd->phy_suspend = 0; *otg_phy_con1 |= (0x01<<2); *otg_phy_con1 |= (0x01<<3); // exit suspend. @@ -1556,7 +1557,8 @@ int rk28_usb_suspend( int exitsuspend ) pcd->phy_suspend = 1; *otg_phy_con1 |= (0x01<<2); *otg_phy_con1 &= ~(0x01<<3); // enter suspend. - clk_disable(pcd->otg_dev->clk); + clk_disable(pcd->otg_dev->phyclk); + clk_disable(pcd->otg_dev->ahbclk); //*otg_phy_con1 &= ~(0x01<<2); //debug_print("disable usb phy\n"); DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); -- 2.34.1