diff options
-rw-r--r-- | arch/powerpc/mm/fsl_booke_mmu.c | 31 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 2 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 21 |
3 files changed, 39 insertions, 15 deletions
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f7802c8bba0a..6f593bd27174 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -146,29 +146,36 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
146 | loadcam_entry(index); | 146 | loadcam_entry(index); |
147 | } | 147 | } |
148 | 148 | ||
149 | unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | ||
150 | phys_addr_t phys) | ||
151 | { | ||
152 | unsigned int camsize = __ilog2(ram) & ~1U; | ||
153 | unsigned int align = __ffs(virt | phys) & ~1U; | ||
154 | unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf; | ||
155 | |||
156 | /* Convert (4^max) kB to (2^max) bytes */ | ||
157 | max_cam = max_cam * 2 + 10; | ||
158 | |||
159 | if (camsize > align) | ||
160 | camsize = align; | ||
161 | if (camsize > max_cam) | ||
162 | camsize = max_cam; | ||
163 | |||
164 | return 1UL << camsize; | ||
165 | } | ||
166 | |||
149 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) | 167 | unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) |
150 | { | 168 | { |
151 | int i; | 169 | int i; |
152 | unsigned long virt = PAGE_OFFSET; | 170 | unsigned long virt = PAGE_OFFSET; |
153 | phys_addr_t phys = memstart_addr; | 171 | phys_addr_t phys = memstart_addr; |
154 | unsigned long amount_mapped = 0; | 172 | unsigned long amount_mapped = 0; |
155 | unsigned long max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf; | ||
156 | |||
157 | /* Convert (4^max) kB to (2^max) bytes */ | ||
158 | max_cam = max_cam * 2 + 10; | ||
159 | 173 | ||
160 | /* Calculate CAM values */ | 174 | /* Calculate CAM values */ |
161 | for (i = 0; ram && i < max_cam_idx; i++) { | 175 | for (i = 0; ram && i < max_cam_idx; i++) { |
162 | unsigned int camsize = __ilog2(ram) & ~1U; | ||
163 | unsigned int align = __ffs(virt | phys) & ~1U; | ||
164 | unsigned long cam_sz; | 176 | unsigned long cam_sz; |
165 | 177 | ||
166 | if (camsize > align) | 178 | cam_sz = calc_cam_sz(ram, virt, phys); |
167 | camsize = align; | ||
168 | if (camsize > max_cam) | ||
169 | camsize = max_cam; | ||
170 | |||
171 | cam_sz = 1UL << camsize; | ||
172 | settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0); | 179 | settlbcam(i, virt, phys, cam_sz, PAGE_KERNEL_X, 0); |
173 | 180 | ||
174 | ram -= cam_sz; | 181 | ram -= cam_sz; |
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index dd0a2589591d..83eb5d5f53d5 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -142,6 +142,8 @@ extern unsigned long mmu_mapin_ram(unsigned long top); | |||
142 | 142 | ||
143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) | 143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) |
144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); | 144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); |
145 | extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, | ||
146 | phys_addr_t phys); | ||
145 | #ifdef CONFIG_PPC32 | 147 | #ifdef CONFIG_PPC32 |
146 | extern void MMU_init_hw(void); | 148 | extern void MMU_init_hw(void); |
147 | extern unsigned long mmu_mapin_ram(unsigned long top); | 149 | extern unsigned long mmu_mapin_ram(unsigned long top); |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index afc95c7304ae..6c2eabf707b7 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -642,13 +642,28 @@ void __cpuinit early_init_mmu_secondary(void) | |||
642 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, | 642 | void setup_initial_memory_limit(phys_addr_t first_memblock_base, |
643 | phys_addr_t first_memblock_size) | 643 | phys_addr_t first_memblock_size) |
644 | { | 644 | { |
645 | /* On Embedded 64-bit, we adjust the RMA size to match | 645 | /* On non-FSL Embedded 64-bit, we adjust the RMA size to match |
646 | * the bolted TLB entry. We know for now that only 1G | 646 | * the bolted TLB entry. We know for now that only 1G |
647 | * entries are supported though that may eventually | 647 | * entries are supported though that may eventually |
648 | * change. We crop it to the size of the first MEMBLOCK to | 648 | * change. |
649 | * | ||
650 | * on FSL Embedded 64-bit, we adjust the RMA size to match the | ||
651 | * first bolted TLB entry size. We still limit max to 1G even if | ||
652 | * the TLB could cover more. This is due to what the early init | ||
653 | * code is setup to do. | ||
654 | * | ||
655 | * We crop it to the size of the first MEMBLOCK to | ||
649 | * avoid going over total available memory just in case... | 656 | * avoid going over total available memory just in case... |
650 | */ | 657 | */ |
651 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | 658 | #ifdef CONFIG_PPC_FSL_BOOK3E |
659 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | ||
660 | unsigned long linear_sz; | ||
661 | linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET, | ||
662 | first_memblock_base); | ||
663 | ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); | ||
664 | } else | ||
665 | #endif | ||
666 | ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); | ||
652 | 667 | ||
653 | /* Finally limit subsequent allocations */ | 668 | /* Finally limit subsequent allocations */ |
654 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); | 669 | memblock_set_current_limit(first_memblock_base + ppc64_rma_size); |