+ mdelay(50);
+ /* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */
+ if (controller->has_hostpc)
+ *reg |= EHCI_PS_PE;
+
+ if (((u32)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc)
+ return;
+ /* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
+ if (ehci_readl(status_reg) & EHCI_PS_CSC)
+ *reg |= EHCI_PS_CSC;
+}
+
+/*
+ * This ehci_set_usbmode overrides the weak function ehci_set_usbmode
+ * in "ehci-hcd.c".
+ */
+void ehci_set_usbmode(int index)
+{
+ struct fdt_usb *config;
+ struct usb_ctlr *usbctlr;
+ uint32_t tmp;
+
+ config = &port[index];
+ usbctlr = config->reg;
+
+ tmp = ehci_readl(&usbctlr->usb_mode);
+ tmp |= USBMODE_CM_HC;
+ ehci_writel(&usbctlr->usb_mode, tmp);
+}
+
+/*
+ * This ehci_get_port_speed overrides the weak function ehci_get_port_speed
+ * in "ehci-hcd.c".
+ */
+int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+{
+ uint32_t tmp;
+ uint32_t *reg_ptr;
+
+ if (controller->has_hostpc) {
+ reg_ptr = (uint32_t *)((u8 *)&hcor->or_usbcmd + HOSTPC1_DEVLC);
+ tmp = ehci_readl(reg_ptr);
+ return HOSTPC1_PSPD(tmp);
+ } else
+ return PORTSC_PSPD(reg);
+}
+
+/* Set up VBUS for host/device mode */
+static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
+{
+ /*
+ * If we are an OTG port initializing in host mode,
+ * check if remote host is driving VBus and bail out in this case.
+ */
+ if (init == USB_INIT_HOST &&
+ config->dr_mode == DR_MODE_OTG &&
+ (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) {
+ printf("tegrausb: VBUS input active; not enabling as host\n");
+ return;
+ }
+
+ if (fdt_gpio_isvalid(&config->vbus_gpio)) {
+ int vbus_value;
+
+ fdtdec_setup_gpio(&config->vbus_gpio);
+
+ vbus_value = (init == USB_INIT_HOST) ^
+ !!(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW);
+ gpio_direction_output(config->vbus_gpio.gpio, vbus_value);
+
+ debug("set_up_vbus: GPIO %d %d\n", config->vbus_gpio.gpio,
+ vbus_value);
+ }
+}
+
+void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
+{
+ /* Reset the USB controller with 2us delay */
+ reset_periph(config->periph_id, 2);
+
+ /*
+ * Set USB1_NO_LEGACY_MODE to 1, Registers are accessible under
+ * base address
+ */
+ if (config->has_legacy_mode)
+ setbits_le32(&usbctlr->usb1_legacy_ctrl, USB1_NO_LEGACY_MODE);
+
+ /* Put UTMIP1/3 in reset */
+ setbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);
+
+ /* Enable the UTMIP PHY */
+ if (config->utmi)
+ setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB);
+}
+
+static const unsigned *get_pll_timing(void)
+{
+ const unsigned *timing;
+
+ timing = controller->pll_parameter +
+ clock_get_osc_freq() * PARAM_COUNT;
+
+ return timing;
+}
+
+/* select the PHY to use with a USB controller */
+static void init_phy_mux(struct fdt_usb *config, uint pts,
+ enum usb_init_type init)
+{
+ struct usb_ctlr *usbctlr = config->reg;
+
+#if defined(CONFIG_TEGRA20)
+ if (config->periph_id == PERIPH_ID_USBD) {
+ clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
+ pts << PTS1_SHIFT);
+ clrbits_le32(&usbctlr->port_sc1, STS1);
+ } else {
+ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
+ pts << PTS_SHIFT);
+ clrbits_le32(&usbctlr->port_sc1, STS);
+ }
+#else
+ /* Set to Host mode (if applicable) after Controller Reset was done */
+ clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC,
+ (init == USB_INIT_HOST) ? USBMODE_CM_HC : 0);
+ /*
+ * Select PHY interface after setting host mode.
+ * For device mode, the ordering requirement is not an issue, since
+ * only the first USB controller supports device mode, and that USB
+ * controller can only talk to a UTMI PHY, so the PHY selection is
+ * already made at reset time, so this write is a no-op.
+ */
+ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK,
+ pts << PTS_SHIFT);
+ clrbits_le32(&usbctlr->hostpc1_devlc, STS);
+#endif
+}
+
+/* set up the UTMI USB controller with the parameters provided */
+static int init_utmi_usb_controller(struct fdt_usb *config,
+ enum usb_init_type init)
+{
+ u32 b_sess_valid_mask, val;
+ int loop_count;
+ const unsigned *timing;
+ struct usb_ctlr *usbctlr = config->reg;
+ struct clk_rst_ctlr *clkrst;
+ struct usb_ctlr *usb1ctlr;
+
+ clock_enable(config->periph_id);
+
+ /* Reset the usb controller */
+ usbf_reset_controller(config, usbctlr);
+
+ /* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */
+ clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);
+
+ /* Follow the crystal clock disable by >100ns delay */
+ udelay(1);
+
+ b_sess_valid_mask = (VBUS_B_SESS_VLD_SW_VALUE | VBUS_B_SESS_VLD_SW_EN);
+ clrsetbits_le32(&usbctlr->phy_vbus_sensors, b_sess_valid_mask,
+ (init == USB_INIT_DEVICE) ? b_sess_valid_mask : 0);
+
+ /*
+ * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP
+ * mux must be switched to actually use a_sess_vld threshold.
+ */
+ if (config->dr_mode == DR_MODE_OTG &&
+ fdt_gpio_isvalid(&config->vbus_gpio))
+ clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
+ VBUS_SENSE_CTL_MASK,
+ VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
+
+ /*
+ * PLL Delay CONFIGURATION settings. The following parameters control
+ * the bring up of the plls.
+ */
+ timing = get_pll_timing();
+
+ if (!controller->has_hostpc) {
+ val = readl(&usbctlr->utmip_misc_cfg1);
+ clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
+ timing[PARAM_STABLE_COUNT] <<
+ UTMIP_PLLU_STABLE_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
+ timing[PARAM_ACTIVE_DELAY_COUNT] <<
+ UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
+ writel(val, &usbctlr->utmip_misc_cfg1);
+
+ /* Set PLL enable delay count and crystal frequency count */
+ val = readl(&usbctlr->utmip_pll_cfg1);
+ clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
+ timing[PARAM_ENABLE_DELAY_COUNT] <<
+ UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
+ timing[PARAM_XTAL_FREQ_COUNT] <<
+ UTMIP_XTAL_FREQ_COUNT_SHIFT);
+ writel(val, &usbctlr->utmip_pll_cfg1);
+ } else {
+ clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+ val = readl(&clkrst->crc_utmip_pll_cfg2);
+ clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
+ timing[PARAM_STABLE_COUNT] <<
+ UTMIP_PLLU_STABLE_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
+ timing[PARAM_ACTIVE_DELAY_COUNT] <<
+ UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
+ writel(val, &clkrst->crc_utmip_pll_cfg2);
+
+ /* Set PLL enable delay count and crystal frequency count */
+ val = readl(&clkrst->crc_utmip_pll_cfg1);
+ clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
+ timing[PARAM_ENABLE_DELAY_COUNT] <<
+ UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
+ clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
+ timing[PARAM_XTAL_FREQ_COUNT] <<
+ UTMIP_XTAL_FREQ_COUNT_SHIFT);
+ writel(val, &clkrst->crc_utmip_pll_cfg1);
+
+ /* Disable Power Down state for PLL */
+ clrbits_le32(&clkrst->crc_utmip_pll_cfg1,
+ PLLU_POWERDOWN | PLL_ENABLE_POWERDOWN |
+ PLL_ACTIVE_POWERDOWN);
+
+ /* Recommended PHY settings for EYE diagram */
+ val = readl(&usbctlr->utmip_xcvr_cfg0);
+ clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MASK,
+ 0x4 << UTMIP_XCVR_SETUP_SHIFT);
+ clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MSB_MASK,
+ 0x3 << UTMIP_XCVR_SETUP_MSB_SHIFT);
+ clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW_MSB_MASK,
+ 0x8 << UTMIP_XCVR_HSSLEW_MSB_SHIFT);
+ writel(val, &usbctlr->utmip_xcvr_cfg0);
+ clrsetbits_le32(&usbctlr->utmip_xcvr_cfg1,
+ UTMIP_XCVR_TERM_RANGE_ADJ_MASK,
+ 0x7 << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT);
+
+ /* Some registers can be controlled from USB1 only. */
+ if (config->periph_id != PERIPH_ID_USBD) {
+ clock_enable(PERIPH_ID_USBD);
+ /* Disable Reset if in Reset state */
+ reset_set_enable(PERIPH_ID_USBD, 0);
+ }
+ usb1ctlr = (struct usb_ctlr *)
+ ((u32)config->reg & USB1_ADDR_MASK);
+ val = readl(&usb1ctlr->utmip_bias_cfg0);
+ setbits_le32(&val, UTMIP_HSDISCON_LEVEL_MSB);
+ clrsetbits_le32(&val, UTMIP_HSDISCON_LEVEL_MASK,
+ 0x1 << UTMIP_HSDISCON_LEVEL_SHIFT);
+ clrsetbits_le32(&val, UTMIP_HSSQUELCH_LEVEL_MASK,
+ 0x2 << UTMIP_HSSQUELCH_LEVEL_SHIFT);
+ writel(val, &usb1ctlr->utmip_bias_cfg0);
+
+ /* Miscellaneous setting mentioned in Programming Guide */
+ clrbits_le32(&usbctlr->utmip_misc_cfg0,
+ UTMIP_SUSPEND_EXIT_ON_EDGE);
+ }
+
+ /* Setting the tracking length time */
+ clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
+ UTMIP_BIAS_PDTRK_COUNT_MASK,
+ timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT);
+
+ /* Program debounce time for VBUS to become valid */
+ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
+ UTMIP_DEBOUNCE_CFG0_MASK,
+ timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);
+
+ setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);
+
+ /* Disable battery charge enabling bit */
+ setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG);
+
+ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE);
+ setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);