summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2011-07-11 18:24:50 +0800
committerPeter Chen <peter.chen@freescale.com>2011-07-11 18:47:21 +0800
commit4bd94809e3934eb52e8ee0a9129396975b2e6b1a (patch)
tree82c63032116b5210d9ac2a1f05f4c7104a808e33 /arch
parent647144424958b5079c26cdcd057e045d1c79869c (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.c8
-rw-r--r--arch/arm/mach-mx6/clock.c34
-rw-r--r--arch/arm/mach-mx6/usb_dr.c18
-rw-r--r--arch/arm/mach-mx6/usb_h1.c27
-rw-r--r--arch/arm/plat-mxc/usb_wakeup.c3
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 100644
--- 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) {