diff options
author | Thomas Bogendoerfer <tbogendoerfer@suse.de> | 2019-10-09 15:27:17 +0200 |
---|---|---|
committer | Paul Burton <paul.burton@mips.com> | 2019-10-09 14:55:57 -0700 |
commit | c0de00b286ed1c14064ff94ca70abdfd4e4d11e8 (patch) | |
tree | afe10195df3371bcaf5ce2c67732aa5007c77d9a /arch/mips/sgi-ip22 | |
parent | 931e1bfea4031811b75f7af688a3e17fc2b121fb (diff) | |
download | linux-c0de00b286ed1c14064ff94ca70abdfd4e4d11e8.tar.bz2 |
MIPS: SGI-IP22/28: Use PROM for memory detection
EARLY_PRINTK uses ArcWrite (via prom_putchar) on IP22/28, which needs
to not mess up PROMs data structures. ARC PROM gives out a list of
memory chunks, which are used and which are free. This fixes the
problem of not working early printk.
By using XKPHYS spaces more than 256MB memory on Indigo2 R4k machines
is working now, too.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Diffstat (limited to 'arch/mips/sgi-ip22')
-rw-r--r-- | arch/mips/sgi-ip22/ip22-mc.c | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 1944d41507ef..74e5b9e27d6c 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/export.h> #include <linux/kernel.h> +#include <linux/memblock.h> #include <linux/spinlock.h> #include <asm/io.h> @@ -40,70 +41,36 @@ static inline unsigned int get_bank_config(int bank) return bank % 2 ? res & 0xffff : res >> 16; } -struct mem { - unsigned long addr; - unsigned long size; -}; - +#if defined(CONFIG_SGI_IP28) || defined(CONFIG_32BIT) +static void __init probe_memory(void) +{ + /* prom detects all usable memory */ +} +#else /* - * Detect installed memory, do some sanity checks and notify kernel about it + * Detect installed memory, which PROM misses */ static void __init probe_memory(void) { - int i, j, found, cnt = 0; - struct mem bank[4]; - struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}}; + unsigned long addr, size; + int i; printk(KERN_INFO "MC: Probing memory configuration:\n"); - for (i = 0; i < ARRAY_SIZE(bank); i++) { + for (i = 0; i < 4; i++) { unsigned int tmp = get_bank_config(i); if (!(tmp & SGIMC_MCONFIG_BVALID)) continue; - bank[cnt].size = get_bank_size(tmp); - bank[cnt].addr = get_bank_addr(tmp); + size = get_bank_size(tmp); + addr = get_bank_addr(tmp); printk(KERN_INFO " bank%d: %3ldM @ %08lx\n", - i, bank[cnt].size / 1024 / 1024, bank[cnt].addr); - cnt++; - } + i, size / 1024 / 1024, addr); - /* And you thought bubble sort is dead algorithm... */ - do { - unsigned long addr, size; - - found = 0; - for (i = 1; i < cnt; i++) - if (bank[i-1].addr > bank[i].addr) { - addr = bank[i].addr; - size = bank[i].size; - bank[i].addr = bank[i-1].addr; - bank[i].size = bank[i-1].size; - bank[i-1].addr = addr; - bank[i-1].size = size; - found = 1; - } - } while (found); - - /* Figure out how are memory banks mapped into spaces */ - for (i = 0; i < cnt; i++) { - found = 0; - for (j = 0; j < ARRAY_SIZE(space) && !found; j++) - if (space[j].addr + space[j].size == bank[i].addr) { - space[j].size += bank[i].size; - found = 1; - } - /* There is either hole or overlapping memory */ - if (!found) - printk(KERN_CRIT "MC: Memory configuration mismatch " - "(%08lx), expect Bus Error soon\n", - bank[i].addr); + if (addr >= SGIMC_SEG1_BADDR) + memblock_add(addr, size); } - - for (i = 0; i < ARRAY_SIZE(space); i++) - if (space[i].size) - add_memory_region(space[i].addr, space[i].size, - BOOT_MEM_RAM); } +#endif void __init sgimc_init(void) { @@ -205,10 +172,9 @@ void __init sgimc_init(void) probe_memory(); } -void __init prom_meminit(void) {} -void __init prom_free_prom_memory(void) -{ #ifdef CONFIG_SGI_IP28 +void __init prom_cleanup(void) +{ u32 mconfig1; unsigned long flags; spinlock_t lock; @@ -233,5 +199,5 @@ void __init prom_free_prom_memory(void) sgimc->mconfig1 = mconfig1; iob(); spin_unlock_irqrestore(&lock, flags); -#endif } +#endif |