1 /* 2 * Copyright (C) 2006 Chris Dearman (chris@mips.com), 3 */ 4 #include <linux/init.h> 5 #include <linux/kernel.h> 6 #include <linux/sched.h> 7 #include <linux/mm.h> 8 9 #include <asm/cpu-type.h> 10 #include <asm/mipsregs.h> 11 #include <asm/bcache.h> 12 #include <asm/cacheops.h> 13 #include <asm/page.h> 14 #include <asm/pgtable.h> 15 #include <asm/mmu_context.h> 16 #include <asm/r4kcache.h> 17 #include <asm/mips-cm.h> 18 19 /* 20 * MIPS32/MIPS64 L2 cache handling 21 */ 22 23 /* 24 * Writeback and invalidate the secondary cache before DMA. 25 */ 26 static void mips_sc_wback_inv(unsigned long addr, unsigned long size) 27 { 28 blast_scache_range(addr, addr + size); 29 } 30 31 /* 32 * Invalidate the secondary cache before DMA. 33 */ 34 static void mips_sc_inv(unsigned long addr, unsigned long size) 35 { 36 unsigned long lsize = cpu_scache_line_size(); 37 unsigned long almask = ~(lsize - 1); 38 39 cache_op(Hit_Writeback_Inv_SD, addr & almask); 40 cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask); 41 blast_inv_scache_range(addr, addr + size); 42 } 43 44 static void mips_sc_enable(void) 45 { 46 /* L2 cache is permanently enabled */ 47 } 48 49 static void mips_sc_disable(void) 50 { 51 /* L2 cache is permanently enabled */ 52 } 53 54 static void mips_sc_prefetch_enable(void) 55 { 56 unsigned long pftctl; 57 58 if (mips_cm_revision() < CM_REV_CM2_5) 59 return; 60 61 /* 62 * If there is one or more L2 prefetch unit present then enable 63 * prefetching for both code & data, for all ports. 64 */ 65 pftctl = read_gcr_l2_pft_control(); 66 if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) { 67 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; 68 pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; 69 pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; 70 write_gcr_l2_pft_control(pftctl); 71 72 pftctl = read_gcr_l2_pft_control_b(); 73 pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; 74 pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; 75 write_gcr_l2_pft_control_b(pftctl); 76 } 77 } 78 79 static void mips_sc_prefetch_disable(void) 80 { 81 unsigned long pftctl; 82 83 if (mips_cm_revision() < CM_REV_CM2_5) 84 return; 85 86 pftctl = read_gcr_l2_pft_control(); 87 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; 88 write_gcr_l2_pft_control(pftctl); 89 90 pftctl = read_gcr_l2_pft_control_b(); 91 pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; 92 pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; 93 write_gcr_l2_pft_control_b(pftctl); 94 } 95 96 static bool mips_sc_prefetch_is_enabled(void) 97 { 98 unsigned long pftctl; 99 100 if (mips_cm_revision() < CM_REV_CM2_5) 101 return false; 102 103 pftctl = read_gcr_l2_pft_control(); 104 if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK)) 105 return false; 106 return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK); 107 } 108 109 static struct bcache_ops mips_sc_ops = { 110 .bc_enable = mips_sc_enable, 111 .bc_disable = mips_sc_disable, 112 .bc_wback_inv = mips_sc_wback_inv, 113 .bc_inv = mips_sc_inv, 114 .bc_prefetch_enable = mips_sc_prefetch_enable, 115 .bc_prefetch_disable = mips_sc_prefetch_disable, 116 .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled, 117 }; 118 119 /* 120 * Check if the L2 cache controller is activated on a particular platform. 121 * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS 122 * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the 123 * cache being disabled. However there is no guarantee for this to be 124 * true on all platforms. In an act of stupidity the spec defined bits 125 * 12..15 as implementation defined so below function will eventually have 126 * to be replaced by a platform specific probe. 127 */ 128 static inline int mips_sc_is_activated(struct cpuinfo_mips *c) 129 { 130 unsigned int config2 = read_c0_config2(); 131 unsigned int tmp; 132 133 /* Check the bypass bit (L2B) */ 134 switch (current_cpu_type()) { 135 case CPU_34K: 136 case CPU_74K: 137 case CPU_1004K: 138 case CPU_1074K: 139 case CPU_INTERAPTIV: 140 case CPU_PROAPTIV: 141 case CPU_P5600: 142 case CPU_BMIPS5000: 143 case CPU_QEMU_GENERIC: 144 if (config2 & (1 << 12)) 145 return 0; 146 } 147 148 tmp = (config2 >> 4) & 0x0f; 149 if (0 < tmp && tmp <= 7) 150 c->scache.linesz = 2 << tmp; 151 else 152 return 0; 153 return 1; 154 } 155 156 static int __init mips_sc_probe_cm3(void) 157 { 158 struct cpuinfo_mips *c = ¤t_cpu_data; 159 unsigned long cfg = read_gcr_l2_config(); 160 unsigned long sets, line_sz, assoc; 161 162 if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK) 163 return 0; 164 165 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK; 166 sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF; 167 c->scache.sets = 64 << sets; 168 169 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK; 170 line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF; 171 c->scache.linesz = 2 << line_sz; 172 173 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK; 174 assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF; 175 c->scache.ways = assoc + 1; 176 c->scache.waysize = c->scache.sets * c->scache.linesz; 177 c->scache.waybit = __ffs(c->scache.waysize); 178 179 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 180 181 return 1; 182 } 183 184 void __weak platform_early_l2_init(void) 185 { 186 } 187 188 static inline int __init mips_sc_probe(void) 189 { 190 struct cpuinfo_mips *c = ¤t_cpu_data; 191 unsigned int config1, config2; 192 unsigned int tmp; 193 194 /* Mark as not present until probe completed */ 195 c->scache.flags |= MIPS_CACHE_NOT_PRESENT; 196 197 /* 198 * Do we need some platform specific probing before 199 * we configure L2? 200 */ 201 platform_early_l2_init(); 202 203 if (mips_cm_revision() >= CM_REV_CM3) 204 return mips_sc_probe_cm3(); 205 206 /* Ignore anything but MIPSxx processors */ 207 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | 208 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 | 209 MIPS_CPU_ISA_M64R2 | MIPS_CPU_ISA_M64R6))) 210 return 0; 211 212 /* Does this MIPS32/MIPS64 CPU have a config2 register? */ 213 config1 = read_c0_config1(); 214 if (!(config1 & MIPS_CONF_M)) 215 return 0; 216 217 config2 = read_c0_config2(); 218 219 if (!mips_sc_is_activated(c)) 220 return 0; 221 222 tmp = (config2 >> 8) & 0x0f; 223 if (tmp <= 7) 224 c->scache.sets = 64 << tmp; 225 else 226 return 0; 227 228 tmp = (config2 >> 0) & 0x0f; 229 if (tmp <= 7) 230 c->scache.ways = tmp + 1; 231 else 232 return 0; 233 234 c->scache.waysize = c->scache.sets * c->scache.linesz; 235 c->scache.waybit = __ffs(c->scache.waysize); 236 237 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 238 239 return 1; 240 } 241 242 int mips_sc_init(void) 243 { 244 int found = mips_sc_probe(); 245 if (found) { 246 mips_sc_enable(); 247 mips_sc_prefetch_enable(); 248 bcops = &mips_sc_ops; 249 } 250 return found; 251 } 252