summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx5
diff options
context:
space:
mode:
authorHu hui <b29976@freescale.com>2010-10-08 11:08:40 +0800
committerHu Hui <b29976@freescale.com>2010-10-09 11:11:07 +0800
commitc885c13754ed958d1b2042d933d2b5c5868f7e88 (patch)
tree70cb0d292c972dd04c98dcb9ada7400febb2d74a /arch/arm/mach-mx5
parent3ef7a7f4227970a4fb048b08d3f1d7bbbd3836ed (diff)
ENGR00132377 I.MX53 USB: enable usb host2 on imx53 ard board
enable usb host2 on imx53 ard board, external ULPI phy is used on this board. Signed-off-by: Hu Hui <b29976@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx5')
-rw-r--r--arch/arm/mach-mx5/mx53_ard.c1
-rw-r--r--arch/arm/mach-mx5/usb_h2.c97
2 files changed, 91 insertions, 7 deletions
diff --git a/arch/arm/mach-mx5/mx53_ard.c b/arch/arm/mach-mx5/mx53_ard.c
index daad5e475f82..7a2aa0d4dd55 100644
--- a/arch/arm/mach-mx5/mx53_ard.c
+++ b/arch/arm/mach-mx5/mx53_ard.c
@@ -1370,6 +1370,7 @@ static void __init mxc_board_init(void)
mx5_usb_dr_init();
mx5_set_host1_vbus_func(mx53_ard_host1_driver_vbus);
mx5_usbh1_init();
+ mx5_usbh2_init();
mxc_register_device(&mxc_nandv2_mtd_device, &mxc_nand_data);
mxc_register_device(&mxc_esai_device, &esai_data);
mxc_register_device(&mxc_alsa_surround_device,
diff --git a/arch/arm/mach-mx5/usb_h2.c b/arch/arm/mach-mx5/usb_h2.c
index c3279e50daf5..57384f89be02 100644
--- a/arch/arm/mach-mx5/usb_h2.c
+++ b/arch/arm/mach-mx5/usb_h2.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <mach/arc_otg.h>
@@ -43,32 +44,114 @@ static void gpio_usbh2_inactive(void)
mxc_free_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_GPIO);
}
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ printk(KERN_DEBUG "host2, %s, enable is %d\n", __func__, enable);
+ if (enable)
+ USBCTRL_HOST2 |= UCTRL_H2WIE;
+ else {
+ USBCTRL_HOST2 &= ~UCTRL_H2WIE;
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _phy_lowpower_suspend(bool enable)
+{
+ printk(KERN_DEBUG "host2, %s, enable is %d\n", __func__, enable);
+ if (enable) {
+ UH2_PORTSC1 |= PORTSC_PHCD;
+ } else {
+ UH2_PORTSC1 &= ~PORTSC_PHCD;
+ }
+}
+
+static void fsl_usbh2_clock_gate(bool on)
+{
+ struct clk *usb_clk;
+ if (on) {
+ usb_clk = clk_get(NULL, "usb_ahb_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+ } else {
+ usb_clk = clk_get(NULL, "usb_ahb_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+ }
+}
+
static int fsl_usb_host_init_ext(struct platform_device *pdev)
{
- int ret = fsl_usb_host_init(pdev);
- if (ret)
- return ret;
+ int ret = 0;
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ /*derive clock from oscillator */
+ usb_clk = clk_get(NULL, "usb_utmi_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ /* on mx53, there is a hardware limitation that when switch the host2's clk mode
+ * ,usb phy1 clk must be on, after finish switching this clk can be off */
+ if (cpu_is_mx53()) {
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+ }
+
+ ret = fsl_usb_host_init(pdev);
+
+ if (cpu_is_mx53()) {
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+ }
/* setback USBH2_STP to be function */
mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2);
- return 0;
+ return ret;
+}
+
+static void fsl_usb_host_uninit_ext(struct fsl_usb2_platform_data *pdata)
+{
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ fsl_usb_host_uninit(pdata);
}
static struct fsl_usb2_platform_data usbh2_config = {
.name = "Host 2",
.platform_init = fsl_usb_host_init_ext,
- .platform_uninit = fsl_usb_host_uninit,
+ .platform_uninit = fsl_usb_host_uninit_ext,
.operating_mode = FSL_USB2_MPH_HOST,
.phy_mode = FSL_USB2_PHY_ULPI,
.power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = fsl_usbh2_clock_gate,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
.gpio_usb_active = gpio_usbh2_active,
.gpio_usb_inactive = gpio_usbh2_inactive,
.transceiver = "isp1504",
};
-void __init mx51_usbh2_init(void)
+void __init mx5_usbh2_init(void)
{
mxc_register_device(&mxc_usbh2_device, &usbh2_config);
}
-