summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/nvidia/tegra132/addressmap.c98
-rw-r--r--src/soc/nvidia/tegra132/cbmem.c13
-rw-r--r--src/soc/nvidia/tegra132/include/soc/addressmap.h27
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__ */