/* * _dpll_test_fint - test whether an Fint value is valid for the DPLL * @clk: DPLL struct clk to test * @n: divider value (N) to test * * Tests whether a particular divider @n will result in a valid DPLL * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate * (assuming that it is counting N upwards), or -2 if the enclosing loop * should skip to the next iteration (again assuming N is increasing). */ static int _dpll_test_fint(struct clk *clk, u8 n) { struct dpll_data *dd; long fint, fint_min, fint_max; int ret = 0; dd = clk->dpll_data; /* DPLL divider must result in a valid jitter correction val */ fint = clk->parent->rate / n; if (cpu_is_omap24xx()) { /* Should not be called for OMAP2, so warn if it is called */ WARN(1, "No fint limits available for OMAP2!\n"); return DPLL_FINT_INVALID; } else if (cpu_is_omap3430()) { fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; } else if (dd->flags & DPLL_J_TYPE) { fint_min = OMAP3PLUS_DPLL_FINT_JTYPE_MIN; fint_max = OMAP3PLUS_DPLL_FINT_JTYPE_MAX; } else { fint_min = OMAP3PLUS_DPLL_FINT_MIN; fint_max = OMAP3PLUS_DPLL_FINT_MAX; } if (fint < fint_min) { pr_debug("rejecting n=%d due to Fint failure, " "lowering max_divider\n", n); dd->max_divider = n; ret = DPLL_FINT_UNDERFLOW; } else if (fint > fint_max) { pr_debug("rejecting n=%d due to Fint failure, " "boosting min_divider\n", n); dd->min_divider = n; ret = DPLL_FINT_INVALID; } else if (cpu_is_omap3430() && fint > OMAP3430_DPLL_FINT_BAND1_MAX && fint < OMAP3430_DPLL_FINT_BAND2_MIN) { pr_debug("rejecting n=%d due to Fint failure\n", n); ret = DPLL_FINT_INVALID; } return ret; }
int __init musb_platform_init(struct musb *musb) { u32 l; #if defined(CONFIG_ARCH_OMAP2430) omap_cfg_reg(AE5_2430_USB0HS_STP); #endif /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } musb_platform_resume(musb); l = musb_readl(musb->mregs, OTG_SYSCONFIG); l &= ~ENABLEWAKEUP; /* disable wakeup */ l &= ~NOSTDBY; /* remove possible nostdby */ l |= SMARTSTDBY; /* enable smart standby */ l &= ~AUTOIDLE; /* disable auto idle */ l &= ~NOIDLE; /* remove possible noidle */ l |= SMARTIDLE; /* enable smart idle */ /* * MUSB AUTOIDLE don't work in 3430. * Workaround by Richard Woodruff/TI */ if (!cpu_is_omap3430()) l |= AUTOIDLE; /* enable auto idle */ musb_writel(musb->mregs, OTG_SYSCONFIG, l); l = musb_readl(musb->mregs, OTG_INTERFSEL); l |= ULPI_12PIN; musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1); if (is_host_enabled(musb)) musb->board_set_vbus = omap_set_vbus; setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; }
static inline void omap_init_mbox(void) { if (cpu_is_omap2420() || cpu_is_omap3430() || cpu_is_omap44xx()) { mbox_device.num_resources = ARRAY_SIZE(omap_mbox_resources); mbox_device.resource = omap_mbox_resources; } else { pr_err("%s: platform not supported\n", __func__); return; } platform_device_register(&mbox_device); }
static inline void __init omap3evm_init_smsc911x(void) { /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST; else smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST; } gpmc_smsc911x_init(&smsc911x_cfg); }
static inline void omap_init_mbox(void) { if (cpu_is_omap2420()) { mbox_device.num_resources = ARRAY_SIZE(omap2_mbox_resources); mbox_device.resource = omap2_mbox_resources; } else if (cpu_is_omap3430() || cpu_is_omap3630()) { mbox_device.num_resources = ARRAY_SIZE(omap3_mbox_resources); mbox_device.resource = omap3_mbox_resources; } else { return; } platform_device_register(&mbox_device); }
static int __devinit omap2_mbox_probe(struct platform_device *pdev) { struct resource *mem; int ret; struct omap_mbox **list; if (false) ; #if defined(CONFIG_ARCH_OMAP3430) else if (cpu_is_omap3430()) { list = omap3_mboxes; list[0]->irq = platform_get_irq_byname(pdev, "dsp"); } #endif #if defined(CONFIG_ARCH_OMAP2420) else if (cpu_is_omap2420()) { list = omap2_mboxes; list[0]->irq = platform_get_irq_byname(pdev, "dsp"); list[1]->irq = platform_get_irq_byname(pdev, "iva"); } #endif #if defined(CONFIG_ARCH_OMAP4) else if (cpu_is_omap44xx()) { list = omap4_mboxes; list[0]->irq = list[1]->irq = platform_get_irq_byname(pdev, "mbox"); } #endif else { pr_err("%s: platform not supported\n", __func__); return -ENODEV; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mbox_base = ioremap(mem->start, resource_size(mem)); if (!mbox_base) return -ENOMEM; ret = omap_mbox_register(&pdev->dev, list); if (ret) { iounmap(mbox_base); return ret; } return 0; return ret; }
static inline void __init omap3evm_init_smsc911x(void) { int eth_cs, eth_rst; struct clk *l3ck; unsigned int rate; if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) eth_rst = OMAP3EVM_GEN1_ETHR_GPIO_RST; else eth_rst = OMAP3EVM_GEN2_ETHR_GPIO_RST; eth_cs = OMAP3EVM_SMSC911X_CS; l3ck = clk_get(NULL, "l3_ck"); if (IS_ERR(l3ck)) rate = 100000000; else rate = clk_get_rate(l3ck); /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { if (gpio_request(eth_rst, "SMSC911x gpio") < 0) { pr_err(KERN_ERR "Failed to request %d for smsc911x\n", eth_rst); return; } if (gpio_direction_output(eth_rst, 1) < 0) { pr_err(KERN_ERR "Failed to set direction of %d for" \ " smsc911x\n", eth_rst); return; } /* reset pulse to ethernet controller*/ usleep_range(150, 220); gpio_set_value(eth_rst, 0); usleep_range(150, 220); gpio_set_value(eth_rst, 1); usleep_range(1, 2); } if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) { printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", OMAP3EVM_ETHR_GPIO_IRQ); return; } gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ); platform_device_register(&omap3evm_smsc911x_device); }
int __init musb_platform_init(struct musb *musb) { u32 l; #if defined(CONFIG_ARCH_OMAP2430) omap_cfg_reg(AE5_2430_USB0HS_STP); #endif musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } musb_platform_resume(musb); l = omap_readl(OTG_SYSCONFIG); l &= ~ENABLEWAKEUP; l &= ~NOSTDBY; l |= SMARTSTDBY; l &= ~AUTOIDLE; l &= ~NOIDLE; l |= SMARTIDLE; if (!cpu_is_omap3430()) l |= AUTOIDLE; omap_writel(l, OTG_SYSCONFIG); l = omap_readl(OTG_INTERFSEL); l |= ULPI_12PIN; omap_writel(l, OTG_INTERFSEL); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", omap_readl(OTG_REVISION), omap_readl(OTG_SYSCONFIG), omap_readl(OTG_SYSSTATUS), omap_readl(OTG_INTERFSEL), omap_readl(OTG_SIMENABLE)); omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1); if (is_host_enabled(musb)) musb->board_set_vbus = omap_set_vbus; setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; }
/** * ti_clk_init_features - init clock features struct for the SoC * * Initializes the clock features struct based on the SoC type. */ void __init ti_clk_init_features(void) { /* Fint setup for DPLLs */ if (cpu_is_omap3430()) { ti_clk_features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN; ti_clk_features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX; ti_clk_features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX; ti_clk_features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN; } else { ti_clk_features.fint_min = OMAP3PLUS_DPLL_FINT_MIN; ti_clk_features.fint_max = OMAP3PLUS_DPLL_FINT_MAX; } /* Bypass value setup for DPLLs */ if (cpu_is_omap24xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP2XXX_EN_DPLL_LPBYPASS) | (1 << OMAP2XXX_EN_DPLL_FRBYPASS); } else if (cpu_is_omap34xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP3XXX_EN_DPLL_LPBYPASS) | (1 << OMAP3XXX_EN_DPLL_FRBYPASS); } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() || soc_is_omap54xx() || soc_is_dra7xx()) { ti_clk_features.dpll_bypass_vals |= (1 << OMAP4XXX_EN_DPLL_LPBYPASS) | (1 << OMAP4XXX_EN_DPLL_FRBYPASS) | (1 << OMAP4XXX_EN_DPLL_MNBYPASS); } /* Jitter correction only available on OMAP343X */ if (cpu_is_omap343x()) ti_clk_features.flags |= TI_CLK_DPLL_HAS_FREQSEL; /* Idlest value for interface clocks. * 24xx uses 0 to indicate not ready, and 1 to indicate ready. * 34xx reverses this, just to keep us on our toes * AM35xx uses both, depending on the module. */ if (cpu_is_omap24xx()) ti_clk_features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL; else if (cpu_is_omap34xx()) ti_clk_features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL; /* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */ if (omap_rev() == OMAP3430_REV_ES1_0) ti_clk_features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM; }
static inline void __init omap3evm_init_smsc911x(void) { struct clk *l3ck; unsigned int rate; l3ck = clk_get(NULL, "l3_ck"); if (IS_ERR(l3ck)) rate = 100000000; else rate = clk_get_rate(l3ck); /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST; else smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST; } gpmc_smsc911x_init(&smsc911x_cfg); }
/*------------------------------------------------------------------------- * Setup Usb High Speed Host mode. * */ static int set_uhh_mode(struct ehci_hcd_omap *omap) { unsigned reg = 0; if (cpu_is_omap44xx()) { /* Put UHH in NoIdle/NoStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg &= OMAP_UHH_SYSCONFIG_IDLEMODE_RESET; reg |= OMAP_UHH_SYSCONFIG_NIDLEMODE_SET; reg &= OMAP_UHH_SYSCONFIG_STDYMODE_RESET; reg |= OMAP_UHH_SYSCONFIG_NSTDYMODE_SET; ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); /* setup ULPI bypass and burst configurations */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 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; /* set p1 & p2 modes */ reg &= OMAP_UHH_HOST_PORTS_RESET; if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) reg |= OMAP_UHH_HOST_P1_SET_ULPIPHY; else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) reg |= OMAP_UHH_HOST_P1_SET_ULPITLL; if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) reg |= OMAP_UHH_HOST_P2_SET_ULPIPHY; else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) reg |= OMAP_UHH_HOST_P2_SET_ULPITLL; ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); } else { /* Put UHH in NoIdle/NoStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg |= OMAP_UHH_SYSCONFIG_ENAWAKEUP; reg |= OMAP_UHH_SYSCONFIG_SIDLEMODE; reg |= OMAP_UHH_SYSCONFIG_CACTIVITY; reg |= OMAP_UHH_SYSCONFIG_MIDLEMODE ; reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); /* setup ULPI bypass and burst configurations */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); reg |= OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN; reg |= OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN; reg |= 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; 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); /* * 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); } dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); return 0; }
static void omap_usbhs_init(struct device *dev) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = &omap->platdata; unsigned long flags = 0; unsigned reg; dev_dbg(dev, "starting TI HSUSB Controller\n"); pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { gpio_request(pdata->ehci_data->reset_gpio_port[0], "USB1 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[0], 0); } if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { gpio_request(pdata->ehci_data->reset_gpio_port[1], "USB2 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[1], 0); } /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); } omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); /* * Really enable the port clocks * first call of pm_runtime_get_sync does not enable these * port clocks; because omap->usbhs_rev was not available * This omap->usbhs_rev is available now! */ usbhs_runtime_resume(dev); reg = usbhs_read(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); /* Keep ENA_INCR_ALIGN = 0: Known to cause OCP delays */ reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_usbhs_rev1(omap)) { if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) 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(dev, "OMAP3 ES version <= ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0]) || is_ehci_phy_mode(pdata->port_mode[1]) || is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[1])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } } else if (is_omap_usbhs_rev2(omap)) { /* Clear port mode fields for PHY mode*/ reg &= ~OMAP4_P1_MODE_CLEAR; reg &= ~OMAP4_P2_MODE_CLEAR; if (is_ehci_tll_mode(pdata->port_mode[0]) || (is_ohci_port(pdata->port_mode[0]))) reg |= OMAP4_P1_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[0])) reg |= OMAP4_P1_MODE_HSIC; if (is_ehci_tll_mode(pdata->port_mode[1]) || (is_ohci_port(pdata->port_mode[1]))) reg |= OMAP4_P2_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[1])) reg |= OMAP4_P2_MODE_HSIC; } usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); if (is_ehci_tll_mode(pdata->port_mode[0]) || is_ehci_tll_mode(pdata->port_mode[1]) || is_ehci_tll_mode(pdata->port_mode[2]) || (is_ohci_port(pdata->port_mode[0])) || (is_ohci_port(pdata->port_mode[1])) || (is_ohci_port(pdata->port_mode[2]))) { /* Enable UTMI mode for required TLL channels */ if (is_omap_usbhs_rev2(omap)) usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); else usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } if (pdata->ehci_data->phy_reset) { /* Hold the PHY in RESET for enough time till * PHY is settled and ready */ udelay(10); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_set_value (pdata->ehci_data->reset_gpio_port[0], 1); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_set_value (pdata->ehci_data->reset_gpio_port[1], 1); } spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); }
/* 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 int omap3_select_table_rate(struct clk *clk, unsigned long rate) { u8 cpu_mask = 0; u32 cur_vdd_rate, current_opp; struct vdd_prcm_config *prcm_vdd; unsigned long found_speed = 0; int ret = -EINVAL; int div = 0; if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set)) return ret; if (cpu_is_omap3430()) cpu_mask = RATE_IN_343X; if (clk == &virt_vdd1_prcm_set) prcm_vdd = vdd1_rate_table + MAX_VDD1_OPP; else prcm_vdd = vdd2_rate_table + MAX_VDD2_OPP; for (; prcm_vdd->speed; prcm_vdd--) { if (!(prcm_vdd->flags & cpu_mask)) continue; if (prcm_vdd->speed <= rate) { found_speed = prcm_vdd->speed; pr_debug("Found speed = %lu\n", found_speed); break; } } if (!found_speed) { printk(KERN_INFO "Could not set table rate to %luMHz\n", rate / 1000000); return -EINVAL; } if (clk == &virt_vdd1_prcm_set) { ret = prcm_get_processor_speed(clk->parent->prcmid, &cur_vdd_rate); if (ret != PRCM_PASS) return -EINVAL; current_opp = curr_vdd1_prcm_set->opp; } else { ret = prcm_get_dpll_rate(clk->parent->prcmid, &cur_vdd_rate); if (ret != PRCM_PASS) return -EINVAL; /* Now cur_vdd_rate holds value of core_ck */ /* The divider for l3_ck */ ret = prcm_clksel_get_divider((&l3_ck)->prcmid, &div); if ((ret != PRCM_PASS) || (div == 0)) return -EINVAL; cur_vdd_rate /= div; current_opp = curr_vdd2_prcm_set->opp; } cur_vdd_rate *= 1000; pr_debug("Current rate:%u\n", cur_vdd_rate); if (cur_vdd_rate != found_speed) { ret = prcm_do_frequency_scaling(prcm_vdd->opp, current_opp); if (ret != PRCM_PASS) return -EINVAL; #ifdef CONFIG_CORE_OFF save_scratchpad_contents(); #endif } if (clk == &virt_vdd1_prcm_set) { curr_vdd1_prcm_set = prcm_vdd; omap3_clk_recalc(&mpu_ck); omap3_propagate_rate(&mpu_ck); omap3_clk_recalc(&iva2_ck); omap3_propagate_rate(&iva2_ck); #ifndef CONFIG_CPU_FREQ /*Update loops_per_jiffy if processor speed is being changed*/ loops_per_jiffy = compute_lpj(loops_per_jiffy, (cur_vdd_rate / 1000), (found_speed / 1000)); #endif } else { curr_vdd2_prcm_set = prcm_vdd; omap3_clk_recalc(&core_ck); omap3_propagate_rate(&core_ck); omap3_clk_recalc(&core_x2_ck); omap3_propagate_rate(&core_x2_ck); omap3_clk_recalc(&emul_core_alwon_ck); omap3_propagate_rate(&emul_core_alwon_ck); } return 0; }
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, int controller_nr) { if (cpu_is_omap2420() && controller_nr == 0) { omap_cfg_reg(H18_24XX_MMC_CMD); omap_cfg_reg(H15_24XX_MMC_CLKI); omap_cfg_reg(G19_24XX_MMC_CLKO); omap_cfg_reg(F20_24XX_MMC_DAT0); omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); omap_cfg_reg(G18_24XX_MMC_CMD_DIR); if (mmc_controller->slots[0].wires == 4) { omap_cfg_reg(H14_24XX_MMC_DAT1); omap_cfg_reg(E19_24XX_MMC_DAT2); omap_cfg_reg(D19_24XX_MMC_DAT3); omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); } /* * Use internal loop-back in MMC/SDIO Module Input Clock * selection */ if (mmc_controller->slots[0].internal_clock) { u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); v |= (1 << 24); omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); } } if (cpu_is_omap3430()) { if (controller_nr == 0) { omap_cfg_reg(N28_3430_MMC1_CLK); omap_cfg_reg(M27_3430_MMC1_CMD); omap_cfg_reg(N27_3430_MMC1_DAT0); if (mmc_controller->slots[0].wires == 4 || mmc_controller->slots[0].wires == 8) { omap_cfg_reg(N26_3430_MMC1_DAT1); omap_cfg_reg(N25_3430_MMC1_DAT2); omap_cfg_reg(P28_3430_MMC1_DAT3); } if (mmc_controller->slots[0].wires == 8) { omap_cfg_reg(P27_3430_MMC1_DAT4); omap_cfg_reg(P26_3430_MMC1_DAT5); omap_cfg_reg(R27_3430_MMC1_DAT6); omap_cfg_reg(R25_3430_MMC1_DAT7); } } if (controller_nr == 1) { /* MMC2 */ omap_cfg_reg(AE2_3430_MMC2_CLK); omap_cfg_reg(AG5_3430_MMC2_CMD); omap_cfg_reg(AH5_3430_MMC2_DAT0); /* * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed * in the board-*.c files */ if (mmc_controller->slots[0].wires == 4 || mmc_controller->slots[0].wires == 8) { omap_cfg_reg(AH4_3430_MMC2_DAT1); omap_cfg_reg(AG4_3430_MMC2_DAT2); omap_cfg_reg(AF4_3430_MMC2_DAT3); } } /* * For MMC3 the pins need to be muxed in the board-*.c files */ } }
static int usbhs_enable(struct device *dev) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = &omap->platdata; unsigned long flags = 0; int ret = 0; unsigned long timeout; unsigned reg; dev_dbg(dev, "starting TI HSUSB Controller\n"); if (!pdata) { dev_dbg(dev, "missing platform_data\n"); return -ENODEV; } spin_lock_irqsave(&omap->lock, flags); if (omap->count > 0) goto end_count; clk_enable(omap->usbhost_ick); clk_enable(omap->usbhost_hs_fck); clk_enable(omap->usbhost_fs_fck); clk_enable(omap->usbtll_fck); clk_enable(omap->usbtll_ick); if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { gpio_request(pdata->ehci_data->reset_gpio_port[0], "USB1 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[0], 0); } if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { gpio_request(pdata->ehci_data->reset_gpio_port[1], "USB2 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[1], 0); } /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); } omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); /* perform TLL soft reset, and wait until reset is complete */ usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, OMAP_USBTLL_SYSCONFIG_SOFTRESET); /* Wait for TLL reset to complete */ timeout = jiffies + msecs_to_jiffies(1000); while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { cpu_relax(); if (time_after(jiffies, timeout)) { dev_dbg(dev, "operation timed out\n"); ret = -EINVAL; goto err_tll; } } dev_dbg(dev, "TLL RESET DONE\n"); /* (1<<3) = no idle mode only for initial debugging */ usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | OMAP_USBTLL_SYSCONFIG_SIDLEMODE | OMAP_USBTLL_SYSCONFIG_AUTOIDLE); /* Put UHH in NoIdle/NoStandby mode */ reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); if (is_omap_usbhs_rev1(omap)) { reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | OMAP_UHH_SYSCONFIG_SIDLEMODE | OMAP_UHH_SYSCONFIG_CACTIVITY | OMAP_UHH_SYSCONFIG_MIDLEMODE); reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; } else if (is_omap_usbhs_rev2(omap)) { reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; } usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); reg = usbhs_read(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 |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_usbhs_rev1(omap)) { if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) 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(dev, "OMAP3 ES version <= ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0]) || is_ehci_phy_mode(pdata->port_mode[1]) || is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[1])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } } else if (is_omap_usbhs_rev2(omap)) { /* Clear port mode fields for PHY mode*/ reg &= ~OMAP4_P1_MODE_CLEAR; reg &= ~OMAP4_P2_MODE_CLEAR; if (is_ehci_phy_mode(pdata->port_mode[0])) { ret = clk_set_parent(omap->utmi_p1_fck, omap->xclk60mhsp1_ck); if (ret != 0) { dev_err(dev, "xclk60mhsp1_ck set parent" "failed error:%d\n", ret); goto err_tll; } } else if (is_ehci_tll_mode(pdata->port_mode[0])) { ret = clk_set_parent(omap->utmi_p1_fck, omap->init_60m_fclk); if (ret != 0) { dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); goto err_tll; } clk_enable(omap->usbhost_p1_fck); clk_enable(omap->usbtll_p1_fck); } if (is_ehci_phy_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->xclk60mhsp2_ck); if (ret != 0) { dev_err(dev, "xclk60mhsp1_ck set parent" "failed error:%d\n", ret); goto err_tll; } } else if (is_ehci_tll_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->init_60m_fclk); if (ret != 0) { dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); goto err_tll; } clk_enable(omap->usbhost_p2_fck); clk_enable(omap->usbtll_p2_fck); } clk_enable(omap->utmi_p1_fck); clk_enable(omap->utmi_p2_fck); if (is_ehci_tll_mode(pdata->port_mode[0]) || (is_ohci_port(pdata->port_mode[0]))) reg |= OMAP4_P1_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[0])) reg |= OMAP4_P1_MODE_HSIC; if (is_ehci_tll_mode(pdata->port_mode[1]) || (is_ohci_port(pdata->port_mode[1]))) reg |= OMAP4_P2_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[1])) reg |= OMAP4_P2_MODE_HSIC; } usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); if (is_ehci_tll_mode(pdata->port_mode[0]) || is_ehci_tll_mode(pdata->port_mode[1]) || is_ehci_tll_mode(pdata->port_mode[2]) || (is_ohci_port(pdata->port_mode[0])) || (is_ohci_port(pdata->port_mode[1])) || (is_ohci_port(pdata->port_mode[2]))) { /* Enable UTMI mode for required TLL channels */ if (is_omap_usbhs_rev2(omap)) usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); else usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } if (pdata->ehci_data->phy_reset) { /* Hold the PHY in RESET for enough time till * PHY is settled and ready */ udelay(10); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_set_value (pdata->ehci_data->reset_gpio_port[0], 1); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_set_value (pdata->ehci_data->reset_gpio_port[1], 1); } end_count: omap->count++; spin_unlock_irqrestore(&omap->lock, flags); return 0; err_tll: if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_free(pdata->ehci_data->reset_gpio_port[0]); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_free(pdata->ehci_data->reset_gpio_port[1]); } clk_disable(omap->usbtll_ick); clk_disable(omap->usbtll_fck); clk_disable(omap->usbhost_fs_fck); clk_disable(omap->usbhost_hs_fck); clk_disable(omap->usbhost_ick); spin_unlock_irqrestore(&omap->lock, flags); return ret; }
static int omap2430_musb_init(struct musb *musb) { u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } omap2430_low_level_init(musb); l = musb_readl(musb->mregs, OTG_SYSCONFIG); l &= ~ENABLEWAKEUP; /* disable wakeup */ l &= ~NOSTDBY; /* remove possible nostdby */ l |= SMARTSTDBY; /* enable smart standby */ l &= ~AUTOIDLE; /* disable auto idle */ l &= ~NOIDLE; /* remove possible noidle */ l |= SMARTIDLE; /* enable smart idle */ /* * MUSB AUTOIDLE don't work in 3430. * Workaround by Richard Woodruff/TI */ if (!cpu_is_omap3430()) l |= AUTOIDLE; /* enable auto idle */ musb_writel(musb->mregs, OTG_SYSCONFIG, l); l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) DBG(1, "notification register failed\n"); /* check whether cable is already connected */ if (musb->xceiv->state ==OTG_STATE_B_IDLE) musb_otg_notifications(&musb->nb, 1, musb->xceiv->gadget); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; }
static void omap_usbhs_init(struct device *dev) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = &omap->platdata; unsigned long flags; unsigned reg; dev_dbg(dev, "starting TI HSUSB Controller\n"); pm_runtime_get_sync(dev); if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_request_one(pdata->ehci_data->reset_gpio_port[0], GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_request_one(pdata->ehci_data->reset_gpio_port[1], GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[2])) gpio_request_one(pdata->ehci_data->reset_gpio_port[2], GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); } spin_lock_irqsave(&omap->lock, flags); omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); reg = usbhs_read(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 |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_usbhs_rev1(omap)) { if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) 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(dev, "OMAP3 ES version <= ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0]) || is_ehci_phy_mode(pdata->port_mode[1]) || is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[1])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } } else if (is_omap_usbhs_rev2(omap)) { /* Clear port mode fields for PHY mode*/ reg &= ~OMAP4_P1_MODE_CLEAR; reg &= ~OMAP4_P2_MODE_CLEAR; if (is_ehci_tll_mode(pdata->port_mode[0]) || (is_ohci_port(pdata->port_mode[0]))) reg |= OMAP4_P1_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[0])) reg |= OMAP4_P1_MODE_HSIC; if (is_ehci_tll_mode(pdata->port_mode[1]) || (is_ohci_port(pdata->port_mode[1]))) reg |= OMAP4_P2_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[1])) reg |= OMAP4_P2_MODE_HSIC; if (is_ehci_hsic_mode(pdata->port_mode[2])) reg |= OMAP5_P3_MODE_HSIC; } usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); spin_unlock_irqrestore(&omap->lock, flags); if (pdata->ehci_data->phy_reset) { /* Hold the PHY in RESET for enough time till * PHY is settled and ready */ udelay(10); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_set_value(pdata->ehci_data->reset_gpio_port[0], 1); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_set_value(pdata->ehci_data->reset_gpio_port[1], 1); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[2])) gpio_set_value(pdata->ehci_data->reset_gpio_port[2], 1); } pm_runtime_put_sync(dev); }
void __init usb_musb_init(struct omap_musb_board_data *board_data) { char oh_name[MAX_OMAP_MUSB_HWMOD_NAME_LEN]; struct omap_hwmod *oh; struct omap_device *od; struct platform_device *pdev; struct device *dev; int l, bus_id = -1; struct musb_hdrc_platform_data *pdata; if (!board_data) { pr_err("Board data is required for hdrc device register\n"); return; } l = snprintf(oh_name, MAX_OMAP_MUSB_HWMOD_NAME_LEN, "usb_otg_hs"); WARN(l >= MAX_OMAP_MUSB_HWMOD_NAME_LEN, "String buffer overflow in MUSB device setup\n"); oh = omap_hwmod_lookup(oh_name); if (!oh) { pr_err("Could not look up %s\n", oh_name); } else { /* * REVISIT: This line can be removed once all the platforms * using musb_core.c have been converted to use use clkdev. */ musb_plat.clock = "ick"; musb_plat.board_data = board_data; musb_plat.power = board_data->power >> 1; musb_plat.mode = board_data->mode; musb_plat.device_enable = omap_device_enable; musb_plat.device_idle = omap_device_idle; musb_plat.enable_wakeup = omap_device_enable_wakeup; musb_plat.disable_wakeup = omap_device_disable_wakeup; #ifdef CONFIG_PM musb_plat.set_min_bus_tput = omap_pm_set_min_bus_tput; #endif /* * Errata 1.166 idle_req/ack is broken in omap3430 * workaround is to disable the autodile bit for omap3430. */ if (cpu_is_omap3430() || cpu_is_omap3630()) oh->flags |= HWMOD_NO_OCP_AUTOIDLE; musb_plat.oh = oh; oh_p = oh; pdata = &musb_plat; od = omap_device_build(name, bus_id, oh, pdata, sizeof(struct musb_hdrc_platform_data), omap_musb_latency, ARRAY_SIZE(omap_musb_latency), false); if (IS_ERR(od)) { pr_err("Could not build omap_device for %s %s\n", name, oh_name); } else { pdev = &od->pdev; dev = &pdev->dev; get_device(dev); dev->dma_mask = &musb_dmamask; dev->coherent_dma_mask = musb_dmamask; put_device(dev); } /*powerdown the phy*/ if (board_data->interface_type == MUSB_INTERFACE_UTMI) omap_writel(PHY_PD, DIE_ID_REG_BASE + CONTROL_DEV_CONF); usb_gadget_init(); } }
void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) { struct omap_hwmod *oh; struct platform_device *pdev; struct device *dev; int bus_id = -1; const char *oh_name, *name; struct omap_musb_board_data *board_data; if (musb_board_data) board_data = musb_board_data; else board_data = &musb_default_board_data; /* * REVISIT: This line can be removed once all the platforms using * musb_core.c have been converted to use use clkdev. */ musb_plat[0].clock = "ick"; musb_plat[0].board_data = board_data; musb_plat[0].power = board_data->power >> 1; musb_plat[0].mode = board_data->mode; musb_plat[0].extvbus = board_data->extvbus; /* * OMAP3630/AM35x platform has MUSB RTL-1.8 which has the fix for the * issue restricting active endpoints to use first 8K of FIFO space. * This issue restricts OMAP35x platform to use fifo_mode '5'. */ if (cpu_is_omap3430()) musb_config.fifo_mode = 5; if (cpu_is_omap3517() || cpu_is_omap3505()) { oh_name = "am35x_otg_hs"; name = "musb-am35x"; } else if (cpu_is_ti81xx() || cpu_is_am33xx()) { board_data->set_phy_power = ti81xx_musb_phy_power; oh_name = "usb_otg_hs"; name = "musb-ti81xx"; } else { oh_name = "usb_otg_hs"; name = "musb-omap2430"; } oh = omap_hwmod_lookup(oh_name); if (WARN(!oh, "%s: could not find omap_hwmod for %s\n", __func__, oh_name)) return; pdev = omap_device_build(name, bus_id, oh, &musb_plat, sizeof(musb_plat), NULL, 0, false); if (IS_ERR(pdev)) { pr_err("Could not build omap_device for %s %s\n", name, oh_name); return; } dev = &pdev->dev; get_device(dev); dev->dma_mask = &musb_dmamask; dev->coherent_dma_mask = musb_dmamask; put_device(dev); if (cpu_is_omap44xx()) omap4430_phy_init(dev); }
/*! ****************************************************************************** @Function EnableSGXClocks @Description Enable SGX clocks @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) { #if !defined(NO_HARDWARE) SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; /* SGX clocks already enabled? */ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) { return PVRSRV_OK; } PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); #if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) #if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) { struct gpu_platform_data *pdata; IMG_UINT32 max_freq_index; int res; pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; /* * Request maximum frequency from DVFS layer if not already set. DVFS may * report busy if early in initialization, but all other errors are * considered serious. Upon any error we proceed assuming our safe frequency * value to be in use as indicated by the "unknown" index. */ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) { PVR_ASSERT(pdata->device_scale != IMG_NULL); res = pdata->device_scale(&gpsPVRLDMDev->dev, &gpsPVRLDMDev->dev, psSysSpecData->pui32SGXFreqList[max_freq_index]); if (res == 0) { psSysSpecData->ui32SGXFreqListIndex = max_freq_index; } else if (res == -EBUSY) { PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; } else if (res < 0) { PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; } } } #endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ { /* * pm_runtime_get_sync returns 1 after the module has * been reloaded. */ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); if (res < 0) { PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; } } #endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ SysEnableSGXInterrupts(psSysData); #if !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) if (cpu_is_omap3430()) { /* pin the memory bus bw to the highest value */ omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 400000); } else if (cpu_is_omap3630()) { /* pin the memory bus bw to the highest value */ omap_pm_set_min_bus_tput(&gpsPVRLDMDev->dev, OCP_INITIATOR_AGENT, 800000); } else { PVR_DPF((PVR_DBG_ERROR, "ForceMaxSGXClocks: \ Invalid OMAP Chip ID")); return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; } #endif /* Indicate that the SGX clocks are enabled */ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); #else /* !defined(NO_HARDWARE) */ PVR_UNREFERENCED_PARAMETER(psSysData); #endif /* !defined(NO_HARDWARE) */ return PVRSRV_OK; }
static void omap_usbhs_init(struct device *dev) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = &omap->platdata; unsigned long flags; unsigned reg; dev_dbg(dev, "starting TI HSUSB Controller\n"); pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); reg = usbhs_read(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 |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_usbhs_rev1(omap)) { if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) 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(dev, "OMAP3 ES version <= ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0]) || is_ehci_phy_mode(pdata->port_mode[1]) || is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[1])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } } else if (is_omap_usbhs_rev2(omap)) { /* Clear port mode fields for PHY mode*/ reg &= ~OMAP4_P1_MODE_CLEAR; reg &= ~OMAP4_P2_MODE_CLEAR; if (is_ehci_tll_mode(pdata->port_mode[0]) || (is_ohci_port(pdata->port_mode[0]))) reg |= OMAP4_P1_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[0])) reg |= OMAP4_P1_MODE_HSIC; if (is_ehci_tll_mode(pdata->port_mode[1]) || (is_ohci_port(pdata->port_mode[1]))) reg |= OMAP4_P2_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[1])) reg |= OMAP4_P2_MODE_HSIC; } usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); if (is_ehci_tll_mode(pdata->port_mode[0]) || is_ehci_tll_mode(pdata->port_mode[1]) || is_ehci_tll_mode(pdata->port_mode[2]) || (is_ohci_port(pdata->port_mode[0])) || (is_ohci_port(pdata->port_mode[1])) || (is_ohci_port(pdata->port_mode[2]))) { /* Enable UTMI mode for required TLL channels */ if (is_omap_usbhs_rev2(omap)) usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); else usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); }
static int usbhs_enable(struct device *dev) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = &omap->platdata; unsigned long flags = 0; int ret = 0; unsigned reg; dev_dbg(dev, "starting TI HSUSB Controller\n"); if (!pdata) { dev_dbg(dev, "missing platform_data\n"); return -ENODEV; } spin_lock_irqsave(&omap->lock, flags); if (omap->count > 0) goto end_count; pm_runtime_get_sync(dev); if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { gpio_request(pdata->ehci_data->reset_gpio_port[0], "USB1 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[0], 0); } if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { gpio_request(pdata->ehci_data->reset_gpio_port[1], "USB2 PHY reset"); gpio_direction_output (pdata->ehci_data->reset_gpio_port[1], 0); } /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); } omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); reg = usbhs_read(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 |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK; reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; if (is_omap_usbhs_rev1(omap)) { if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED) reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED) 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(dev, "OMAP3 ES version <= ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0]) || is_ehci_phy_mode(pdata->port_mode[1]) || is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; } else { dev_dbg(dev, "OMAP3 ES version > ES2.1\n"); if (is_ehci_phy_mode(pdata->port_mode[0])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[1])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; if (is_ehci_phy_mode(pdata->port_mode[2])) reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; else reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; } } else if (is_omap_usbhs_rev2(omap)) { /* Clear port mode fields for PHY mode*/ reg &= ~OMAP4_P1_MODE_CLEAR; reg &= ~OMAP4_P2_MODE_CLEAR; if (is_ehci_phy_mode(pdata->port_mode[0])) { ret = clk_set_parent(omap->utmi_p1_fck, omap->xclk60mhsp1_ck); if (ret != 0) { dev_err(dev, "xclk60mhsp1_ck set parent" "failed error:%d\n", ret); goto err_tll; } } else if (is_ehci_tll_mode(pdata->port_mode[0])) { ret = clk_set_parent(omap->utmi_p1_fck, omap->init_60m_fclk); if (ret != 0) { dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); goto err_tll; } clk_enable(omap->usbhost_p1_fck); clk_enable(omap->usbtll_p1_fck); } if (is_ehci_phy_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->xclk60mhsp2_ck); if (ret != 0) { dev_err(dev, "xclk60mhsp1_ck set parent" "failed error:%d\n", ret); goto err_tll; } } else if (is_ehci_tll_mode(pdata->port_mode[1])) { ret = clk_set_parent(omap->utmi_p2_fck, omap->init_60m_fclk); if (ret != 0) { dev_err(dev, "init_60m_fclk set parent" "failed error:%d\n", ret); goto err_tll; } clk_enable(omap->usbhost_p2_fck); clk_enable(omap->usbtll_p2_fck); } clk_enable(omap->utmi_p1_fck); clk_enable(omap->utmi_p2_fck); if (is_ehci_tll_mode(pdata->port_mode[0]) || (is_ohci_port(pdata->port_mode[0]))) reg |= OMAP4_P1_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[0])) reg |= OMAP4_P1_MODE_HSIC; if (is_ehci_tll_mode(pdata->port_mode[1]) || (is_ohci_port(pdata->port_mode[1]))) reg |= OMAP4_P2_MODE_TLL; else if (is_ehci_hsic_mode(pdata->port_mode[1])) reg |= OMAP4_P2_MODE_HSIC; } usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); if (is_ehci_tll_mode(pdata->port_mode[0]) || is_ehci_tll_mode(pdata->port_mode[1]) || is_ehci_tll_mode(pdata->port_mode[2]) || (is_ohci_port(pdata->port_mode[0])) || (is_ohci_port(pdata->port_mode[1])) || (is_ohci_port(pdata->port_mode[2]))) { /* Enable UTMI mode for required TLL channels */ if (is_omap_usbhs_rev2(omap)) usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT); else usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } if (pdata->ehci_data->phy_reset) { /* Hold the PHY in RESET for enough time till * PHY is settled and ready */ udelay(10); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_set_value (pdata->ehci_data->reset_gpio_port[0], 1); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_set_value (pdata->ehci_data->reset_gpio_port[1], 1); } end_count: omap->count++; spin_unlock_irqrestore(&omap->lock, flags); return 0; err_tll: pm_runtime_put_sync(dev); spin_unlock_irqrestore(&omap->lock, flags); if (pdata->ehci_data->phy_reset) { if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) gpio_free(pdata->ehci_data->reset_gpio_port[0]); if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) gpio_free(pdata->ehci_data->reset_gpio_port[1]); } return ret; }
static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, int controller_nr) { if (cpu_is_omap2420() && controller_nr == 0) { omap_cfg_reg(H18_24XX_MMC_CMD); omap_cfg_reg(H15_24XX_MMC_CLKI); omap_cfg_reg(G19_24XX_MMC_CLKO); omap_cfg_reg(F20_24XX_MMC_DAT0); omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); omap_cfg_reg(G18_24XX_MMC_CMD_DIR); if (mmc_controller->slots[0].wires == 4) { omap_cfg_reg(H14_24XX_MMC_DAT1); omap_cfg_reg(E19_24XX_MMC_DAT2); omap_cfg_reg(D19_24XX_MMC_DAT3); omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); } /* * Use internal loop-back in MMC/SDIO Module Input Clock * selection */ if (mmc_controller->slots[0].internal_clock) { u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); v |= (1 << 24); omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); } } if (cpu_is_omap3430() || cpu_is_omap3630()) { u32 dev_conf = 0, v_shift = 0; if (controller_nr == 0) { omap_cfg_reg(N28_3430_MMC1_CLK); omap_cfg_reg(M27_3430_MMC1_CMD); omap_cfg_reg(N27_3430_MMC1_DAT0); if (mmc_controller->slots[0].wires == 4 || mmc_controller->slots[0].wires == 8) { omap_cfg_reg(N26_3430_MMC1_DAT1); omap_cfg_reg(N25_3430_MMC1_DAT2); omap_cfg_reg(P28_3430_MMC1_DAT3); } if (mmc_controller->slots[0].wires == 8) { omap_cfg_reg(P27_3430_MMC1_DAT4); omap_cfg_reg(P26_3430_MMC1_DAT5); omap_cfg_reg(R27_3430_MMC1_DAT6); omap_cfg_reg(R25_3430_MMC1_DAT7); } dev_conf = OMAP2_CONTROL_DEVCONF0; v_shift = OMAP2_MMCSDIO1ADPCLKISEL; } if (controller_nr == 1) { /* MMC2 */ omap_cfg_reg(AE2_3430_MMC2_CLK); omap_cfg_reg(AG5_3430_MMC2_CMD); omap_cfg_reg(AH5_3430_MMC2_DAT0); if (mmc_controller->slots[0].wires == 4 || mmc_controller->slots[0].wires == 8) { omap_cfg_reg(AH4_3430_MMC2_DAT1); omap_cfg_reg(AG4_3430_MMC2_DAT2); omap_cfg_reg(AF4_3430_MMC2_DAT3); } if (mmc_controller->slots[0].wires == 8) { omap_cfg_reg(AE4_3430_MMC2_DAT4); omap_cfg_reg(AH3_3430_MMC2_DAT5); omap_cfg_reg(AF3_3430_MMC2_DAT6); omap_cfg_reg(AE3_3430_MMC2_DAT7); } dev_conf = OMAP343X_CONTROL_DEVCONF1; v_shift = OMAP2_MMCSDIO2ADPCLKISEL; } if (controller_nr == 2) { /* MMC3 */ omap_cfg_reg(AF10_3430_MMC3_CLK); omap_cfg_reg(AC3_3430_MMC3_CMD); omap_cfg_reg(AE11_3430_MMC3_DAT0); if (mmc_controller->slots[0].wires == 4 || mmc_controller->slots[0].wires == 8) { omap_cfg_reg(AH9_3430_MMC3_DAT1); omap_cfg_reg(AF13_3430_MMC3_DAT2); omap_cfg_reg(AE13_3430_MMC3_DAT3); } } /* * Use internal loop-back in MMC/SDIO Module Input Clock * selection */ if (mmc_controller->slots[0].internal_clock && dev_conf) { u32 v = omap_ctrl_readl(dev_conf); v |= (1 << v_shift); omap_ctrl_writel(v, dev_conf); } } }
/* 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; dev_dbg(omap->dev, "starting TI EHCI USB Controller\n"); /* Enable Clocks for USBHOST */ omap->usbhost_ick = clk_get(omap->dev, "usbhost_ick"); if (IS_ERR(omap->usbhost_ick)) { ret = PTR_ERR(omap->usbhost_ick); goto err_host_ick; } clk_enable(omap->usbhost_ick); omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); if (IS_ERR(omap->usbhost2_120m_fck)) { ret = PTR_ERR(omap->usbhost2_120m_fck); goto err_host_120m_fck; } clk_enable(omap->usbhost2_120m_fck); omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); if (IS_ERR(omap->usbhost1_48m_fck)) { ret = PTR_ERR(omap->usbhost1_48m_fck); goto err_host_48m_fck; } clk_enable(omap->usbhost1_48m_fck); if (omap->phy_reset) { /* 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); } /* Configure TLL for 60Mhz clk for ULPI */ omap->usbtll_fck = clk_get(omap->dev, "usbtll_fck"); if (IS_ERR(omap->usbtll_fck)) { ret = PTR_ERR(omap->usbtll_fck); goto err_tll_fck; } clk_enable(omap->usbtll_fck); omap->usbtll_ick = clk_get(omap->dev, "usbtll_ick"); if (IS_ERR(omap->usbtll_ick)) { ret = PTR_ERR(omap->usbtll_ick); goto err_tll_ick; } clk_enable(omap->usbtll_ick); /* perform TLL soft reset, and wait until reset is complete */ ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, OMAP_USBTLL_SYSCONFIG_SOFTRESET); /* Wait for TLL reset to complete */ while (!(ehci_omap_readl(omap->tll_base, OMAP_USBTLL_SYSSTATUS) & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { cpu_relax(); if (time_after(jiffies, timeout)) { dev_dbg(omap->dev, "operation timed out\n"); ret = -EINVAL; goto err_sys_status; } } dev_dbg(omap->dev, "TLL RESET DONE\n"); /* (1<<3) = no idle mode only for initial debugging */ ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | OMAP_USBTLL_SYSCONFIG_SIDLEMODE | OMAP_USBTLL_SYSCONFIG_CACTIVITY); /* Put UHH in NoIdle/NoStandby mode */ reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | OMAP_UHH_SYSCONFIG_SIDLEMODE | OMAP_UHH_SYSCONFIG_CACTIVITY | OMAP_UHH_SYSCONFIG_MIDLEMODE); reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; 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->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) || (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) || (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) { if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_1_EN_MASK; if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_2_EN_MASK; if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; /* Enable UTMI mode for required TLL channels */ omap_usb_utmi_init(omap, tll_ch_mask); } if (omap->phy_reset) { /* 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); } 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; }