diff options
-rw-r--r-- | src/soc/nvidia/tegra132/addressmap.c | 98 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/cbmem.c | 13 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/include/soc/addressmap.h | 27 |
3 files changed, 129 insertions, 9 deletions
diff --git a/src/soc/nvidia/tegra132/addressmap.c b/src/soc/nvidia/tegra132/addressmap.c index 92a7d76f65..7620b1f789 100644 --- a/src/soc/nvidia/tegra132/addressmap.c +++ b/src/soc/nvidia/tegra132/addressmap.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <console/console.h> #include <soc/addressmap.h> +#include <soc/display.h> #include "mc.h" #include "sdram.h" @@ -46,7 +47,100 @@ int sdram_size_mb(void) return total_size; } -uintptr_t sdram_max_addressable_mb(void) +static void carveout_from_regs(uintptr_t *base_mib, size_t *size_mib, + uint32_t bom, uint32_t bom_hi, uint32_t size) { - return MIN((CONFIG_SYS_SDRAM_BASE/MiB) + sdram_size_mb(), 4096); + + /* All size regs of carveouts are in MiB. */ + if (size == 0) + return; + + *size_mib = size; + bom >>= 20; + bom |= bom_hi >> (32 - 20); + + *base_mib = bom; +} + +void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib) +{ + *base_mib = 0; + *size_mib = 0; + struct tegra_mc_regs * const mc = (struct tegra_mc_regs *)TEGRA_MC_BASE; + + switch (id) { + case CARVEOUT_TZ: + break; + case CARVEOUT_SEC: + carveout_from_regs(base_mib, size_mib, + read32(&mc->sec_carveout_bom), + read32(&mc->sec_carveout_adr_hi), + read32(&mc->sec_carveout_size_mb)); + break; + case CARVEOUT_MTS: + carveout_from_regs(base_mib, size_mib, + read32(&mc->mts_carveout_bom), + read32(&mc->mts_carveout_adr_hi), + read32(&mc->mts_carveout_size_mb)); + break; + case CARVEOUT_VPR: + carveout_from_regs(base_mib, size_mib, + read32(&mc->video_protect_bom), + read32(&mc->video_protect_bom_adr_hi), + read32(&mc->video_protect_size_mb)); + break; + default: + break; + } +} + +void memory_range_by_bits(int bits, uintptr_t *base_mib, uintptr_t *end_mib) +{ + uintptr_t base; + uintptr_t end; + int i; + + base = CONFIG_SYS_SDRAM_BASE / MiB; + end = base + sdram_size_mb(); + + if (bits == ADDRESS_SPACE_32_BIT) + end = MIN(end, 4096); + + for (i = 0; i < CARVEOUT_NUM; i++) { + uintptr_t carveout_base; + size_t carveout_size; + + carveout_range(i, &carveout_base, &carveout_size); + + if (carveout_size == 0) + continue; + + /* Bypass carveouts out of requested range. */ + if (carveout_base >= end) + continue; + + /* + * This is crude, but the assumption is that carveouts live + * at the upper range of physical memory. Therefore, update + * the end address to be equal to the base of the carveout. + */ + end = carveout_base; + } + + *base_mib = base; + *end_mib = end; +} + +uintptr_t framebuffer_attributes(size_t *size_mib) +{ + uintptr_t begin; + uintptr_t end; + + /* Place the framebuffer just below the 32-bit addressable limit. */ + memory_range_by_bits(ADDRESS_SPACE_32_BIT, &begin, &end); + + *size_mib = FB_SIZE_MB; + end -= *size_mib; + + return end; } diff --git a/src/soc/nvidia/tegra132/cbmem.c b/src/soc/nvidia/tegra132/cbmem.c index 136d3eac89..ee95ba985c 100644 --- a/src/soc/nvidia/tegra132/cbmem.c +++ b/src/soc/nvidia/tegra132/cbmem.c @@ -18,15 +18,16 @@ */ #include <cbmem.h> -#include <soc/display.h> #include <soc/addressmap.h> -#define MTS_SIZE_MB 128 - void *cbmem_top(void) { - /* FIXME(adurbin): use carveout registers properly. */ - const uintptr_t reserve = FB_SIZE_MB + MTS_SIZE_MB; + static uintptr_t addr; + size_t fb_size; + + /* CBMEM starts downwards from the framebuffer. */ + if (addr == 0) + addr = framebuffer_attributes(&fb_size); - return (void *)((sdram_max_addressable_mb() - reserve) << 20UL); + return (void *)(addr << 20UL); } diff --git a/src/soc/nvidia/tegra132/include/soc/addressmap.h b/src/soc/nvidia/tegra132/include/soc/addressmap.h index 021a523f0d..2c6dc5efc4 100644 --- a/src/soc/nvidia/tegra132/include/soc/addressmap.h +++ b/src/soc/nvidia/tegra132/include/soc/addressmap.h @@ -81,7 +81,32 @@ enum { TEGRA_I2C_BASE_COUNT = 6, }; +/* Return total size of DRAM memory configured on the platform. */ int sdram_size_mb(void); -uintptr_t sdram_max_addressable_mb(void); + +enum { + ADDRESS_SPACE_32_BIT = 32, + ADDRESS_SPACE_64_BIT = 64, +}; + +/* + * Return the address range of memory for provided address width. The base + * and end parameters in 1MiB units with end being exclusive to the range. + */ +void memory_range_by_bits(int bits, uintptr_t *base_mib, uintptr_t *end_mib); + +enum { + CARVEOUT_TZ, + CARVEOUT_SEC, + CARVEOUT_MTS, + CARVEOUT_VPR, + CARVEOUT_NUM, +}; + +/* Provided the careout id, obtain the base and size in 1MiB units. */ +void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib); + +/* Return pointer and size in 1MiB units. */ +uintptr_t framebuffer_attributes(size_t *size_mib); #endif /* __SOC_NVIDIA_TEGRA132_INCLUDE_SOC_ADDRESS_MAP_H__ */ |