brcm47xx: 3.14: backport MIPS patches for early HIGHMEM support
[openwrt/svn-archive/archive.git] / target / linux / brcm47xx / patches-3.14 / 153-MIPS-BCM47XX-Detect-more-then-128-MiB-of-RAM-HIGHMEM.patch
1 From 6ee1d93455384cef8a0426effe85da241b525b63 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
3 Date: Thu, 17 Jul 2014 23:26:33 +0200
4 Subject: [PATCH 153/153] MIPS: BCM47XX: Detect more then 128 MiB of RAM
5 (HIGHMEM)
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 So far BCM47XX can only detect amount of HIGHMEM. It still requires
11 adding (registering) and well-testing before enabling by default.
12
13 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
14 Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
15 Cc: linux-mips@linux-mips.org
16 Patchwork: https://patchwork.linux-mips.org/patch/7396/
17 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
18 ---
19 arch/mips/bcm47xx/bcm47xx_private.h | 3 ++
20 arch/mips/bcm47xx/prom.c | 68 ++++++++++++++++++++++++++++++++++++-
21 arch/mips/bcm47xx/setup.c | 3 ++
22 arch/mips/include/asm/pgtable-32.h | 2 ++
23 arch/mips/mm/tlb-r4k.c | 2 +-
24 5 files changed, 76 insertions(+), 2 deletions(-)
25
26 --- a/arch/mips/bcm47xx/bcm47xx_private.h
27 +++ b/arch/mips/bcm47xx/bcm47xx_private.h
28 @@ -3,6 +3,9 @@
29
30 #include <linux/kernel.h>
31
32 +/* prom.c */
33 +void __init bcm47xx_prom_highmem_init(void);
34 +
35 /* buttons.c */
36 int __init bcm47xx_buttons_register(void);
37
38 --- a/arch/mips/bcm47xx/prom.c
39 +++ b/arch/mips/bcm47xx/prom.c
40 @@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16
41 chip_id);
42 }
43
44 +static unsigned long lowmem __initdata;
45 +
46 static __init void prom_init_mem(void)
47 {
48 unsigned long mem;
49 @@ -84,6 +86,7 @@ static __init void prom_init_mem(void)
50 if (!memcmp(prom_init, prom_init + mem, 32))
51 break;
52 }
53 + lowmem = mem;
54
55 /* Ignoring the last page when ddr size is 128M. Cached
56 * accesses to last page is causing the processor to prefetch
57 @@ -92,7 +95,6 @@ static __init void prom_init_mem(void)
58 */
59 if (c->cputype == CPU_74K && (mem == (128 << 20)))
60 mem -= 0x1000;
61 -
62 add_memory_region(0, mem, BOOT_MEM_RAM);
63 }
64
65 @@ -111,3 +113,67 @@ void __init prom_init(void)
66 void __init prom_free_prom_memory(void)
67 {
68 }
69 +
70 +#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)
71 +
72 +#define EXTVBASE 0xc0000000
73 +#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)
74 +
75 +#include <asm/tlbflush.h>
76 +
77 +/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
78 + * dropped. Calling it at this stage causes a hang.
79 + */
80 +void __cpuinit early_tlb_init(void)
81 +{
82 + write_c0_pagemask(PM_DEFAULT_MASK);
83 + write_c0_wired(0);
84 + temp_tlb_entry = current_cpu_data.tlbsize - 1;
85 + local_flush_tlb_all();
86 +}
87 +
88 +void __init bcm47xx_prom_highmem_init(void)
89 +{
90 + unsigned long off = (unsigned long)prom_init;
91 + unsigned long extmem = 0;
92 + bool highmem_region = false;
93 +
94 + if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
95 + return;
96 +
97 + if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
98 + highmem_region = true;
99 +
100 + if (lowmem != 128 << 20 || !highmem_region)
101 + return;
102 +
103 + early_tlb_init();
104 +
105 + /* Add one temporary TLB entry to map SDRAM Region 2.
106 + * Physical Virtual
107 + * 0x80000000 0xc0000000 (1st: 256MB)
108 + * 0x90000000 0xd0000000 (2nd: 256MB)
109 + */
110 + add_temporary_entry(ENTRYLO(0x80000000),
111 + ENTRYLO(0x80000000 + (256 << 20)),
112 + EXTVBASE, PM_256M);
113 +
114 + off = EXTVBASE + __pa(off);
115 + for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
116 + if (!memcmp(prom_init, (void *)(off + extmem), 16))
117 + break;
118 + }
119 + extmem -= lowmem;
120 +
121 + early_tlb_init();
122 +
123 + if (!extmem)
124 + return;
125 +
126 + pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n",
127 + extmem >> 20);
128 +
129 + /* TODO: Register extra memory */
130 +}
131 +
132 +#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */
133 --- a/arch/mips/bcm47xx/setup.c
134 +++ b/arch/mips/bcm47xx/setup.c
135 @@ -218,6 +218,9 @@ void __init plat_mem_setup(void)
136 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
137 bcm47xx_register_bcma();
138 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
139 +#ifdef CONFIG_HIGHMEM
140 + bcm47xx_prom_highmem_init();
141 +#endif
142 #endif
143 } else {
144 printk(KERN_INFO "bcm47xx: using ssb bus\n");
145 --- a/arch/mips/include/asm/pgtable-32.h
146 +++ b/arch/mips/include/asm/pgtable-32.h
147 @@ -18,6 +18,8 @@
148
149 #include <asm-generic/pgtable-nopmd.h>
150
151 +extern int temp_tlb_entry __cpuinitdata;
152 +
153 /*
154 * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
155 * starting at the top and working down. This is for populating the
156 --- a/arch/mips/mm/tlb-r4k.c
157 +++ b/arch/mips/mm/tlb-r4k.c
158 @@ -417,7 +417,7 @@ int __init has_transparent_hugepage(void
159 * lifetime of the system
160 */
161
162 -static int temp_tlb_entry __cpuinitdata;
163 +int temp_tlb_entry __cpuinitdata;
164
165 __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
166 unsigned long entryhi, unsigned long pagemask)