aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx5/board-mx51_babbage.c
diff options
context:
space:
mode:
authorDinh Nguyen <Dinh.Nguyen@freescale.com>2010-04-30 16:48:25 -0400
committerSascha Hauer <s.hauer@pengutronix.de>2010-05-03 09:18:13 -0400
commit231637f5f2c7f3795d1b0c9b59fda27a23ffdc3e (patch)
treeadc7972d5ce2683ff9ce00e7af46ca636ea506ad /arch/arm/mach-mx5/board-mx51_babbage.c
parentc53bdf1c4488ce196e9a0056285e7b4a36f6f76a (diff)
mx5: Enable board specific functions for enabling USB host on Babbage
This patch enables USB host functionality for Host1 and OTG port on Freescale MX51 Babbage HW. This patch contains the board specific HW initialization of the USB HW. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com> Reviewed-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx5/board-mx51_babbage.c')
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index ee67a71db80d..99f7ea903a51 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -12,11 +12,15 @@
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/gpio.h>
16#include <linux/delay.h>
17#include <linux/io.h>
15 18
16#include <mach/common.h> 19#include <mach/common.h>
17#include <mach/hardware.h> 20#include <mach/hardware.h>
18#include <mach/imx-uart.h> 21#include <mach/imx-uart.h>
19#include <mach/iomux-mx51.h> 22#include <mach/iomux-mx51.h>
23#include <mach/mxc_ehci.h>
20 24
21#include <asm/irq.h> 25#include <asm/irq.h>
22#include <asm/setup.h> 26#include <asm/setup.h>
@@ -26,6 +30,17 @@
26 30
27#include "devices.h" 31#include "devices.h"
28 32
33#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
34#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
35
36/* USB_CTRL_1 */
37#define MX51_USB_CTRL_1_OFFSET 0x10
38#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
39
40#define MX51_USB_PLLDIV_12_MHZ 0x00
41#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
42#define MX51_USB_PLL_DIV_24_MHZ 0x02
43
29static struct platform_device *devices[] __initdata = { 44static struct platform_device *devices[] __initdata = {
30 &mxc_fec_device, 45 &mxc_fec_device,
31}; 46};
@@ -46,6 +61,22 @@ static struct pad_desc mx51babbage_pads[] = {
46 MX51_PAD_EIM_D26__UART3_TXD, 61 MX51_PAD_EIM_D26__UART3_TXD,
47 MX51_PAD_EIM_D27__UART3_RTS, 62 MX51_PAD_EIM_D27__UART3_RTS,
48 MX51_PAD_EIM_D24__UART3_CTS, 63 MX51_PAD_EIM_D24__UART3_CTS,
64
65 /* USB HOST1 */
66 MX51_PAD_USBH1_CLK__USBH1_CLK,
67 MX51_PAD_USBH1_DIR__USBH1_DIR,
68 MX51_PAD_USBH1_NXT__USBH1_NXT,
69 MX51_PAD_USBH1_DATA0__USBH1_DATA0,
70 MX51_PAD_USBH1_DATA1__USBH1_DATA1,
71 MX51_PAD_USBH1_DATA2__USBH1_DATA2,
72 MX51_PAD_USBH1_DATA3__USBH1_DATA3,
73 MX51_PAD_USBH1_DATA4__USBH1_DATA4,
74 MX51_PAD_USBH1_DATA5__USBH1_DATA5,
75 MX51_PAD_USBH1_DATA6__USBH1_DATA6,
76 MX51_PAD_USBH1_DATA7__USBH1_DATA7,
77
78 /* USB HUB reset line*/
79 MX51_PAD_GPIO_1_7__GPIO1_7,
49}; 80};
50 81
51/* Serial ports */ 82/* Serial ports */
@@ -66,15 +97,113 @@ static inline void mxc_init_imx_uart(void)
66} 97}
67#endif /* SERIAL_IMX */ 98#endif /* SERIAL_IMX */
68 99
100static int gpio_usbh1_active(void)
101{
102 struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27;
103 int ret;
104
105 /* Set USBH1_STP to GPIO and toggle it */
106 mxc_iomux_v3_setup_pad(&usbh1stp_gpio);
107 ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp");
108
109 if (ret) {
110 pr_debug("failed to get MX51_PAD_USBH1_STP__GPIO_1_27: %d\n", ret);
111 return ret;
112 }
113 gpio_direction_output(BABBAGE_USBH1_STP, 0);
114 gpio_set_value(BABBAGE_USBH1_STP, 1);
115 msleep(100);
116 gpio_free(BABBAGE_USBH1_STP);
117 return 0;
118}
119
120static inline void babbage_usbhub_reset(void)
121{
122 int ret;
123
124 /* Bring USB hub out of reset */
125 ret = gpio_request(BABBAGE_USB_HUB_RESET, "GPIO1_7");
126 if (ret) {
127 printk(KERN_ERR"failed to get GPIO_USB_HUB_RESET: %d\n", ret);
128 return;
129 }
130 gpio_direction_output(BABBAGE_USB_HUB_RESET, 0);
131
132 /* USB HUB RESET - De-assert USB HUB RESET_N */
133 msleep(1);
134 gpio_set_value(BABBAGE_USB_HUB_RESET, 0);
135 msleep(1);
136 gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
137}
138
139/* This function is board specific as the bit mask for the plldiv will also
140be different for other Freescale SoCs, thus a common bitmask is not
141possible and cannot get place in /plat-mxc/ehci.c.*/
142static int initialize_otg_port(struct platform_device *pdev)
143{
144 u32 v;
145 void __iomem *usb_base;
146 u32 usbother_base;
147
148 usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
149 usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
150
151 /* Set the PHY clock to 19.2MHz */
152 v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
153 v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
154 v |= MX51_USB_PLL_DIV_19_2_MHZ;
155 __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
156 iounmap(usb_base);
157 return 0;
158}
159
160static int initialize_usbh1_port(struct platform_device *pdev)
161{
162 u32 v;
163 void __iomem *usb_base;
164 u32 usbother_base;
165
166 usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
167 usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
168
169 /* The clock for the USBH1 ULPI port will come externally from the PHY. */
170 v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
171 __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET);
172 iounmap(usb_base);
173 return 0;
174}
175
176static struct mxc_usbh_platform_data dr_utmi_config = {
177 .init = initialize_otg_port,
178 .portsc = MXC_EHCI_UTMI_16BIT,
179 .flags = MXC_EHCI_INTERNAL_PHY,
180};
181
182static struct mxc_usbh_platform_data usbh1_config = {
183 .init = initialize_usbh1_port,
184 .portsc = MXC_EHCI_MODE_ULPI,
185 .flags = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD),
186};
187
69/* 188/*
70 * Board specific initialization. 189 * Board specific initialization.
71 */ 190 */
72static void __init mxc_board_init(void) 191static void __init mxc_board_init(void)
73{ 192{
193 struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
194
74 mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, 195 mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
75 ARRAY_SIZE(mx51babbage_pads)); 196 ARRAY_SIZE(mx51babbage_pads));
76 mxc_init_imx_uart(); 197 mxc_init_imx_uart();
77 platform_add_devices(devices, ARRAY_SIZE(devices)); 198 platform_add_devices(devices, ARRAY_SIZE(devices));
199
200 mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
201
202 gpio_usbh1_active();
203 mxc_register_device(&mxc_usbh1_device, &usbh1_config);
204 /* setback USBH1_STP to be function */
205 mxc_iomux_v3_setup_pad(&usbh1stp);
206 babbage_usbhub_reset();
78} 207}
79 208
80static void __init mx51_babbage_timer_init(void) 209static void __init mx51_babbage_timer_init(void)