MLK-16049 imx8qm/qxp: Add support for reserving DDR memory for M4
authorYe Li <ye.li@nxp.com>
Thu, 20 Jul 2017 01:26:57 +0000 (20:26 -0500)
committerJason Liu <jason.hui.liu@nxp.com>
Thu, 2 Nov 2017 18:37:03 +0000 (02:37 +0800)
We assign the DDR memory from 0x88000000 to 0x8FFFFFFF to M4 on QM and QXP.
The M4 can allocate this memory by two ways, in SCD or u-boot.

There are 3 things needed to change in u-boot:
1. Move the u-boot INIT SP address to first 128M memory to avoid conflict with M4 memory.

2. The memory regions may be allocated in SCD or ATF. So we can't staticly set the memory
   bank information in u-boot, need to get it from owned memory regions.

3. u-boot addes the memory reserve node to DTB to pass the info to kernel, no matter
   the M4 memory is reserved in SCD or u-boot. So kernel won't access M4 reserved memory.

The codes for M4 resources and memory regions allocated by u-boot will be added
later when they are finalized.

Signed-off-by: Ye Li <ye.li@nxp.com>
arch/arm/cpu/armv8/imx8/cpu.c
board/freescale/imx8qm_arm2/imx8qm_arm2.c
board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
board/freescale/imx8qxp_mek/imx8qxp_mek.c
include/configs/imx8qm_arm2.h
include/configs/imx8qxp_arm2.h
include/configs/imx8qxp_mek.h

index f28f66a..f855596 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/arch-imx/cpu.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/video_common.h>
+#include <libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -748,3 +749,179 @@ int mmc_get_env_dev(void)
        return board_mmc_get_env_dev(devno);
 }
 #endif
