MIPS: ralink: mt7621: add memory detection support
authorChuanhong Guo <gch981213@gmail.com>
Sat, 27 Mar 2021 05:38:40 +0000 (22:38 -0700)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Mon, 29 Mar 2021 09:18:54 +0000 (11:18 +0200)
mt7621 has the following memory map:
0x0-0x1c000000: lower 448m memory
0x1c000000-0x2000000: peripheral registers
0x20000000-0x2400000: higher 64m memory

detect_memory_region in arch/mips/kernel/setup.c only adds the first
memory region and isn't suitable for 512m memory detection because
it may accidentally read the memory area for peripheral registers.

This commit adds memory detection capability for mt7621:
  1. Add the highmem area when 512m is detected.
  2. Guard memcmp from accessing peripheral registers:
     This only happens when a user decided to change kernel load address
     to 256m or higher address. Since this is a quite unusual case, we
     just skip 512m testing and return 256m as memory size.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
[Minor commit message reword, make mt7621_memory_detect static]
Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/include/asm/mach-ralink/mt7621.h
arch/mips/ralink/common.h
arch/mips/ralink/mt7621.c
arch/mips/ralink/of.c

index e1af1ba50bd8ce9b086dc13856f508ba80d22d04..6bbf082dd149ef90571ae8137d66eb9d4f14af05 100644 (file)
 #define CHIP_REV_VER_SHIFT             8
 #define CHIP_REV_ECO_MASK              0xf
 
-#define MT7621_DRAM_BASE                0x0
-#define MT7621_DDR2_SIZE_MIN           32
-#define MT7621_DDR2_SIZE_MAX           256
+#define MT7621_LOWMEM_BASE             0x0
+#define MT7621_LOWMEM_MAX_SIZE         0x1C000000
+#define MT7621_HIGHMEM_BASE            0x20000000
+#define MT7621_HIGHMEM_SIZE            0x4000000
 
 #define MT7621_CHIP_NAME0              0x3637544D
 #define MT7621_CHIP_NAME1              0x20203132
index 49ae370d023d70d1cf11e265810c2e9e6337a9d3..87fc16751281ed0363d050d145e5441d83626aad 100644 (file)
@@ -17,6 +17,7 @@ struct ralink_soc_info {
        unsigned long mem_size;
        unsigned long mem_size_min;
        unsigned long mem_size_max;
+       void (*mem_detect)(void);
 };
 extern struct ralink_soc_info soc_info;
 
index ec87ce5610493c46d0fed425f1f0b55fd4426f76..6b3db98894cbc1cbc6e06175cac1d6483bdafbb0 100644 (file)
@@ -9,7 +9,9 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
+#include <linux/memblock.h>
 
+#include <asm/bootinfo.h>
 #include <asm/mipsregs.h>
 #include <asm/smp-ops.h>
 #include <asm/mips-cps.h>
@@ -49,6 +51,8 @@
 #define MT7621_GPIO_MODE_SDHCI_SHIFT   18
 #define MT7621_GPIO_MODE_SDHCI_GPIO    1
 
+static void *detect_magic __initdata = detect_memory_region;
+
 static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
 static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
 static struct rt2880_pmx_func uart3_grp[] = {
@@ -110,6 +114,26 @@ phys_addr_t mips_cpc_default_phys_base(void)
        panic("Cannot detect cpc address");
 }
 
+static void __init mt7621_memory_detect(void)
+{
+       void *dm = &detect_magic;
+       phys_addr_t size;
+
+       for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
+               if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
+                       break;
+       }
+
+       if ((size == 256 * SZ_1M) &&
+           (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
+           __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
+               memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
+               memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
+       } else {
+               memblock_add(MT7621_LOWMEM_BASE, size);
+       }
+}
+
 void __init ralink_of_remap(void)
 {
        rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
@@ -194,10 +218,7 @@ void __init prom_soc_init(struct ralink_soc_info *soc_info)
                (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
                (rev & CHIP_REV_ECO_MASK));
 
-       soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
-       soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
-       soc_info->mem_base = MT7621_DRAM_BASE;
-
+       soc_info->mem_detect = mt7621_memory_detect;
        rt2880_pinmux_data = mt7621_pinmux_data;
 
        soc_dev_init(soc_info, rev);
index 8286c3521476f2840ab425ab0b1796bc7bbb8698..0c5de07da097ad5e9733aaffa100debb6699d0d3 100644 (file)
@@ -78,6 +78,8 @@ void __init plat_mem_setup(void)
        of_scan_flat_dt(early_init_dt_find_memory, NULL);
        if (memory_dtb)
                of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+       else if (soc_info.mem_detect)
+               soc_info.mem_detect();
        else if (soc_info.mem_size)
                memblock_add(soc_info.mem_base, soc_info.mem_size * SZ_1M);
        else