0001
0002
0003
0004
0005 #include <linux/init.h>
0006 #include <linux/kernel.h>
0007 #include <linux/sched.h>
0008 #include <linux/mm.h>
0009
0010 #include <asm/cpu-type.h>
0011 #include <asm/mipsregs.h>
0012 #include <asm/bcache.h>
0013 #include <asm/cacheops.h>
0014 #include <asm/page.h>
0015 #include <asm/mmu_context.h>
0016 #include <asm/r4kcache.h>
0017 #include <asm/mips-cps.h>
0018 #include <asm/bootinfo.h>
0019
0020
0021
0022
0023
0024
0025
0026
0027 static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
0028 {
0029 blast_scache_range(addr, addr + size);
0030 }
0031
0032
0033
0034
0035 static void mips_sc_inv(unsigned long addr, unsigned long size)
0036 {
0037 unsigned long lsize = cpu_scache_line_size();
0038 unsigned long almask = ~(lsize - 1);
0039
0040 cache_op(Hit_Writeback_Inv_SD, addr & almask);
0041 cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask);
0042 blast_inv_scache_range(addr, addr + size);
0043 }
0044
0045 static void mips_sc_enable(void)
0046 {
0047
0048 }
0049
0050 static void mips_sc_disable(void)
0051 {
0052
0053 }
0054
0055 static void mips_sc_prefetch_enable(void)
0056 {
0057 unsigned long pftctl;
0058
0059 if (mips_cm_revision() < CM_REV_CM2_5)
0060 return;
0061
0062
0063
0064
0065
0066 pftctl = read_gcr_l2_pft_control();
0067 if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) {
0068 pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK;
0069 pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK;
0070 pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
0071 write_gcr_l2_pft_control(pftctl);
0072
0073 set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
0074 CM_GCR_L2_PFT_CONTROL_B_CEN);
0075 }
0076 }
0077
0078 static void mips_sc_prefetch_disable(void)
0079 {
0080 if (mips_cm_revision() < CM_REV_CM2_5)
0081 return;
0082
0083 clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN);
0084 clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
0085 CM_GCR_L2_PFT_CONTROL_B_CEN);
0086 }
0087
0088 static bool mips_sc_prefetch_is_enabled(void)
0089 {
0090 unsigned long pftctl;
0091
0092 if (mips_cm_revision() < CM_REV_CM2_5)
0093 return false;
0094
0095 pftctl = read_gcr_l2_pft_control();
0096 if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT))
0097 return false;
0098 return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN);
0099 }
0100
0101 static struct bcache_ops mips_sc_ops = {
0102 .bc_enable = mips_sc_enable,
0103 .bc_disable = mips_sc_disable,
0104 .bc_wback_inv = mips_sc_wback_inv,
0105 .bc_inv = mips_sc_inv,
0106 .bc_prefetch_enable = mips_sc_prefetch_enable,
0107 .bc_prefetch_disable = mips_sc_prefetch_disable,
0108 .bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled,
0109 };
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
0121 {
0122 unsigned int config2 = read_c0_config2();
0123 unsigned int tmp;
0124
0125
0126 switch (current_cpu_type()) {
0127 case CPU_34K:
0128 case CPU_74K:
0129 case CPU_1004K:
0130 case CPU_1074K:
0131 case CPU_INTERAPTIV:
0132 case CPU_PROAPTIV:
0133 case CPU_P5600:
0134 case CPU_BMIPS5000:
0135 case CPU_QEMU_GENERIC:
0136 case CPU_P6600:
0137 if (config2 & (1 << 12))
0138 return 0;
0139 }
0140
0141 tmp = (config2 >> 4) & 0x0f;
0142 if (0 < tmp && tmp <= 7)
0143 c->scache.linesz = 2 << tmp;
0144 else
0145 return 0;
0146 return 1;
0147 }
0148
0149 static int mips_sc_probe_cm3(void)
0150 {
0151 struct cpuinfo_mips *c = ¤t_cpu_data;
0152 unsigned long cfg = read_gcr_l2_config();
0153 unsigned long sets, line_sz, assoc;
0154
0155 if (cfg & CM_GCR_L2_CONFIG_BYPASS)
0156 return 0;
0157
0158 sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE;
0159 sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE);
0160 if (sets)
0161 c->scache.sets = 64 << sets;
0162
0163 line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE;
0164 line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE);
0165 if (line_sz)
0166 c->scache.linesz = 2 << line_sz;
0167
0168 assoc = cfg & CM_GCR_L2_CONFIG_ASSOC;
0169 assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC);
0170 c->scache.ways = assoc + 1;
0171 c->scache.waysize = c->scache.sets * c->scache.linesz;
0172 c->scache.waybit = __ffs(c->scache.waysize);
0173
0174 if (c->scache.linesz) {
0175 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
0176 c->options |= MIPS_CPU_INCLUSIVE_CACHES;
0177 return 1;
0178 }
0179
0180 return 0;
0181 }
0182
0183 static inline int mips_sc_probe(void)
0184 {
0185 struct cpuinfo_mips *c = ¤t_cpu_data;
0186 unsigned int config1, config2;
0187 unsigned int tmp;
0188
0189
0190 c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
0191
0192 if (mips_cm_revision() >= CM_REV_CM3)
0193 return mips_sc_probe_cm3();
0194
0195
0196 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
0197 MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
0198 MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5 |
0199 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)))
0200 return 0;
0201
0202
0203 config1 = read_c0_config1();
0204 if (!(config1 & MIPS_CONF_M))
0205 return 0;
0206
0207 config2 = read_c0_config2();
0208
0209 if (!mips_sc_is_activated(c))
0210 return 0;
0211
0212 tmp = (config2 >> 8) & 0x0f;
0213 if (tmp <= 7)
0214 c->scache.sets = 64 << tmp;
0215 else
0216 return 0;
0217
0218 tmp = (config2 >> 0) & 0x0f;
0219 if (tmp <= 7)
0220 c->scache.ways = tmp + 1;
0221 else
0222 return 0;
0223
0224 if (current_cpu_type() == CPU_XBURST) {
0225 switch (mips_machtype) {
0226
0227
0228
0229
0230 case MACH_INGENIC_JZ4770:
0231 case MACH_INGENIC_JZ4775:
0232 c->scache.ways = 4;
0233 break;
0234
0235
0236
0237
0238
0239 case MACH_INGENIC_X1000:
0240 case MACH_INGENIC_X1000E:
0241 c->scache.sets = 256;
0242 c->scache.ways = 4;
0243 break;
0244 }
0245 }
0246
0247 c->scache.waysize = c->scache.sets * c->scache.linesz;
0248 c->scache.waybit = __ffs(c->scache.waysize);
0249
0250 c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
0251
0252 return 1;
0253 }
0254
0255 int mips_sc_init(void)
0256 {
0257 int found = mips_sc_probe();
0258 if (found) {
0259 mips_sc_enable();
0260 mips_sc_prefetch_enable();
0261 bcops = &mips_sc_ops;
0262 }
0263 return found;
0264 }