Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Malta: Setup RAM regions via DT

Move memory configuration to be performed via device tree for the Malta
board. This moves more Malta specific code to malta-dtshim.c, leaving
the rest of the mti-malta code a little more board-agnostic. This will
be useful to share more code between boards, with the device tree
providing the board specifics as intended.

Since we can't rely upon Malta boards running a bootloader capable of
handling devictrees & filling in the required information, a piece of
shim code (malta_dt_shim) is added to consume the (e)memsize variables
provided as part of the bootloader environment (or on the kernel command
line) then generate the DT memory node using the provided values.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Cc: Kumar Gala <galak@codeaurora.org>
Cc: linux-kernel@vger.kernel.org
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Patchwork: https://patchwork.linux-mips.org/patch/11222/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Paul Burton and committed by
Ralf Baechle
e81a8c7d ea050714

+204 -93
+2
arch/mips/Kconfig
··· 450 450 select SYS_SUPPORTS_ZBOOT 451 451 select USE_OF 452 452 select ZONE_DMA32 if 64BIT 453 + select BUILTIN_DTB 454 + select LIBFDT 453 455 help 454 456 This enables support for the MIPS Technologies Malta evaluation 455 457 board.
+4
arch/mips/boot/dts/mti/malta.dts
··· 1 1 /dts-v1/; 2 2 3 + /memreserve/ 0x00000000 0x00001000; /* YAMON exception vectors */ 4 + /memreserve/ 0x00001000 0x000ef000; /* YAMON */ 5 + /memreserve/ 0x000f0000 0x00010000; /* PIIX4 ISA memory */ 6 + 3 7 / { 4 8 #address-cells = <1>; 5 9 #size-cells = <1>;
+29
arch/mips/include/asm/mach-malta/malta-dtshim.h
··· 1 + /* 2 + * Copyright (C) 2015 Imagination Technologies 3 + * Author: Paul Burton <paul.burton@imgtec.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + */ 10 + 11 + #ifndef __MIPS_MALTA_DTSHIM_H__ 12 + #define __MIPS_MALTA_DTSHIM_H__ 13 + 14 + #include <linux/init.h> 15 + 16 + #ifdef CONFIG_MIPS_MALTA 17 + 18 + extern void __init *malta_dt_shim(void *fdt); 19 + 20 + #else /* !CONFIG_MIPS_MALTA */ 21 + 22 + static inline void *malta_dt_shim(void *fdt) 23 + { 24 + return fdt; 25 + } 26 + 27 + #endif /* !CONFIG_MIPS_MALTA */ 28 + 29 + #endif /* __MIPS_MALTA_DTSHIM_H__ */
+3
arch/mips/mti-malta/Makefile
··· 7 7 # 8 8 obj-y += malta-display.o 9 9 obj-y += malta-dt.o 10 + obj-y += malta-dtshim.o 10 11 obj-y += malta-init.o 11 12 obj-y += malta-int.o 12 13 obj-y += malta-memory.o ··· 18 17 19 18 obj-$(CONFIG_MIPS_CMP) += malta-amon.o 20 19 obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o 20 + 21 + CFLAGS_malta-dtshim.o = -I$(src)/../../../scripts/dtc/libfdt
+162
arch/mips/mti-malta/malta-dtshim.c
··· 1 + /* 2 + * Copyright (C) 2015 Imagination Technologies 3 + * Author: Paul Burton <paul.burton@imgtec.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the 7 + * Free Software Foundation; either version 2 of the License, or (at your 8 + * option) any later version. 9 + */ 10 + 11 + #include <linux/bug.h> 12 + #include <linux/kernel.h> 13 + #include <linux/libfdt.h> 14 + #include <linux/of_fdt.h> 15 + #include <linux/sizes.h> 16 + #include <asm/bootinfo.h> 17 + #include <asm/fw/fw.h> 18 + #include <asm/page.h> 19 + 20 + static unsigned char fdt_buf[16 << 10] __initdata; 21 + 22 + /* determined physical memory size, not overridden by command line args */ 23 + extern unsigned long physical_memsize; 24 + 25 + #define MAX_MEM_ARRAY_ENTRIES 1 26 + 27 + static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) 28 + { 29 + unsigned long size_preio; 30 + unsigned entries; 31 + 32 + entries = 1; 33 + mem_array[0] = cpu_to_be32(PHYS_OFFSET); 34 + if (config_enabled(CONFIG_EVA)) { 35 + /* 36 + * The current Malta EVA configuration is "special" in that it 37 + * always makes use of addresses in the upper half of the 32 bit 38 + * physical address map, which gives it a contiguous region of 39 + * DDR but limits it to 2GB. 40 + */ 41 + mem_array[1] = cpu_to_be32(size); 42 + } else { 43 + size_preio = min_t(unsigned long, size, SZ_256M); 44 + mem_array[1] = cpu_to_be32(size_preio); 45 + } 46 + 47 + BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES); 48 + return entries; 49 + } 50 + 51 + static void __init append_memory(void *fdt, int root_off) 52 + { 53 + __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; 54 + unsigned long memsize; 55 + unsigned mem_entries; 56 + int i, err, mem_off; 57 + char *var, param_name[10], *var_names[] = { 58 + "ememsize", "memsize", 59 + }; 60 + 61 + /* if a memory node already exists, leave it alone */ 62 + mem_off = fdt_path_offset(fdt, "/memory"); 63 + if (mem_off >= 0) 64 + return; 65 + 66 + /* find memory size from the bootloader environment */ 67 + for (i = 0; i < ARRAY_SIZE(var_names); i++) { 68 + var = fw_getenv(var_names[i]); 69 + if (!var) 70 + continue; 71 + 72 + err = kstrtoul(var, 0, &physical_memsize); 73 + if (!err) 74 + break; 75 + 76 + pr_warn("Failed to read the '%s' env variable '%s'\n", 77 + var_names[i], var); 78 + } 79 + 80 + if (!physical_memsize) { 81 + pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); 82 + physical_memsize = 32 << 20; 83 + } 84 + 85 + if (config_enabled(CONFIG_CPU_BIG_ENDIAN)) { 86 + /* 87 + * SOC-it swaps, or perhaps doesn't swap, when DMA'ing 88 + * the last word of physical memory. 89 + */ 90 + physical_memsize -= PAGE_SIZE; 91 + } 92 + 93 + /* default to using all available RAM */ 94 + memsize = physical_memsize; 95 + 96 + /* allow the user to override the usable memory */ 97 + for (i = 0; i < ARRAY_SIZE(var_names); i++) { 98 + snprintf(param_name, sizeof(param_name), "%s=", var_names[i]); 99 + var = strstr(arcs_cmdline, param_name); 100 + if (!var) 101 + continue; 102 + 103 + memsize = memparse(var + strlen(param_name), NULL); 104 + } 105 + 106 + /* if the user says there's more RAM than we thought, believe them */ 107 + physical_memsize = max_t(unsigned long, physical_memsize, memsize); 108 + 109 + /* append memory to the DT */ 110 + mem_off = fdt_add_subnode(fdt, root_off, "memory"); 111 + if (mem_off < 0) 112 + panic("Unable to add memory node to DT: %d", mem_off); 113 + 114 + err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); 115 + if (err) 116 + panic("Unable to set memory node device_type: %d", err); 117 + 118 + mem_entries = gen_fdt_mem_array(mem_array, physical_memsize); 119 + err = fdt_setprop(fdt, mem_off, "reg", mem_array, 120 + mem_entries * 2 * sizeof(mem_array[0])); 121 + if (err) 122 + panic("Unable to set memory regs property: %d", err); 123 + 124 + mem_entries = gen_fdt_mem_array(mem_array, memsize); 125 + err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array, 126 + mem_entries * 2 * sizeof(mem_array[0])); 127 + if (err) 128 + panic("Unable to set linux,usable-memory property: %d", err); 129 + } 130 + 131 + void __init *malta_dt_shim(void *fdt) 132 + { 133 + int root_off, len, err; 134 + const char *compat; 135 + 136 + if (fdt_check_header(fdt)) 137 + panic("Corrupt DT"); 138 + 139 + err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); 140 + if (err) 141 + panic("Unable to open FDT: %d", err); 142 + 143 + root_off = fdt_path_offset(fdt_buf, "/"); 144 + if (root_off < 0) 145 + panic("No / node in DT"); 146 + 147 + compat = fdt_getprop(fdt_buf, root_off, "compatible", &len); 148 + if (!compat) 149 + panic("No root compatible property in DT: %d", len); 150 + 151 + /* if this isn't Malta, leave the DT alone */ 152 + if (strncmp(compat, "mti,malta", len)) 153 + return fdt; 154 + 155 + append_memory(fdt_buf, root_off); 156 + 157 + err = fdt_pack(fdt_buf); 158 + if (err) 159 + panic("Unable to pack FDT: %d\n", err); 160 + 161 + return fdt_buf; 162 + }
-92
arch/mips/mti-malta/malta-memory.c
··· 32 32 33 33 void __init fw_meminit(void) 34 34 { 35 - char *memsize_str, *ememsize_str = NULL, *ptr; 36 - unsigned long memsize = 0, ememsize = 0; 37 - unsigned long kernel_start_phys, kernel_end_phys; 38 - static char cmdline[COMMAND_LINE_SIZE] __initdata; 39 35 bool eva = config_enabled(CONFIG_EVA); 40 - int tmp; 41 36 42 37 free_init_pages_eva = eva ? free_init_pages_eva_malta : NULL; 43 - 44 - memsize_str = fw_getenv("memsize"); 45 - if (memsize_str) { 46 - tmp = kstrtoul(memsize_str, 0, &memsize); 47 - if (tmp) 48 - pr_warn("Failed to read the 'memsize' env variable.\n"); 49 - } 50 - if (eva) { 51 - /* Look for ememsize for EVA */ 52 - ememsize_str = fw_getenv("ememsize"); 53 - if (ememsize_str) { 54 - tmp = kstrtoul(ememsize_str, 0, &ememsize); 55 - if (tmp) 56 - pr_warn("Failed to read the 'ememsize' env variable.\n"); 57 - } 58 - } 59 - if (!memsize && !ememsize) { 60 - pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); 61 - physical_memsize = 0x02000000; 62 - } else { 63 - if (memsize > (256 << 20)) { /* memsize should be capped to 256M */ 64 - pr_warn("Unsupported memsize value (0x%lx) detected! " 65 - "Using 0x10000000 (256M) instead\n", 66 - memsize); 67 - memsize = 256 << 20; 68 - } 69 - /* If ememsize is set, then set physical_memsize to that */ 70 - physical_memsize = ememsize ? : memsize; 71 - } 72 - 73 - #ifdef CONFIG_CPU_BIG_ENDIAN 74 - /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last 75 - word of physical memory */ 76 - physical_memsize -= PAGE_SIZE; 77 - #endif 78 - 79 - /* Check the command line for a memsize directive that overrides 80 - the physical/default amount */ 81 - strcpy(cmdline, arcs_cmdline); 82 - ptr = strstr(cmdline, "memsize="); 83 - if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) 84 - ptr = strstr(ptr, " memsize="); 85 - /* And now look for ememsize */ 86 - if (eva) { 87 - ptr = strstr(cmdline, "ememsize="); 88 - if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' ')) 89 - ptr = strstr(ptr, " ememsize="); 90 - } 91 - 92 - if (ptr) 93 - memsize = memparse(ptr + 8 + (eva ? 1 : 0), &ptr); 94 - else 95 - memsize = physical_memsize; 96 - 97 - /* Last 64K for HIGHMEM arithmetics */ 98 - if (memsize > 0x7fff0000) 99 - memsize = 0x7fff0000; 100 - 101 - add_memory_region(PHYS_OFFSET, 0x00001000, BOOT_MEM_RESERVED); 102 - 103 - /* 104 - * YAMON may still be using the region of memory from 0x1000 to 0xfffff 105 - * if it has started secondary CPUs. 106 - */ 107 - add_memory_region(PHYS_OFFSET + 0x00001000, 0x000ef000, 108 - BOOT_MEM_ROM_DATA); 109 - 110 - /* 111 - * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the 112 - * south bridge and PCI access always forwarded to the ISA Bus and 113 - * BIOSCS# is always generated. 114 - * This mean that this area can't be used as DMA memory for PCI 115 - * devices. 116 - */ 117 - add_memory_region(PHYS_OFFSET + 0x000f0000, 0x00010000, 118 - BOOT_MEM_RESERVED); 119 - 120 - /* 121 - * Reserve the memory used by kernel code, and allow the rest of RAM to 122 - * be used. 123 - */ 124 - kernel_start_phys = PHYS_OFFSET + 0x00100000; 125 - kernel_end_phys = PHYS_OFFSET + CPHYSADDR(PFN_ALIGN(&_end)); 126 - add_memory_region(kernel_start_phys, kernel_end_phys, 127 - BOOT_MEM_RESERVED); 128 - add_memory_region(kernel_end_phys, memsize - kernel_end_phys, 129 - BOOT_MEM_RAM); 130 38 } 131 39 132 40 void __init prom_free_prom_memory(void)
+4 -1
arch/mips/mti-malta/malta-setup.c
··· 27 27 #include <linux/time.h> 28 28 29 29 #include <asm/fw/fw.h> 30 + #include <asm/mach-malta/malta-dtshim.h> 30 31 #include <asm/mips-cm.h> 31 32 #include <asm/mips-boards/generic.h> 32 33 #include <asm/mips-boards/malta.h> ··· 251 250 void __init plat_mem_setup(void) 252 251 { 253 252 unsigned int i; 253 + void *fdt = __dtb_start; 254 254 255 - __dt_setup_arch(__dtb_start); 255 + fdt = malta_dt_shim(fdt); 256 + __dt_setup_arch(fdt); 256 257 257 258 if (config_enabled(CONFIG_EVA)) 258 259 /* EVA has already been configured in mach-malta/kernel-init.h */