static void ulpi_set_trimmer(struct tegra_usb_phy *phy)
{
	struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi;
	void __iomem *base = phy->regs;
	unsigned long val;

	val = ULPI_DATA_TRIMMER_SEL(config->data_trimmer);
	val |= ULPI_STPDIRNXT_TRIMMER_SEL(config->stpdirnxt_trimmer);
	val |= ULPI_DIR_TRIMMER_SEL(config->dir_trimmer);
	writel(val, base + ULPI_TIMING_CTRL_1);
	udelay(10);

	val |= ULPI_DATA_TRIMMER_LOAD;
	val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
	val |= ULPI_DIR_TRIMMER_LOAD;
	writel(val, base + ULPI_TIMING_CTRL_1);
}
Beispiel #2
0
/* set up the ULPI USB controller with the parameters provided */
static int init_ulpi_usb_controller(struct fdt_usb *config,
				struct usb_ctlr *usbctlr)
{
	u32 val;
	int loop_count;
	struct ulpi_viewport ulpi_vp;

	/* set up ULPI reference clock on pllp_out4 */
	clock_enable(PERIPH_ID_DEV2_OUT);
	clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CONFIG_ULPI_REF_CLK);

	/* reset ULPI phy */
	if (fdt_gpio_isvalid(&config->phy_reset_gpio)) {
		fdtdec_setup_gpio(&config->phy_reset_gpio);
		gpio_direction_output(config->phy_reset_gpio.gpio, 0);
		mdelay(5);
		gpio_set_value(config->phy_reset_gpio.gpio, 1);
	}

	/* Reset the usb controller */
	clock_enable(config->periph_id);
	usbf_reset_controller(config, usbctlr);

	/* enable pinmux bypass */
	setbits_le32(&usbctlr->ulpi_timing_ctrl_0,
			ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);

	/* Select ULPI parallel interface */
	clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT);

	/* enable ULPI transceiver */
	setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB);

	/* configure ULPI transceiver timings */
	val = 0;
	writel(val, &usbctlr->ulpi_timing_ctrl_1);

	val |= ULPI_DATA_TRIMMER_SEL(4);
	val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
	val |= ULPI_DIR_TRIMMER_SEL(4);
	writel(val, &usbctlr->ulpi_timing_ctrl_1);
	udelay(10);

	val |= ULPI_DATA_TRIMMER_LOAD;
	val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
	val |= ULPI_DIR_TRIMMER_LOAD;
	writel(val, &usbctlr->ulpi_timing_ctrl_1);

	/* set up phy for host operation with external vbus supply */
	ulpi_vp.port_num = 0;
	ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport;

	if (ulpi_init(&ulpi_vp)) {
		printf("Tegra ULPI viewport init failed\n");
		return -1;
	}

	ulpi_set_vbus(&ulpi_vp, 1, 1);
	ulpi_set_vbus_indicator(&ulpi_vp, 1, 1, 0);

	/* enable wakeup events */
	setbits_le32(&usbctlr->port_sc1, WKCN | WKDS | WKOC);

	/* Enable and wait for the phy clock to become valid in 100 ms */
	setbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
	for (loop_count = 100000; loop_count != 0; loop_count--) {
		if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
			break;
		udelay(1);
	}
	if (!loop_count)
		return -1;
	clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);

	return 0;
}
Beispiel #3
0
// ulpi phy power on
static void ulpi_phy_power_on(void) {
        uint32_t val;
        uint32_t base = USBADDR2;
        udelay(1000);

	usb_reset(base);

        val = readl(base + ULPI_TIMING_CTRL_0);
        val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
        writel(val, base + ULPI_TIMING_CTRL_0);

        val = readl(base + USB_SUSP_CTRL);
        val |= ULPI_PHY_ENABLE;
        writel(val, base + USB_SUSP_CTRL);

        val = 0;
        writel(val, base + ULPI_TIMING_CTRL_1);

        val |= ULPI_DATA_TRIMMER_SEL(4);
        val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
        val |= ULPI_DIR_TRIMMER_SEL(4);
        writel(val, base + ULPI_TIMING_CTRL_1);

        udelay(10);

        val |= ULPI_DATA_TRIMMER_LOAD;
        val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
        val |= ULPI_DIR_TRIMMER_LOAD;
        writel(val, base + ULPI_TIMING_CTRL_1);

        val = ULPI_WAKEUP | ULPI_RD_RW_WRITE | ULPI_PORT(0);
        writel(val, base + ULPI_VIEWPORT);

        if (wait_for_register(base + ULPI_VIEWPORT, ULPI_WAKEUP, 0, 1000)) {
                printf("%s: timeout waiting for ulpi phy wakeup\n", __func__);
                return;
        }

        /* Fix VbusInvalid due to floating VBUS */
	val = ULPI_RUN | ULPI_RD_RW_WRITE | ULPI_PORT(0) | ULPI_ADDR(0x08) | ULPI_DATA_WR(0x40);
        writel(val, base + ULPI_VIEWPORT);
        if (wait_for_register(base + ULPI_VIEWPORT, ULPI_RUN, 0, 1000)) {
		printf("%s: timeout accessing ulpi phy\n", __func__);        
		return;
	}
        val = ULPI_RUN | ULPI_RD_RW_WRITE | ULPI_PORT(0) | ULPI_ADDR(0x0B) | ULPI_DATA_WR(0x80);
        writel(val, base + ULPI_VIEWPORT);
        if (wait_for_register(base + ULPI_VIEWPORT, ULPI_RUN, 0, 1000)) {
                printf("%s: timeout accessing ulpi phy\n", __func__);
                return;
        }

        val = readl(base + USB_PORTSC1);
        val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
        writel(val, base + USB_PORTSC1);

        val = readl(base + USB_SUSP_CTRL);
        val |= USB_SUSP_CLR;
        writel(val, base + USB_SUSP_CTRL);
        udelay(100);

        val = readl(base + USB_SUSP_CTRL);
        val &= ~USB_SUSP_CLR;
        writel(val, base + USB_SUSP_CTRL);
}