Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ee1d934 authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Ralf Baechle
Browse files

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: default avatarRafał Miłecki <zajec5@gmail.com>
Acked-by: default avatarHauke Mehrtens <hauke@hauke-m.de>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7396/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent d377732c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

+67 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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);
}

@@ -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 −0
Original line number Diff line number Diff line
@@ -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");
+2 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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)