/* * process_usb_nodes() - Process a list of USB nodes, adding them to our list * of USB ports. * @blob: fdt blob * @node_list: list of nodes to process (any <=0 are ignored) * @count: number of nodes to process * * Return: 0 - ok, -1 - error */ static int process_usb_nodes(const void *blob, int node_list[], int count) { struct fdt_usb config; int node, i; int clk_done = 0; port_count = 0; for (i = 0; i < count; i++) { if (port_count == USB_PORTS_MAX) { printf("tegrausb: Cannot register more than %d ports\n", USB_PORTS_MAX); return -1; } debug("USB %d: ", i); node = node_list[i]; if (!node) continue; if (fdt_decode_usb(blob, node, &config)) { debug("Cannot decode USB node %s\n", fdt_get_name(blob, node, NULL)); return -1; } if (!clk_done) { config_clock(get_pll_timing()); clk_done = 1; } config.initialized = 0; /* add new USB port to the list of available ports */ port[port_count++] = config; } return 0; }
/* 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) { struct fdt_usb_controller *controller; 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 && dm_gpio_is_valid(&config->vbus_gpio)) clrsetbits_le32(&usbctlr->usb1_legacy_ctrl, VBUS_SENSE_CTL_MASK, VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT); controller = &fdt_usb_controllers[config->type]; debug("controller=%p, type=%d\n", controller, config->type); /* * PLL Delay CONFIGURATION settings. The following parameters control * the bring up of the plls. */ timing = get_pll_timing(controller); 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 *) ((unsigned long)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); if (timing[PARAM_DEBOUNCE_A_TIME] > 0xFFFF) { clrsetbits_le32(&usbctlr->utmip_debounce_cfg0, UTMIP_DEBOUNCE_CFG0_MASK, (timing[PARAM_DEBOUNCE_A_TIME] >> 1) << UTMIP_DEBOUNCE_CFG0_SHIFT); clrsetbits_le32(&usbctlr->utmip_bias_cfg1, UTMIP_BIAS_DEBOUNCE_TIMESCALE_MASK, 1 << UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT); }
/* set up the UTMI USB controller with the parameters provided */ static int init_utmi_usb_controller(struct fdt_usb *config) { u32 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); /* * 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); /* * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT * Setting these fields, together with default values of the * other fields, results in programming the registers below as * follows: * UTMIP_HSRX_CFG0 = 0x9168c000 * UTMIP_HSRX_CFG1 = 0x13 */ /* Set PLL enable delay count and Crystal frequency count */ val = readl(&usbctlr->utmip_hsrx_cfg0); clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK, utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT); clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK, utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT); writel(val, &usbctlr->utmip_hsrx_cfg0); /* Configure the UTMIP_HS_SYNC_START_DLY */ clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1, UTMIP_HS_SYNC_START_DLY_MASK, utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT); /* Preceed the crystal clock disable by >100ns delay. */ udelay(1); /* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */ setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN); if (controller->has_hostpc) { if (config->periph_id == PERIPH_ID_USBD) clrbits_le32(&clkrst->crc_utmip_pll_cfg2, UTMIP_FORCE_PD_SAMP_A_POWERDOWN); if (config->periph_id == PERIPH_ID_USB3) clrbits_le32(&clkrst->crc_utmip_pll_cfg2, UTMIP_FORCE_PD_SAMP_C_POWERDOWN); } /* Finished the per-controller init. */ /* De-assert UTMIP_RESET to bring out of reset. */ clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET); /* Wait for the phy clock to become valid in 100 ms */ 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; /* Disable ICUSB FS/LS transceiver */ clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1); /* Select UTMI parallel interface */ clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_UTMI << PTS_SHIFT); clrbits_le32(&usbctlr->port_sc1, STS); /* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN); clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN); if (controller->has_hostpc) { /* * BIAS Pad Power Down is common among all 3 USB * controllers and can be controlled from USB1 only. */ usb1ctlr = (struct usb_ctlr *) ((u32)config->reg & USB1_ADDR_MASK); clrbits_le32(&usb1ctlr->utmip_bias_cfg0, UTMIP_BIASPD); udelay(25); clrbits_le32(&usb1ctlr->utmip_bias_cfg1, UTMIP_FORCE_PDTRK_POWERDOWN); } return 0; }