X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=board%2Fnvidia%2Fcommon%2Fboard.c;h=76ec6876e21b51d4ea4da512109c2fc76215cfc1;hb=da77a0e593c370c9ed79ea22c1df321d5f4e4bbf;hp=32d3cfb14e1edadb72085f60a9a91910e9eb508d;hpb=03c609f69b12dca47b9422595fdde29be1fb35c9;p=karo-tx-uboot.git diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 32d3cfb14e..76ec6876e2 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -23,44 +23,34 @@ #include #include +#include #include -#include -#include - -#include #include +#include +#include +#include #include -#include -#include "board.h" - -#ifdef CONFIG_TEGRA2_MMC -#include -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "emc.h" DECLARE_GLOBAL_DATA_PTR; -const struct tegra2_sysinfo sysinfo = { - CONFIG_TEGRA2_BOARD_STRING +const struct tegra_sysinfo sysinfo = { + CONFIG_TEGRA_BOARD_STRING }; -#ifdef CONFIG_BOARD_EARLY_INIT_F -int board_early_init_f(void) -{ - /* Initialize periph clocks */ - clock_init(); - - /* Initialize periph pinmuxes */ - pinmux_init(); - - /* Initialize periph GPIOs */ - gpio_init(); - - /* Init UART, scratch regs, and start CPU */ - tegra2_start(); - return 0; -} -#endif /* EARLY_INIT */ - +#ifndef CONFIG_SPL_BUILD /* * Routine: timer_init * Description: init the timestamp and lastinc value @@ -69,198 +59,47 @@ int timer_init(void) { return 0; } +#endif -/* - * Routine: clock_init_uart - * Description: init the PLL and clock for the UART(s) - */ -static void clock_init_uart(void) +void __pin_mux_usb(void) { - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll *pll = &clkrst->crc_pll[CLOCK_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 */ } -/* - * Routine: pin_mux_uart - * Description: setup the pin muxes/tristate values for the UART(s) - */ -static void pin_mux_uart(void) -{ - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - u32 reg; - -#if defined(CONFIG_TEGRA2_ENABLE_UARTA) - reg = readl(&pmt->pmt_ctl_c); - reg &= 0xFFF0FFFF; /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */ - writel(reg, &pmt->pmt_ctl_c); - - pinmux_tristate_disable(PIN_IRRX); - pinmux_tristate_disable(PIN_IRTX); -#endif /* CONFIG_TEGRA2_ENABLE_UARTA */ -#if defined(CONFIG_TEGRA2_ENABLE_UARTD) - reg = readl(&pmt->pmt_ctl_b); - reg &= 0xFFFFFFF3; /* GMC_SEL [3:2] = 00, UARTD */ - writel(reg, &pmt->pmt_ctl_b); - - pinmux_tristate_disable(PIN_GMC); -#endif /* CONFIG_TEGRA2_ENABLE_UARTD */ -} +void pin_mux_usb(void) __attribute__((weak, alias("__pin_mux_usb"))); -/* - * Routine: clock_init_mmc - * Description: init the PLL and clocks for the SDMMC controllers - */ -static void clock_init_mmc(void) +void __pin_mux_spi(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); } -/* - * Routine: pin_mux_mmc - * Description: setup the pin muxes/tristate values for the SDMMC(s) - */ -static void pin_mux_mmc(void) -{ - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - u32 reg; - - /* SDMMC4 */ - /* config 2, x8 on 2nd set of pins */ - reg = readl(&pmt->pmt_ctl_a); - reg |= (3 << 16); /* ATB_SEL [17:16] = 11 SDIO4 */ - writel(reg, &pmt->pmt_ctl_a); - reg = readl(&pmt->pmt_ctl_b); - reg |= (3 << 0); /* GMA_SEL [1:0] = 11 SDIO4 */ - writel(reg, &pmt->pmt_ctl_b); - reg = readl(&pmt->pmt_ctl_d); - reg |= (3 << 0); /* GME_SEL [1:0] = 11 SDIO4 */ - writel(reg, &pmt->pmt_ctl_d); - - pinmux_tristate_disable(PIN_ATB); - pinmux_tristate_disable(PIN_GMA); - pinmux_tristate_disable(PIN_GME); - - /* SDMMC3 */ - /* SDIO3_CLK, SDIO3_CMD, SDIO3_DAT[3:0] */ - reg = readl(&pmt->pmt_ctl_d); - reg &= 0xFFFF03FF; - reg |= (2 << 10); /* SDB_SEL [11:10] = 01 SDIO3 */ - reg |= (2 << 12); /* SDC_SEL [13:12] = 01 SDIO3 */ - reg |= (2 << 14); /* SDD_SEL [15:14] = 01 SDIO3 */ - writel(reg, &pmt->pmt_ctl_d); +void pin_mux_spi(void) __attribute__((weak, alias("__pin_mux_spi"))); - pinmux_tristate_disable(PIN_SDC); - pinmux_tristate_disable(PIN_SDD); - pinmux_tristate_disable(PIN_SDB); -} - -/* - * Routine: clock_init - * Description: Do individual peripheral clock reset/enables - */ -void clock_init(void) +void __gpio_early_init_uart(void) { - clock_init_uart(); } -/* - * Routine: pinmux_init - * Description: Do individual peripheral pinmux configs - */ -void pinmux_init(void) +void gpio_early_init_uart(void) +__attribute__((weak, alias("__gpio_early_init_uart"))); + +void __pin_mux_nand(void) { - pin_mux_uart(); + funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT); } +void pin_mux_nand(void) __attribute__((weak, alias("__pin_mux_nand"))); + /* - * Routine: gpio_init - * Description: Do individual peripheral GPIO configs + * Routine: power_det_init + * Description: turn off power detects */ -void gpio_init(void) +static void power_det_init(void) { - gpio_config_uart(); +#if defined(CONFIG_TEGRA20) + struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; + + /* turn off power detects */ + writel(0, &pmc->pmc_pwr_det_latch); + writel(0, &pmc->pmc_pwr_det); +#endif } /* @@ -269,41 +108,97 @@ void gpio_init(void) */ int board_init(void) { + __maybe_unused int err; + + /* Do clocks and UART first so that printf() works */ + clock_init(); + clock_verify(); + +#ifdef CONFIG_SPI_UART_SWITCH + gpio_config_uart(); +#endif +#ifdef CONFIG_TEGRA_SPI + pin_mux_spi(); + spi_init(); +#endif +#ifdef CONFIG_PWM_TEGRA + if (pwm_init(gd->fdt_blob)) + debug("%s: Failed to init pwm\n", __func__); +#endif +#ifdef CONFIG_LCD + tegra_lcd_check_next_stage(gd->fdt_blob, 0); +#endif /* boot param addr */ gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100); + power_det_init(); + +#ifdef CONFIG_TEGRA_I2C +#ifndef CONFIG_SYS_I2C_INIT_BOARD +#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards" +#endif + i2c_init_board(); +# ifdef CONFIG_TEGRA_PMU + if (pmu_set_nominal()) + debug("Failed to select nominal voltages\n"); +# ifdef CONFIG_TEGRA_CLOCK_SCALING + err = board_emc_init(); + if (err) + debug("Memory controller init failed: %d\n", err); +# endif +# endif /* CONFIG_TEGRA_PMU */ +#endif /* CONFIG_TEGRA_I2C */ + +#ifdef CONFIG_USB_EHCI_TEGRA + pin_mux_usb(); + board_usb_init(gd->fdt_blob); +#endif +#ifdef CONFIG_LCD + tegra_lcd_check_next_stage(gd->fdt_blob, 0); +#endif + +#ifdef CONFIG_TEGRA_NAND + pin_mux_nand(); +#endif + +#ifdef CONFIG_TEGRA_LP0 + /* save Sdram params to PMC 2, 4, and 24 for WB0 */ + warmboot_save_sdram_params(); + + /* prepare the WB code to LP0 location */ + warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE); +#endif + return 0; } -#ifdef CONFIG_TEGRA2_MMC -/* this is a weak define that we are overriding */ -int board_mmc_init(bd_t *bd) +#ifdef CONFIG_BOARD_EARLY_INIT_F +static void __gpio_early_init(void) { - debug("board_mmc_init called\n"); - /* Enable clocks, muxes, etc. for SDMMC controllers */ - clock_init_mmc(); - pin_mux_mmc(); +} - debug("board_mmc_init: init eMMC\n"); - /* init dev 0, eMMC chip, with 4-bit bus */ - tegra2_mmc_init(0, 4); +void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init"))); - debug("board_mmc_init: init SD slot\n"); - /* init dev 1, SD slot, with 4-bit bus */ - tegra2_mmc_init(1, 4); +int board_early_init_f(void) +{ + board_init_uart_f(); + + /* Initialize periph GPIOs */ + gpio_early_init(); + gpio_early_init_uart(); +#ifdef CONFIG_LCD + tegra_lcd_early_init(gd->fdt_blob); +#endif return 0; } +#endif /* EARLY_INIT */ -/* this is a weak define that we are overriding */ -int board_mmc_getcd(u8 *cd, struct mmc *mmc) +int board_late_init(void) { - debug("board_mmc_getcd called\n"); - /* - * Hard-code CD presence for now. Need to add GPIO inputs - * for Seaboard & Harmony (& Kaen/Aebl/Wario?) - */ - *cd = 1; +#ifdef CONFIG_LCD + /* Make sure we finish initing the LCD */ + tegra_lcd_check_next_stage(gd->fdt_blob, 1); +#endif return 0; } -#endif