diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-11-30 20:04:33 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-11-30 20:04:51 -0500 |
commit | 0ae86689d88bebba16c2db899f845446578d53b3 (patch) | |
tree | 221f807566461620c240a190d551c73118529da0 | |
parent | e7cddda48c7f892a3fb5c10a6f41a4395f46c0c2 (diff) | |
parent | 6aa85a5ae610106d89e50c7e1f760c56d12f9bc4 (diff) |
Merge branch 'omap4-ehci-for-greg' of git://dev.omapzoom.org/pub/scm/anand/linux-omap-usb into usb-next
* 'omap4-ehci-for-greg' of git://dev.omapzoom.org/pub/scm/anand/linux-omap-usb:
omap4: 4430sdp: enable the ehci port on 4430SDP
arm: omap4: select USB_ARCH_HAS_EHCI
arm: omap4: usb: add platform init code for EHCI
arm: omap4: add USBHOST and related base addresses
usb: ehci-omap: Add OMAP4 support
omap: usb: ehci: introduce HSIC mode
usb: ehci-omap: add helpers for checking port mode
usb: ehci-omap: use clkdev aliases for functional clocks
omap: clock: add clkdev aliases for EHCI clocks
usb: ehci: introduce CONFIG_USB_EHCI_HCD_OMAP
usb: ehci-omap: don't hard-code TLL channel count
usb: ehci-omap: update clock names to be more generic
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock3xxx_data.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock44xx_data.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/usb-ehci.c | 144 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap44xx.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/usb.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 310 |
10 files changed, 424 insertions, 77 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ab784bfde908..766727c4031d 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -44,6 +44,7 @@ config ARCH_OMAP4 | |||
44 | select ARM_GIC | 44 | select ARM_GIC |
45 | select PL310_ERRATA_588369 | 45 | select PL310_ERRATA_588369 |
46 | select ARM_ERRATA_720789 | 46 | select ARM_ERRATA_720789 |
47 | select USB_ARCH_HAS_EHCI | ||
47 | 48 | ||
48 | comment "OMAP Core Type" | 49 | comment "OMAP Core Type" |
49 | depends on ARCH_OMAP2 | 50 | depends on ARCH_OMAP2 |
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index df5a425a49d1..d7cb9680b4fa 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #define ETH_KS8851_IRQ 34 | 42 | #define ETH_KS8851_IRQ 34 |
43 | #define ETH_KS8851_POWER_ON 48 | 43 | #define ETH_KS8851_POWER_ON 48 |
44 | #define ETH_KS8851_QUART 138 | 44 | #define ETH_KS8851_QUART 138 |
45 | #define OMAP4SDP_MDM_PWR_EN_GPIO 157 | ||
45 | #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 | 46 | #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 |
46 | #define OMAP4_SFH7741_ENABLE_GPIO 188 | 47 | #define OMAP4_SFH7741_ENABLE_GPIO 188 |
47 | 48 | ||
@@ -225,6 +226,16 @@ static void __init omap_4430sdp_init_irq(void) | |||
225 | omap_gpio_init(); | 226 | omap_gpio_init(); |
226 | } | 227 | } |
227 | 228 | ||
229 | static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { | ||
230 | .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, | ||
231 | .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, | ||
232 | .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, | ||
233 | .phy_reset = false, | ||
234 | .reset_gpio_port[0] = -EINVAL, | ||
235 | .reset_gpio_port[1] = -EINVAL, | ||
236 | .reset_gpio_port[2] = -EINVAL, | ||
237 | }; | ||
238 | |||
228 | static struct omap_musb_board_data musb_board_data = { | 239 | static struct omap_musb_board_data musb_board_data = { |
229 | .interface_type = MUSB_INTERFACE_UTMI, | 240 | .interface_type = MUSB_INTERFACE_UTMI, |
230 | .mode = MUSB_PERIPHERAL, | 241 | .mode = MUSB_PERIPHERAL, |
@@ -514,6 +525,15 @@ static void __init omap_4430sdp_init(void) | |||
514 | platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); | 525 | platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); |
515 | omap_serial_init(); | 526 | omap_serial_init(); |
516 | omap4_twl6030_hsmmc_init(mmc); | 527 | omap4_twl6030_hsmmc_init(mmc); |
528 | |||
529 | /* Power on the ULPI PHY */ | ||
530 | if (gpio_is_valid(OMAP4SDP_MDM_PWR_EN_GPIO)) { | ||
531 | /* FIXME: Assumes pad is already muxed for GPIO mode */ | ||
532 | gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); | ||
533 | gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); | ||
534 | } | ||
535 | usb_ehci_init(&ehci_pdata); | ||
536 | |||
517 | /* OMAP4 SDP uses internal transceiver so register nop transceiver */ | 537 | /* OMAP4 SDP uses internal transceiver so register nop transceiver */ |
518 | usb_nop_xceiv_register(); | 538 | usb_nop_xceiv_register(); |
519 | /* FIXME: allow multi-omap to boot until musb is updated for omap4 */ | 539 | /* FIXME: allow multi-omap to boot until musb is updated for omap4 */ |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index d85ecd5aebfd..a04cb03db51f 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -3278,6 +3278,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3278 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2 | CK_AM35XX), | 3278 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2 | CK_AM35XX), |
3279 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2 | CK_AM35XX), | 3279 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2 | CK_AM35XX), |
3280 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX), | 3280 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX), |
3281 | CLK("ehci-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX), | ||
3281 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), | 3282 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), |
3282 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), | 3283 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), |
3283 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), | 3284 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), |
@@ -3313,6 +3314,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3313 | CLK(NULL, "pka_ick", &pka_ick, CK_343X), | 3314 | CLK(NULL, "pka_ick", &pka_ick, CK_343X), |
3314 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), | 3315 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), |
3315 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX), | 3316 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX), |
3317 | CLK("ehci-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2 | CK_AM35XX), | ||
3316 | CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX), | 3318 | CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2 | CK_AM35XX), |
3317 | CLK(NULL, "icr_ick", &icr_ick, CK_343X), | 3319 | CLK(NULL, "icr_ick", &icr_ick, CK_343X), |
3318 | CLK("omap-aes", "ick", &aes2_ick, CK_343X), | 3320 | CLK("omap-aes", "ick", &aes2_ick, CK_343X), |
@@ -3358,8 +3360,11 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3358 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), | 3360 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), |
3359 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), | 3361 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), |
3360 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2 | CK_AM35XX), | 3362 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2 | CK_AM35XX), |
3363 | CLK("ehci-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2 | CK_AM35XX), | ||
3361 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX), | 3364 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX), |
3365 | CLK("ehci-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2 | CK_AM35XX), | ||
3362 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2 | CK_AM35XX), | 3366 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2 | CK_AM35XX), |
3367 | CLK("ehci-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2 | CK_AM35XX), | ||
3363 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2), | 3368 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2), |
3364 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), | 3369 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), |
3365 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), | 3370 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), |
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 1599836ba3d9..f473e8922664 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c | |||
@@ -2937,6 +2937,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
2937 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), | 2937 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), |
2938 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), | 2938 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), |
2939 | CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), | 2939 | CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), |
2940 | CLK("ehci-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X), | ||
2940 | CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X), | 2941 | CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X), |
2941 | CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X), | 2942 | CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X), |
2942 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), | 2943 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), |
@@ -2948,6 +2949,8 @@ static struct omap_clk omap44xx_clks[] = { | |||
2948 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), | 2949 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), |
2949 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), | 2950 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), |
2950 | CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X), | 2951 | CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X), |
2952 | CLK("ehci-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X), | ||
2953 | CLK("ehci-omap.0", "usbhost_ick", &dummy_ck, CK_443X), | ||
2951 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), | 2954 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), |
2952 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), | 2955 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), |
2953 | CLK("musb_hdrc", "ick", &usb_otg_hs_ick, CK_443X), | 2956 | CLK("musb_hdrc", "ick", &usb_otg_hs_ick, CK_443X), |
@@ -2956,6 +2959,8 @@ static struct omap_clk omap44xx_clks[] = { | |||
2956 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), | 2959 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), |
2957 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), | 2960 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), |
2958 | CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X), | 2961 | CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X), |
2962 | CLK("ehci-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X), | ||
2963 | CLK("ehci-omap.0", "usbtll_fck", &dummy_ck, CK_443X), | ||
2959 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), | 2964 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), |
2960 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), | 2965 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), |
2961 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), | 2966 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), |
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c index b11bf385d360..25eeadabc39b 100644 --- a/arch/arm/mach-omap2/usb-ehci.c +++ b/arch/arm/mach-omap2/usb-ehci.c | |||
@@ -34,22 +34,15 @@ | |||
34 | 34 | ||
35 | static struct resource ehci_resources[] = { | 35 | static struct resource ehci_resources[] = { |
36 | { | 36 | { |
37 | .start = OMAP34XX_EHCI_BASE, | ||
38 | .end = OMAP34XX_EHCI_BASE + SZ_1K - 1, | ||
39 | .flags = IORESOURCE_MEM, | 37 | .flags = IORESOURCE_MEM, |
40 | }, | 38 | }, |
41 | { | 39 | { |
42 | .start = OMAP34XX_UHH_CONFIG_BASE, | ||
43 | .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1, | ||
44 | .flags = IORESOURCE_MEM, | 40 | .flags = IORESOURCE_MEM, |
45 | }, | 41 | }, |
46 | { | 42 | { |
47 | .start = OMAP34XX_USBTLL_BASE, | ||
48 | .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1, | ||
49 | .flags = IORESOURCE_MEM, | 43 | .flags = IORESOURCE_MEM, |
50 | }, | 44 | }, |
51 | { /* general IRQ */ | 45 | { /* general IRQ */ |
52 | .start = INT_34XX_EHCI_IRQ, | ||
53 | .flags = IORESOURCE_IRQ, | 46 | .flags = IORESOURCE_IRQ, |
54 | } | 47 | } |
55 | }; | 48 | }; |
@@ -214,13 +207,148 @@ static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) | |||
214 | return; | 207 | return; |
215 | } | 208 | } |
216 | 209 | ||
210 | static void setup_4430ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) | ||
211 | { | ||
212 | switch (port_mode[0]) { | ||
213 | case EHCI_HCD_OMAP_MODE_PHY: | ||
214 | omap_mux_init_signal("usbb1_ulpiphy_stp", | ||
215 | OMAP_PIN_OUTPUT); | ||
216 | omap_mux_init_signal("usbb1_ulpiphy_clk", | ||
217 | OMAP_PIN_INPUT_PULLDOWN); | ||
218 | omap_mux_init_signal("usbb1_ulpiphy_dir", | ||
219 | OMAP_PIN_INPUT_PULLDOWN); | ||
220 | omap_mux_init_signal("usbb1_ulpiphy_nxt", | ||
221 | OMAP_PIN_INPUT_PULLDOWN); | ||
222 | omap_mux_init_signal("usbb1_ulpiphy_dat0", | ||
223 | OMAP_PIN_INPUT_PULLDOWN); | ||
224 | omap_mux_init_signal("usbb1_ulpiphy_dat1", | ||
225 | OMAP_PIN_INPUT_PULLDOWN); | ||
226 | omap_mux_init_signal("usbb1_ulpiphy_dat2", | ||
227 | OMAP_PIN_INPUT_PULLDOWN); | ||
228 | omap_mux_init_signal("usbb1_ulpiphy_dat3", | ||
229 | OMAP_PIN_INPUT_PULLDOWN); | ||
230 | omap_mux_init_signal("usbb1_ulpiphy_dat4", | ||
231 | OMAP_PIN_INPUT_PULLDOWN); | ||
232 | omap_mux_init_signal("usbb1_ulpiphy_dat5", | ||
233 | OMAP_PIN_INPUT_PULLDOWN); | ||
234 | omap_mux_init_signal("usbb1_ulpiphy_dat6", | ||
235 | OMAP_PIN_INPUT_PULLDOWN); | ||
236 | omap_mux_init_signal("usbb1_ulpiphy_dat7", | ||
237 | OMAP_PIN_INPUT_PULLDOWN); | ||
238 | break; | ||
239 | case EHCI_HCD_OMAP_MODE_TLL: | ||
240 | omap_mux_init_signal("usbb1_ulpitll_stp", | ||
241 | OMAP_PIN_INPUT_PULLUP); | ||
242 | omap_mux_init_signal("usbb1_ulpitll_clk", | ||
243 | OMAP_PIN_INPUT_PULLDOWN); | ||
244 | omap_mux_init_signal("usbb1_ulpitll_dir", | ||
245 | OMAP_PIN_INPUT_PULLDOWN); | ||
246 | omap_mux_init_signal("usbb1_ulpitll_nxt", | ||
247 | OMAP_PIN_INPUT_PULLDOWN); | ||
248 | omap_mux_init_signal("usbb1_ulpitll_dat0", | ||
249 | OMAP_PIN_INPUT_PULLDOWN); | ||
250 | omap_mux_init_signal("usbb1_ulpitll_dat1", | ||
251 | OMAP_PIN_INPUT_PULLDOWN); | ||
252 | omap_mux_init_signal("usbb1_ulpitll_dat2", | ||
253 | OMAP_PIN_INPUT_PULLDOWN); | ||
254 | omap_mux_init_signal("usbb1_ulpitll_dat3", | ||
255 | OMAP_PIN_INPUT_PULLDOWN); | ||
256 | omap_mux_init_signal("usbb1_ulpitll_dat4", | ||
257 | OMAP_PIN_INPUT_PULLDOWN); | ||
258 | omap_mux_init_signal("usbb1_ulpitll_dat5", | ||
259 | OMAP_PIN_INPUT_PULLDOWN); | ||
260 | omap_mux_init_signal("usbb1_ulpitll_dat6", | ||
261 | OMAP_PIN_INPUT_PULLDOWN); | ||
262 | omap_mux_init_signal("usbb1_ulpitll_dat7", | ||
263 | OMAP_PIN_INPUT_PULLDOWN); | ||
264 | break; | ||
265 | case EHCI_HCD_OMAP_MODE_UNKNOWN: | ||
266 | default: | ||
267 | break; | ||
268 | } | ||
269 | switch (port_mode[1]) { | ||
270 | case EHCI_HCD_OMAP_MODE_PHY: | ||
271 | omap_mux_init_signal("usbb2_ulpiphy_stp", | ||
272 | OMAP_PIN_OUTPUT); | ||
273 | omap_mux_init_signal("usbb2_ulpiphy_clk", | ||
274 | OMAP_PIN_INPUT_PULLDOWN); | ||
275 | omap_mux_init_signal("usbb2_ulpiphy_dir", | ||
276 | OMAP_PIN_INPUT_PULLDOWN); | ||
277 | omap_mux_init_signal("usbb2_ulpiphy_nxt", | ||
278 | OMAP_PIN_INPUT_PULLDOWN); | ||
279 | omap_mux_init_signal("usbb2_ulpiphy_dat0", | ||
280 | OMAP_PIN_INPUT_PULLDOWN); | ||
281 | omap_mux_init_signal("usbb2_ulpiphy_dat1", | ||
282 | OMAP_PIN_INPUT_PULLDOWN); | ||
283 | omap_mux_init_signal("usbb2_ulpiphy_dat2", | ||
284 | OMAP_PIN_INPUT_PULLDOWN); | ||
285 | omap_mux_init_signal("usbb2_ulpiphy_dat3", | ||
286 | OMAP_PIN_INPUT_PULLDOWN); | ||
287 | omap_mux_init_signal("usbb2_ulpiphy_dat4", | ||
288 | OMAP_PIN_INPUT_PULLDOWN); | ||
289 | omap_mux_init_signal("usbb2_ulpiphy_dat5", | ||
290 | OMAP_PIN_INPUT_PULLDOWN); | ||
291 | omap_mux_init_signal("usbb2_ulpiphy_dat6", | ||
292 | OMAP_PIN_INPUT_PULLDOWN); | ||
293 | omap_mux_init_signal("usbb2_ulpiphy_dat7", | ||
294 | OMAP_PIN_INPUT_PULLDOWN); | ||
295 | break; | ||
296 | case EHCI_HCD_OMAP_MODE_TLL: | ||
297 | omap_mux_init_signal("usbb2_ulpitll_stp", | ||
298 | OMAP_PIN_INPUT_PULLUP); | ||
299 | omap_mux_init_signal("usbb2_ulpitll_clk", | ||
300 | OMAP_PIN_INPUT_PULLDOWN); | ||
301 | omap_mux_init_signal("usbb2_ulpitll_dir", | ||
302 | OMAP_PIN_INPUT_PULLDOWN); | ||
303 | omap_mux_init_signal("usbb2_ulpitll_nxt", | ||
304 | OMAP_PIN_INPUT_PULLDOWN); | ||
305 | omap_mux_init_signal("usbb2_ulpitll_dat0", | ||
306 | OMAP_PIN_INPUT_PULLDOWN); | ||
307 | omap_mux_init_signal("usbb2_ulpitll_dat1", | ||
308 | OMAP_PIN_INPUT_PULLDOWN); | ||
309 | omap_mux_init_signal("usbb2_ulpitll_dat2", | ||
310 | OMAP_PIN_INPUT_PULLDOWN); | ||
311 | omap_mux_init_signal("usbb2_ulpitll_dat3", | ||
312 | OMAP_PIN_INPUT_PULLDOWN); | ||
313 | omap_mux_init_signal("usbb2_ulpitll_dat4", | ||
314 | OMAP_PIN_INPUT_PULLDOWN); | ||
315 | omap_mux_init_signal("usbb2_ulpitll_dat5", | ||
316 | OMAP_PIN_INPUT_PULLDOWN); | ||
317 | omap_mux_init_signal("usbb2_ulpitll_dat6", | ||
318 | OMAP_PIN_INPUT_PULLDOWN); | ||
319 | omap_mux_init_signal("usbb2_ulpitll_dat7", | ||
320 | OMAP_PIN_INPUT_PULLDOWN); | ||
321 | break; | ||
322 | case EHCI_HCD_OMAP_MODE_UNKNOWN: | ||
323 | default: | ||
324 | break; | ||
325 | } | ||
326 | } | ||
327 | |||
217 | void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) | 328 | void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) |
218 | { | 329 | { |
219 | platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); | 330 | platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); |
220 | 331 | ||
221 | /* Setup Pin IO MUX for EHCI */ | 332 | /* Setup Pin IO MUX for EHCI */ |
222 | if (cpu_is_omap34xx()) | 333 | if (cpu_is_omap34xx()) { |
334 | ehci_resources[0].start = OMAP34XX_EHCI_BASE; | ||
335 | ehci_resources[0].end = OMAP34XX_EHCI_BASE + SZ_1K - 1; | ||
336 | ehci_resources[1].start = OMAP34XX_UHH_CONFIG_BASE; | ||
337 | ehci_resources[1].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1; | ||
338 | ehci_resources[2].start = OMAP34XX_USBTLL_BASE; | ||
339 | ehci_resources[2].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1; | ||
340 | ehci_resources[3].start = INT_34XX_EHCI_IRQ; | ||
223 | setup_ehci_io_mux(pdata->port_mode); | 341 | setup_ehci_io_mux(pdata->port_mode); |
342 | } else if (cpu_is_omap44xx()) { | ||
343 | ehci_resources[0].start = OMAP44XX_HSUSB_EHCI_BASE; | ||
344 | ehci_resources[0].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1; | ||
345 | ehci_resources[1].start = OMAP44XX_UHH_CONFIG_BASE; | ||
346 | ehci_resources[1].end = OMAP44XX_UHH_CONFIG_BASE + SZ_2K - 1; | ||
347 | ehci_resources[2].start = OMAP44XX_USBTLL_BASE; | ||
348 | ehci_resources[2].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1; | ||
349 | ehci_resources[3].start = OMAP44XX_IRQ_EHCI; | ||
350 | setup_4430ehci_io_mux(pdata->port_mode); | ||
351 | } | ||
224 | 352 | ||
225 | if (platform_device_register(&ehci_device) < 0) { | 353 | if (platform_device_register(&ehci_device) < 0) { |
226 | printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); | 354 | printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n"); |
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index 8b3f12ff5cbc..ea2b8a6306e7 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h | |||
@@ -52,5 +52,10 @@ | |||
52 | #define OMAP4_MMU1_BASE 0x55082000 | 52 | #define OMAP4_MMU1_BASE 0x55082000 |
53 | #define OMAP4_MMU2_BASE 0x4A066000 | 53 | #define OMAP4_MMU2_BASE 0x4A066000 |
54 | 54 | ||
55 | #define OMAP44XX_USBTLL_BASE (L4_44XX_BASE + 0x62000) | ||
56 | #define OMAP44XX_UHH_CONFIG_BASE (L4_44XX_BASE + 0x64000) | ||
57 | #define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800) | ||
58 | #define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00) | ||
59 | |||
55 | #endif /* __ASM_ARCH_OMAP44XX_H */ | 60 | #endif /* __ASM_ARCH_OMAP44XX_H */ |
56 | 61 | ||
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 59c7fe731f28..9b1893f31fc8 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h | |||
@@ -11,6 +11,7 @@ enum ehci_hcd_omap_mode { | |||
11 | EHCI_HCD_OMAP_MODE_UNKNOWN, | 11 | EHCI_HCD_OMAP_MODE_UNKNOWN, |
12 | EHCI_HCD_OMAP_MODE_PHY, | 12 | EHCI_HCD_OMAP_MODE_PHY, |
13 | EHCI_HCD_OMAP_MODE_TLL, | 13 | EHCI_HCD_OMAP_MODE_TLL, |
14 | EHCI_HCD_OMAP_MODE_HSIC, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | enum ohci_omap3_port_mode { | 17 | enum ohci_omap3_port_mode { |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2391c396ca32..6a7c688b4781 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -133,6 +133,14 @@ config USB_EHCI_MXC | |||
133 | ---help--- | 133 | ---help--- |
134 | Variation of ARC USB block used in some Freescale chips. | 134 | Variation of ARC USB block used in some Freescale chips. |
135 | 135 | ||
136 | config USB_EHCI_HCD_OMAP | ||
137 | bool "EHCI support for OMAP3 and later chips" | ||
138 | depends on USB_EHCI_HCD && ARCH_OMAP | ||
139 | default y | ||
140 | --- help --- | ||
141 | Enables support for the on-chip EHCI controller on | ||
142 | OMAP3 and later chips. | ||
143 | |||
136 | config USB_EHCI_HCD_PPC_OF | 144 | config USB_EHCI_HCD_PPC_OF |
137 | bool "EHCI support for PPC USB controller on OF platform bus" | 145 | bool "EHCI support for PPC USB controller on OF platform bus" |
138 | depends on USB_EHCI_HCD && PPC_OF | 146 | depends on USB_EHCI_HCD && PPC_OF |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 87157db155f6..2f06ba471953 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1171,7 +1171,7 @@ MODULE_LICENSE ("GPL"); | |||
1171 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver | 1171 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver |
1172 | #endif | 1172 | #endif |
1173 | 1173 | ||
1174 | #ifdef CONFIG_ARCH_OMAP3 | 1174 | #ifdef CONFIG_USB_EHCI_HCD_OMAP |
1175 | #include "ehci-omap.c" | 1175 | #include "ehci-omap.c" |
1176 | #define PLATFORM_DRIVER ehci_hcd_omap_driver | 1176 | #define PLATFORM_DRIVER ehci_hcd_omap_driver |
1177 | #endif | 1177 | #endif |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 116ae280053a..0374eb47f09b 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -1,11 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * ehci-omap.c - driver for USBHOST on OMAP 34xx processor | 2 | * ehci-omap.c - driver for USBHOST on OMAP3/4 processors |
3 | * | 3 | * |
4 | * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller | 4 | * Bus Glue for the EHCI controllers in OMAP3/4 |
5 | * Tested on OMAP3430 ES2.0 SDP | 5 | * Tested on several OMAP3 boards, and OMAP4 Pandaboard |
6 | * | 6 | * |
7 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 7 | * Copyright (C) 2007-2010 Texas Instruments, Inc. |
8 | * Author: Vikram Pandita <vikram.pandita@ti.com> | 8 | * Author: Vikram Pandita <vikram.pandita@ti.com> |
9 | * Author: Anand Gadiyar <gadiyar@ti.com> | ||
9 | * | 10 | * |
10 | * Copyright (C) 2009 Nokia Corporation | 11 | * Copyright (C) 2009 Nokia Corporation |
11 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | 12 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> |
@@ -26,11 +27,14 @@ | |||
26 | * along with this program; if not, write to the Free Software | 27 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | * | 29 | * |
29 | * TODO (last updated Feb 12, 2010): | 30 | * TODO (last updated Nov 21, 2010): |
30 | * - add kernel-doc | 31 | * - add kernel-doc |
31 | * - enable AUTOIDLE | 32 | * - enable AUTOIDLE |
32 | * - add suspend/resume | 33 | * - add suspend/resume |
33 | * - move workarounds to board-files | 34 | * - move workarounds to board-files |
35 | * - factor out code common to OHCI | ||
36 | * - add HSIC and TLL support | ||
37 | * - convert to use hwmod and runtime PM | ||
34 | */ | 38 | */ |
35 | 39 | ||
36 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
@@ -114,6 +118,23 @@ | |||
114 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) | 118 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) |
115 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) | 119 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) |
116 | 120 | ||
121 | /* OMAP4-specific defines */ | ||
122 | #define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) | ||
123 | #define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) | ||
124 | |||
125 | #define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) | ||
126 | #define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) | ||
127 | #define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) | ||
128 | |||
129 | #define OMAP4_P1_MODE_CLEAR (3 << 16) | ||
130 | #define OMAP4_P1_MODE_TLL (1 << 16) | ||
131 | #define OMAP4_P1_MODE_HSIC (3 << 16) | ||
132 | #define OMAP4_P2_MODE_CLEAR (3 << 18) | ||
133 | #define OMAP4_P2_MODE_TLL (1 << 18) | ||
134 | #define OMAP4_P2_MODE_HSIC (3 << 18) | ||
135 | |||
136 | #define OMAP_REV2_TLL_CHANNEL_COUNT 2 | ||
137 | |||
117 | #define OMAP_UHH_DEBUG_CSR (0x44) | 138 | #define OMAP_UHH_DEBUG_CSR (0x44) |
118 | 139 | ||
119 | /* EHCI Register Set */ | 140 | /* EHCI Register Set */ |
@@ -127,6 +148,17 @@ | |||
127 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 148 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
128 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 149 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
129 | 150 | ||
151 | /* Values of UHH_REVISION - Note: these are not given in the TRM */ | ||
152 | #define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */ | ||
153 | #define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */ | ||
154 | |||
155 | #define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1) | ||
156 | #define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2) | ||
157 | |||
158 | #define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) | ||
159 | #define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) | ||
160 | #define is_ehci_hsic_mode(x) (x == EHCI_HCD_OMAP_MODE_HSIC) | ||
161 | |||
130 | /*-------------------------------------------------------------------------*/ | 162 | /*-------------------------------------------------------------------------*/ |
131 | 163 | ||
132 | static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) | 164 | static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) |
@@ -156,10 +188,14 @@ struct ehci_hcd_omap { | |||
156 | struct device *dev; | 188 | struct device *dev; |
157 | 189 | ||
158 | struct clk *usbhost_ick; | 190 | struct clk *usbhost_ick; |
159 | struct clk *usbhost2_120m_fck; | 191 | struct clk *usbhost_hs_fck; |
160 | struct clk *usbhost1_48m_fck; | 192 | struct clk *usbhost_fs_fck; |
161 | struct clk *usbtll_fck; | 193 | struct clk *usbtll_fck; |
162 | struct clk *usbtll_ick; | 194 | struct clk *usbtll_ick; |
195 | struct clk *xclk60mhsp1_ck; | ||
196 | struct clk *xclk60mhsp2_ck; | ||
197 | struct clk *utmi_p1_fck; | ||
198 | struct clk *utmi_p2_fck; | ||
163 | 199 | ||
164 | /* FIXME the following two workarounds are | 200 | /* FIXME the following two workarounds are |
165 | * board specific not silicon-specific so these | 201 | * board specific not silicon-specific so these |
@@ -176,6 +212,9 @@ struct ehci_hcd_omap { | |||
176 | /* phy reset workaround */ | 212 | /* phy reset workaround */ |
177 | int phy_reset; | 213 | int phy_reset; |
178 | 214 | ||
215 | /* IP revision */ | ||
216 | u32 omap_ehci_rev; | ||
217 | |||
179 | /* desired phy_mode: TLL, PHY */ | 218 | /* desired phy_mode: TLL, PHY */ |
180 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; | 219 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; |
181 | 220 | ||
@@ -191,13 +230,14 @@ struct ehci_hcd_omap { | |||
191 | 230 | ||
192 | /*-------------------------------------------------------------------------*/ | 231 | /*-------------------------------------------------------------------------*/ |
193 | 232 | ||
194 | static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) | 233 | static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask, |
234 | u8 tll_channel_count) | ||
195 | { | 235 | { |
196 | unsigned reg; | 236 | unsigned reg; |
197 | int i; | 237 | int i; |
198 | 238 | ||
199 | /* Program the 3 TLL channels upfront */ | 239 | /* Program the 3 TLL channels upfront */ |
200 | for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { | 240 | for (i = 0; i < tll_channel_count; i++) { |
201 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); | 241 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); |
202 | 242 | ||
203 | /* Disable AutoIdle, BitStuffing and use SDR Mode */ | 243 | /* Disable AutoIdle, BitStuffing and use SDR Mode */ |
@@ -217,7 +257,7 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) | |||
217 | ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); | 257 | ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); |
218 | 258 | ||
219 | /* Enable channels now */ | 259 | /* Enable channels now */ |
220 | for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { | 260 | for (i = 0; i < tll_channel_count; i++) { |
221 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); | 261 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); |
222 | 262 | ||
223 | /* Enable only the reg that is needed */ | 263 | /* Enable only the reg that is needed */ |
@@ -286,19 +326,19 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
286 | } | 326 | } |
287 | clk_enable(omap->usbhost_ick); | 327 | clk_enable(omap->usbhost_ick); |
288 | 328 | ||
289 | omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); | 329 | omap->usbhost_hs_fck = clk_get(omap->dev, "hs_fck"); |
290 | if (IS_ERR(omap->usbhost2_120m_fck)) { | 330 | if (IS_ERR(omap->usbhost_hs_fck)) { |
291 | ret = PTR_ERR(omap->usbhost2_120m_fck); | 331 | ret = PTR_ERR(omap->usbhost_hs_fck); |
292 | goto err_host_120m_fck; | 332 | goto err_host_120m_fck; |
293 | } | 333 | } |
294 | clk_enable(omap->usbhost2_120m_fck); | 334 | clk_enable(omap->usbhost_hs_fck); |
295 | 335 | ||
296 | omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); | 336 | omap->usbhost_fs_fck = clk_get(omap->dev, "fs_fck"); |
297 | if (IS_ERR(omap->usbhost1_48m_fck)) { | 337 | if (IS_ERR(omap->usbhost_fs_fck)) { |
298 | ret = PTR_ERR(omap->usbhost1_48m_fck); | 338 | ret = PTR_ERR(omap->usbhost_fs_fck); |
299 | goto err_host_48m_fck; | 339 | goto err_host_48m_fck; |
300 | } | 340 | } |
301 | clk_enable(omap->usbhost1_48m_fck); | 341 | clk_enable(omap->usbhost_fs_fck); |
302 | 342 | ||
303 | if (omap->phy_reset) { | 343 | if (omap->phy_reset) { |
304 | /* Refer: ISSUE1 */ | 344 | /* Refer: ISSUE1 */ |
@@ -333,6 +373,80 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
333 | } | 373 | } |
334 | clk_enable(omap->usbtll_ick); | 374 | clk_enable(omap->usbtll_ick); |
335 | 375 | ||
376 | omap->omap_ehci_rev = ehci_omap_readl(omap->uhh_base, | ||
377 | OMAP_UHH_REVISION); | ||
378 | dev_dbg(omap->dev, "OMAP UHH_REVISION 0x%x\n", | ||
379 | omap->omap_ehci_rev); | ||
380 | |||
381 | /* | ||
382 | * Enable per-port clocks as needed (newer controllers only). | ||
383 | * - External ULPI clock for PHY mode | ||
384 | * - Internal clocks for TLL and HSIC modes (TODO) | ||
385 | */ | ||
386 | if (is_omap_ehci_rev2(omap)) { | ||
387 | switch (omap->port_mode[0]) { | ||
388 | case EHCI_HCD_OMAP_MODE_PHY: | ||
389 | omap->xclk60mhsp1_ck = clk_get(omap->dev, | ||
390 | "xclk60mhsp1_ck"); | ||
391 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | ||
392 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | ||
393 | dev_err(omap->dev, | ||
394 | "Unable to get Port1 ULPI clock\n"); | ||
395 | } | ||
396 | |||
397 | omap->utmi_p1_fck = clk_get(omap->dev, | ||
398 | "utmi_p1_gfclk"); | ||
399 | if (IS_ERR(omap->utmi_p1_fck)) { | ||
400 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
401 | dev_err(omap->dev, | ||
402 | "Unable to get utmi_p1_fck\n"); | ||
403 | } | ||
404 | |||
405 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
406 | omap->xclk60mhsp1_ck); | ||
407 | if (ret != 0) { | ||
408 | dev_err(omap->dev, | ||
409 | "Unable to set P1 f-clock\n"); | ||
410 | } | ||
411 | break; | ||
412 | case EHCI_HCD_OMAP_MODE_TLL: | ||
413 | /* TODO */ | ||
414 | default: | ||
415 | break; | ||
416 | } | ||
417 | switch (omap->port_mode[1]) { | ||
418 | case EHCI_HCD_OMAP_MODE_PHY: | ||
419 | omap->xclk60mhsp2_ck = clk_get(omap->dev, | ||
420 | "xclk60mhsp2_ck"); | ||
421 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | ||
422 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | ||
423 | dev_err(omap->dev, | ||
424 | "Unable to get Port2 ULPI clock\n"); | ||
425 | } | ||
426 | |||
427 | omap->utmi_p2_fck = clk_get(omap->dev, | ||
428 | "utmi_p2_gfclk"); | ||
429 | if (IS_ERR(omap->utmi_p2_fck)) { | ||
430 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
431 | dev_err(omap->dev, | ||
432 | "Unable to get utmi_p2_fck\n"); | ||
433 | } | ||
434 | |||
435 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
436 | omap->xclk60mhsp2_ck); | ||
437 | if (ret != 0) { | ||
438 | dev_err(omap->dev, | ||
439 | "Unable to set P2 f-clock\n"); | ||
440 | } | ||
441 | break; | ||
442 | case EHCI_HCD_OMAP_MODE_TLL: | ||
443 | /* TODO */ | ||
444 | default: | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | |||
336 | /* perform TLL soft reset, and wait until reset is complete */ | 450 | /* perform TLL soft reset, and wait until reset is complete */ |
337 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | 451 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, |
338 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | 452 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); |
@@ -360,12 +474,20 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
360 | 474 | ||
361 | /* Put UHH in NoIdle/NoStandby mode */ | 475 | /* Put UHH in NoIdle/NoStandby mode */ |
362 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); | 476 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); |
363 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | 477 | if (is_omap_ehci_rev1(omap)) { |
364 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | 478 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP |
365 | | OMAP_UHH_SYSCONFIG_CACTIVITY | 479 | | OMAP_UHH_SYSCONFIG_SIDLEMODE |
366 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | 480 | | OMAP_UHH_SYSCONFIG_CACTIVITY |
367 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | 481 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); |
482 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
483 | |||
368 | 484 | ||
485 | } else if (is_omap_ehci_rev2(omap)) { | ||
486 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
487 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
488 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
489 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
490 | } | ||
369 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | 491 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); |
370 | 492 | ||
371 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 493 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
@@ -376,40 +498,56 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
376 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); | 498 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); |
377 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; | 499 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; |
378 | 500 | ||
379 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 501 | if (is_omap_ehci_rev1(omap)) { |
380 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; | 502 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
381 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 503 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; |
382 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; | 504 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
383 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 505 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; |
384 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | 506 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
385 | 507 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | |
386 | /* Bypass the TLL module for PHY mode operation */ | 508 | |
387 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { | 509 | /* Bypass the TLL module for PHY mode operation */ |
388 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); | 510 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { |
389 | if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || | 511 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); |
390 | (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || | 512 | if (is_ehci_phy_mode(omap->port_mode[0]) || |
391 | (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) | 513 | is_ehci_phy_mode(omap->port_mode[1]) || |
392 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 514 | is_ehci_phy_mode(omap->port_mode[2])) |
393 | else | 515 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
394 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 516 | else |
395 | } else { | 517 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
396 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); | 518 | } else { |
397 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) | 519 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); |
398 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 520 | if (is_ehci_phy_mode(omap->port_mode[0])) |
399 | else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) | 521 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; |
400 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 522 | else if (is_ehci_tll_mode(omap->port_mode[0])) |
401 | 523 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | |
402 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) | 524 | |
403 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 525 | if (is_ehci_phy_mode(omap->port_mode[1])) |
404 | else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) | 526 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; |
405 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 527 | else if (is_ehci_tll_mode(omap->port_mode[1])) |
406 | 528 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | |
407 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY) | 529 | |
408 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 530 | if (is_ehci_phy_mode(omap->port_mode[2])) |
409 | else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) | 531 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; |
410 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 532 | else if (is_ehci_tll_mode(omap->port_mode[2])) |
533 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | ||
534 | } | ||
535 | } else if (is_omap_ehci_rev2(omap)) { | ||
536 | /* Clear port mode fields for PHY mode*/ | ||
537 | reg &= ~OMAP4_P1_MODE_CLEAR; | ||
538 | reg &= ~OMAP4_P2_MODE_CLEAR; | ||
539 | |||
540 | if (is_ehci_tll_mode(omap->port_mode[0])) | ||
541 | reg |= OMAP4_P1_MODE_TLL; | ||
542 | else if (is_ehci_hsic_mode(omap->port_mode[0])) | ||
543 | reg |= OMAP4_P1_MODE_HSIC; | ||
411 | 544 | ||
545 | if (is_ehci_tll_mode(omap->port_mode[1])) | ||
546 | reg |= OMAP4_P2_MODE_TLL; | ||
547 | else if (is_ehci_hsic_mode(omap->port_mode[1])) | ||
548 | reg |= OMAP4_P2_MODE_HSIC; | ||
412 | } | 549 | } |
550 | |||
413 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); | 551 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); |
414 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); | 552 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); |
415 | 553 | ||
@@ -438,7 +576,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
438 | tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; | 576 | tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; |
439 | 577 | ||
440 | /* Enable UTMI mode for required TLL channels */ | 578 | /* Enable UTMI mode for required TLL channels */ |
441 | omap_usb_utmi_init(omap, tll_ch_mask); | 579 | omap_usb_utmi_init(omap, tll_ch_mask, OMAP_TLL_CHANNEL_COUNT); |
442 | } | 580 | } |
443 | 581 | ||
444 | if (omap->phy_reset) { | 582 | if (omap->phy_reset) { |
@@ -464,6 +602,14 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
464 | return 0; | 602 | return 0; |
465 | 603 | ||
466 | err_sys_status: | 604 | err_sys_status: |
605 | clk_disable(omap->utmi_p2_fck); | ||
606 | clk_put(omap->utmi_p2_fck); | ||
607 | clk_disable(omap->xclk60mhsp2_ck); | ||
608 | clk_put(omap->xclk60mhsp2_ck); | ||
609 | clk_disable(omap->utmi_p1_fck); | ||
610 | clk_put(omap->utmi_p1_fck); | ||
611 | clk_disable(omap->xclk60mhsp1_ck); | ||
612 | clk_put(omap->xclk60mhsp1_ck); | ||
467 | clk_disable(omap->usbtll_ick); | 613 | clk_disable(omap->usbtll_ick); |
468 | clk_put(omap->usbtll_ick); | 614 | clk_put(omap->usbtll_ick); |
469 | 615 | ||
@@ -472,8 +618,8 @@ err_tll_ick: | |||
472 | clk_put(omap->usbtll_fck); | 618 | clk_put(omap->usbtll_fck); |
473 | 619 | ||
474 | err_tll_fck: | 620 | err_tll_fck: |
475 | clk_disable(omap->usbhost1_48m_fck); | 621 | clk_disable(omap->usbhost_fs_fck); |
476 | clk_put(omap->usbhost1_48m_fck); | 622 | clk_put(omap->usbhost_fs_fck); |
477 | 623 | ||
478 | if (omap->phy_reset) { | 624 | if (omap->phy_reset) { |
479 | if (gpio_is_valid(omap->reset_gpio_port[0])) | 625 | if (gpio_is_valid(omap->reset_gpio_port[0])) |
@@ -484,8 +630,8 @@ err_tll_fck: | |||
484 | } | 630 | } |
485 | 631 | ||
486 | err_host_48m_fck: | 632 | err_host_48m_fck: |
487 | clk_disable(omap->usbhost2_120m_fck); | 633 | clk_disable(omap->usbhost_hs_fck); |
488 | clk_put(omap->usbhost2_120m_fck); | 634 | clk_put(omap->usbhost_hs_fck); |
489 | 635 | ||
490 | err_host_120m_fck: | 636 | err_host_120m_fck: |
491 | clk_disable(omap->usbhost_ick); | 637 | clk_disable(omap->usbhost_ick); |
@@ -503,6 +649,8 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
503 | 649 | ||
504 | /* Reset OMAP modules for insmod/rmmod to work */ | 650 | /* Reset OMAP modules for insmod/rmmod to work */ |
505 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, | 651 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, |
652 | is_omap_ehci_rev2(omap) ? | ||
653 | OMAP4_UHH_SYSCONFIG_SOFTRESET : | ||
506 | OMAP_UHH_SYSCONFIG_SOFTRESET); | 654 | OMAP_UHH_SYSCONFIG_SOFTRESET); |
507 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 655 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) |
508 | & (1 << 0))) { | 656 | & (1 << 0))) { |
@@ -550,16 +698,16 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
550 | omap->usbhost_ick = NULL; | 698 | omap->usbhost_ick = NULL; |
551 | } | 699 | } |
552 | 700 | ||
553 | if (omap->usbhost1_48m_fck != NULL) { | 701 | if (omap->usbhost_fs_fck != NULL) { |
554 | clk_disable(omap->usbhost1_48m_fck); | 702 | clk_disable(omap->usbhost_fs_fck); |
555 | clk_put(omap->usbhost1_48m_fck); | 703 | clk_put(omap->usbhost_fs_fck); |
556 | omap->usbhost1_48m_fck = NULL; | 704 | omap->usbhost_fs_fck = NULL; |
557 | } | 705 | } |
558 | 706 | ||
559 | if (omap->usbhost2_120m_fck != NULL) { | 707 | if (omap->usbhost_hs_fck != NULL) { |
560 | clk_disable(omap->usbhost2_120m_fck); | 708 | clk_disable(omap->usbhost_hs_fck); |
561 | clk_put(omap->usbhost2_120m_fck); | 709 | clk_put(omap->usbhost_hs_fck); |
562 | omap->usbhost2_120m_fck = NULL; | 710 | omap->usbhost_hs_fck = NULL; |
563 | } | 711 | } |
564 | 712 | ||
565 | if (omap->usbtll_ick != NULL) { | 713 | if (omap->usbtll_ick != NULL) { |
@@ -568,6 +716,32 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
568 | omap->usbtll_ick = NULL; | 716 | omap->usbtll_ick = NULL; |
569 | } | 717 | } |
570 | 718 | ||
719 | if (is_omap_ehci_rev2(omap)) { | ||
720 | if (omap->xclk60mhsp1_ck != NULL) { | ||
721 | clk_disable(omap->xclk60mhsp1_ck); | ||
722 | clk_put(omap->xclk60mhsp1_ck); | ||
723 | omap->xclk60mhsp1_ck = NULL; | ||
724 | } | ||
725 | |||
726 | if (omap->utmi_p1_fck != NULL) { | ||
727 | clk_disable(omap->utmi_p1_fck); | ||
728 | clk_put(omap->utmi_p1_fck); | ||
729 | omap->utmi_p1_fck = NULL; | ||
730 | } | ||
731 | |||
732 | if (omap->xclk60mhsp2_ck != NULL) { | ||
733 | clk_disable(omap->xclk60mhsp2_ck); | ||
734 | clk_put(omap->xclk60mhsp2_ck); | ||
735 | omap->xclk60mhsp2_ck = NULL; | ||
736 | } | ||
737 | |||
738 | if (omap->utmi_p2_fck != NULL) { | ||
739 | clk_disable(omap->utmi_p2_fck); | ||
740 | clk_put(omap->utmi_p2_fck); | ||
741 | omap->utmi_p2_fck = NULL; | ||
742 | } | ||
743 | } | ||
744 | |||
571 | if (omap->phy_reset) { | 745 | if (omap->phy_reset) { |
572 | if (gpio_is_valid(omap->reset_gpio_port[0])) | 746 | if (gpio_is_valid(omap->reset_gpio_port[0])) |
573 | gpio_free(omap->reset_gpio_port[0]); | 747 | gpio_free(omap->reset_gpio_port[0]); |