diff options
author | Peter Chen <peter.chen@freescale.com> | 2011-07-11 18:24:50 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:14:21 +0800 |
commit | 9cce1de108015b4befc84281bde0db1347150ac2 (patch) | |
tree | b3caa028038ef6860c7ef0b9db8b32fc30ac148a /arch | |
parent | 1c5b416a4705faee39825e6ab0c39d5289747f9a (diff) |
ENGR00152915-1 mx6q-usb: refine usb phy usage
(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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabreauto.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-mx6/clock.c | 34 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_dr.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_h1.c | 27 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/usb_wakeup.c | 3 |
5 files changed, 37 insertions, 53 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 23a5b07c38eb..9791f676f7e0 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -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) { diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 394bf2bb4140..3f20e453bbd7 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -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), }; diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index c2441c7ad8e6..d9b16a1c1a28 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -26,11 +26,16 @@ #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); } diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index 2261235fe879..353b79fd2051 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -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); } diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c index d55abc47d10b..9afd479aaf19 100755 --- a/arch/arm/plat-mxc/usb_wakeup.c +++ b/arch/arm/plat-mxc/usb_wakeup.c @@ -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) { |