1237c3637SMasahiro Yamada /* 2237c3637SMasahiro Yamada * (C) Copyright 2010,2011 3237c3637SMasahiro Yamada * NVIDIA Corporation <www.nvidia.com> 4237c3637SMasahiro Yamada * 5237c3637SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 6237c3637SMasahiro Yamada */ 7237c3637SMasahiro Yamada 8237c3637SMasahiro Yamada #include <common.h> 9237c3637SMasahiro Yamada #include <dm.h> 10237c3637SMasahiro Yamada #include <errno.h> 11237c3637SMasahiro Yamada #include <ns16550.h> 12237c3637SMasahiro Yamada #include <linux/compiler.h> 13237c3637SMasahiro Yamada #include <asm/io.h> 14237c3637SMasahiro Yamada #include <asm/arch/clock.h> 15237c3637SMasahiro Yamada #ifdef CONFIG_LCD 16237c3637SMasahiro Yamada #include <asm/arch/display.h> 17237c3637SMasahiro Yamada #endif 18237c3637SMasahiro Yamada #include <asm/arch/funcmux.h> 19237c3637SMasahiro Yamada #include <asm/arch/pinmux.h> 20237c3637SMasahiro Yamada #include <asm/arch/pmu.h> 21237c3637SMasahiro Yamada #ifdef CONFIG_PWM_TEGRA 22237c3637SMasahiro Yamada #include <asm/arch/pwm.h> 23237c3637SMasahiro Yamada #endif 24237c3637SMasahiro Yamada #include <asm/arch/tegra.h> 25237c3637SMasahiro Yamada #include <asm/arch-tegra/ap.h> 26237c3637SMasahiro Yamada #include <asm/arch-tegra/board.h> 27237c3637SMasahiro Yamada #include <asm/arch-tegra/clk_rst.h> 28237c3637SMasahiro Yamada #include <asm/arch-tegra/pmc.h> 29237c3637SMasahiro Yamada #include <asm/arch-tegra/sys_proto.h> 30237c3637SMasahiro Yamada #include <asm/arch-tegra/uart.h> 31237c3637SMasahiro Yamada #include <asm/arch-tegra/warmboot.h> 32237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_CLOCK_SCALING 33237c3637SMasahiro Yamada #include <asm/arch/emc.h> 34237c3637SMasahiro Yamada #endif 35237c3637SMasahiro Yamada #ifdef CONFIG_USB_EHCI_TEGRA 36237c3637SMasahiro Yamada #include <asm/arch-tegra/usb.h> 37237c3637SMasahiro Yamada #include <usb.h> 38237c3637SMasahiro Yamada #endif 39237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_MMC 40237c3637SMasahiro Yamada #include <asm/arch-tegra/tegra_mmc.h> 41237c3637SMasahiro Yamada #include <asm/arch-tegra/mmc.h> 42237c3637SMasahiro Yamada #endif 43237c3637SMasahiro Yamada #include <asm/arch-tegra/xusb-padctl.h> 44237c3637SMasahiro Yamada #include <power/as3722.h> 45237c3637SMasahiro Yamada #include <i2c.h> 46237c3637SMasahiro Yamada #include <spi.h> 47237c3637SMasahiro Yamada #include "emc.h" 48237c3637SMasahiro Yamada 49237c3637SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 50237c3637SMasahiro Yamada 51237c3637SMasahiro Yamada #ifdef CONFIG_SPL_BUILD 52237c3637SMasahiro Yamada /* TODO(sjg@chromium.org): Remove once SPL supports device tree */ 53237c3637SMasahiro Yamada U_BOOT_DEVICE(tegra_gpios) = { 54237c3637SMasahiro Yamada "gpio_tegra" 55237c3637SMasahiro Yamada }; 56237c3637SMasahiro Yamada #endif 57237c3637SMasahiro Yamada 58237c3637SMasahiro Yamada __weak void pinmux_init(void) {} 59237c3637SMasahiro Yamada __weak void pin_mux_usb(void) {} 60237c3637SMasahiro Yamada __weak void pin_mux_spi(void) {} 61237c3637SMasahiro Yamada __weak void gpio_early_init_uart(void) {} 62237c3637SMasahiro Yamada __weak void pin_mux_display(void) {} 63237c3637SMasahiro Yamada 64237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_NAND) 65237c3637SMasahiro Yamada __weak void pin_mux_nand(void) 66237c3637SMasahiro Yamada { 67237c3637SMasahiro Yamada funcmux_select(PERIPH_ID_NDFLASH, FUNCMUX_DEFAULT); 68237c3637SMasahiro Yamada } 69237c3637SMasahiro Yamada #endif 70237c3637SMasahiro Yamada 71237c3637SMasahiro Yamada /* 72237c3637SMasahiro Yamada * Routine: power_det_init 73237c3637SMasahiro Yamada * Description: turn off power detects 74237c3637SMasahiro Yamada */ 75237c3637SMasahiro Yamada static void power_det_init(void) 76237c3637SMasahiro Yamada { 77237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA20) 78237c3637SMasahiro Yamada struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; 79237c3637SMasahiro Yamada 80237c3637SMasahiro Yamada /* turn off power detects */ 81237c3637SMasahiro Yamada writel(0, &pmc->pmc_pwr_det_latch); 82237c3637SMasahiro Yamada writel(0, &pmc->pmc_pwr_det); 83237c3637SMasahiro Yamada #endif 84237c3637SMasahiro Yamada } 85237c3637SMasahiro Yamada 86237c3637SMasahiro Yamada __weak int tegra_board_id(void) 87237c3637SMasahiro Yamada { 88237c3637SMasahiro Yamada return -1; 89237c3637SMasahiro Yamada } 90237c3637SMasahiro Yamada 91237c3637SMasahiro Yamada #ifdef CONFIG_DISPLAY_BOARDINFO 92237c3637SMasahiro Yamada int checkboard(void) 93237c3637SMasahiro Yamada { 94237c3637SMasahiro Yamada int board_id = tegra_board_id(); 95237c3637SMasahiro Yamada 96237c3637SMasahiro Yamada printf("Board: %s", CONFIG_TEGRA_BOARD_STRING); 97237c3637SMasahiro Yamada if (board_id != -1) 98237c3637SMasahiro Yamada printf(", ID: %d\n", board_id); 99237c3637SMasahiro Yamada printf("\n"); 100237c3637SMasahiro Yamada 101237c3637SMasahiro Yamada return 0; 102237c3637SMasahiro Yamada } 103237c3637SMasahiro Yamada #endif /* CONFIG_DISPLAY_BOARDINFO */ 104237c3637SMasahiro Yamada 105237c3637SMasahiro Yamada __weak int tegra_lcd_pmic_init(int board_it) 106237c3637SMasahiro Yamada { 107237c3637SMasahiro Yamada return 0; 108237c3637SMasahiro Yamada } 109237c3637SMasahiro Yamada 110c96d709fSSimon Glass __weak int nvidia_board_init(void) 111c96d709fSSimon Glass { 112c96d709fSSimon Glass return 0; 113c96d709fSSimon Glass } 114c96d709fSSimon Glass 115237c3637SMasahiro Yamada /* 116237c3637SMasahiro Yamada * Routine: board_init 117237c3637SMasahiro Yamada * Description: Early hardware init. 118237c3637SMasahiro Yamada */ 119237c3637SMasahiro Yamada int board_init(void) 120237c3637SMasahiro Yamada { 121237c3637SMasahiro Yamada __maybe_unused int err; 122237c3637SMasahiro Yamada __maybe_unused int board_id; 123237c3637SMasahiro Yamada 124237c3637SMasahiro Yamada /* Do clocks and UART first so that printf() works */ 125237c3637SMasahiro Yamada clock_init(); 126237c3637SMasahiro Yamada clock_verify(); 127237c3637SMasahiro Yamada 128237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_SPI 129237c3637SMasahiro Yamada pin_mux_spi(); 130237c3637SMasahiro Yamada #endif 131237c3637SMasahiro Yamada 132237c3637SMasahiro Yamada #ifdef CONFIG_PWM_TEGRA 133237c3637SMasahiro Yamada if (pwm_init(gd->fdt_blob)) 134237c3637SMasahiro Yamada debug("%s: Failed to init pwm\n", __func__); 135237c3637SMasahiro Yamada #endif 136237c3637SMasahiro Yamada #ifdef CONFIG_LCD 137237c3637SMasahiro Yamada pin_mux_display(); 138237c3637SMasahiro Yamada tegra_lcd_check_next_stage(gd->fdt_blob, 0); 139237c3637SMasahiro Yamada #endif 140237c3637SMasahiro Yamada /* boot param addr */ 141237c3637SMasahiro Yamada gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100); 142237c3637SMasahiro Yamada 143237c3637SMasahiro Yamada power_det_init(); 144237c3637SMasahiro Yamada 145237c3637SMasahiro Yamada #ifdef CONFIG_SYS_I2C_TEGRA 146237c3637SMasahiro Yamada # ifdef CONFIG_TEGRA_PMU 147237c3637SMasahiro Yamada if (pmu_set_nominal()) 148237c3637SMasahiro Yamada debug("Failed to select nominal voltages\n"); 149237c3637SMasahiro Yamada # ifdef CONFIG_TEGRA_CLOCK_SCALING 150237c3637SMasahiro Yamada err = board_emc_init(); 151237c3637SMasahiro Yamada if (err) 152237c3637SMasahiro Yamada debug("Memory controller init failed: %d\n", err); 153237c3637SMasahiro Yamada # endif 154237c3637SMasahiro Yamada # endif /* CONFIG_TEGRA_PMU */ 155237c3637SMasahiro Yamada #ifdef CONFIG_AS3722_POWER 156237c3637SMasahiro Yamada err = as3722_init(NULL); 157237c3637SMasahiro Yamada if (err && err != -ENODEV) 158237c3637SMasahiro Yamada return err; 159237c3637SMasahiro Yamada #endif 160237c3637SMasahiro Yamada #endif /* CONFIG_SYS_I2C_TEGRA */ 161237c3637SMasahiro Yamada 162237c3637SMasahiro Yamada #ifdef CONFIG_USB_EHCI_TEGRA 163237c3637SMasahiro Yamada pin_mux_usb(); 164*534f9d3fSSimon Glass # ifndef CONFIG_DM_USB 165237c3637SMasahiro Yamada usb_process_devicetree(gd->fdt_blob); 166237c3637SMasahiro Yamada # endif 167*534f9d3fSSimon Glass #endif 168237c3637SMasahiro Yamada 169237c3637SMasahiro Yamada #ifdef CONFIG_LCD 170237c3637SMasahiro Yamada board_id = tegra_board_id(); 171237c3637SMasahiro Yamada err = tegra_lcd_pmic_init(board_id); 172237c3637SMasahiro Yamada if (err) 173237c3637SMasahiro Yamada return err; 174237c3637SMasahiro Yamada tegra_lcd_check_next_stage(gd->fdt_blob, 0); 175237c3637SMasahiro Yamada #endif 176237c3637SMasahiro Yamada 177237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_NAND 178237c3637SMasahiro Yamada pin_mux_nand(); 179237c3637SMasahiro Yamada #endif 180237c3637SMasahiro Yamada 181237c3637SMasahiro Yamada tegra_xusb_padctl_init(gd->fdt_blob); 182237c3637SMasahiro Yamada 183237c3637SMasahiro Yamada #ifdef CONFIG_TEGRA_LP0 184237c3637SMasahiro Yamada /* save Sdram params to PMC 2, 4, and 24 for WB0 */ 185237c3637SMasahiro Yamada warmboot_save_sdram_params(); 186237c3637SMasahiro Yamada 187237c3637SMasahiro Yamada /* prepare the WB code to LP0 location */ 188237c3637SMasahiro Yamada warmboot_prepare_code(TEGRA_LP0_ADDR, TEGRA_LP0_SIZE); 189237c3637SMasahiro Yamada #endif 190c96d709fSSimon Glass return nvidia_board_init(); 191237c3637SMasahiro Yamada } 192237c3637SMasahiro Yamada 193237c3637SMasahiro Yamada #ifdef CONFIG_BOARD_EARLY_INIT_F 194237c3637SMasahiro Yamada static void __gpio_early_init(void) 195237c3637SMasahiro Yamada { 196237c3637SMasahiro Yamada } 197237c3637SMasahiro Yamada 198237c3637SMasahiro Yamada void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init"))); 199237c3637SMasahiro Yamada 200237c3637SMasahiro Yamada int board_early_init_f(void) 201237c3637SMasahiro Yamada { 202237c3637SMasahiro Yamada pinmux_init(); 203237c3637SMasahiro Yamada board_init_uart_f(); 204237c3637SMasahiro Yamada 205237c3637SMasahiro Yamada /* Initialize periph GPIOs */ 206237c3637SMasahiro Yamada gpio_early_init(); 207237c3637SMasahiro Yamada gpio_early_init_uart(); 208237c3637SMasahiro Yamada #ifdef CONFIG_LCD 209237c3637SMasahiro Yamada tegra_lcd_early_init(gd->fdt_blob); 210237c3637SMasahiro Yamada #endif 211237c3637SMasahiro Yamada 212237c3637SMasahiro Yamada return 0; 213237c3637SMasahiro Yamada } 214237c3637SMasahiro Yamada #endif /* EARLY_INIT */ 215237c3637SMasahiro Yamada 216237c3637SMasahiro Yamada int board_late_init(void) 217237c3637SMasahiro Yamada { 218237c3637SMasahiro Yamada #ifdef CONFIG_LCD 219237c3637SMasahiro Yamada /* Make sure we finish initing the LCD */ 220237c3637SMasahiro Yamada tegra_lcd_check_next_stage(gd->fdt_blob, 1); 221237c3637SMasahiro Yamada #endif 222237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) 223237c3637SMasahiro Yamada if (tegra_cpu_is_non_secure()) { 224237c3637SMasahiro Yamada printf("CPU is in NS mode\n"); 225237c3637SMasahiro Yamada setenv("cpu_ns_mode", "1"); 226237c3637SMasahiro Yamada } else { 227237c3637SMasahiro Yamada setenv("cpu_ns_mode", ""); 228237c3637SMasahiro Yamada } 229237c3637SMasahiro Yamada #endif 230237c3637SMasahiro Yamada return 0; 231237c3637SMasahiro Yamada } 232237c3637SMasahiro Yamada 233237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA_MMC) 234237c3637SMasahiro Yamada __weak void pin_mux_mmc(void) 235237c3637SMasahiro Yamada { 236237c3637SMasahiro Yamada } 237237c3637SMasahiro Yamada 238237c3637SMasahiro Yamada /* this is a weak define that we are overriding */ 239237c3637SMasahiro Yamada int board_mmc_init(bd_t *bd) 240237c3637SMasahiro Yamada { 241237c3637SMasahiro Yamada debug("%s called\n", __func__); 242237c3637SMasahiro Yamada 243237c3637SMasahiro Yamada /* Enable muxes, etc. for SDMMC controllers */ 244237c3637SMasahiro Yamada pin_mux_mmc(); 245237c3637SMasahiro Yamada 246237c3637SMasahiro Yamada debug("%s: init MMC\n", __func__); 247237c3637SMasahiro Yamada tegra_mmc_init(); 248237c3637SMasahiro Yamada 249237c3637SMasahiro Yamada return 0; 250237c3637SMasahiro Yamada } 251237c3637SMasahiro Yamada 252237c3637SMasahiro Yamada void pad_init_mmc(struct mmc_host *host) 253237c3637SMasahiro Yamada { 254237c3637SMasahiro Yamada #if defined(CONFIG_TEGRA30) 255237c3637SMasahiro Yamada enum periph_id id = host->mmc_id; 256237c3637SMasahiro Yamada u32 val; 257237c3637SMasahiro Yamada 258237c3637SMasahiro Yamada debug("%s: sdmmc address = %08x, id = %d\n", __func__, 259237c3637SMasahiro Yamada (unsigned int)host->reg, id); 260237c3637SMasahiro Yamada 261237c3637SMasahiro Yamada /* Set the pad drive strength for SDMMC1 or 3 only */ 262237c3637SMasahiro Yamada if (id != PERIPH_ID_SDMMC1 && id != PERIPH_ID_SDMMC3) { 263237c3637SMasahiro Yamada debug("%s: settings are only valid for SDMMC1/SDMMC3!\n", 264237c3637SMasahiro Yamada __func__); 265237c3637SMasahiro Yamada return; 266237c3637SMasahiro Yamada } 267237c3637SMasahiro Yamada 268237c3637SMasahiro Yamada val = readl(&host->reg->sdmemcmppadctl); 269237c3637SMasahiro Yamada val &= 0xFFFFFFF0; 270237c3637SMasahiro Yamada val |= MEMCOMP_PADCTRL_VREF; 271237c3637SMasahiro Yamada writel(val, &host->reg->sdmemcmppadctl); 272237c3637SMasahiro Yamada 273237c3637SMasahiro Yamada val = readl(&host->reg->autocalcfg); 274237c3637SMasahiro Yamada val &= 0xFFFF0000; 275237c3637SMasahiro Yamada val |= AUTO_CAL_PU_OFFSET | AUTO_CAL_PD_OFFSET | AUTO_CAL_ENABLED; 276237c3637SMasahiro Yamada writel(val, &host->reg->autocalcfg); 277237c3637SMasahiro Yamada #endif /* T30 */ 278237c3637SMasahiro Yamada } 279237c3637SMasahiro Yamada #endif /* MMC */ 280