+
+#ifdef CONFIG_OF_SYSTEM_SETUP
+int ft_system_setup(void *blob, bd_t *bd)
+{
+#ifdef BOOTAUX_RESERVED_MEM_BASE
+       int off;
+       off = fdt_add_mem_rsv(blob, BOOTAUX_RESERVED_MEM_BASE,
+                                     BOOTAUX_RESERVED_MEM_SIZE);
+               if (off < 0)
+                       printf("Failed  to reserve memory for bootaux: %s\n",
+                              fdt_strerror(off));
+#endif
+
+       return 0;
+}
+#endif
+
+#define MEMSTART_ALIGNMENT  SZ_2M /* Align the memory start with 2MB */
+
+static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, sc_faddr_t *addr_end)
+{
+       sc_ipc_t ipcHndl = 0;
+       sc_err_t sciErr = 0;
+       bool owned;
+       sc_faddr_t start, end;
+
+       ipcHndl = gd->arch.ipc_channel_handle;
+
+       if (ipcHndl) {
+               owned = sc_rm_is_memreg_owned(ipcHndl, mr);
+               if (owned) {
+                       sciErr = sc_rm_get_memreg_info(ipcHndl, mr, &start, &end);
+                       if (sciErr) {
+                               printf("Memreg get info failed, %d\n", sciErr);
+                               return -EINVAL;
+                       } else {
+                               debug("0x%llx -- 0x%llx\n", start, end);
+                               start = roundup(start, MEMSTART_ALIGNMENT);
+                               if (start > end) /* Too small memory region, not use it */
+                                       return -EINVAL;
+
+                               *addr_start = start;
+                               *addr_end = end;
+
+                               return 0;
+                       }
+               }
+       }
+
+       return -EINVAL;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+       sc_rm_mr_t mr;
+       sc_faddr_t start, end;
+       int err;
+
+       for (mr = 0; mr < 64; mr++) {
+               err = get_owned_memreg(mr, &start, &end);
+               if (!err) {
+                       /* Find the memory region runs the u-boot */
+                       if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)
+                               && (start <= CONFIG_SYS_TEXT_BASE && CONFIG_SYS_TEXT_BASE <= end)){
+                               if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE))
+                                       return (end - start + 1);
+                               else
+                                       return PHYS_SDRAM_1_SIZE;
+                       }
+               }
+       }
+
+       return PHYS_SDRAM_1_SIZE;
+}
+
+int dram_init(void)
+{
+       sc_rm_mr_t mr;
+       sc_faddr_t start, end;
+       int err;
+
+       for (mr = 0; mr < 64; mr++) {
+               err = get_owned_memreg(mr, &start, &end);
+               if (!err) {
+                       start = roundup(start, MEMSTART_ALIGNMENT);
+                       if (start > end) /* Too small memory region, not use it */
+                               continue;
+
+                       if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) {
+
+                               if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE))
+                                       gd->ram_size += end - start + 1;
+                               else
+                                       gd->ram_size += PHYS_SDRAM_1_SIZE;
+
+                       } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) {
+
+                               if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE))
+                                       gd->ram_size += end - start + 1;
+                               else
+                                       gd->ram_size += PHYS_SDRAM_2_SIZE;
+                       }
+               }
+       }
+
+       /* If error, set to the default value */
+       if (!gd->ram_size) {
+               gd->ram_size = PHYS_SDRAM_1_SIZE;
+               gd->ram_size += PHYS_SDRAM_2_SIZE;
+       }
+       return 0;
+}
+
+static void dram_bank_sort(int current_bank)
+{
+       phys_addr_t start;
+       phys_size_t size;
+       while (current_bank > 0) {
+               if (gd->bd->bi_dram[current_bank - 1].start > gd->bd->bi_dram[current_bank].start) {
+                       start = gd->bd->bi_dram[current_bank - 1].start;
+                       size = gd->bd->bi_dram[current_bank - 1].size;
+
+                       gd->bd->bi_dram[current_bank - 1].start = gd->bd->bi_dram[current_bank].start;
+                       gd->bd->bi_dram[current_bank - 1].size = gd->bd->bi_dram[current_bank].size;
+
+                       gd->bd->bi_dram[current_bank].start = start;
+                       gd->bd->bi_dram[current_bank].size = size;
+               }
+
+               current_bank--;
+       }
+}
+
+void dram_init_banksize(void)
+{
+       sc_rm_mr_t mr;
+       sc_faddr_t start, end;
+       int i = 0;
+       int err;
+
+       for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) {
+               err = get_owned_memreg(mr, &start, &end);
+               if (!err) {
+                       if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) {
+                               gd->bd->bi_dram[i].start = start;
+
+                               if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE))
+                                       gd->bd->bi_dram[i].size = end - start + 1;
+                               else
+                                       gd->bd->bi_dram[i].size = PHYS_SDRAM_1_SIZE;
+
+                               dram_bank_sort(i);
+                               i++;
+                       } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) {
+                               gd->bd->bi_dram[i].start = start;
+
+                               if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE))
+                                       gd->bd->bi_dram[i].size = end - start + 1;
+                               else
+                                       gd->bd->bi_dram[i].size = PHYS_SDRAM_2_SIZE;
+
+                               dram_bank_sort(i);
+                               i++;
+                       }
+
+               }
+       }
+
+       /* If error, set to the default value */
+       if (!i) {
+               gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+               gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+               gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+               gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+       }
+}
index c8818cd..054ebb5 100644 (file)
@@ -749,26 +749,6 @@ void detail_board_ddr_info(void)
        puts("\nDDR    ");
 }
 
-phys_size_t get_effective_memsize(void)
-{
-       return PHYS_SDRAM_1_SIZE;
-}
-
-int dram_init(void)
-{
-       gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
-
-       return 0;
-}
-
-void dram_init_banksize(void)
-{
-       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
-       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
-}
-
 /*
  * Board specific reset that is system reset.
  */
index 80c5371..ffaf202 100644 (file)
@@ -669,26 +669,6 @@ void detail_board_ddr_info(void)
        puts("\nDDR    ");
 }
 
-phys_size_t get_effective_memsize(void)
-{
-       return PHYS_SDRAM_1_SIZE;
-}
-
-int dram_init(void)
-{
-       gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
-
-       return 0;
-}
-
-void dram_init_banksize(void)
-{
-       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
-       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
-}
-
 /*
  * Board specific reset that is system reset.
  */
index 6081657..f55af4b 100644 (file)
@@ -592,26 +592,6 @@ void detail_board_ddr_info(void)
        puts("\nDDR    ");
 }
 
