summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc
diff options
context:
space:
mode:
authorDinh Nguyen <Dinh.Nguyen@freescale.com>2010-03-18 14:48:45 -0500
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-05-25 11:20:13 +0200
commitcca02bb8eed2e3ce1520cfb0c7f7860edfe3b99c (patch)
treeed920b0193dea280dedfec1ed095f993d848cf71 /arch/arm/plat-mxc
parentf5f6182ae75da1981f3fc50798a630af5e63349e (diff)
ENGR00121651 MX53: Add support for USB
Move USB initialization to be board specific functions and add USB support for MX53. Renamed USB phy clocks to usb_phy1_clk and usb_phy2_clk to distinguish between different PHY clocks for USB. Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com> Signed-off-by: Jun Li <r65092@freescale.com> Signed-off-by: Alejandro Gonzalez <alex.gonzalez@digi.com>
Diffstat (limited to 'arch/arm/plat-mxc')
-rw-r--r--arch/arm/plat-mxc/include/mach/arc_otg.h4
-rw-r--r--arch/arm/plat-mxc/usb_common.c80
2 files changed, 78 insertions, 6 deletions
diff --git a/arch/arm/plat-mxc/include/mach/arc_otg.h b/arch/arm/plat-mxc/include/mach/arc_otg.h
index 0e834fe0b9fa..1b2511079560 100644
--- a/arch/arm/plat-mxc/include/mach/arc_otg.h
+++ b/arch/arm/plat-mxc/include/mach/arc_otg.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -145,6 +145,8 @@
#define USB_CTRL_1 USBOTHER_REG(0x10) /* USB Cotrol Register 1*/
#define USBCTRL_HOST2 USBOTHER_REG(0x14) /* USB Cotrol Register 1*/
#define USBCTRL_HOST3 USBOTHER_REG(0x18) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL0 USBOTHER_REG(0x1c) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL1 USBOTHER_REG(0x20) /* USB Cotrol Register 1*/
/*
* register bits
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
index 8b69ad9ab52e..c8b8ba41b559 100644
--- a/arch/arm/plat-mxc/usb_common.c
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -261,6 +261,68 @@ static void usbh1_set_ulpi_xcvr(void)
/* Turn off the usbpll for ulpi tranceivers */
clk_disable(usb_clk);
}
+
+static void usbh1_set_utmi_xcvr(void)
+{
+ u32 tmp;
+
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while ((UH1_USBCMD) & (UCMD_RESET))
+ ;
+
+ /* MX53 EVK is not using OC */
+ USB_PHY_CTR_FUNC |= USB_UH1_OC_DIS;
+
+ USBCTRL &= ~UCTRL_H1PM; /* OTG Power Mask */
+ USBCTRL &= ~UCTRL_H1WIE; /* OTG Wakeup Intr Disable */
+
+ /* Over current disable */
+ USB_PHY_CTR_FUNC |= (0x1 << 5);
+
+ /* set UTMI xcvr */
+ tmp = UH1_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_UTMI;
+ UH1_PORTSC1 = tmp;
+
+ /* Set the PHY clock to 19.2MHz */
+ USBH1_PHY_CTRL1 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
+ USBH1_PHY_CTRL1 |= 0x01;
+
+ /* Workaround an IC issue for ehci driver:
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTW with 0
+ * means 8 bits tranceiver width, here change
+ * it back to be 16 bits and do PHY diable and
+ * then enable.
+ */
+ UH1_PORTSC1 |= PORTSC_PTW;
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while ((UH1_USBCMD) & (UCMD_RESET))
+ ;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for UTMI tranceivers */
+ clk_disable(usb_clk);
+}
+
static void usbh2_set_ulpi_xcvr(void)
{
u32 tmp;
@@ -410,7 +472,7 @@ int fsl_usb_host_init(struct platform_device *pdev)
return -EINVAL;
pr_debug("%s: grab pins\n", __func__);
- if (pdata->gpio_usb_active())
+ if (pdata->gpio_usb_active && pdata->gpio_usb_active())
return -EINVAL;
if (clk_enable(usb_clk)) {
@@ -452,6 +514,8 @@ int fsl_usb_host_init(struct platform_device *pdev)
usbh1_set_ulpi_xcvr();
if (!strcmp("Host 2", pdata->name))
usbh2_set_ulpi_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_UTMI) {
+ usbh1_set_utmi_xcvr();
}
pr_debug("%s: %s success\n", __func__, pdata->name);
@@ -468,7 +532,8 @@ void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata)
pdata->regs = NULL;
- pdata->gpio_usb_inactive();
+ if (pdata->gpio_usb_inactive)
+ pdata->gpio_usb_inactive();
if (pdata->xcvr_type == PORTSC_PTS_SERIAL) {
/* Workaround an IC issue for ehci driver.
* when turn off root hub port power, EHCI set
@@ -624,6 +689,9 @@ static void otg_set_utmi_xcvr(void)
UOG_USBCMD |= UCMD_RESET;
while ((UOG_USBCMD) & (UCMD_RESET)) ;
+ if (cpu_is_mx53())
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS;
+
if (cpu_is_mx51()) {
if (machine_is_mx51_3ds()) {
/* OTG Polarity of Overcurrent is Low active */
@@ -648,7 +716,8 @@ static void otg_set_utmi_xcvr(void)
USBCTRL |= UCTRL_OLOCKD;
}
- USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */
+ if (!cpu_is_mx53())
+ USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */
USBCTRL &= ~UCTRL_OWIE; /* OTG Wakeup Intr Disable */
/* set UTMI xcvr */
@@ -730,7 +799,7 @@ int usbotg_init(struct platform_device *pdev)
return -EINVAL;
pr_debug("%s: grab pins\n", __func__);
- if (pdata->gpio_usb_active())
+ if (pdata->gpio_usb_active && pdata->gpio_usb_active())
return -EINVAL;
if (clk_enable(usb_clk)) {
@@ -785,7 +854,8 @@ void usbotg_uninit(struct fsl_usb2_platform_data *pdata)
}
msleep(1);
UOG_PORTSC1 = UOG_PORTSC1 | PORTSC_PHCD;
- pdata->gpio_usb_inactive();
+ if (pdata->gpio_usb_inactive)
+ pdata->gpio_usb_inactive();
if (pdata->xcvr_type == PORTSC_PTS_SERIAL)
clk_disable(usb_clk);
clk_disable(usb_ahb_clk);