Skip to content

Commit

Permalink
MIPS: BCM47XX: Detect more then 128 MiB of RAM (HIGHMEM)
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Hauke Mehrtens <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/7396/
Signed-off-by: Ralf Baechle <[email protected]>
  • Loading branch information
rmilecki authored and ralfbaechle committed Jul 30, 2014
1 parent d377732 commit 6ee1d93
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
3 changes: 3 additions & 0 deletions arch/mips/bcm47xx/bcm47xx_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include <linux/kernel.h>

/* prom.c */
void __init bcm47xx_prom_highmem_init(void);

/* buttons.c */
int __init bcm47xx_buttons_register(void);

Expand Down
68 changes: 67 additions & 1 deletion arch/mips/bcm47xx/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id)
chip_id);
}

static unsigned long lowmem __initdata;

static __init void prom_init_mem(void)
{
unsigned long mem;
Expand Down Expand Up @@ -87,6 +89,7 @@ static __init void prom_init_mem(void)
if (!memcmp(prom_init, prom_init + mem, 32))
break;
}
lowmem = mem;

/* Ignoring the last page when ddr size is 128M. Cached
* accesses to last page is causing the processor to prefetch
Expand All @@ -95,7 +98,6 @@ static __init void prom_init_mem(void)
*/
if (c->cputype == CPU_74K && (mem == (128 << 20)))
mem -= 0x1000;

add_memory_region(0, mem, BOOT_MEM_RAM);
}

Expand All @@ -114,3 +116,67 @@ void __init prom_init(void)
void __init prom_free_prom_memory(void)
{
}

#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)

#define EXTVBASE 0xc0000000
#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)

#include <asm/tlbflush.h>

/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
* dropped. Calling it at this stage causes a hang.
*/
void __cpuinit early_tlb_init(void)
{
write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_wired(0);
temp_tlb_entry = current_cpu_data.tlbsize - 1;
local_flush_tlb_all();
}

void __init bcm47xx_prom_highmem_init(void)
{
unsigned long off = (unsigned long)prom_init;
unsigned long extmem = 0;
bool highmem_region = false;

if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
return;

if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
highmem_region = true;

if (lowmem != 128 << 20 || !highmem_region)
return;

early_tlb_init();

/* Add one temporary TLB entry to map SDRAM Region 2.
* Physical Virtual
* 0x80000000 0xc0000000 (1st: 256MB)
* 0x90000000 0xd0000000 (2nd: 256MB)
*/
add_temporary_entry(ENTRYLO(0x80000000),
ENTRYLO(0x80000000 + (256 << 20)),
EXTVBASE, PM_256M);

off = EXTVBASE + __pa(off);
for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
if (!memcmp(prom_init, (void *)(off + extmem), 16))
break;
}
extmem -= lowmem;

early_tlb_init();

if (!extmem)
return;

pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n",
extmem >> 20);

/* TODO: Register extra memory */
}

#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */
3 changes: 3 additions & 0 deletions arch/mips/bcm47xx/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ void __init plat_mem_setup(void)
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
bcm47xx_register_bcma();
bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
#ifdef CONFIG_HIGHMEM
bcm47xx_prom_highmem_init();
#endif
#endif
} else {
printk(KERN_INFO "bcm47xx: using ssb bus\n");
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/include/asm/pgtable-32.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <asm-generic/pgtable-nopmd.h>

extern int temp_tlb_entry __cpuinitdata;

/*
* - add_temporary_entry() add a temporary TLB entry. We use TLB entries
* starting at the top and working down. This is for populating the
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/mm/tlb-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ int __init has_transparent_hugepage(void)
* lifetime of the system
*/

static int temp_tlb_entry __cpuinitdata;
int temp_tlb_entry __cpuinitdata;

__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
unsigned long entryhi, unsigned long pagemask)
Expand Down

0 comments on commit 6ee1d93

Please sign in to comment.