Beispiel #1
0
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);
    }
}
Beispiel #2
0
static void ohci_context_save(void)
{
	int i;

	if (is_sil_rev_less_than(OMAP3430_REV_ES3_1)) {
		ohci_context.usbtll_sysconfig =
				omap_readl(OMAP_USBTLL_SYSCONFIG);
		ohci_context.usbtll_irqenable =
				omap_readl(OMAP_USBTLL_IRQENABLE);
		ohci_context.tll_shared_conf =
				omap_readl(OMAP_TLL_SHARED_CONF);

		for (i = 0; i < 3; i++) {
			ohci_context.tll_channel_conf[i] =
				omap_readl(OMAP_TLL_CHANNEL_CONF(i));
			ohci_context.ulpi_function_ctrl[i] =
				omap_readb(OMAP_TLL_ULPI_FUNCTION_CTRL(i));
			ohci_context.ulpi_interface_ctrl[i] =
				omap_readb(OMAP_TLL_ULPI_INTERFACE_CTRL(i));
			ohci_context.ulpi_otg_ctrl[i] =
				omap_readb(OMAP_TLL_ULPI_OTG_CTRL(i));
			ohci_context.ulpi_usb_int_en_rise[i] =
				omap_readb(OMAP_TLL_ULPI_INT_EN_RISE(i));
			ohci_context.ulpi_usb_int_en_fall[i] =
				omap_readb(OMAP_TLL_ULPI_INT_EN_FALL(i));
			ohci_context.ulpi_usb_int_status[i] =
				omap_readb(OMAP_TLL_ULPI_INT_STATUS(i));
		}
	}
}
Beispiel #3
0
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);
	}
}
static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask,
				u8 tll_channel_count)
{
	unsigned reg;
	int i;

	/* Program the 3 TLL channels upfront */
	for (i = 0; i < tll_channel_count; i++) {
		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));

		/* Disable AutoIdle, BitStuffing and use SDR Mode */
		reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
				| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
				| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
	}

	/* Program Common TLL register */
	reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_SHARED_CONF);
	reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
			| OMAP_TLL_SHARED_CONF_USB_DIVRATION
			| OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN);
	reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;

	ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);

	/* Enable channels now */
	for (i = 0; i < tll_channel_count; i++) {
		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));

		/* Enable only the reg that is needed */
		if (!(tll_channel_mask & 1<<i))
			continue;

		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);

		ehci_omap_writeb(omap->tll_base,
				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
		dev_dbg(omap->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n",
				i+1, ehci_omap_readb(omap->tll_base,
				OMAP_TLL_ULPI_SCRATCH_REGISTER(i)));
	}
}
Beispiel #5
0
static void ohci_context_restore(void)
{
	int i;

	if (is_sil_rev_less_than(OMAP3430_REV_ES3_1)) {

#if 0
	/* FIXME: This was reported as not working. Temporarily
	 * disable this infinite loop pending investigation
	 */

	/* perform TLL soft reset, and wait until reset is complete */
	omap_writel(1 << OMAP_USBTLL_SYSCONFIG_SOFTRESET_SHIFT,
				OMAP_USBTLL_SYSCONFIG);

	/* Wait for TLL reset to complete */
	while (!(omap_readl(OMAP_USBTLL_SYSSTATUS) &
			(1 << OMAP_USBTLL_SYSSTATUS_RESETDONE_SHIFT)));
#endif

		omap_writel(ohci_context.usbtll_sysconfig,
					OMAP_USBTLL_SYSCONFIG);
		omap_writel(ohci_context.tll_shared_conf,
					OMAP_TLL_SHARED_CONF);

		for (i = 0; i < 3; i++) {

			omap_writel(ohci_context.tll_channel_conf[i],
					OMAP_TLL_CHANNEL_CONF(i));
			omap_writeb(ohci_context.ulpi_interface_ctrl[i],
					OMAP_TLL_ULPI_INTERFACE_CTRL(i));
			omap_writeb(ohci_context.ulpi_function_ctrl[i],
					OMAP_TLL_ULPI_FUNCTION_CTRL(i));
			omap_writeb(ohci_context.ulpi_otg_ctrl[i],
					OMAP_TLL_ULPI_OTG_CTRL(i));
			omap_writeb(ohci_context.ulpi_usb_int_en_rise[i],
					OMAP_TLL_ULPI_INT_EN_RISE(i));
			omap_writeb(ohci_context.ulpi_usb_int_en_fall[i],
					OMAP_TLL_ULPI_INT_EN_FALL(i));
			omap_writeb(ohci_context.ulpi_usb_int_status[i],
					OMAP_TLL_ULPI_INT_STATUS(i));
		}
		omap_writel(ohci_context.usbtll_irqenable,
					OMAP_USBTLL_IRQENABLE);
	}
}
Beispiel #6
0
static void omap_usb_utmi_init(struct ehci_hcd_omap *omap)
{
	unsigned reg;
	int i;

	/* Program the 3 TLL channels upfront */
	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
		dev_dbg(&omap->dev->dev,
			"port %d: OMAP_TTL_CHANNEL_CONF_%d=%08x\n",
			i, i+1, ehci_omap_readl(omap->tll_base,
						OMAP_TLL_CHANNEL_CONF(i)));

		if (omap->port_data[i].flags & EHCI_HCD_OMAP_FLAG_NOBITSTUFF)
			reg |= OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;
		else
			reg &= ~OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF;


		if (omap_usb_port_utmi_chanel_config(omap->port_data[i].mode)) {
			if (omap->port_data[i].flags
				& EHCI_HCD_OMAP_FLAG_AUTOIDLE)
				reg |= OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE;
			else
				reg &= ~OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE;
		} else {
			if (omap->port_data[i].flags
				& EHCI_HCD_OMAP_FLAG_AUTOIDLE)
				reg |= OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE;
			else
				reg &= ~OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE;
		}

		if (omap->port_data[i].mode == EHCI_HCD_OMAP_MODE_ULPI_TLL_DDR)
			reg |= OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE;
		else
			reg &= ~OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE;
		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
	}

	/* Program Common TLL register */
	ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF,
			 OMAP_TLL_SHARED_CONF_FCLK_IS_ON
			| OMAP_TLL_SHARED_CONF_USB_DIVRATION);

	/* Enable channels now */
	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {
		/* Enable only the reg that is needed */
		if (!(omap->port_data[i].flags & EHCI_HCD_OMAP_FLAG_ENABLED))
			continue;

		reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));

		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;

		if (omap_usb_port_utmi_chanel_config(omap->port_data[i].mode))
			reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE(1);
		else
			reg &= ~OMAP_TLL_CHANNEL_CONF_CHANMODE(3);

		reg &= ~(OMAP_TLL_CHANNEL_CONF_FSLSMODE(0xf));
		reg |= OMAP_TLL_CHANNEL_CONF_FSLSMODE(
			omap_usb_port_fslsmode(omap->port_data[i].mode));

		ehci_omap_writel(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i), reg);
		dev_dbg(&omap->dev->dev,
			"port %d enabled: OMAP_TTL_CHANNEL_CONF_%d=%08x:%08x\n",
			i, i+1, reg, ehci_omap_readl(omap->tll_base,
			OMAP_TLL_CHANNEL_CONF(i)));

		ehci_omap_writeb(omap->tll_base,
				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
		dev_dbg(&omap->dev->dev, "ULPI_SCRATCH_REG[ch=%d]= 0x%02x\n",
				i+1, ehci_omap_readb(omap->tll_base,
				OMAP_TLL_ULPI_SCRATCH_REGISTER(i)));
	}
}
Beispiel #7
0
/**
 * usb_hcd_omap_probe - initialize OMAP-based HCDs
 * Context: !in_interrupt()
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
static int usb_hcd_omap_probe(const struct hc_driver *driver,
			  struct platform_device *pdev)
{
	int retval;
	int i;
	u32 uhh_hostconfig_value;
	u8 ohci_port_enable_mask = 0;
	struct usb_hcd *hcd = 0;
	struct ohci_hcd *ohci;
	struct ohci_omap_clock_defs *ohci_clocks;

	if (pdev->num_resources != 2) {
		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n",
		       pdev->num_resources);
		return -ENODEV;
	}

	if (pdev->resource[0].flags != IORESOURCE_MEM
			|| pdev->resource[1].flags != IORESOURCE_IRQ) {
		printk(KERN_ERR "hcd probe: invalid resource type\n");
		return -ENODEV;
	}

	hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
	if (!hcd) {
		retval = -ENOMEM;
		goto err0;
	}

	ohci_clocks = (struct ohci_omap_clock_defs *)
			(((char *)hcd_to_ohci(hcd)) + sizeof(struct ohci_hcd));

	/* Enable Clocks for USBHOST */
	ohci_clocks->usbhost_ick_clk = clk_get(&pdev->dev,
						USBHOST_ICLK);
	if (IS_ERR(ohci_clocks->usbhost_ick_clk))
		return PTR_ERR(ohci_clocks->usbhost_ick_clk);
	clk_enable(ohci_clocks->usbhost_ick_clk);

	ohci_clocks->usbhost2_120m_fck_clk = clk_get(&pdev->dev,
						USBHOST_120M_FCLK);
	if (IS_ERR(ohci_clocks->usbhost2_120m_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		return PTR_ERR(ohci_clocks->usbhost2_120m_fck_clk);
	}
	clk_enable(ohci_clocks->usbhost2_120m_fck_clk);

	ohci_clocks->usbhost1_48m_fck_clk = clk_get(&pdev->dev,
						USBHOST_48M_FCLK);
	if (IS_ERR(ohci_clocks->usbhost1_48m_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		return PTR_ERR(ohci_clocks->usbhost1_48m_fck_clk);
	}
	clk_enable(ohci_clocks->usbhost1_48m_fck_clk);

	/* Configure TLL for 60Mhz clk for ULPI */
	ohci_clocks->usbtll_fck_clk = clk_get(&pdev->dev,
						USBHOST_TLL_FCLK);
	if (IS_ERR(ohci_clocks->usbtll_fck_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
		clk_put(ohci_clocks->usbhost1_48m_fck_clk);
		return PTR_ERR(ohci_clocks->usbtll_fck_clk);
	}
	clk_enable(ohci_clocks->usbtll_fck_clk);

	ohci_clocks->usbtll_ick_clk = clk_get(&pdev->dev,
						USBHOST_TLL_ICLK);
	if (IS_ERR(ohci_clocks->usbtll_ick_clk)) {
		clk_disable(ohci_clocks->usbhost_ick_clk);
		clk_put(ohci_clocks->usbhost_ick_clk);
		clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
		clk_put(ohci_clocks->usbhost2_120m_fck_clk);
		clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
		clk_put(ohci_clocks->usbhost1_48m_fck_clk);
		clk_disable(ohci_clocks->usbtll_fck_clk);
		clk_put(ohci_clocks->usbtll_fck_clk);
		return PTR_ERR(ohci_clocks->usbtll_ick_clk);
	}

	clk_enable(ohci_clocks->usbtll_ick_clk);

	ohci_clocks->suspended = 0;

	/* Disable Auto Idle of USBTLL */
	cm_write_mod_reg((0 << OMAP3430ES2_AUTO_USBTLL_SHIFT),
				CORE_MOD, CM_AUTOIDLE3);

	/* Wait for TLL to be Active */
	while ((cm_read_mod_reg(CORE_MOD, OMAP2430_CM_IDLEST3) &
				(1 << OMAP3430ES2_ST_USBTLL_SHIFT)));

	/* perform TLL soft reset, and wait until reset is complete */
	omap_writel(1 << OMAP_USBTLL_SYSCONFIG_SOFTRESET_SHIFT,
				OMAP_USBTLL_SYSCONFIG);
	/* Wait for TLL reset to complete */
	while (!(omap_readl(OMAP_USBTLL_SYSSTATUS) &
			(1 << OMAP_USBTLL_SYSSTATUS_RESETDONE_SHIFT)));

	/* smart idle mode */
	omap_writel((1 << OMAP_USBTLL_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(2 << OMAP_USBTLL_SYSCONFIG_SIDLEMODE_SHIFT) |
			(0 << OMAP_USBTLL_SYSCONFIG_CACTIVITY_SHIFT) |
			(1 << OMAP_USBTLL_SYSCONFIG_AUTOIDLE_SHIFT),
						OMAP_USBTLL_SYSCONFIG);


	/* Put UHH in SmartIdle/SmartStandby mode */
	omap_writel((1 << OMAP_UHH_SYSCONFIG_AUTOIDLE_SHIFT) |
			(1 << OMAP_UHH_SYSCONFIG_ENAWAKEUP_SHIFT) |
			(2 << OMAP_UHH_SYSCONFIG_SIDLEMODE_SHIFT) |
			(0 << OMAP_UHH_SYSCONFIG_CACTIVITY_SHIFT) |
			(2 << OMAP_UHH_SYSCONFIG_MIDLEMODE_SHIFT),
						OMAP_UHH_SYSCONFIG);

#ifdef CONFIG_OMAP_OHCI_PHY_MODE
	/* TLL in FS-PHY mode operation */
	uhh_hostconfig_value = (1 << OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN_SHIFT) |
			(1 << OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN_SHIFT) |
			(0 << OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN_SHIFT);

	if (is_sil_rev_greater_than(OMAP3430_REV_ES2_1)) {

/* For ES 3, we have per-port control for the ULPI Bypass
 * The ULPI Bypass needs to be set to 0 only if the EHCI PHY Mode
 * is selected for that port.
 * Hence it is easier to make it conditional on EHCI_PHY_MODE
 *
 * ES 2 does not have per-port control. Hence it is not possible to have
 * EHCI in PHY Mode and OHCI both working at the same time
 *
 * FIXME: This common code should be moved elsewhere
 *
 */

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT1
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
#endif

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT2
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P2_ULPI_BYPASS_SHIFT);
#endif

#ifndef CONFIG_OMAP_EHCI_PHY_MODE_PORT3
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P3_ULPI_BYPASS_SHIFT);
#endif
	} else {
		uhh_hostconfig_value |=
			(1 << OMAP_UHH_HOSTCONFIG_P1_ULPI_BYPASS_SHIFT);
	}

	omap_writel(uhh_hostconfig_value, OMAP_UHH_HOSTCONFIG);

#if 0
	/* Ensure BYPASS bit is not set */
	while (!(omap_readl(OMAP_UHH_HOSTCONFIG) &
		(1 << OMAP_UHH_HOSTCONFIG_P3_ULPI_BYPASS_SHIFT)));
#endif

	pr_debug("Entered UTMI PHY MODE: success");

	/* Program Common TLL register */
	omap_writel((1 << OMAP_TLL_SHARED_CONF_FCLK_IS_ON_SHIFT) |
			(1 << OMAP_TLL_SHARED_CONF_USB_DIVRATION_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN_SHFT),
				OMAP_TLL_SHARED_CONF);
#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT1)
		ohci_port_enable_mask |= (1 << 0);
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT2)
		ohci_port_enable_mask |= (1 << 1);
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT3) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT3)
		ohci_port_enable_mask |= (1 << 2);
