Пример #1
0
static int
usbphy_utmi_enable(struct usbphy_softc *sc)
{
	int rv;
	uint32_t val;

	/* Reset phy */
	val = RD4(sc, IF_USB_SUSP_CTRL);
	val |= UTMIP_RESET;
	WR4(sc, IF_USB_SUSP_CTRL, val);


	val = RD4(sc, UTMIP_TX_CFG0);
	val |= UTMIP_FS_PREAMBLE_J;
	WR4(sc, UTMIP_TX_CFG0, val);

	val = RD4(sc, UTMIP_HSRX_CFG0);
	val &= ~UTMIP_IDLE_WAIT(~0);
	val &= ~UTMIP_ELASTIC_LIMIT(~0);
	val |= UTMIP_IDLE_WAIT(sc->idle_wait_delay);
	val |= UTMIP_ELASTIC_LIMIT(sc->elastic_limit);
	WR4(sc, UTMIP_HSRX_CFG0, val);

	val = RD4(sc, UTMIP_HSRX_CFG1);
	val &= ~UTMIP_HS_SYNC_START_DLY(~0);
	val |= UTMIP_HS_SYNC_START_DLY(sc->hssync_start_delay);
	WR4(sc, UTMIP_HSRX_CFG1, val);

	val = RD4(sc, UTMIP_DEBOUNCE_CFG0);
	val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
	val |= UTMIP_BIAS_DEBOUNCE_A(0x7530);  /* For 12MHz */
	WR4(sc, UTMIP_DEBOUNCE_CFG0, val);

	val = RD4(sc, UTMIP_MISC_CFG0);
	val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
	WR4(sc, UTMIP_MISC_CFG0, val);

	if (sc->dr_mode == USB_DR_MODE_DEVICE) {
		val = RD4(sc,IF_USB_SUSP_CTRL);
		val &= ~USB_WAKE_ON_CNNT_EN_DEV;
		val &= ~USB_WAKE_ON_DISCON_EN_DEV;
		WR4(sc, IF_USB_SUSP_CTRL, val);

		val = RD4(sc, UTMIP_BAT_CHRG_CFG0);
		val &= ~UTMIP_PD_CHRG;
		WR4(sc, UTMIP_BAT_CHRG_CFG0, val);
	} else {
		val = RD4(sc, UTMIP_BAT_CHRG_CFG0);
		val |= UTMIP_PD_CHRG;
		WR4(sc, UTMIP_BAT_CHRG_CFG0, val);
	}

	usbpby_enable_cnt++;
	if (usbpby_enable_cnt == 1) {
		rv = hwreset_deassert(sc->reset_pads);
		if (rv != 0) {
			device_printf(sc->dev,
			     "Cannot unreset 'utmi-pads' reset\n");
			return (rv);
		}
		rv = clk_enable(sc->clk_pads);
		if (rv != 0) {
			device_printf(sc->dev,
			    "Cannot enable 'utmi-pads' clock\n");
			return (rv);
		}

		val = bus_read_4(sc->pads_res, UTMIP_BIAS_CFG0);
		val &= ~UTMIP_OTGPD;
		val &= ~UTMIP_BIASPD;
		val &= ~UTMIP_HSSQUELCH_LEVEL(~0);
		val &= ~UTMIP_HSDISCON_LEVEL(~0);
		val &= ~UTMIP_HSDISCON_LEVEL_MSB(~0);
		val |= UTMIP_HSSQUELCH_LEVEL(sc->hssquelch_level);
		val |= UTMIP_HSDISCON_LEVEL(sc->hsdiscon_level);
		val |= UTMIP_HSDISCON_LEVEL_MSB(sc->hsdiscon_level);
		bus_write_4(sc->pads_res, UTMIP_BIAS_CFG0, val);

		rv = clk_disable(sc->clk_pads);
		if (rv != 0) {
			device_printf(sc->dev,
			    "Cannot disable 'utmi-pads' clock\n");
			return (rv);
		}
	}

	val = RD4(sc, UTMIP_XCVR_CFG0);
	val &= ~UTMIP_FORCE_PD_POWERDOWN;
	val &= ~UTMIP_FORCE_PD2_POWERDOWN ;
	val &= ~UTMIP_FORCE_PDZI_POWERDOWN;
	val &= ~UTMIP_XCVR_LSBIAS_SEL;
	val &= ~UTMIP_XCVR_LSFSLEW(~0);
	val &= ~UTMIP_XCVR_LSRSLEW(~0);
	val &= ~UTMIP_XCVR_HSSLEW(~0);
	val &= ~UTMIP_XCVR_HSSLEW_MSB(~0);
	val |= UTMIP_XCVR_LSFSLEW(sc->xcvr_lsfslew);
	val |= UTMIP_XCVR_LSRSLEW(sc->xcvr_lsrslew);
	val |= UTMIP_XCVR_HSSLEW(sc->xcvr_hsslew);
	val |= UTMIP_XCVR_HSSLEW_MSB(sc->xcvr_hsslew);
	if (!sc->xcvr_setup_use_fuses) {
		val &= ~UTMIP_XCVR_SETUP(~0);
		val &= ~UTMIP_XCVR_SETUP_MSB(~0);
		val |= UTMIP_XCVR_SETUP(sc->xcvr_setup);
		val |= UTMIP_XCVR_SETUP_MSB(sc->xcvr_setup);
	}
	WR4(sc, UTMIP_XCVR_CFG0, val);

	val = RD4(sc, UTMIP_XCVR_CFG1);
	val &= ~UTMIP_FORCE_PDDISC_POWERDOWN;
	val &= ~UTMIP_FORCE_PDCHRP_POWERDOWN;
	val &= ~UTMIP_FORCE_PDDR_POWERDOWN;
	val &= ~UTMIP_XCVR_TERM_RANGE_ADJ(~0);
	val |= UTMIP_XCVR_TERM_RANGE_ADJ(sc->term_range_adj);
	WR4(sc, UTMIP_XCVR_CFG1, val);


	val = RD4(sc, UTMIP_BIAS_CFG1);
	val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
	val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
	WR4(sc, UTMIP_BIAS_CFG1, val);

	val = RD4(sc, UTMIP_SPARE_CFG0);
	if (sc->xcvr_setup_use_fuses)
		val |= FUSE_SETUP_SEL;
	else
		val &= ~FUSE_SETUP_SEL;
	WR4(sc, UTMIP_SPARE_CFG0, val);

	val = RD4(sc, IF_USB_SUSP_CTRL);
	val |= UTMIP_PHY_ENB;
	WR4(sc, IF_USB_SUSP_CTRL, val);

	val = RD4(sc, IF_USB_SUSP_CTRL);
	val &= ~UTMIP_RESET;
	WR4(sc, IF_USB_SUSP_CTRL, val);

	usbphy_utmi_phy_clk(sc, true);

	val = RD4(sc, CTRL_USB_USBMODE);
	val &= ~USB_USBMODE_MASK;
	if (sc->dr_mode == USB_DR_MODE_HOST)
		val |= USB_USBMODE_HOST;
	else
		val |= USB_USBMODE_DEVICE;
	WR4(sc, CTRL_USB_USBMODE, val);

	val = RD4(sc, CTRL_USB_HOSTPC1_DEVLC);
	val &= ~USB_HOSTPC1_DEVLC_PTS(~0);
	val |= USB_HOSTPC1_DEVLC_PTS(0);
	WR4(sc, CTRL_USB_HOSTPC1_DEVLC, val);

	return (0);
}
Пример #2
0
static int utmi_phy_power_on(struct tegra_usb_phy *phy)
{
	unsigned long val;
	void __iomem *base = phy->regs;
	struct tegra_utmi_config *config = &phy->pdata->u_cfg.utmi;
	DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
	if (phy->phy_clk_on) {
		DBG("%s(%d) inst:[%d] phy clk is already on\n",
					__func__, __LINE__, phy->inst);
		return 0;
	}

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

	val = readl(base + UTMIP_TX_CFG0);
	val |= UTMIP_FS_PREABMLE_J;
	writel(val, base + UTMIP_TX_CFG0);

	val = readl(base + UTMIP_HSRX_CFG0);
	val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0));
	val |= UTMIP_IDLE_WAIT(config->idle_wait_delay);
	val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit);
	writel(val, base + UTMIP_HSRX_CFG0);

	val = readl(base + UTMIP_HSRX_CFG1);
	val &= ~(UTMIP_HS_SYNC_START_DLY(~0));
	val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay);
	writel(val, base + UTMIP_HSRX_CFG1);

	val = readl(base + UTMIP_DEBOUNCE_CFG0);
	val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
	val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce);
	writel(val, base + UTMIP_DEBOUNCE_CFG0);

	val = readl(base + UTMIP_MISC_CFG0);
	val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
	writel(val, base + UTMIP_MISC_CFG0);

	val = readl(base + UTMIP_MISC_CFG1);
	val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0));
	val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) |
		UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count);
	writel(val, base + UTMIP_MISC_CFG1);

	val = readl(base + UTMIP_PLL_CFG1);
	val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0));
	val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) |
		UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
	writel(val, base + UTMIP_PLL_CFG1);

	if (phy->pdata->op_mode == TEGRA_USB_OPMODE_DEVICE) {
		val = readl(base + USB_SUSP_CTRL);
		val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
		writel(val, base + USB_SUSP_CTRL);

		val = readl(base + UTMIP_BAT_CHRG_CFG0);
		val &= ~UTMIP_PD_CHRG;
		writel(val, base + UTMIP_BAT_CHRG_CFG0);
	} else {
		val = readl(base + UTMIP_BAT_CHRG_CFG0);
		val |= UTMIP_PD_CHRG;
		writel(val, base + UTMIP_BAT_CHRG_CFG0);
	}

	utmi_phy_pad_power_on(phy);

	val = readl(base + UTMIP_XCVR_UHSIC_HSRX_CFG0);
	val &= ~(UTMIP_XCVR_LSBIAS_SEL | UTMIP_FORCE_PD_POWERDOWN |
		 UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN |
		 UTMIP_XCVR_SETUP(~0) | UTMIP_XCVR_LSFSLEW(~0) |
		 UTMIP_XCVR_LSRSLEW(~0) | UTMIP_XCVR_HSSLEW_MSB(~0));
	val |= UTMIP_XCVR_SETUP(phy->utmi_xcvr_setup);
	val |= UTMIP_XCVR_SETUP_MSB(XCVR_SETUP_MSB_CALIB(phy->utmi_xcvr_setup));
	val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
	val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);

	writel(val, base + UTMIP_XCVR_UHSIC_HSRX_CFG0);

	val = readl(base + UTMIP_XCVR_CFG1);
	val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
		 UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0));
	val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj);
	writel(val, base + UTMIP_XCVR_CFG1);


	val = readl(base + UTMIP_BIAS_CFG1);
	val &= ~(UTMIP_BIAS_PDTRK_COUNT(~0));
	val |= UTMIP_BIAS_PDTRK_COUNT(phy->freq->pdtrk_count);
	writel(val, base + UTMIP_BIAS_CFG1);

	val = readl(base + UTMIP_SPARE_CFG0);
	val &= ~FUSE_SETUP_SEL;
	writel(val, base + UTMIP_SPARE_CFG0);

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

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

	if (phy->inst == 0) {
		val = readl(base + USB_SUSP_CTRL);
		val &= ~USB_SUSP_SET;
		writel(val, base + USB_SUSP_CTRL);
	} else {
		val = readl(base + USB_PORTSC);
		val &= ~USB_PORTSC_PHCD;
		writel(val, base + USB_PORTSC);
	}

	if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
		USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500))
		pr_warn("%s: timeout waiting for phy to stabilize\n", __func__);

	if (phy->inst == 2) {
		val = readl(base + USB_PORTSC);
		val &= ~(USB_PORTSC_PTS(~0));
		writel(val, base + USB_PORTSC);
	}

	phy->phy_clk_on = true;
	phy->hw_accessible = true;

	return 0;
}
Пример #3
0
int utmi_phy_set_snps_trking_data(void)
{
	void __iomem *base = IO_ADDRESS(TEGRA_USB_BASE);
	u32 val;
	struct clk *utmi_pad_clk;

	utmi_pad_clk = clk_get_sys("utmip-pad", NULL);
	if (IS_ERR(utmi_pad_clk)) {
		pr_err("%s: can't get utmip pad clock\n", __func__);
		return PTR_ERR(utmi_pad_clk);
	}

	if (!pmc_base)
		pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);

	clk_enable(utmi_pad_clk);
	spin_lock_irqsave(&pmc_lock, flags);
	/* Bias pad MASTER_ENABLE=1 */
	val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
	val |= BIAS_MASTER_PROG_VAL;
	writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);

	/* Setting the tracking length time */
	val = readl(base + UTMIP_BIAS_CFG1);
	val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
	val |= UTMIP_BIAS_PDTRK_COUNT(5);
	writel(val, base + UTMIP_BIAS_CFG1);

	/* Bias PDTRK is Shared and MUST be done from USB1 ONLY, PD_TRK=0 */
	val = readl(base + UTMIP_BIAS_CFG1);
	val &= ~UTMIP_BIAS_PDTRK_POWERDOWN;
	writel(val, base + UTMIP_BIAS_CFG1);

	val = readl(base + UTMIP_BIAS_CFG1);
	val |= UTMIP_BIAS_PDTRK_POWERUP;
	writel(val, base + UTMIP_BIAS_CFG1);

	/* Wait for 25usec */
	udelay(25);

	/* Bias pad MASTER_ENABLE=0 */
	val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
	val &= ~BIAS_MASTER_PROG_VAL;
	writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);

	/* Wait for 1usec */
	udelay(1);

	/* Bias pad MASTER_ENABLE=1 */
	val = readl(pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);
	val |= BIAS_MASTER_PROG_VAL;
	writel(val, pmc_base + PMC_UTMIP_BIAS_MASTER_CNTRL);

	/* Read RCTRL and TCTRL from UTMIP space */
	val = readl(base + UTMIP_BIAS_STS0);
	utmip_rctrl_val = 0xf + ffz(UTMIP_RCTRL_VAL(val));
	utmip_tctrl_val = 0xf + ffz(UTMIP_TCTRL_VAL(val));

	/* PD_TRK=1 */
	val = readl(base + UTMIP_BIAS_CFG1);
	val |= UTMIP_BIAS_PDTRK_POWERDOWN;
	writel(val, base + UTMIP_BIAS_CFG1);

	/* Program thermally encoded RCTRL_VAL, TCTRL_VAL into PMC space */
	val = readl(pmc_base + PMC_UTMIP_TERM_PAD_CFG);
	val = PMC_TCTRL_VAL(utmip_tctrl_val) |
		PMC_RCTRL_VAL(utmip_rctrl_val);
	writel(val, pmc_base + PMC_UTMIP_TERM_PAD_CFG);
	spin_unlock_irqrestore(&pmc_lock, flags);
	clk_disable(utmi_pad_clk);
	clk_put(utmi_pad_clk);

	return 0;
}