From d90859a67c0860bd24ee6fee7ab13f3db00929c4 Mon Sep 17 00:00:00 2001 From: Alexander Holler Date: Tue, 19 Apr 2011 09:30:35 -0400 Subject: omap3_beagle: enable EHCI and USB storage. The reset sequence/configuration for ehci is highly board specific, so this will be done in the source for the board, instead of introducing several CONFIG_* which would be needed to make those few lines in beagle.c usable across different OMAP boards. Signed-off-by: Alexander Holler Signed-off-by: Sandeep Paulraj --- board/ti/beagle/beagle.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'board/ti/beagle') diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 9f4e3dc..4e194a2 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -40,8 +40,19 @@ #include #include #include +#ifdef CONFIG_USB_EHCI +#include +#include +#include +#include +/* from drivers/usb/host/ehci-core.h */ +extern struct ehci_hccr *hccr; +extern volatile struct ehci_hcor *hcor; +#endif #include "beagle.h" +#define pr_debug(fmt, args...) debug(fmt, ##args) + #define TWL4030_I2C_BUS 0 #define EXPANSION_EEPROM_I2C_BUS 1 #define EXPANSION_EEPROM_I2C_ADDRESS 0x50 @@ -324,3 +335,98 @@ int board_mmc_init(bd_t *bis) return 0; } #endif + +#ifdef CONFIG_USB_EHCI + +#define GPIO_PHY_RESET 147 + +/* Reset is needed otherwise the kernel-driver will throw an error. */ +int ehci_hcd_stop(void) +{ + pr_debug("Resetting OMAP3 EHCI\n"); + omap_set_gpio_dataout(GPIO_PHY_RESET, 0); + writel(OMAP_UHH_SYSCONFIG_SOFTRESET, OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG); + return 0; +} + +/* Call usb_stop() before starting the kernel */ +void show_boot_progress(int val) +{ + if(val == 15) + usb_stop(); +} + +/* + * Initialize the OMAP3 EHCI controller and PHY on the BeagleBoard. + * Based on "drivers/usb/host/ehci-omap.c" from Linux 2.6.37. + * See there for additional Copyrights. + */ +int ehci_hcd_init(void) +{ + pr_debug("Initializing OMAP3 ECHI\n"); + + /* Put the PHY in RESET */ + omap_request_gpio(GPIO_PHY_RESET); + omap_set_gpio_direction(GPIO_PHY_RESET, 0); + omap_set_gpio_dataout(GPIO_PHY_RESET, 0); + + /* Hold the PHY in RESET for enough time till DIR is high */ + /* Refer: ISSUE1 */ + udelay(10); + + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + /* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */ + sr32(&prcm_base->iclken_usbhost, 0, 1, 1); + /* + * Enable USBHOST_48M_FCLK (USBHOST_FCLK1) + * and USBHOST_120M_FCLK (USBHOST_FCLK2) + */ + sr32(&prcm_base->fclken_usbhost, 0, 2, 3); + /* Enable USBTTL_ICLK */ + sr32(&prcm_base->iclken3_core, 2, 1, 1); + /* Enable USBTTL_FCLK */ + sr32(&prcm_base->fclken3_core, 2, 1, 1); + pr_debug("USB clocks enabled\n"); + + /* perform TLL soft reset, and wait until reset is complete */ + writel(OMAP_USBTLL_SYSCONFIG_SOFTRESET, + OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG); + /* Wait for TLL reset to complete */ + while (!(readl(OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSSTATUS) + & OMAP_USBTLL_SYSSTATUS_RESETDONE)); + pr_debug("TLL reset done\n"); + + writel(OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | + OMAP_USBTLL_SYSCONFIG_SIDLEMODE | + OMAP_USBTLL_SYSCONFIG_CACTIVITY, + OMAP3_USBTLL_BASE + OMAP_USBTLL_SYSCONFIG); + + /* Put UHH in NoIdle/NoStandby mode */ + writel(OMAP_UHH_SYSCONFIG_ENAWAKEUP + | OMAP_UHH_SYSCONFIG_SIDLEMODE + | OMAP_UHH_SYSCONFIG_CACTIVITY + | OMAP_UHH_SYSCONFIG_MIDLEMODE, + OMAP3_UHH_BASE + OMAP_UHH_SYSCONFIG); + + /* setup burst configurations */ + writel(OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN + | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN + | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN, + OMAP3_UHH_BASE + OMAP_UHH_HOSTCONFIG); + + /* + * Refer ISSUE1: + * Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + omap_set_gpio_dataout(GPIO_PHY_RESET, 1); + + hccr = (struct ehci_hccr *)(OMAP3_EHCI_BASE); + hcor = (struct ehci_hcor *)(OMAP3_EHCI_BASE + 0x10); + + pr_debug("OMAP3 EHCI init done\n"); + return 0; +} + +#endif /* CONFIG_USB_EHCI */ -- cgit v1.1