Merge pull request #1704 from marex/arm/master/memsize-passing-v1
Arm/master/memsize passing v1
diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
index 112a1ed..728eac6 100644
--- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c
+++ b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
@@ -8,6 +8,7 @@
#include <desc_image_load.h>
#include <platform.h>
#include <platform_def.h>
+#include <xlat_tables_defs.h>
#if (RCAR_BL33_EXECUTION_EL != 0) && (RCAR_BL33_EXECUTION_EL != 1)
#error
@@ -19,6 +20,8 @@
#define BL33_MODE MODE_EL2
#endif
+extern uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)];
+
static bl_mem_params_node_t bl2_mem_params_descs[] = {
{
.image_id = BL31_IMAGE_ID,
@@ -69,6 +72,7 @@
#ifdef RCAR_BL33_ARG0
.ep_info.args.arg0 = RCAR_BL33_ARG0,
#endif
+ .ep_info.args.arg3 = (uintptr_t)fdt_blob,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
image_info_t, 0),
.image_info.image_max_size =
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 4f3329f..7567813 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -10,10 +10,12 @@
#include <bl1.h>
#include <console.h>
#include <debug.h>
+#include <libfdt.h>
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <string.h>
+#include <xlat_tables_defs.h>
#include "avs_driver.h"
#include "boot_init_dram.h"
@@ -85,6 +87,32 @@
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+/* FDT with DRAM configuration */
+uint64_t fdt_blob[PAGE_SIZE_4KB / sizeof(uint64_t)];
+static void *fdt = (void *)fdt_blob;
+
+static void unsigned_num_print(unsigned long long int unum, unsigned int radix,
+ char *string)
+{
+ /* Just need enough space to store 64 bit decimal integer */
+ char num_buf[20];
+ int i = 0;
+ unsigned int rem;
+
+ do {
+ rem = unum % radix;
+ if (rem < 0xa)
+ num_buf[i] = '0' + rem;
+ else
+ num_buf[i] = 'a' + (rem - 0xa);
+ i++;
+ unum /= radix;
+ } while (unum > 0U);
+
+ while (--i >= 0)
+ *string++ = num_buf[i];
+}
+
#if (RCAR_LOSSY_ENABLE == 1)
typedef struct bl2_lossy_info {
uint32_t magic;
@@ -92,13 +120,75 @@
uint32_t b0;
} bl2_lossy_info_t;
+static void bl2_lossy_gen_fdt(uint32_t no, uint64_t start_addr,
+ uint64_t end_addr, uint32_t format,
+ uint32_t enable, int fcnlnode)
+{
+ const uint64_t fcnlsize = cpu_to_fdt64(end_addr - start_addr);
+ char nodename[40] = { 0 };
+ int ret, node;
+
+ /* Ignore undefined addresses */
+ if (start_addr == 0 && end_addr == 0)
+ return;
+
+ snprintf(nodename, sizeof(nodename), "lossy-decompression@");
+ unsigned_num_print(start_addr, 16, nodename + strlen(nodename));
+
+ node = ret = fdt_add_subnode(fdt, fcnlnode, nodename);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot create FCNL node (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_string(fdt, node, "compatible",
+ "renesas,lossy-decompression");
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL compat string (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_appendprop_string(fdt, node, "compatible",
+ "shared-dma-pool");
+ if (ret < 0) {
+ NOTICE("BL2: Cannot append FCNL compat string (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_u64(fdt, node, "reg", start_addr);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL reg prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_appendprop(fdt, node, "reg", &fcnlsize, sizeof(fcnlsize));
+ if (ret < 0) {
+ NOTICE("BL2: Cannot append FCNL reg size prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop(fdt, node, "no-map", NULL, 0);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL no-map prop (ret=%i)\n", ret);
+ panic();
+ }
+
+ ret = fdt_setprop_u32(fdt, node, "renesas,formats", format);
+ if (ret < 0) {
+ NOTICE("BL2: Cannot add FCNL formats prop (ret=%i)\n", ret);
+ panic();
+ }
+}
+
static void bl2_lossy_setting(uint32_t no, uint64_t start_addr,
uint64_t end_addr, uint32_t format,
- uint32_t enable)
+ uint32_t enable, int fcnlnode)
{
bl2_lossy_info_t info;
uint32_t reg;
+ bl2_lossy_gen_fdt(no, start_addr, end_addr, format, enable, fcnlnode);
+
reg = format | (start_addr >> 20);
mmio_write_32(AXI_DCMPAREACRA0 + 0x8 * no, reg);
mmio_write_32(AXI_DCMPAREACRB0 + 0x8 * no, end_addr >> 20);
@@ -300,11 +390,207 @@
return &bl2_tzram_layout;
}
+static void bl2_populate_compatible_string(void *fdt)
+{
+ uint32_t board_type;
+ uint32_t board_rev;
+ uint32_t reg;
+ int ret;
+
+ /* Populate compatible string */
+ rcar_get_board_type(&board_type, &board_rev);
+ switch (board_type) {
+ case BOARD_SALVATOR_X:
+ ret = fdt_setprop_string(fdt, 0, "compatible",
+ "renesas,salvator-x");
+ break;
+ case BOARD_SALVATOR_XS:
+ ret = fdt_setprop_string(fdt, 0, "compatible",
+ "renesas,salvator-xs");
+ break;
+ case BOARD_STARTER_KIT:
+ ret = fdt_setprop_string(fdt, 0, "compatible",
+ "renesas,m3ulcb");
+ break;
+ case BOARD_STARTER_KIT_PRE:
+ ret = fdt_setprop_string(fdt, 0, "compatible",
+ "renesas,h3ulcb");
+ break;
+ case BOARD_EBISU:
+ case BOARD_EBISU_4D:
+ ret = fdt_setprop_string(fdt, 0, "compatible",
+ "renesas,ebisu");
+ break;
+ default:
+ NOTICE("BL2: Cannot set compatible string, board unsupported\n");
+ panic();
+ }
+
+ if (ret < 0) {
+ NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
+ panic();
+ }
+
+ reg = mmio_read_32(RCAR_PRR);
+ switch (reg & RCAR_PRODUCT_MASK) {
+ case RCAR_PRODUCT_H3:
+ ret = fdt_appendprop_string(fdt, 0, "compatible",
+ "renesas,r8a7795");
+ break;
+ case RCAR_PRODUCT_M3:
+ ret = fdt_appendprop_string(fdt, 0, "compatible",
+ "renesas,r8a7796");
+ break;
+ case RCAR_PRODUCT_M3N:
+ ret = fdt_appendprop_string(fdt, 0, "compatible",
+ "renesas,r8a77965");
+ break;
+ case RCAR_PRODUCT_E3:
+ ret = fdt_appendprop_string(fdt, 0, "compatible",
+ "renesas,r8a77990");
+ break;
+ default:
+ NOTICE("BL2: Cannot set compatible string, SoC unsupported\n");
+ panic();
+ }
+
+ if (ret < 0) {
+ NOTICE("BL2: Cannot set compatible string (ret=%i)\n", ret);
+ panic();
+ }
+}
+
+static void bl2_advertise_dram_entries(uint64_t dram_config[8])
+{
+ char nodename[32] = { 0 };
+ uint64_t start, size;
+ uint64_t fdtsize;
+ int ret, node, chan;
+
+ for (chan = 0; chan < 4; chan++) {
+ start = dram_config[2 * chan];
+ size = dram_config[2 * chan + 1];
+ if (!size)
+ continue;
+
+ NOTICE("BL2: CH%d: %llx - %llx, %lld GiB\n",
+ chan, start, start + size - 1, size >> 30);
+ }
+
+ /*
+ * We add the DT nodes in reverse order here. The fdt_add_subnode()
+ * adds the DT node before the first existing DT node, so we have
+ * to add them in reverse order to get nodes sorted by address in
+ * the resulting DT.
+ */
+ for (chan = 3; chan >= 0; chan--) {
+ start = dram_config[2 * chan];
+ size = dram_config[2 * chan + 1];
+ if (!size)
+ continue;
+
+ /*
+ * Channel 0 is mapped in 32bit space and the first
+ * 128 MiB are reserved
+ */
+ if (chan == 0) {
+ start = 0x48000000;
+ size -= 0x8000000;
+ }
+
+ fdtsize = cpu_to_fdt64(size);
+
+ snprintf(nodename, sizeof(nodename), "memory@");
+ unsigned_num_print(start, 16, nodename + strlen(nodename));
+ node = ret = fdt_add_subnode(fdt, 0, nodename);
+ if (ret < 0)
+ goto err;
+
+ ret = fdt_setprop_string(fdt, node, "device_type", "memory");
+ if (ret < 0)
+ goto err;
+
+ ret = fdt_setprop_u64(fdt, node, "reg", start);
+ if (ret < 0)
+ goto err;
+
+ ret = fdt_appendprop(fdt, node, "reg", &fdtsize,
+ sizeof(fdtsize));
+ if (ret < 0)
+ goto err;
+ }
+
+ return;
+err:
+ NOTICE("BL2: Cannot add memory node to FDT (ret=%i)\n", ret);
+ panic();
+}
+
+static void bl2_advertise_dram_size(uint32_t product)
+{
+ uint64_t dram_config[8] = {
+ [0] = 0x400000000ULL,
+ [2] = 0x500000000ULL,
+ [4] = 0x600000000ULL,
+ [6] = 0x700000000ULL,
+ };
+
+ switch (product) {
+ case RCAR_PRODUCT_H3:
+#if (RCAR_DRAM_LPDDR4_MEMCONF == 0)
+ /* 4GB(1GBx4) */
+ dram_config[1] = 0x40000000ULL;
+ dram_config[3] = 0x40000000ULL;
+ dram_config[5] = 0x40000000ULL;
+ dram_config[7] = 0x40000000ULL;
+#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \
+ (RCAR_DRAM_CHANNEL == 5) && \
+ (RCAR_DRAM_SPLIT == 2)
+ /* 4GB(2GBx2 2ch split) */
+ dram_config[1] = 0x80000000ULL;
+ dram_config[3] = 0x80000000ULL;
+#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15)
+ /* 8GB(2GBx4: default) */
+ dram_config[1] = 0x80000000ULL;
+ dram_config[3] = 0x80000000ULL;
+ dram_config[5] = 0x80000000ULL;
+ dram_config[7] = 0x80000000ULL;
+#endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */
+ break;
+
+ case RCAR_PRODUCT_M3:
+ /* 4GB(2GBx2 2ch split) */
+ dram_config[1] = 0x80000000ULL;
+ dram_config[5] = 0x80000000ULL;
+ break;
+
+ case RCAR_PRODUCT_M3N:
+ /* 2GB(1GBx2) */
+ dram_config[1] = 0x80000000ULL;
+ break;
+
+ case RCAR_PRODUCT_E3:
+#if (RCAR_DRAM_DDR3L_MEMCONF == 0)
+ /* 1GB(512MBx2) */
+ dram_config[1] = 0x40000000ULL;
+#elif (RCAR_DRAM_DDR3L_MEMCONF == 1)
+ /* 2GB(512MBx4) */
+ dram_config[1] = 0x80000000ULL;
+#elif (RCAR_DRAM_DDR3L_MEMCONF == 2)
+ /* 4GB(1GBx4) */
+ dram_config[1] = 0x100000000ULL;
+#endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */
+ break;
+ }
+
+ bl2_advertise_dram_entries(dram_config);
+}
+
void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2,
u_register_t arg3, u_register_t arg4)
{
uint32_t reg, midr, lcs, boot_dev, boot_cpu, sscg, type, rev;
- uint32_t cut, product, product_cut, major, minor;
+ uint32_t product, product_cut, major, minor;
int32_t ret;
const char *str;
const char *unknown = "unknown";
@@ -331,6 +617,9 @@
#else
const char *boot_hyper160 = "HyperFlash(160MHz)";
#endif
+#if (RCAR_LOSSY_ENABLE == 1)
+ int fcnlnode;
+#endif
reg = mmio_read_32(RCAR_MODEMR);
boot_dev = reg & MODEMR_BOOT_DEV_MASK;
@@ -374,7 +663,6 @@
reg = mmio_read_32(RCAR_PRR);
product_cut = reg & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK);
product = reg & RCAR_PRODUCT_MASK;
- cut = reg & RCAR_CUT_MASK;
switch (product) {
case RCAR_PRODUCT_H3:
@@ -506,33 +794,6 @@
bl2_tzram_layout.total_base = BL31_BASE;
bl2_tzram_layout.total_size = BL31_LIMIT - BL31_BASE;
- if (product == RCAR_PRODUCT_H3 && cut >= RCAR_CUT_VER30) {
-#if (RCAR_DRAM_LPDDR4_MEMCONF == 0)
- NOTICE("BL2: CH0: 0x400000000 - 0x440000000, 1 GiB\n");
- NOTICE("BL2: CH1: 0x500000000 - 0x540000000, 1 GiB\n");
- NOTICE("BL2: CH2: 0x600000000 - 0x640000000, 1 GiB\n");
- NOTICE("BL2: CH3: 0x700000000 - 0x740000000, 1 GiB\n");
-#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && \
- (RCAR_DRAM_CHANNEL == 5) && \
- (RCAR_DRAM_SPLIT == 2)
- NOTICE("BL2: CH0: 0x400000000 - 0x480000000, 2 GiB\n");
- NOTICE("BL2: CH1: 0x500000000 - 0x580000000, 2 GiB\n");
-#elif (RCAR_DRAM_LPDDR4_MEMCONF == 1) && (RCAR_DRAM_CHANNEL == 15)
- NOTICE("BL2: CH0: 0x400000000 - 0x480000000, 2 GiB\n");
- NOTICE("BL2: CH1: 0x500000000 - 0x580000000, 2 GiB\n");
- NOTICE("BL2: CH2: 0x600000000 - 0x680000000, 2 GiB\n");
- NOTICE("BL2: CH3: 0x700000000 - 0x780000000, 2 GiB\n");
-#endif
- }
-
- if (product == RCAR_PRODUCT_E3) {
-#if (RCAR_DRAM_DDR3L_MEMCONF == 0)
- NOTICE("BL2: 0x400000000 - 0x440000000, 1 GiB\n");
-#elif (RCAR_DRAM_DDR3L_MEMCONF == 1)
- NOTICE("BL2: 0x400000000 - 0x480000000, 2 GiB\n");
-#endif
- }
-
if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
boot_cpu == MODEMR_BOOT_CPU_CA53) {
ret = rcar_dram_init();
@@ -543,6 +804,19 @@
rcar_qos_init();
}
+ /* Set up FDT */
+ ret = fdt_create_empty_tree(fdt, sizeof(fdt_blob));
+ if (ret) {
+ NOTICE("BL2: Cannot allocate FDT for U-Boot (ret=%i)\n", ret);
+ panic();
+ }
+
+ /* Add platform compatible string */
+ bl2_populate_compatible_string(fdt);
+
+ /* Print DRAM layout */
+ bl2_advertise_dram_size(product);
+
if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
boot_dev == MODEMR_BOOT_DEV_EMMC_50X8) {
if (rcar_emmc_init() != EMMC_SUCCESS) {
@@ -591,14 +865,25 @@
}
#if (RCAR_LOSSY_ENABLE == 1)
NOTICE("BL2: Lossy Decomp areas\n");
+
+ fcnlnode = fdt_add_subnode(fdt, 0, "reserved-memory");
+ if (fcnlnode < 0) {
+ NOTICE("BL2: Cannot create reserved mem node (ret=%i)\n",
+ fcnlnode);
+ panic();
+ }
+
bl2_lossy_setting(0, LOSSY_ST_ADDR0, LOSSY_END_ADDR0,
- LOSSY_FMT0, LOSSY_ENA_DIS0);
+ LOSSY_FMT0, LOSSY_ENA_DIS0, fcnlnode);
bl2_lossy_setting(1, LOSSY_ST_ADDR1, LOSSY_END_ADDR1,
- LOSSY_FMT1, LOSSY_ENA_DIS1);
+ LOSSY_FMT1, LOSSY_ENA_DIS1, fcnlnode);
bl2_lossy_setting(2, LOSSY_ST_ADDR2, LOSSY_END_ADDR2,
- LOSSY_FMT2, LOSSY_ENA_DIS2);
+ LOSSY_FMT2, LOSSY_ENA_DIS2, fcnlnode);
#endif
+ fdt_pack(fdt);
+ NOTICE("BL2: FDT at %p\n", fdt);
+
if (boot_dev == MODEMR_BOOT_DEV_EMMC_25X1 ||
boot_dev == MODEMR_BOOT_DEV_EMMC_50X8)
rcar_io_emmc_setup();
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index f7d6216..0cc746d 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -303,6 +303,7 @@
include drivers/staging/renesas/rcar/ddr/ddr.mk
include drivers/staging/renesas/rcar/qos/qos.mk
include drivers/staging/renesas/rcar/pfc/pfc.mk
+include lib/libfdt/libfdt.mk
PLAT_INCLUDES := -Iinclude/common/tbbr \
-Idrivers/staging/renesas/rcar/ddr \
@@ -331,6 +332,7 @@
BL2_SOURCES += ${RCAR_GIC_SOURCES} \
lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
+ ${LIBFDT_SRCS} \
common/desc_image_load.c \
plat/renesas/rcar/aarch64/platform_common.c \
plat/renesas/rcar/aarch64/plat_helpers.S \