diff options
Diffstat (limited to 'arch/powerpc/mm/tlb_nohash.c')
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 6a0f20c25469..36c0c449a899 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -349,11 +349,47 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) | |||
349 | 349 | ||
350 | static void setup_page_sizes(void) | 350 | static void setup_page_sizes(void) |
351 | { | 351 | { |
352 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | 352 | unsigned int tlb0cfg; |
353 | unsigned int tlb0ps = mfspr(SPRN_TLB0PS); | 353 | unsigned int tlb0ps; |
354 | unsigned int eptcfg = mfspr(SPRN_EPTCFG); | 354 | unsigned int eptcfg; |
355 | int i, psize; | 355 | int i, psize; |
356 | 356 | ||
357 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
358 | unsigned int mmucfg = mfspr(SPRN_MMUCFG); | ||
359 | |||
360 | if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) && | ||
361 | (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) { | ||
362 | unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); | ||
363 | unsigned int min_pg, max_pg; | ||
364 | |||
365 | min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; | ||
366 | max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; | ||
367 | |||
368 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
369 | struct mmu_psize_def *def; | ||
370 | unsigned int shift; | ||
371 | |||
372 | def = &mmu_psize_defs[psize]; | ||
373 | shift = def->shift; | ||
374 | |||
375 | if (shift == 0) | ||
376 | continue; | ||
377 | |||
378 | /* adjust to be in terms of 4^shift Kb */ | ||
379 | shift = (shift - 10) >> 1; | ||
380 | |||
381 | if ((shift >= min_pg) && (shift <= max_pg)) | ||
382 | def->flags |= MMU_PAGE_SIZE_DIRECT; | ||
383 | } | ||
384 | |||
385 | goto no_indirect; | ||
386 | } | ||
387 | #endif | ||
388 | |||
389 | tlb0cfg = mfspr(SPRN_TLB0CFG); | ||
390 | tlb0ps = mfspr(SPRN_TLB0PS); | ||
391 | eptcfg = mfspr(SPRN_EPTCFG); | ||
392 | |||
357 | /* Look for supported direct sizes */ | 393 | /* Look for supported direct sizes */ |
358 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | 394 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { |
359 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | 395 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; |
@@ -505,6 +541,20 @@ static void __early_init_mmu(int boot_cpu) | |||
505 | */ | 541 | */ |
506 | linear_map_top = memblock_end_of_DRAM(); | 542 | linear_map_top = memblock_end_of_DRAM(); |
507 | 543 | ||
544 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
545 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | ||
546 | unsigned int num_cams; | ||
547 | |||
548 | /* use a quarter of the TLBCAM for bolted linear map */ | ||
549 | num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; | ||
550 | linear_map_top = map_mem_in_cams(linear_map_top, num_cams); | ||
551 | |||
552 | /* limit memory so we dont have linear faults */ | ||
553 | memblock_enforce_memory_limit(linear_map_top); | ||
554 | memblock_analyze(); | ||
555 | } | ||
556 | #endif | ||
557 | |||
508 | /* A sync won't hurt us after mucking around with | 558 | /* A sync won't hurt us after mucking around with |
509 | * the MMU configuration | 559 | * the MMU configuration |
510 | */ | 560 | */ |