X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fmach-tegra%2Fboard2.c;h=c03f3e2052a2f8e0b265f11b8b37612dd81eb4ed;hb=135a87ef43566cdd592fa9fd899bf435aa14aaa3;hp=ebcee4ed9a516529f1c04e79ea471316bf93f871;hpb=c96d709f30cdf57ba78ef780066784a09276705f;p=u-boot diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index ebcee4ed9a..c03f3e2052 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_LCD @@ -29,11 +30,12 @@ #include #include #include +#include #ifdef CONFIG_TEGRA_CLOCK_SCALING #include #endif -#ifdef CONFIG_USB_EHCI_TEGRA #include +#ifdef CONFIG_USB_EHCI_TEGRA #include #endif #ifdef CONFIG_TEGRA_MMC @@ -60,6 +62,7 @@ __weak void pin_mux_usb(void) {} __weak void pin_mux_spi(void) {} __weak void gpio_early_init_uart(void) {} __weak void pin_mux_display(void) {} +__weak void start_cpu_fan(void) {} #if defined(CONFIG_TEGRA_NAND) __weak void pin_mux_nand(void) @@ -125,16 +128,21 @@ int board_init(void) clock_init(); clock_verify(); + tegra_gpu_config(); + #ifdef CONFIG_TEGRA_SPI pin_mux_spi(); #endif -#ifdef CONFIG_PWM_TEGRA + /* Init is handled automatically in the driver-model case */ +#if defined(CONFIG_PWM_TEGRA) && !defined(CONFIG_PWM) if (pwm_init(gd->fdt_blob)) debug("%s: Failed to init pwm\n", __func__); #endif -#ifdef CONFIG_LCD +#if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO) pin_mux_display(); +#endif +#ifdef CONFIG_LCD tegra_lcd_check_next_stage(gd->fdt_blob, 0); #endif /* boot param addr */ @@ -161,14 +169,15 @@ int board_init(void) #ifdef CONFIG_USB_EHCI_TEGRA pin_mux_usb(); - usb_process_devicetree(gd->fdt_blob); #endif -#ifdef CONFIG_LCD +#if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO) board_id = tegra_board_id(); err = tegra_lcd_pmic_init(board_id); if (err) return err; +#endif +#ifdef CONFIG_LCD tegra_lcd_check_next_stage(gd->fdt_blob, 0); #endif @@ -197,6 +206,20 @@ void gpio_early_init(void) __attribute__((weak, alias("__gpio_early_init"))); int board_early_init_f(void) { +#if defined(CONFIG_TEGRA_DISCONNECT_UDC_ON_BOOT) +#define USBCMD_FS2 (1 << 15) + { + struct usb_ctlr *usbctlr = (struct usb_ctlr *)0x7d000000; + writel(USBCMD_FS2, &usbctlr->usb_cmd); + } +#endif + + /* Do any special system timer/TSC setup */ +#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE) + if (!tegra_cpu_is_non_secure()) +#endif + arch_timer_init(); + pinmux_init(); board_init_uart_f(); @@ -225,6 +248,8 @@ int board_late_init(void) setenv("cpu_ns_mode", ""); } #endif + start_cpu_fan(); + return 0; } @@ -275,3 +300,143 @@ void pad_init_mmc(struct mmc_host *host) #endif /* T30 */ } #endif /* MMC */ + +/* + * In some SW environments, a memory carve-out exists to house a secure + * monitor, a trusted OS, and/or various statically allocated media buffers. + * + * This carveout exists at the highest possible address that is within a + * 32-bit physical address space. + * + * This function returns the total size of this carve-out. At present, the + * returned value is hard-coded for simplicity. In the future, it may be + * possible to determine the carve-out size: + * - By querying some run-time information source, such as: + * - A structure passed to U-Boot by earlier boot software. + * - SoC registers. + * - A call into the secure monitor. + * - In the per-board U-Boot configuration header, based on knowledge of the + * SW environment that U-Boot is being built for. + * + * For now, we support two configurations in U-Boot: + * - 32-bit ports without any form of carve-out. + * - 64 bit ports which are assumed to use a carve-out of a conservatively + * hard-coded size. + */ +static ulong carveout_size(void) +{ +#ifdef CONFIG_ARM64 + return SZ_512M; +#else + return 0; +#endif +} + +/* + * Determine the amount of usable RAM below 4GiB, taking into account any + * carve-out that may be assigned. + */ +static ulong usable_ram_size_below_4g(void) +{ + ulong total_size_below_4g; + ulong usable_size_below_4g; + + /* + * The total size of RAM below 4GiB is the lesser address of: + * (a) 2GiB itself (RAM starts at 2GiB, and 4GiB - 2GiB == 2GiB). + * (b) The size RAM physically present in the system. + */ + if (gd->ram_size < SZ_2G) + total_size_below_4g = gd->ram_size; + else + total_size_below_4g = SZ_2G; + + /* Calculate usable RAM by subtracting out any carve-out size */ + usable_size_below_4g = total_size_below_4g - carveout_size(); + + return usable_size_below_4g; +} + +/* + * Represent all available RAM in either one or two banks. + * + * The first bank describes any usable RAM below 4GiB. + * The second bank describes any RAM above 4GiB. + * + * This split is driven by the following requirements: + * - The NVIDIA L4T kernel requires separate entries in the DT /memory/reg + * property for memory below and above the 4GiB boundary. The layout of that + * DT property is directly driven by the entries in the U-Boot bank array. + * - The potential existence of a carve-out at the end of RAM below 4GiB can + * only be represented using multiple banks. + * + * Explicitly removing the carve-out RAM from the bank entries makes the RAM + * layout a bit more obvious, e.g. when running "bdinfo" at the U-Boot + * command-line. + * + * This does mean that the DT U-Boot passes to the Linux kernel will not + * include this RAM in /memory/reg at all. An alternative would be to include + * all RAM in the U-Boot banks (and hence DT), and add a /memreserve/ node + * into DT to stop the kernel from using the RAM. IIUC, I don't /think/ the + * Linux kernel will ever need to access any RAM in* the carve-out via a CPU + * mapping, so either way is acceptable. + * + * On 32-bit systems, we never define a bank for RAM above 4GiB, since the + * start address of that bank cannot be represented in the 32-bit .size + * field. + */ +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = usable_ram_size_below_4g(); + +#ifdef CONFIG_PCI + gd->pci_ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; +#endif + +#ifdef CONFIG_PHYS_64BIT + if (gd->ram_size > SZ_2G) { + gd->bd->bi_dram[1].start = 0x100000000; + gd->bd->bi_dram[1].size = gd->ram_size - SZ_2G; + } else +#endif + { + gd->bd->bi_dram[1].start = 0; + gd->bd->bi_dram[1].size = 0; + } +} + +/* + * Most hardware on 64-bit Tegra is still restricted to DMA to the lower + * 32-bits of the physical address space. Cap the maximum usable RAM area + * at 4 GiB to avoid DMA buffers from being allocated beyond the 32-bit + * boundary that most devices can address. Also, don't let U-Boot use any + * carve-out, as mentioned above. + * + * This function is called before dram_init_banksize(), so we can't simply + * return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return CONFIG_SYS_SDRAM_BASE + usable_ram_size_below_4g(); +} + +/* + * This function is called right before the kernel is booted. "blob" is the + * device tree that will be passed to the kernel. + */ +int ft_system_setup(void *blob, bd_t *bd) +{ + const char *gpu_path = +#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210) + "/gpu@0,57000000"; +#else + NULL; +#endif + + /* Enable GPU node if GPU setup has been performed */ + if (gpu_path != NULL) + return tegra_gpu_enable_node(blob, gpu_path); + + return 0; +}