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-cps.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) { 67 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK; 68 pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK; 69 pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN; 70 write_gcr_l2_pft_control(pftctl); 71 72 set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | 73 CM_GCR_L2_PFT_CONTROL_B_CEN); 74 } 75 } 76 77 static void mips_sc_prefetch_disable(void) 78 { 79 if (mips_cm_revision() < CM_REV_CM2_5) 80 return; 81 82 clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN); 83 clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | 84 CM_GCR_L2_PFT_CONTROL_B_CEN); 85 } 86 87 static bool mips_sc_prefetch_is_enabled(void) 88 { 89 unsigned long pftctl; 90 91 if (mips_cm_revision() < CM_REV_CM2_5) 92 return false; 93 94 pftctl = read_gcr_l2_pft_control(); 95 if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT)) 96 return false; 97 return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN); 98 } 99 100 static struct bcache_ops mips_sc_ops = { 101 .bc_enable = mips_sc_enable, 102 .bc_disable = mips_sc_disable, 103 .bc_wback_inv = mips_sc_wback_inv, 104 .bc_inv = mips_sc_inv, 105 .bc_prefetch_enable = mips_sc_prefetch_enable, 106 .bc_prefetch_disable = mips_sc_prefetch_disable, 107 .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled, 108 }; 109 110 /* 111 * Check if the L2 cache controller is activated on a particular platform. 112 * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS 113 * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the 114 * cache being disabled. However there is no guarantee for this to be 115 * true on all platforms. In an act of stupidity the spec defined bits 116 * 12..15 as implementation defined so below function will eventually have 117 * to be replaced by a platform specific probe. 118 */ 119 static inline int mips_sc_is_activated(struct cpuinfo_mips *c) 120 { 121 unsigned int config2 = read_c0_config2(); 122 unsigned int tmp; 123 124 /* Check the bypass bit (L2B) */ 125 switch (current_cpu_type()) { 126 case CPU_34K: 127 case CPU_74K: 128 case CPU_1004K: 129 case CPU_1074K: 130 case CPU_INTERAPTIV: 131 case CPU_PROAPTIV: 132 case CPU_P5600: 133 case CPU_BMIPS5000: 134 case CPU_QEMU_GENERIC: 135 case CPU_P6600: 136 if (config2 & (1 << 12)) 137 return 0; 138 } 139 140 tmp = (config2 >> 4) & 0x0f; 141 if (0 < tmp && tmp <= 7) 142 c->scache.linesz = 2 << tmp; 143 else 144 return 0; 145 return 1; 146 } 147 148 static int __init mips_sc_probe_cm3(void) 149 { 150 struct cpuinfo_mips *c = ¤t_cpu_data; 151 unsigned long cfg = read_gcr_l2_config(); 152 unsigned long sets, line_sz, assoc; 153 154 if (cfg & CM_GCR_L2_CONFIG_BYPASS) 155 return 0; 156 157 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE; 158 sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE); 159 if (sets) 160 c->scache.sets = 64 << sets; 161 162 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE; 163 line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE); 164 if (line_sz) 165 c->scache.linesz = 2 << line_sz; 166 167 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC; 168 assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC); 169 c->scache.ways = assoc + 1; 170 c->scache.waysize = c->scache.sets * c->scache.linesz; 171 c->scache.waybit = __ffs(c->scache.waysize); 172 173 if (c->scache.linesz) { 174 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 175 c->options |= MIPS_CPU_INCLUSIVE_CACHES; 176 return 1; 177 } 178 179 return 0; 180 } 181 182 static inline int __init mips_sc_probe(void) 183 { 184 struct cpuinfo_mips *c = ¤t_cpu_data; 185 unsigned int config1, config2; 186 unsigned int tmp; 187 188 /* Mark as not present until probe completed */ 189 c->scache.flags |= MIPS_CACHE_NOT_PRESENT; 190 191 if (mips_cm_revision() >= CM_REV_CM3) 192 return mips_sc_probe_cm3(); 193 194 /* Ignore anything but MIPSxx processors */ 195 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | 196 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 | 197 MIPS_CPU_ISA_M64R2 | MIPS_CPU_ISA_M64R6))) 198 return 0; 199 200 /* Does this MIPS32/MIPS64 CPU have a config2 register? */ 201 config1 = read_c0_config1(); 202 if (!(config1 & MIPS_CONF_M)) 203 return 0; 204 205 config2 = read_c0_config2(); 206 207 if (!mips_sc_is_activated(c)) 208 return 0; 209 210 tmp = (config2 >> 8) & 0x0f; 211 if (tmp <= 7) 212 c->scache.sets = 64 << tmp; 213 else 214 return 0; 215 216 tmp = (config2 >> 0) & 0x0f; 217 if (tmp <= 7) 218 c->scache.ways = tmp + 1; 219 else 220 return 0; 221 222 c->scache.waysize = c->scache.sets * c->scache.linesz; 223 c->scache.waybit = __ffs(c->scache.waysize); 224 225 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; 226 227 return 1; 228 } 229 230 int mips_sc_init(void) 231 { 232 int found = mips_sc_probe(); 233 if (found) { 234 mips_sc_enable(); 235 mips_sc_prefetch_enable(); 236 bcops = &mips_sc_ops; 237 } 238 return found; 239 } 240