root/arch/sh/mm/cache-sh2.c

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

DEFINITIONS

This source file includes following definitions.
  1. sh2__flush_wback_region
  2. sh2__flush_purge_region
  3. sh2__flush_invalidate_region
  4. sh2_cache_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * arch/sh/mm/cache-sh2.c
   4  *
   5  * Copyright (C) 2002 Paul Mundt
   6  * Copyright (C) 2008 Yoshinori Sato
   7  */
   8 
   9 #include <linux/init.h>
  10 #include <linux/mm.h>
  11 
  12 #include <asm/cache.h>
  13 #include <asm/addrspace.h>
  14 #include <asm/processor.h>
  15 #include <asm/cacheflush.h>
  16 #include <asm/io.h>
  17 
  18 static void sh2__flush_wback_region(void *start, int size)
  19 {
  20         unsigned long v;
  21         unsigned long begin, end;
  22 
  23         begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  24         end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  25                 & ~(L1_CACHE_BYTES-1);
  26         for (v = begin; v < end; v+=L1_CACHE_BYTES) {
  27                 unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
  28                 int way;
  29                 for (way = 0; way < 4; way++) {
  30                         unsigned long data =  __raw_readl(addr | (way << 12));
  31                         if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
  32                                 data &= ~SH_CACHE_UPDATED;
  33                                 __raw_writel(data, addr | (way << 12));
  34                         }
  35                 }
  36         }
  37 }
  38 
  39 static void sh2__flush_purge_region(void *start, int size)
  40 {
  41         unsigned long v;
  42         unsigned long begin, end;
  43 
  44         begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  45         end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  46                 & ~(L1_CACHE_BYTES-1);
  47 
  48         for (v = begin; v < end; v+=L1_CACHE_BYTES)
  49                 __raw_writel((v & CACHE_PHYSADDR_MASK),
  50                           CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
  51 }
  52 
  53 static void sh2__flush_invalidate_region(void *start, int size)
  54 {
  55 #ifdef CONFIG_CACHE_WRITEBACK
  56         /*
  57          * SH-2 does not support individual line invalidation, only a
  58          * global invalidate.
  59          */
  60         unsigned long ccr;
  61         unsigned long flags;
  62         local_irq_save(flags);
  63         jump_to_uncached();
  64 
  65         ccr = __raw_readl(SH_CCR);
  66         ccr |= CCR_CACHE_INVALIDATE;
  67         __raw_writel(ccr, SH_CCR);
  68 
  69         back_to_cached();
  70         local_irq_restore(flags);
  71 #else
  72         unsigned long v;
  73         unsigned long begin, end;
  74 
  75         begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
  76         end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
  77                 & ~(L1_CACHE_BYTES-1);
  78 
  79         for (v = begin; v < end; v+=L1_CACHE_BYTES)
  80                 __raw_writel((v & CACHE_PHYSADDR_MASK),
  81                           CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
  82 #endif
  83 }
  84 
  85 void __init sh2_cache_init(void)
  86 {
  87         __flush_wback_region            = sh2__flush_wback_region;
  88         __flush_purge_region            = sh2__flush_purge_region;
  89         __flush_invalidate_region       = sh2__flush_invalidate_region;
  90 }

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