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 6a0f20c2546..36c0c449a89 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 | */ |
