static void ehci_omap_enable(struct ehci_hcd_omap *omap, int enable) { u32 reg; if (enable) { printk(KERN_DEBUG "ehci_omap_enable\n"); ehci_omap_clock_power(omap, 1); /* Enable NoIdle/NoStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg &= ~(OMAP_UHH_SYSCONFIG_SIDLEMASK | OMAP_UHH_SYSCONFIG_MIDLEMASK); reg |= OMAP_UHH_SYSCONFIG_NOIDLE | OMAP_UHH_SYSCONFIG_NOSTDBY; ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); omap->suspended = 0; printk("[ehci]OMAP_UHH_SYSCONFIG=0x%x\n",reg); } else { printk(KERN_DEBUG "ehci_omap_enable\n"); /* Enable ForceIdle/ForceStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg &= ~(OMAP_UHH_SYSCONFIG_SIDLEMASK | OMAP_UHH_SYSCONFIG_MIDLEMASK); reg |= OMAP_UHH_SYSCONFIG_FORCEIDLE | OMAP_UHH_SYSCONFIG_FORCESTDBY; ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); ehci_omap_clock_power(omap, 0); omap->suspended = 1; } }
static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) { unsigned long timeout = jiffies + msecs_to_jiffies(100); dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); printk(KERN_DEBUG " omap_stop_ehc\n"); /* Reset OMAP modules for insmod/rmmod to work */ ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, OMAP_UHH_SYSCONFIG_SOFTRESET); while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 0))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 1))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 2))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } ehci_omap_clock_power(omap, 0); if (omap->usbtll_fck != NULL) { clk_put(omap->usbtll_fck); omap->usbtll_fck = NULL; } if (omap->usbhost_ick != NULL) { clk_put(omap->usbhost_ick); omap->usbhost_ick = NULL; } if (omap->usbhost1_48m_fck != NULL) { clk_put(omap->usbhost1_48m_fck); omap->usbhost1_48m_fck = NULL; } if (omap->usbhost2_120m_fck != NULL) { clk_put(omap->usbhost2_120m_fck); omap->usbhost2_120m_fck = NULL; } if (omap->usbtll_ick != NULL) { clk_put(omap->usbtll_ick); omap->usbtll_ick = NULL; } if (omap->phy_reset) { printk(KERN_DEBUG " free the reset the GPIOs\n"); if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_free(omap->reset_gpio_port[0]); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_free(omap->reset_gpio_port[1]); } dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); gpio_direction_output(23, 0); PHY_reset = 0; #ifndef CONFIG_MODEM_SMS if(!modem_resume_state || !g_sim_carddetect_status){ gpio_direction_output(4, 0); gpio_direction_output(35, 0); gpio_direction_output(36, 0); modem_PW = 0; } #endif }
/* omap_start_ehc * - Start the TI USBHOST controller */ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) { unsigned long timeout = jiffies + msecs_to_jiffies(1000); u8 tll_ch_mask = 0; unsigned reg = 0; int ret = 0; printk("omap_start_ehc kernel 2.6.35 V0.5 [07/12/2011] \n"); gpio_direction_output(23, 0); PHY_reset = 0; #ifndef CONFIG_MODEM_SMS gpio_direction_output(4, 1); gpio_direction_output(35, 1); gpio_direction_output(36, 1); modem_PW = 1; #endif dev_dbg(omap->dev, "starting TI EHCI USB Controller\n"); /* Get all the clock handles we need */ omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); if (IS_ERR(omap->usbhost_ick)) { dev_err(omap->dev, "could not get usbhost_ick\n"); ret = PTR_ERR(omap->usbhost_ick); goto err_host_ick; } omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); if (IS_ERR(omap->usbhost2_120m_fck)) { dev_err(omap->dev, "could not get usbhost2_120m_fck\n"); ret = PTR_ERR(omap->usbhost2_120m_fck); goto err_host_120m_fck; } omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); if (IS_ERR(omap->usbhost1_48m_fck)) { dev_err(omap->dev, "could not get usbhost_48m_fck\n"); ret = PTR_ERR(omap->usbhost1_48m_fck); goto err_host_48m_fck; } if (omap->phy_reset) { printk(KERN_DEBUG "reset the phys\n"); /* Refer: ISSUE1 */ if (gpio_is_valid(omap->reset_gpio_port[0])) { gpio_request(omap->reset_gpio_port[0], "USB1 PHY reset"); gpio_direction_output(omap->reset_gpio_port[0], 0); } if (gpio_is_valid(omap->reset_gpio_port[1])) { gpio_request(omap->reset_gpio_port[1],"USB2 PHY reset"); gpio_direction_output(omap->reset_gpio_port[1], 0); } /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); } omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); if (IS_ERR(omap->usbtll_fck)) { dev_err(omap->dev, "could not get usbtll_fck\n"); ret = PTR_ERR(omap->usbtll_fck); goto err_tll_fck; } omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); if (IS_ERR(omap->usbtll_ick)) { dev_err(omap->dev, "could not get usbtll_ick\n"); ret = PTR_ERR(omap->usbtll_ick); goto err_tll_ick; } /* Now enable all the clocks in the correct order */ ehci_omap_clock_power(omap, 1); /* Put UHH in NoIdle/NoStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg |= OMAP_UHH_SYSCONFIG_CACTIVITY | OMAP_UHH_SYSCONFIG_AUTOIDLE | OMAP_UHH_SYSCONFIG_ENAWAKEUP; reg &= ~(OMAP_UHH_SYSCONFIG_SIDLEMASK | OMAP_UHH_SYSCONFIG_MIDLEMASK); reg |= OMAP_UHH_SYSCONFIG_NOIDLE | OMAP_UHH_SYSCONFIG_NOSTDBY; ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); /* setup ULPI bypass and burst configurations */ reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; /* Bypass the TLL module for PHY mode operation */ if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); /* * An undocumented "feature" in the OMAP3 EHCI controller, * causes suspended ports to be taken out of suspend when * the USBCMD.Run/Stop bit is cleared (for example when * we do ehci_bus_suspend). * This breaks suspend-resume if the root-hub is allowed * to suspend. Writing 1 to this undocumented register bit * disables this feature and restores normal behavior. */ ehci_omap_writel(omap->ehci_base, EHCI_INSNREG04, EHCI_INSNREG04_DISABLE_UNSUSPEND); if (omap->phy_reset) { printk(KERN_DEBUG "unreset the phys\n"); /* Refer ISSUE1: * Hold the PHY in RESET for enough time till * PHY is settled and ready */ udelay(10); if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_set_value(omap->reset_gpio_port[0], 1); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_set_value(omap->reset_gpio_port[1], 1); } //gpio_direction_output(21, 1); //gpio_direction_output(36, 1); //gpio_direction_output(35, 1); //msleep(10); printk("RESET USB PHY\n"); gpio_direction_output(23, 1); PHY_reset = 1; return 0; err_sys_status: ehci_omap_clock_power(omap, 0); clk_put(omap->usbtll_ick); err_tll_ick: clk_put(omap->usbtll_fck); err_tll_fck: clk_put(omap->usbhost1_48m_fck); if (omap->phy_reset) { if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_free(omap->reset_gpio_port[0]); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_free(omap->reset_gpio_port[1]); } err_host_48m_fck: clk_put(omap->usbhost2_120m_fck); err_host_120m_fck: clk_put(omap->usbhost_ick); err_host_ick: return ret; }
static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) { unsigned long timeout = jiffies + msecs_to_jiffies(100); dev_dbg(omap->dev, "stopping TI EHCI USB Controller\n"); /* Reset OMAP modules for insmod/rmmod to work */ ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, OMAP_UHH_SYSCONFIG_SOFTRESET); while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 0))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 1))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) & (1 << 2))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) & (1 << 0))) { cpu_relax(); if (time_after(jiffies, timeout)) dev_dbg(omap->dev, "operation timed out\n"); } ehci_omap_clock_power(omap, 0); if (omap->usbtll_fck != NULL) { clk_disable(omap->usbtll_fck); clk_put(omap->usbtll_fck); omap->usbtll_fck = NULL; } if (omap->usbhost_ick != NULL) { clk_disable(omap->usbhost_ick); clk_put(omap->usbhost_ick); omap->usbhost_ick = NULL; } if (omap->usbhost1_48m_fck != NULL) { clk_disable(omap->usbhost1_48m_fck); clk_put(omap->usbhost1_48m_fck); omap->usbhost1_48m_fck = NULL; } if (omap->usbhost2_120m_fck != NULL) { clk_disable(omap->usbhost2_120m_fck); clk_put(omap->usbhost2_120m_fck); omap->usbhost2_120m_fck = NULL; } if (omap->usbtll_ick != NULL) { clk_disable(omap->usbtll_ick); clk_put(omap->usbtll_ick); omap->usbtll_ick = NULL; } if (omap->phy_reset) { if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_free(omap->reset_gpio_port[0]); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_free(omap->reset_gpio_port[1]); } dev_dbg(omap->dev, "Clock to USB host has been disabled\n"); }
/* omap_start_ehc * - Start the TI USBHOST controller */ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) { int ret = 0; dev_dbg(omap->dev, "starting TI EHCI USB Controller\n"); /* Get all the clock handles we need */ omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); if (IS_ERR(omap->usbhost_ick)) { dev_err(omap->dev, "could not get usbhost_ick\n"); ret = PTR_ERR(omap->usbhost_ick); goto err_host_ick; } omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); if (IS_ERR(omap->usbhost2_120m_fck)) { dev_err(omap->dev, "could not get usbhost_120m_fck\n"); ret = PTR_ERR(omap->usbhost2_120m_fck); goto err_host_120m_fck; } omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); if (IS_ERR(omap->usbhost1_48m_fck)) { dev_err(omap->dev, "could not get usbhost_48m_fck\n"); ret = PTR_ERR(omap->usbhost1_48m_fck); goto err_host_48m_fck; } /* Configure TLL for 60Mhz clk for ULPI */ omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); if (IS_ERR(omap->usbtll_fck)) { dev_err(omap->dev, "could not get usbttl_fck\n"); ret = PTR_ERR(omap->usbtll_fck); goto err_tll_fck; } omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); if (IS_ERR(omap->usbtll_ick)) { dev_err(omap->dev, "could not get usbtll_ick\n"); ret = PTR_ERR(omap->usbtll_ick); goto err_tll_ick; } /* Now enable all the clocks in the correct order */ ehci_omap_clock_power(omap, 1); ret = omap_init_uhh_registers(omap, hcd); if(ret < 0) { goto err_sys_status; } return 0; err_sys_status: clk_disable(omap->usbtll_ick); clk_put(omap->usbtll_ick); err_tll_ick: clk_disable(omap->usbtll_fck); clk_put(omap->usbtll_fck); err_tll_fck: clk_disable(omap->usbhost1_48m_fck); clk_put(omap->usbhost1_48m_fck); if (omap->phy_reset) { if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_free(omap->reset_gpio_port[0]); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_free(omap->reset_gpio_port[1]); } err_host_48m_fck: clk_disable(omap->usbhost2_120m_fck); clk_put(omap->usbhost2_120m_fck); err_host_120m_fck: clk_disable(omap->usbhost_ick); clk_put(omap->usbhost_ick); err_host_ick: return ret; }