aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm47xx/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/bcm47xx/prom.c')
-rw-r--r--arch/mips/bcm47xx/prom.c68
1 files changed, 67 insertions, 1 deletions
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
54static unsigned long lowmem __initdata;
55
54static __init void prom_init_mem(void) 56static __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)
114void __init prom_free_prom_memory(void) 116void __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 */
130void __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
138void __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) */