/** * The T30 requires some special clock initialization, including setting up * the dvc i2c, turning on mselect and selecting the G CPU cluster */ void t30_init_clocks(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; u32 val; debug("t30_init_clocks entry\n"); /* Set active CPU cluster to G */ clrbits_le32(flow->cluster_control, 1 << 0); /* * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run * at 108 MHz. This is glitch free as only the source is changed, no * special precaution needed. */ val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); writel(val, &clkrst->crc_sclk_brst_pol); writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | (0 << CLK_SYS_RATE_APB_RATE_SHIFT); writel(val, &clkrst->crc_clk_sys_rate); /* Put i2c, mselect in reset and enable clocks */ reset_set_enable(PERIPH_ID_DVC_I2C, 1); clock_set_enable(PERIPH_ID_DVC_I2C, 1); reset_set_enable(PERIPH_ID_MSELECT, 1); clock_set_enable(PERIPH_ID_MSELECT, 1); /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2); /* * Our high-level clock routines are not available prior to * relocation. We use the low-level functions which require a * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) */ clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); /* * Give clocks time to stabilize, then take i2c and mselect out of * reset */ udelay(1000); reset_set_enable(PERIPH_ID_DVC_I2C, 0); reset_set_enable(PERIPH_ID_MSELECT, 0); }
/* * Routine: clock_init_uart * Description: init the PLL and clock for the UART(s) */ static void clock_init_uart(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; struct clk_pll *pll = &clkrst->crc_pll[CLOCK_PLL_ID_PERIPH]; u32 reg; reg = readl(&pll->pll_base); if (!(reg & PLL_BASE_OVRRIDE_MASK)) { /* Override pllp setup for 216MHz operation. */ reg = PLL_BYPASS_MASK | PLL_BASE_OVRRIDE_MASK | (1 << PLL_DIVP_SHIFT) | (0xc << PLL_DIVM_SHIFT); reg |= (NVRM_PLLP_FIXED_FREQ_KHZ / 500) << PLL_DIVN_SHIFT; writel(reg, &pll->pll_base); reg |= PLL_ENABLE_MASK; writel(reg, &pll->pll_base); reg &= ~PLL_BYPASS_MASK; writel(reg, &pll->pll_base); } #if defined(CONFIG_TEGRA2_ENABLE_UARTA) /* Assert UART reset and enable clock */ reset_set_enable(PERIPH_ID_UART1, 1); clock_enable(PERIPH_ID_UART1); /* Enable pllp_out0 to UART */ reg = readl(&clkrst->crc_clk_src_uarta); reg &= 0x3FFFFFFF; /* UARTA_CLK_SRC = 00, PLLP_OUT0 */ writel(reg, &clkrst->crc_clk_src_uarta); /* wait for 2us */ udelay(2); /* De-assert reset to UART */ reset_set_enable(PERIPH_ID_UART1, 0); #endif /* CONFIG_TEGRA2_ENABLE_UARTA */ #if defined(CONFIG_TEGRA2_ENABLE_UARTD) /* Assert UART reset and enable clock */ reset_set_enable(PERIPH_ID_UART4, 1); clock_enable(PERIPH_ID_UART4); /* Enable pllp_out0 to UART */ reg = readl(&clkrst->crc_clk_src_uartd); reg &= 0x3FFFFFFF; /* UARTD_CLK_SRC = 00, PLLP_OUT0 */ writel(reg, &clkrst->crc_clk_src_uartd); /* wait for 2us */ udelay(2); /* De-assert reset to UART */ reset_set_enable(PERIPH_ID_UART4, 0); #endif /* CONFIG_TEGRA2_ENABLE_UARTD */ }
int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, const struct tegra_xusb_padctl_soc *socdata) { unsigned int i; int err; for (i = 0; i < count; i++) { if (!fdtdec_get_is_enabled(fdt, nodes[i])) continue; padctl.socdata = socdata; err = tegra_xusb_padctl_parse_dt(&padctl, fdt, nodes[i]); if (err < 0) { error("failed to parse DT: %d", err); continue; } /* deassert XUSB padctl reset */ reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config); if (err < 0) { error("failed to apply pinmux: %d", err); continue; } /* only a single instance is supported */ break; } return 0; }
/* * We need to take ALL audio devices conntected to AHUB (AUDIO, APBIF, * I2S, DAM, AMX, ADX, SPDIF, AFC) out of reset and enable the clocks. * Otherwise reading AHUB devices will hang when the kernel boots. */ static void enable_required_clocks(void) { static enum periph_id ids[] = { PERIPH_ID_I2S0, PERIPH_ID_I2S1, PERIPH_ID_I2S2, PERIPH_ID_I2S3, PERIPH_ID_I2S4, PERIPH_ID_AUDIO, PERIPH_ID_APBIF, PERIPH_ID_DAM0, PERIPH_ID_DAM1, PERIPH_ID_DAM2, PERIPH_ID_AMX0, PERIPH_ID_AMX1, PERIPH_ID_ADX0, PERIPH_ID_ADX1, PERIPH_ID_SPDIF, PERIPH_ID_AFC0, PERIPH_ID_AFC1, PERIPH_ID_AFC2, PERIPH_ID_AFC3, PERIPH_ID_AFC4, PERIPH_ID_AFC5, PERIPH_ID_EXTPERIPH1 }; int i; for (i = 0; i < ARRAY_SIZE(ids); i++) clock_enable(ids[i]); udelay(2); for (i = 0; i < ARRAY_SIZE(ids); i++) reset_set_enable(ids[i], 0); }
/** * The T30 requires some special clock initialization, including setting up * the dvc i2c, turning on mselect and selecting the G CPU cluster */ void t30_init_clocks(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; u32 val; debug("t30_init_clocks entry\n"); /* Set active CPU cluster to G */ clrbits_le32(flow->cluster_control, 1 << 0); writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); val = (0 << CLK_SYS_RATE_HCLK_DISABLE_SHIFT) | (1 << CLK_SYS_RATE_AHB_RATE_SHIFT) | (0 << CLK_SYS_RATE_PCLK_DISABLE_SHIFT) | (0 << CLK_SYS_RATE_APB_RATE_SHIFT); writel(val, &clkrst->crc_clk_sys_rate); /* Put i2c, mselect in reset and enable clocks */ reset_set_enable(PERIPH_ID_DVC_I2C, 1); clock_set_enable(PERIPH_ID_DVC_I2C, 1); reset_set_enable(PERIPH_ID_MSELECT, 1); clock_set_enable(PERIPH_ID_MSELECT, 1); /* Switch MSELECT clock to PLLP (00) and use a divisor of 2 */ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, 2); /* * Our high-level clock routines are not available prior to * relocation. We use the low-level functions which require a * hard-coded divisor. Use CLK_M with divide by (n + 1 = 17) */ clock_ll_set_source_divisor(PERIPH_ID_DVC_I2C, 3, 16); /* * Give clocks time to stabilize, then take i2c and mselect out of * reset */ udelay(1000); reset_set_enable(PERIPH_ID_DVC_I2C, 0); reset_set_enable(PERIPH_ID_MSELECT, 0); }
static int process_nodes(const void *fdt, int nodes[], unsigned int count) { unsigned int i; for (i = 0; i < count; i++) { enum fdt_compat_id id; int err; if (!fdtdec_get_is_enabled(fdt, nodes[i])) continue; id = fdtdec_lookup(fdt, nodes[i]); switch (id) { case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: break; default: error("tegra-xusb-padctl: unsupported compatible: %s", fdtdec_get_compatible(id)); continue; } padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); padctl->lanes = tegra124_lanes; padctl->num_functions = ARRAY_SIZE(tegra124_functions); padctl->functions = tegra124_functions; err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); if (err < 0) { error("tegra-xusb-padctl: failed to parse DT: %d", err); continue; } /* deassert XUSB padctl reset */ reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); if (err < 0) { error("tegra-xusb-padctl: failed to apply pinmux: %d", err); continue; } /* only a single instance is supported */ break; } return 0; }
/* * Routine: clock_init_mmc * Description: init the PLL and clocks for the SDMMC controllers */ static void clock_init_mmc(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 reg; /* Do the SDMMC resets/clock enables */ reset_set_enable(PERIPH_ID_SDMMC4, 1); clock_enable(PERIPH_ID_SDMMC4); /* Enable pllp_out0 to SDMMC4 */ reg = readl(&clkrst->crc_clk_src_sdmmc4); reg &= 0x3FFFFF00; /* SDMMC4_CLK_SRC = 00, PLLP_OUT0 */ reg |= (10 << 1); /* n-1, 11-1 shl 1 */ writel(reg, &clkrst->crc_clk_src_sdmmc4); /* * As per the Tegra2 TRM, section 5.3.4: * 'Wait 2 us for the clock to flush through the pipe/logic' */ udelay(2); reset_set_enable(PERIPH_ID_SDMMC4, 1); reset_set_enable(PERIPH_ID_SDMMC3, 1); clock_enable(PERIPH_ID_SDMMC3); /* Enable pllp_out0 to SDMMC4, set divisor to 11 for 20MHz */ reg = readl(&clkrst->crc_clk_src_sdmmc3); reg &= 0x3FFFFF00; /* SDMMC3_CLK_SRC = 00, PLLP_OUT0 */ reg |= (10 << 1); /* n-1, 11-1 shl 1 */ writel(reg, &clkrst->crc_clk_src_sdmmc3); /* wait for 2us */ udelay(2); reset_set_enable(PERIPH_ID_SDMMC3, 0); }
static int tegra124_lcd_init(struct udevice *dev, void *lcdbase, enum video_log2_bpp l2bpp) { struct video_priv *uc_priv = dev_get_uclass_priv(dev); struct display_timing timing; int ret; clock_set_up_plldp(); clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, 408000000); clock_enable(PERIPH_ID_HOST1X); clock_enable(PERIPH_ID_DISP1); clock_enable(PERIPH_ID_PWM); clock_enable(PERIPH_ID_DPAUX); clock_enable(PERIPH_ID_SOR0); udelay(2); reset_set_enable(PERIPH_ID_HOST1X, 0); reset_set_enable(PERIPH_ID_DISP1, 0); reset_set_enable(PERIPH_ID_PWM, 0); reset_set_enable(PERIPH_ID_DPAUX, 0); reset_set_enable(PERIPH_ID_SOR0, 0); ret = display_init(dev, lcdbase, 1 << l2bpp, &timing); if (ret) return ret; uc_priv->xsize = roundup(timing.hactive.typ, 16); uc_priv->ysize = timing.vactive.typ; uc_priv->bpix = l2bpp; video_set_flush_dcache(dev, 1); debug("%s: done\n", __func__); return 0; }
/** * The T114 requires some special clock initialization, including setting up * the DVC I2C, turning on MSELECT and selecting the G CPU cluster */ void t114_init_clocks(void) { struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; u32 val; debug("t114_init_clocks entry\n"); /* Set active CPU cluster to G */ clrbits_le32(&flow->cluster_control, 1); /* * Switch system clock to PLLP_OUT4 (108 MHz), AVP will now run * at 108 MHz. This is glitch free as only the source is changed, no * special precaution needed. */ val = (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) | (SCLK_SOURCE_PLLP_OUT4 << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) | (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT); writel(val, &clkrst->crc_sclk_brst_pol); writel(SUPER_SCLK_ENB_MASK, &clkrst->crc_super_sclk_div); debug("Setting up PLLX\n"); init_pllx(); val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); writel(val, &clkrst->crc_clk_sys_rate); /* Enable clocks to required peripherals. TBD - minimize this list */ debug("Enabling clocks\n"); clock_set_enable(PERIPH_ID_CACHE2, 1); clock_set_enable(PERIPH_ID_GPIO, 1); clock_set_enable(PERIPH_ID_TMR, 1); clock_set_enable(PERIPH_ID_RTC, 1); clock_set_enable(PERIPH_ID_CPU, 1); clock_set_enable(PERIPH_ID_EMC, 1); clock_set_enable(PERIPH_ID_I2C5, 1); clock_set_enable(PERIPH_ID_FUSE, 1); clock_set_enable(PERIPH_ID_PMC, 1); clock_set_enable(PERIPH_ID_APBDMA, 1); clock_set_enable(PERIPH_ID_MEM, 1); clock_set_enable(PERIPH_ID_IRAMA, 1); clock_set_enable(PERIPH_ID_IRAMB, 1); clock_set_enable(PERIPH_ID_IRAMC, 1); clock_set_enable(PERIPH_ID_IRAMD, 1); clock_set_enable(PERIPH_ID_CORESIGHT, 1); clock_set_enable(PERIPH_ID_MSELECT, 1); clock_set_enable(PERIPH_ID_EMC1, 1); clock_set_enable(PERIPH_ID_MC1, 1); clock_set_enable(PERIPH_ID_DVFS, 1); /* Switch MSELECT clock to PLLP (00) */ clock_ll_set_source(PERIPH_ID_MSELECT, 0); /* * Clock divider request for 102MHz would setup MSELECT clock as * 102MHz for PLLP base 408MHz */ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, (NVBL_PLLP_KHZ/102000)); /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); /* Give clocks time to stabilize */ udelay(1000); /* Take required peripherals out of reset */ debug("Taking periphs out of reset\n"); reset_set_enable(PERIPH_ID_CACHE2, 0); reset_set_enable(PERIPH_ID_GPIO, 0); reset_set_enable(PERIPH_ID_TMR, 0); reset_set_enable(PERIPH_ID_COP, 0); reset_set_enable(PERIPH_ID_EMC, 0); reset_set_enable(PERIPH_ID_I2C5, 0); reset_set_enable(PERIPH_ID_FUSE, 0); reset_set_enable(PERIPH_ID_APBDMA, 0); reset_set_enable(PERIPH_ID_MEM, 0); reset_set_enable(PERIPH_ID_CORESIGHT, 0); reset_set_enable(PERIPH_ID_MSELECT, 0); reset_set_enable(PERIPH_ID_EMC1, 0); reset_set_enable(PERIPH_ID_MC1, 0); debug("t114_init_clocks exit\n"); }
/* 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; }
/** * Tegra124 requires some special clock initialization, including setting up * the DVC I2C, turning on MSELECT and selecting the G CPU cluster */ void tegra124_init_clocks(void) { struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE; struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; u32 val; debug("%s entry\n", __func__); /* Set active CPU cluster to G */ clrbits_le32(&flow->cluster_control, 1); /* Change the oscillator drive strength */ val = readl(&clkrst->crc_osc_ctrl); val &= ~OSC_XOFS_MASK; val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT); writel(val, &clkrst->crc_osc_ctrl); /* Update same value in PMC_OSC_EDPD_OVER XOFS field for warmboot */ val = readl(&pmc->pmc_osc_edpd_over); val &= ~PMC_XOFS_MASK; val |= (OSC_DRIVE_STRENGTH << PMC_XOFS_SHIFT); writel(val, &pmc->pmc_osc_edpd_over); /* Set HOLD_CKE_LOW_EN to 1 */ setbits_le32(&pmc->pmc_cntrl2, HOLD_CKE_LOW_EN); debug("Setting up PLLX\n"); init_pllx(); val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT); writel(val, &clkrst->crc_clk_sys_rate); /* Enable clocks to required peripherals. TBD - minimize this list */ debug("Enabling clocks\n"); clock_set_enable(PERIPH_ID_CACHE2, 1); clock_set_enable(PERIPH_ID_GPIO, 1); clock_set_enable(PERIPH_ID_TMR, 1); clock_set_enable(PERIPH_ID_CPU, 1); clock_set_enable(PERIPH_ID_EMC, 1); clock_set_enable(PERIPH_ID_I2C5, 1); clock_set_enable(PERIPH_ID_APBDMA, 1); clock_set_enable(PERIPH_ID_MEM, 1); clock_set_enable(PERIPH_ID_CORESIGHT, 1); clock_set_enable(PERIPH_ID_MSELECT, 1); clock_set_enable(PERIPH_ID_DVFS, 1); /* * Set MSELECT clock source as PLLP (00), and ask for a clock * divider that would set the MSELECT clock at 102MHz for a * PLLP base of 408MHz. */ clock_ll_set_source_divisor(PERIPH_ID_MSELECT, 0, CLK_DIVIDER(NVBL_PLLP_KHZ, 102000)); /* Give clock time to stabilize */ udelay(IO_STABILIZATION_DELAY); /* I2C5 (DVC) gets CLK_M and a divisor of 17 */ clock_ll_set_source_divisor(PERIPH_ID_I2C5, 3, 16); /* Give clock time to stabilize */ udelay(IO_STABILIZATION_DELAY); /* Take required peripherals out of reset */ debug("Taking periphs out of reset\n"); reset_set_enable(PERIPH_ID_CACHE2, 0); reset_set_enable(PERIPH_ID_GPIO, 0); reset_set_enable(PERIPH_ID_TMR, 0); reset_set_enable(PERIPH_ID_COP, 0); reset_set_enable(PERIPH_ID_EMC, 0); reset_set_enable(PERIPH_ID_I2C5, 0); reset_set_enable(PERIPH_ID_APBDMA, 0); reset_set_enable(PERIPH_ID_MEM, 0); reset_set_enable(PERIPH_ID_CORESIGHT, 0); reset_set_enable(PERIPH_ID_MSELECT, 0); reset_set_enable(PERIPH_ID_DVFS, 0); debug("%s exit\n", __func__); }