aboutsummaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra132/addressmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/nvidia/tegra132/addressmap.c')
-rw-r--r--src/soc/nvidia/tegra132/addressmap.c98
1 files changed, 96 insertions, 2 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;
}