diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2014-07-17 17:26:33 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-07-30 17:27:02 -0400 |
commit | 6ee1d93455384cef8a0426effe85da241b525b63 (patch) | |
tree | b3e66dbb882a5dbcdbcbc45cda66639d3141a5ca /arch/mips/bcm47xx | |
parent | d377732c8c9aac14ccb900b65678558b0fb8f0f3 (diff) |
MIPS: BCM47XX: Detect more then 128 MiB of RAM (HIGHMEM)
So far BCM47XX can only detect amount of HIGHMEM. It still requires
adding (registering) and well-testing before enabling by default.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7396/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r-- | arch/mips/bcm47xx/bcm47xx_private.h | 3 | ||||
-rw-r--r-- | arch/mips/bcm47xx/prom.c | 68 | ||||
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 3 |
3 files changed, 73 insertions, 1 deletions
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index 0194c3b9a729..f1cc9d0495d8 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | 5 | ||
6 | /* prom.c */ | ||
7 | void __init bcm47xx_prom_highmem_init(void); | ||
8 | |||
6 | /* buttons.c */ | 9 | /* buttons.c */ |
7 | int __init bcm47xx_buttons_register(void); | 10 | int __init bcm47xx_buttons_register(void); |
8 | 11 | ||
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 1a03a2f43496..1b170bf5f7f0 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c | |||
@@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id) | |||
51 | chip_id); | 51 | chip_id); |
52 | } | 52 | } |
53 | 53 | ||
54 | static unsigned long lowmem __initdata; | ||
55 | |||
54 | static __init void prom_init_mem(void) | 56 | static __init void prom_init_mem(void) |
55 | { | 57 | { |
56 | unsigned long mem; | 58 | unsigned long mem; |
@@ -87,6 +89,7 @@ static __init void prom_init_mem(void) | |||
87 | if (!memcmp(prom_init, prom_init + mem, 32)) | 89 | if (!memcmp(prom_init, prom_init + mem, 32)) |
88 | break; | 90 | break; |
89 | } | 91 | } |
92 | lowmem = mem; | ||
90 | 93 | ||
91 | /* Ignoring the last page when ddr size is 128M. Cached | 94 | /* Ignoring the last page when ddr size is 128M. Cached |
92 | * accesses to last page is causing the processor to prefetch | 95 | * accesses to last page is causing the processor to prefetch |
@@ -95,7 +98,6 @@ static __init void prom_init_mem(void) | |||
95 | */ | 98 | */ |
96 | if (c->cputype == CPU_74K && (mem == (128 << 20))) | 99 | if (c->cputype == CPU_74K && (mem == (128 << 20))) |
97 | mem -= 0x1000; | 100 | mem -= 0x1000; |
98 | |||
99 | add_memory_region(0, mem, BOOT_MEM_RAM); | 101 | add_memory_region(0, mem, BOOT_MEM_RAM); |
100 | } | 102 | } |
101 | 103 | ||
@@ -114,3 +116,67 @@ void __init prom_init(void) | |||
114 | void __init prom_free_prom_memory(void) | 116 | void __init prom_free_prom_memory(void) |
115 | { | 117 | { |
116 | } | 118 | } |
119 | |||
120 | #if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) | ||
121 | |||
122 | #define EXTVBASE 0xc0000000 | ||
123 | #define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1) | ||
124 | |||
125 | #include <asm/tlbflush.h> | ||
126 | |||
127 | /* Stripped version of tlb_init, with the call to build_tlb_refill_handler | ||
128 | * dropped. Calling it at this stage causes a hang. | ||
129 | */ | ||
130 | void __cpuinit early_tlb_init(void) | ||
131 | { | ||
132 | write_c0_pagemask(PM_DEFAULT_MASK); | ||
133 | write_c0_wired(0); | ||
134 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | ||
135 | local_flush_tlb_all(); | ||
136 | } | ||
137 | |||
138 | void __init bcm47xx_prom_highmem_init(void) | ||
139 | { | ||
140 | unsigned long off = (unsigned long)prom_init; | ||
141 | unsigned long extmem = 0; | ||
142 | bool highmem_region = false; | ||
143 | |||
144 | if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA)) | ||
145 | return; | ||
146 | |||
147 | if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) | ||
148 | highmem_region = true; | ||
149 | |||
150 | if (lowmem != 128 << 20 || !highmem_region) | ||
151 | return; | ||
152 | |||
153 | early_tlb_init(); | ||
154 | |||
155 | /* Add one temporary TLB entry to map SDRAM Region 2. | ||
156 | * Physical Virtual | ||
157 | * 0x80000000 0xc0000000 (1st: 256MB) | ||
158 | * 0x90000000 0xd0000000 (2nd: 256MB) | ||
159 | */ | ||
160 | add_temporary_entry(ENTRYLO(0x80000000), | ||
161 | ENTRYLO(0x80000000 + (256 << 20)), | ||
162 | EXTVBASE, PM_256M); | ||
163 | |||
164 | off = EXTVBASE + __pa(off); | ||
165 | for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { | ||
166 | if (!memcmp(prom_init, (void *)(off + extmem), 16)) | ||
167 | break; | ||
168 | } | ||
169 | extmem -= lowmem; | ||
170 | |||
171 | early_tlb_init(); | ||
172 | |||
173 | if (!extmem) | ||
174 | return; | ||
175 | |||
176 | pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n", | ||
177 | extmem >> 20); | ||
178 | |||
179 | /* TODO: Register extra memory */ | ||
180 | } | ||
181 | |||
182 | #endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */ | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index cc75861c0187..2b63e7e7d3d3 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -218,6 +218,9 @@ void __init plat_mem_setup(void) | |||
218 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | 218 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
219 | bcm47xx_register_bcma(); | 219 | bcm47xx_register_bcma(); |
220 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | 220 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
221 | #ifdef CONFIG_HIGHMEM | ||
222 | bcm47xx_prom_highmem_init(); | ||
223 | #endif | ||
221 | #endif | 224 | #endif |
222 | } else { | 225 | } else { |
223 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); | 226 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); |