static void ohci_omap3_tll_config(struct ohci_hcd_omap3 *omap) { u32 reg; int i; /* Program TLL SHARED CONF */ reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF); reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; reg |= OMAP_TLL_SHARED_CONF_USB_DIVRATION; reg |= OMAP_TLL_SHARED_CONF_FCLK_IS_ON; ohci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); /* Program each TLL channel */ /* * REVISIT: Only the 3-pin and 4-pin PHY modes have * actually been tested. */ for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { /* Enable only those channels that are actually used */ if (omap->port_mode[i] == OMAP_OHCI_PORT_MODE_UNUSED) continue; reg = ohci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); reg |= ohci_omap3_fslsmode(omap->port_mode[i]) << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; ohci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); } }
static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) { struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); struct usbhs_omap_platform_data *pdata = dev->platform_data; unsigned reg; int i; /* Program Common TLL register */ reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF); reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON | OMAP_TLL_SHARED_CONF_USB_DIVRATION); reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); /* Enable channels now */ for (i = 0; i < tll_channel_count; i++) { reg = usbhs_read(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); if (is_ohci_port(pdata->port_mode[i])) { reg |= ohci_omap3_fslsmode(pdata->port_mode[i]) << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) { /* Disable AutoIdle, BitStuffing and use SDR Mode */ reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); reg |= (1 << (i + 1)); } else continue; reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; usbhs_write(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg); usbhs_writeb(omap->tll_base, OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); } }
int omap_tll_init(struct usbhs_omap_platform_data *pdata) { int i; bool needs_tll; unsigned reg; struct usbtll_omap *tll; if (!tll_dev) return -ENODEV; pm_runtime_get_sync(tll_dev); spin_lock(&tll_lock); tll = dev_get_drvdata(tll_dev); needs_tll = false; for (i = 0; i < tll->nch; i++) needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); if (needs_tll) { void __iomem *base = tll->base; /* Program Common TLL register */ reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON | OMAP_TLL_SHARED_CONF_USB_DIVRATION); reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN; reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN; usbtll_write(base, OMAP_TLL_SHARED_CONF, reg); /* Enable channels now */ for (i = 0; i < tll->nch; i++) { reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i)); if (is_ohci_port(pdata->port_mode[i])) { reg |= ohci_omap3_fslsmode(pdata->port_mode[i]) << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT; reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS; } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) { /* * Disable AutoIdle, BitStuffing * and use SDR Mode */ reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE); } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_HSIC) { /* * HSIC Mode requires UTMI port configurations */ reg |= OMAP_TLL_CHANNEL_CONF_DRVVBUS | OMAP_TLL_CHANNEL_CONF_CHRGVBUS | OMAP_TLL_CHANNEL_CONF_MODE_TRANSPARENT_UTMI | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF; } else { continue; } reg |= OMAP_TLL_CHANNEL_CONF_CHANEN; usbtll_write(base, OMAP_TLL_CHANNEL_CONF(i), reg); usbtll_writeb(base, OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe); } } spin_unlock(&tll_lock); pm_runtime_put_sync(tll_dev); return 0; }