/** * Register a new display based on device tree configuration. * * The frame buffer can be positioned by U-Boot or overriden by the fdt. * You should pass in the U-Boot address here, and check the contents of * struct tegra_lcd_priv to see what was actually chosen. * * @param blob Device tree blob * @param priv Driver's private data * @param default_lcd_base Default address of LCD frame buffer * @return 0 if ok, -1 on error (unsupported bits per pixel) */ static int tegra_display_probe(const void *blob, struct tegra_lcd_priv *priv, void *default_lcd_base) { struct disp_ctl_win window; struct dc_ctlr *dc; priv->frame_buffer = (u32)default_lcd_base; dc = (struct dc_ctlr *)priv->disp; /* * A header file for clock constants was NAKed upstream. * TODO: Put this into the FDT and fdt_lcd struct when we have clock * support there */ clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, 144 * 1000000); clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL, 600 * 1000000); basic_init(&dc->cmd); basic_init_timer(&dc->disp); rgb_enable(&dc->com); if (priv->pixel_clock) update_display_mode(&dc->disp, priv); if (setup_window(&window, priv)) return -1; update_window(dc, &window); return 0; }
int nvidia_board_init(void) { clock_start_periph_pll(PERIPH_ID_EXTPERIPH1, CLOCK_ID_OSC, 12000000); clock_start_periph_pll(PERIPH_ID_I2S1, CLOCK_ID_OSC, 1500000); /* For external MAX98090 audio codec */ clock_external_output(1); setup_kernel_info(); enable_required_clocks(); return 0; }
static int tegra30_spi_claim_bus(struct udevice *dev) { struct udevice *bus = dev->parent; struct tegra30_spi_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; u32 reg; /* Change SPI clock to correct frequency, PLLP_OUT0 source */ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); /* Clear stale status here */ reg = SLINK_STAT_RDY | SLINK_STAT_RXF_FLUSH | SLINK_STAT_TXF_FLUSH | \ SLINK_STAT_RXF_UNR | SLINK_STAT_TXF_OVF; writel(reg, ®s->status); debug("%s: STATUS = %08x\n", __func__, readl(®s->status)); /* Set master mode and sw controlled CS */ reg = readl(®s->command); reg |= SLINK_CMD_M_S | SLINK_CMD_CS_SOFT; writel(reg, ®s->command); debug("%s: COMMAND = %08x\n", __func__, readl(®s->command)); return 0; }
static int do_mmc_init(int dev_index, bool removable) { struct mmc_host *host; struct mmc *mmc; /* DT should have been read & host config filled in */ host = &mmc_host[dev_index]; if (!host->enabled) return -1; debug(" do_mmc_init: index %d, bus width %d pwr_gpio %d cd_gpio %d\n", dev_index, host->width, gpio_get_number(&host->pwr_gpio), gpio_get_number(&host->cd_gpio)); host->clock = 0; clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000); if (dm_gpio_is_valid(&host->pwr_gpio)) dm_gpio_set_value(&host->pwr_gpio, 1); memset(&host->cfg, 0, sizeof(host->cfg)); host->cfg.name = "Tegra SD/MMC"; host->cfg.ops = &tegra_mmc_ops; host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; host->cfg.host_caps = 0; if (host->width == 8) host->cfg.host_caps |= MMC_MODE_8BIT; if (host->width >= 4) host->cfg.host_caps |= MMC_MODE_4BIT; host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; /* * min freq is for card identification, and is the highest * low-speed SDIO card frequency (actually 400KHz) * max freq is highest HS eMMC clock as per the SD/MMC spec * (actually 52MHz) */ host->cfg.f_min = 375000; host->cfg.f_max = 48000000; host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; mmc = mmc_create(&host->cfg, host); mmc->block_dev.removable = removable; if (mmc == NULL) return -1; return 0; }
void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider) { u32 reg; assert(channel < PWM_NUM_CHANNELS); /* TODO: Can we use clock_adjust_periph_pll_div() here? */ clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, rate); reg = PWM_ENABLE_MASK; reg |= pulse_width << PWM_WIDTH_SHIFT; reg |= freq_divider << PWM_DIVIDER_SHIFT; writel(reg, &local.pwm[channel].control); debug("%s: channel=%d, rate=%d\n", __func__, channel, rate); }
static int tegra20_sflash_probe(struct udevice *bus) { struct tegra_spi_platdata *plat = dev_get_platdata(bus); struct tegra20_sflash_priv *priv = dev_get_priv(bus); priv->regs = (struct spi_regs *)plat->base; priv->last_transaction_us = timer_get_us(); priv->freq = plat->frequency; priv->periph_id = plat->periph_id; /* Change SPI clock to correct frequency, PLLP_OUT0 source */ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); return 0; }
static void i2c_init_controller(struct i2c_bus *i2c_bus, u32 clock_khz) { /* TODO: Fix bug which makes us need to do this */ clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_OSC, clock_khz * 1000 * (8 * 2 - 1)); /* Reset I2C controller. */ i2c_reset_controller(i2c_bus); /* Configure I2C controller. */ if (i2c_bus->use_dvc_ctlr) { /* only for DVC I2C CONTROLLER */ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; bf_writel(DVC_CTRL_REG3_I2C_HW_SW_PROG, 1, &dvc->ctrl3); } #if defined(CONFIG_TEGRA2) i2c_pin_mux_select(i2c_bus, i2c_bus->pinmux_config); i2c_pin_mux_tristate(i2c_bus, i2c_bus->pinmux_config, 0); #endif }
static void i2c_init_controller(struct i2c_bus *i2c_bus) { /* * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8 * here, in section 23.3.1, but in fact we seem to need a factor of * 16 to get the right frequency. */ clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, i2c_bus->speed * 2 * 8); /* Reset I2C controller. */ i2c_reset_controller(i2c_bus); /* Configure I2C controller. */ if (i2c_bus->is_dvc) { /* only for DVC I2C */ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK); } funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config); }
static int tegra_pwm_set_config(struct udevice *dev, uint channel, uint period_ns, uint duty_ns) { struct tegra_pwm_priv *priv = dev_get_priv(dev); struct pwm_ctlr *regs = priv->regs; uint pulse_width; u32 reg; if (channel >= 4) return -EINVAL; debug("%s: Configure '%s' channel %u\n", __func__, dev->name, channel); /* We ignore the period here and just use 32KHz */ clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, 32768); pulse_width = duty_ns * 255 / period_ns; reg = pulse_width << PWM_WIDTH_SHIFT; reg |= 1 << PWM_DIVIDER_SHIFT; writel(reg, ®s[channel].control); debug("%s: pulse_width=%u\n", __func__, pulse_width); return 0; }
static int tegra20_sflash_claim_bus(struct udevice *dev) { struct udevice *bus = dev->parent; struct tegra20_sflash_priv *priv = dev_get_priv(bus); struct spi_regs *regs = priv->regs; u32 reg; /* Change SPI clock to correct frequency, PLLP_OUT0 source */ clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); /* Clear stale status here */ reg = SPI_STAT_RDY | SPI_STAT_RXF_FLUSH | SPI_STAT_TXF_FLUSH | \ SPI_STAT_RXF_UNR | SPI_STAT_TXF_OVF; writel(reg, ®s->status); debug("%s: STATUS = %08x\n", __func__, readl(®s->status)); /* * Use sw-controlled CS, so we can clock in data after ReadID, etc. */ reg = (priv->mode & 1) << SPI_CMD_ACTIVE_SDA_SHIFT; if (priv->mode & 2) reg |= 1 << SPI_CMD_ACTIVE_SCLK_SHIFT; clrsetbits_le32(®s->command, SPI_CMD_ACTIVE_SCLK_MASK | SPI_CMD_ACTIVE_SDA_MASK, SPI_CMD_CS_SOFT | reg); debug("%s: COMMAND = %08x\n", __func__, readl(®s->command)); /* * SPI pins on Tegra20 are muxed - change pinmux later due to UART * issue. */ pinmux_set_func(PMUX_PINGRP_GMD, PMUX_FUNC_SFLASH); pinmux_tristate_disable(PMUX_PINGRP_LSPI); pinmux_set_func(PMUX_PINGRP_GMC, PMUX_FUNC_SFLASH); return 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; }
int tegra2_mmc_init(int dev_index, int bus_width, int pwr_gpio, int cd_gpio) { struct mmc_host *host; char gpusage[12]; /* "SD/MMCn PWR" or "SD/MMCn CD" */ struct mmc *mmc; debug(" tegra2_mmc_init: index %d, bus width %d " "pwr_gpio %d cd_gpio %d\n", dev_index, bus_width, pwr_gpio, cd_gpio); host = &mmc_host[dev_index]; host->clock = 0; host->pwr_gpio = pwr_gpio; host->cd_gpio = cd_gpio; tegra2_get_setup(host, dev_index); clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000); if (host->pwr_gpio >= 0) { sprintf(gpusage, "SD/MMC%d PWR", dev_index); gpio_request(host->pwr_gpio, gpusage); gpio_direction_output(host->pwr_gpio, 1); } if (host->cd_gpio >= 0) { sprintf(gpusage, "SD/MMC%d CD", dev_index); gpio_request(host->cd_gpio, gpusage); gpio_direction_input(host->cd_gpio); } mmc = &mmc_dev[dev_index]; sprintf(mmc->name, "Tegra2 SD/MMC"); mmc->priv = host; mmc->send_cmd = mmc_send_cmd; mmc->set_ios = mmc_set_ios; mmc->init = mmc_core_init; mmc->getcd = tegra2_mmc_getcd; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; if (bus_width == 8) mmc->host_caps = MMC_MODE_8BIT; else mmc->host_caps = MMC_MODE_4BIT; mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; /* * min freq is for card identification, and is the highest * low-speed SDIO card frequency (actually 400KHz) * max freq is highest HS eMMC clock as per the SD/MMC spec * (actually 52MHz) * Both of these are the closest equivalents w/216MHz source * clock and Tegra2 SDMMC divisors. */ mmc->f_min = 375000; mmc->f_max = 48000000; mmc_register(mmc); return 0; }