#endif


#ifdef CONFIG_OMAP_OHCI_PHY_MODE_3PIN
	/* Program the 3 TLL channels upfront */

	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {

		/* Enable only required ports */
		if (!(ohci_port_enable_mask & (1 << i)))
			continue;

		/* Disable AutoIdle */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1 << OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

		/* Disable BitStuffing */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(1 << OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF_SHIFT),
			OMAP_TLL_CHANNEL_CONF(i));

		/* SDR Mode */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1 << OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

		/* CHANMODE: UTMI-to-serial FS/LS mode */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(1 << OMAP_TLL_CHANNEL_CONF_CHANMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

#if 0
		/* Enable port 3 only. Not enabling ports 1 & 2 */
		if (i != 2)
			continue;
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_4PIN_PORT3)
		/* FSLSMODE: 4-pin bidirectional PHY */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(3 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
#endif

#if defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT1) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT2) || \
    defined(CONFIG_OMAP_OHCI_PHY_MODE_3PIN_PORT3)

		/* FSLSMODE: 3-pin bidirectional PHY */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			(2 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
#endif

		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			    (1<<OMAP_TLL_CHANNEL_CONF_CHANEN_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

	}
#else
	pr_debug("\nOnly 3-pin PHY mode is implemented");
#endif /* CONFIG_OMAP_OHCI_PHY_MODE_3PIN */
#else
#error "FS-TLL Not implemented"
#endif /* CONFIG_OMAP_OHCI_PHY_MODE */

	hcd->rsrc_start = pdev->resource[0].start;
	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;

	/*
	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		retval = -EBUSY;
		goto err1;
	}
	 */

	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
		retval = -ENOMEM;
		goto err2;
	}

	/*
	pr_debug("\n\n-->VIRT-OHCI-BASE [0x%x], [0x%x] irq[%d]\n\n",
			hcd->regs, (unsigned int)io_p2v( 0x48064400 ),
			pdev->resource[1].start);
	 */

	ohci = hcd_to_ohci(hcd);
	ohci_hcd_init(ohci);

	ohci_clocks->host_enabled = 1;

	//irq = platform_get_irq(pdev, 0);
	//if (irq < 0) {
	//	retval = -ENXIO;
	//	goto err3;
	//}
	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
	if (retval)
		goto err3;

	return 0;
err3:
	iounmap(hcd->regs);
err2:
//	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
//err1:
	usb_put_hcd(hcd);
	clk_disable(ohci_clocks->usbhost_ick_clk);
	clk_put(ohci_clocks->usbhost_ick_clk);
	clk_disable(ohci_clocks->usbhost2_120m_fck_clk);
	clk_put(ohci_clocks->usbhost2_120m_fck_clk);
	clk_disable(ohci_clocks->usbhost1_48m_fck_clk);
	clk_put(ohci_clocks->usbhost1_48m_fck_clk);
	clk_disable(ohci_clocks->usbtll_fck_clk);
	clk_put(ohci_clocks->usbtll_fck_clk);
	clk_disable(ohci_clocks->usbtll_ick_clk);
	clk_put(ohci_clocks->usbtll_ick_clk);
err0:
//	clk_put(usb_dc_ck);
//	clk_put(usb_host_ck);
	return retval;
}
Beispiel #8
0
static void omap_usb_utmi_init(struct usb_hcd *hcd, u8 tll_channel_mask)
{
	int i;

	/* Use UTMI Ports of TLL */
	omap_writel((1 << OMAP_UHH_HOSTCONFIG_ULPI_BYPASS_SHIFT)|
			(1<<OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN_SHIFT)|
			(1<<OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN_SHIFT)|
			(1<<OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN_SHIFT)|
			(0<<OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN_SHIFT),
						OMAP_UHH_HOSTCONFIG);
	/* Enusre bit is set */
	while (!(omap_readl(OMAP_UHH_HOSTCONFIG)
			& (1 << OMAP_UHH_HOSTCONFIG_ULPI_BYPASS_SHIFT)))
		cpu_relax();

	dev_dbg(hcd->self.controller, "\nEntered UTMI MODE: success\n");

	/* Program the 3 TLL channels upfront */

	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {

		/* Disable AutoIdle */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1<<OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
		/* Disable BitStuffing */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1<<OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));
		/* SDR Mode */
		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) &
			    ~(1<<OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

	}

	/* Program Common TLL register */
	omap_writel((1 << OMAP_TLL_SHARED_CONF_FCLK_IS_ON_SHIFT) |
			(1 << OMAP_TLL_SHARED_CONF_USB_DIVRATION_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN_SHIFT) |
			(0 << OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN_SHFT),
				OMAP_TLL_SHARED_CONF);

	/* Enable channels now */
	for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) {

		/* Enable only the channel that is needed */
		if (!(tll_channel_mask & 1<<i))
			continue;

		omap_writel(omap_readl(OMAP_TLL_CHANNEL_CONF(i)) |
			    (1<<OMAP_TLL_CHANNEL_CONF_CHANEN_SHIFT),
			    OMAP_TLL_CHANNEL_CONF(i));

		omap_writeb(0xBE, OMAP_TLL_ULPI_SCRATCH_REGISTER(i));
		dev_dbg(hcd->self.controller, "\nULPI_SCRATCH_REG[ch=%d]"
			"= 0x%02x\n",
			i+1, omap_readb(OMAP_TLL_ULPI_SCRATCH_REGISTER(i)));
	}
}
Beispiel #9
0
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;
}