-phys_size_t get_effective_memsize(void)
-{
-       return PHYS_SDRAM_1_SIZE;
-}
-
-int dram_init(void)
-{
-       gd->ram_size = PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE;
-
-       return 0;
-}
-
-void dram_init_banksize(void)
-{
-       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-       gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
-       gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
-}
-
 /*
  * Board specific reset that is system reset.
  */
index f11e101..4f98189 100644 (file)
 
 #define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
 
-#define CONFIG_SYS_INIT_SP_ADDR         0x90000000
+#define CONFIG_SYS_INIT_SP_ADDR         0x80200000
 
 
 /* Default environment is in SD */
 #define CONFIG_SYS_MALLOC_LEN          ((CONFIG_ENV_SIZE + (32*1024)) * 1024)
 
 #define CONFIG_SYS_SDRAM_BASE          0x80000000
-#define CONFIG_NR_DRAM_BANKS           2
+#define CONFIG_NR_DRAM_BANKS           3
 #define PHYS_SDRAM_1                   0x80000000
 #define PHYS_SDRAM_2                   0x880000000
 #define PHYS_SDRAM_1_SIZE              0x80000000      /* 2 GB */
 #define CONFIG_IMX_VIDEO_SKIP
 #endif
 
+#define CONFIG_OF_SYSTEM_SETUP
+#define BOOTAUX_RESERVED_MEM_BASE 0x88000000
+#define BOOTAUX_RESERVED_MEM_SIZE 0x08000000 /* Reserve from second 128MB */
+
 #endif /* __IMX8QM_ARM2_H */
index b8013f8..229cdfc 100644 (file)
 
 #define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
 
-#define CONFIG_SYS_INIT_SP_ADDR         0x90000000
+#define CONFIG_SYS_INIT_SP_ADDR         0x80200000
 
 
 /* Default environment is in SD */
 #define CONFIG_SYS_MALLOC_LEN          ((CONFIG_ENV_SIZE + (32*1024)) * 1024)
 
 #define CONFIG_SYS_SDRAM_BASE          0x80000000
-#define CONFIG_NR_DRAM_BANKS           2
+#define CONFIG_NR_DRAM_BANKS           3
 #define PHYS_SDRAM_1                   0x80000000
 #define PHYS_SDRAM_2                   0x880000000
 #define PHYS_SDRAM_1_SIZE              0x80000000      /* 2 GB */
 #define CONFIG_IMX_VIDEO_SKIP
 #endif
 
+#define CONFIG_OF_SYSTEM_SETUP
+#define BOOTAUX_RESERVED_MEM_BASE 0x88000000
+#define BOOTAUX_RESERVED_MEM_SIZE 0x08000000 /* Reserve from second 128MB */
+
 #endif /* __IMX8QXP_ARM2_H */
index d031d96..02807bf 100644 (file)
 
 #define CONFIG_SYS_LOAD_ADDR           CONFIG_LOADADDR
 
-#define CONFIG_SYS_INIT_SP_ADDR         0x90000000
+#define CONFIG_SYS_INIT_SP_ADDR         0x80200000
 
 
 /* Default environment is in SD */
 #define CONFIG_SYS_MALLOC_LEN          ((CONFIG_ENV_SIZE + (32*1024)) * 1024)
 
 #define CONFIG_SYS_SDRAM_BASE          0x80000000
-#define CONFIG_NR_DRAM_BANKS           2
+#define CONFIG_NR_DRAM_BANKS           3
 #define PHYS_SDRAM_1                   0x80000000
 #define PHYS_SDRAM_2                   0x880000000
 #define PHYS_SDRAM_1_SIZE              0x80000000      /* 2 GB */
 #define CONFIG_USB_FUNCTION_MASS_STORAGE
 #endif
 
+#define CONFIG_OF_SYSTEM_SETUP
+#define BOOTAUX_RESERVED_MEM_BASE 0x88000000
+#define BOOTAUX_RESERVED_MEM_SIZE 0x08000000 /* Reserve from second 128MB */
+
 #endif /* __IMX8QXP_MEK_H */