root/arch/mips/mm/sc-r5k.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. blast_r5000_scache
  2. r5k_dma_cache_inv_sc
  3. r5k_sc_enable
  4. r5k_sc_disable
  5. r5k_sc_probe
  6. r5k_sc_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
   4  * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
   5  */
   6 #include <linux/init.h>
   7 #include <linux/kernel.h>
   8 #include <linux/sched.h>
   9 #include <linux/mm.h>
  10 
  11 #include <asm/mipsregs.h>
  12 #include <asm/bcache.h>
  13 #include <asm/cacheops.h>
  14 #include <asm/page.h>
  15 #include <asm/pgtable.h>
  16 #include <asm/mmu_context.h>
  17 #include <asm/r4kcache.h>
  18 
  19 /* Secondary cache size in bytes, if present.  */
  20 static unsigned long scache_size;
  21 
  22 #define SC_LINE 32
  23 #define SC_PAGE (128*SC_LINE)
  24 
  25 static inline void blast_r5000_scache(void)
  26 {
  27         unsigned long start = INDEX_BASE;
  28         unsigned long end = start + scache_size;
  29 
  30         while(start < end) {
  31                 cache_op(R5K_Page_Invalidate_S, start);
  32                 start += SC_PAGE;
  33         }
  34 }
  35 
  36 static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
  37 {
  38         unsigned long end, a;
  39 
  40         /* Catch bad driver code */
  41         BUG_ON(size == 0);
  42 
  43         if (size >= scache_size) {
  44                 blast_r5000_scache();
  45                 return;
  46         }
  47 
  48         /* On the R5000 secondary cache we cannot
  49          * invalidate less than a page at a time.
  50          * The secondary cache is physically indexed, write-through.
  51          */
  52         a = addr & ~(SC_PAGE - 1);
  53         end = (addr + size - 1) & ~(SC_PAGE - 1);
  54         while (a <= end) {
  55                 cache_op(R5K_Page_Invalidate_S, a);
  56                 a += SC_PAGE;
  57         }
  58 }
  59 
  60 static void r5k_sc_enable(void)
  61 {
  62         unsigned long flags;
  63 
  64         local_irq_save(flags);
  65         set_c0_config(R5K_CONF_SE);
  66         blast_r5000_scache();
  67         local_irq_restore(flags);
  68 }
  69 
  70 static void r5k_sc_disable(void)
  71 {
  72         unsigned long flags;
  73 
  74         local_irq_save(flags);
  75         blast_r5000_scache();
  76         clear_c0_config(R5K_CONF_SE);
  77         local_irq_restore(flags);
  78 }
  79 
  80 static inline int __init r5k_sc_probe(void)
  81 {
  82         unsigned long config = read_c0_config();
  83 
  84         if (config & CONF_SC)
  85                 return 0;
  86 
  87         scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
  88 
  89         printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n",
  90                         scache_size >> 10);
  91 
  92         return 1;
  93 }
  94 
  95 static struct bcache_ops r5k_sc_ops = {
  96         .bc_enable = r5k_sc_enable,
  97         .bc_disable = r5k_sc_disable,
  98         .bc_wback_inv = r5k_dma_cache_inv_sc,
  99         .bc_inv = r5k_dma_cache_inv_sc
 100 };
 101 
 102 void r5k_sc_init(void)
 103 {
 104         if (r5k_sc_probe()) {
 105                 r5k_sc_enable();
 106                 bcops = &r5k_sc_ops;
 107         }
 108 }

/* [<][>][^][v][top][bottom][index][help] */