Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2006 Chris Dearman (chris@mips.com),
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  * MIPS32/MIPS64 L2 cache handling
0022  */
0023 
0024 /*
0025  * Writeback and invalidate the secondary cache before DMA.
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  * Invalidate the secondary cache before DMA.
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     /* L2 cache is permanently enabled */
0048 }
0049 
0050 static void mips_sc_disable(void)
0051 {
0052     /* L2 cache is permanently enabled */
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      * If there is one or more L2 prefetch unit present then enable
0064      * prefetching for both code & data, for all ports.
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  * Check if the L2 cache controller is activated on a particular platform.
0113  * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
0114  * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
0115  * cache being disabled.  However there is no guarantee for this to be
0116  * true on all platforms.  In an act of stupidity the spec defined bits
0117  * 12..15 as implementation defined so below function will eventually have
0118  * to be replaced by a platform specific probe.
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     /* Check the bypass bit (L2B) */
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 = &current_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 = &current_cpu_data;
0186     unsigned int config1, config2;
0187     unsigned int tmp;
0188 
0189     /* Mark as not present until probe completed */
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     /* Ignore anything but MIPSxx processors */
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     /* Does this MIPS32/MIPS64 CPU have a config2 register? */
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          * According to config2 it would be 5-ways, but that is
0228          * contradicted by all documentation.
0229          */
0230         case MACH_INGENIC_JZ4770:
0231         case MACH_INGENIC_JZ4775:
0232             c->scache.ways = 4;
0233             break;
0234 
0235         /*
0236          * According to config2 it would be 5-ways and 512-sets,
0237          * but that is contradicted by all documentation.
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 }