powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
authorKumar Gala <galak@kernel.crashing.org>
Fri, 8 Oct 2010 07:13:25 +0000 (02:13 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 14 Oct 2010 05:55:09 +0000 (00:55 -0500)
Update setup_page_sizes() to support for a MMU v1.0 FSL style MMU
implementation.  In such a processor, we don't have TLB0PS or EPTCFG
registers (and access to these registers may cause exceptions).  We need
to parse the older format of TLBnCFG for page size support.  Additionaly,
assume since we are an FSL implementation that we have 2 TLB arrays and
the second array contains the variable size pages.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/include/asm/mmu-book3e.h
arch/powerpc/mm/tlb_nohash.c

index 87a1d787c5b626cf3747eb915be383f605b11179..8eaed81ea642663d7aae026ae899a667022302b1 100644 (file)
 
 #define MAS7_RPN               0xFFFFFFFF
 
+/* Bit definitions for MMUCFG */
+#define MMUCFG_MAVN    0x00000003      /* MMU Architecture Version Number */
+#define MMUCFG_MAVN_V1 0x00000000      /* v1.0 */
+#define MMUCFG_MAVN_V2 0x00000001      /* v2.0 */
+#define MMUCFG_NTLBS   0x0000000c      /* Number of TLBs */
+#define MMUCFG_PIDSIZE 0x000007c0      /* PID Reg Size */
+#define MMUCFG_TWC     0x00008000      /* TLB Write Conditional (v2.0) */
+#define MMUCFG_LRAT    0x00010000      /* LRAT Supported (v2.0) */
+#define MMUCFG_RASIZE  0x00fe0000      /* Real Addr Size */
+#define MMUCFG_LPIDSIZE        0x0f000000      /* LPID Reg Size */
+
 /* Bit definitions for MMUCSR0 */
 #define MMUCSR0_TLB1FI 0x00000002      /* TLB1 Flash invalidate */
 #define MMUCSR0_TLB0FI 0x00000004      /* TLB0 Flash invalidate */
 #define TLBnCFG_GTWE           0x00010000      /* Guest can write */
 #define TLBnCFG_IND            0x00020000      /* IND entries supported */
 #define TLBnCFG_PT             0x00040000      /* Can load from page table */
+#define TLBnCFG_MINSIZE                0x00f00000      /* Minimum Page Size (v1.0) */
+#define TLBnCFG_MINSIZE_SHIFT  20
+#define TLBnCFG_MAXSIZE                0x000f0000      /* Maximum Page Size (v1.0) */
+#define TLBnCFG_MAXSIZE_SHIFT  16
 #define TLBnCFG_ASSOC          0xff000000      /* Associativity */
 
 /* TLBnPS encoding */
index fe391e942521bee44787a99387c304284184e16a..6651899207621f2c663c028c47a089fb4f011fe8 100644 (file)
@@ -349,11 +349,47 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
 
 static void setup_page_sizes(void)
 {
-       unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG);
-       unsigned int tlb0ps = mfspr(SPRN_TLB0PS);
-       unsigned int eptcfg = mfspr(SPRN_EPTCFG);
+       unsigned int tlb0cfg;
+       unsigned int tlb0ps;
+       unsigned int eptcfg;
        int i, psize;
 
+#ifdef CONFIG_PPC_FSL_BOOK3E
+       unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+
+       if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) &&
+               (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) {
+               unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+               unsigned int min_pg, max_pg;
+
+               min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+               max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+
+               for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+                       struct mmu_psize_def *def;
+                       unsigned int shift;
+
+                       def = &mmu_psize_defs[psize];
+                       shift = def->shift;
+
+                       if (shift == 0)
+                               continue;
+
+                       /* adjust to be in terms of 4^shift Kb */
+                       shift = (shift - 10) >> 1;
+
+                       if ((shift >= min_pg) && (shift <= max_pg))
+                               def->flags |= MMU_PAGE_SIZE_DIRECT;
+               }
+
+               goto no_indirect;
+       }
+#endif
+
+       tlb0cfg = mfspr(SPRN_TLB0CFG);
+       tlb0ps = mfspr(SPRN_TLB0PS);
+       eptcfg = mfspr(SPRN_EPTCFG);
+
        /* Look for supported direct sizes */
        for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
                struct mmu_psize_def *def = &mmu_psize_defs[psize];