uboot/arch/openrisc/cpu/cache.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
   3 * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/system.h>
  10
  11void flush_dcache_range(unsigned long addr, unsigned long stop)
  12{
  13        ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  14
  15        while (addr < stop) {
  16                mtspr(SPR_DCBFR, addr);
  17                addr += block_size;
  18        }
  19}
  20
  21void invalidate_dcache_range(unsigned long addr, unsigned long stop)
  22{
  23        ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  24
  25        while (addr < stop) {
  26                mtspr(SPR_DCBIR, addr);
  27                addr += block_size;
  28        }
  29}
  30
  31static void invalidate_icache_range(unsigned long addr, unsigned long stop)
  32{
  33        ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
  34
  35        while (addr < stop) {
  36                mtspr(SPR_ICBIR, addr);
  37                addr += block_size;
  38        }
  39}
  40
  41void flush_cache(unsigned long addr, unsigned long size)
  42{
  43        flush_dcache_range(addr, addr + size);
  44        invalidate_icache_range(addr, addr + size);
  45}
  46
  47int icache_status(void)
  48{
  49        return mfspr(SPR_SR) & SPR_SR_ICE;
  50}
  51
  52int checkicache(void)
  53{
  54        unsigned long iccfgr;
  55        unsigned long cache_set_size;
  56        unsigned long cache_ways;
  57        unsigned long cache_block_size;
  58
  59        iccfgr = mfspr(SPR_ICCFGR);
  60        cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
  61        cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
  62        cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
  63
  64        return cache_set_size * cache_ways * cache_block_size;
  65}
  66
  67int dcache_status(void)
  68{
  69        return mfspr(SPR_SR) & SPR_SR_DCE;
  70}
  71
  72int checkdcache(void)
  73{
  74        unsigned long dccfgr;
  75        unsigned long cache_set_size;
  76        unsigned long cache_ways;
  77        unsigned long cache_block_size;
  78
  79        dccfgr = mfspr(SPR_DCCFGR);
  80        cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
  81        cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
  82        cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
  83
  84        return cache_set_size * cache_ways * cache_block_size;
  85}
  86
  87void dcache_enable(void)
  88{
  89        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
  90        asm volatile("l.nop");
  91        asm volatile("l.nop");
  92        asm volatile("l.nop");
  93        asm volatile("l.nop");
  94        asm volatile("l.nop");
  95        asm volatile("l.nop");
  96        asm volatile("l.nop");
  97        asm volatile("l.nop");
  98}
  99
 100void dcache_disable(void)
 101{
 102        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
 103}
 104
 105void icache_enable(void)
 106{
 107        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
 108        asm volatile("l.nop");
 109        asm volatile("l.nop");
 110        asm volatile("l.nop");
 111        asm volatile("l.nop");
 112        asm volatile("l.nop");
 113        asm volatile("l.nop");
 114        asm volatile("l.nop");
 115        asm volatile("l.nop");
 116}
 117
 118void icache_disable(void)
 119{
 120        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
 121}
 122
 123int cache_init(void)
 124{
 125        if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
 126                icache_disable();
 127                invalidate_icache_range(0, checkicache());
 128                icache_enable();
 129        }
 130
 131        if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
 132                dcache_disable();
 133                invalidate_dcache_range(0, checkdcache());
 134                dcache_enable();
 135        }
 136
 137        return 0;
 138}
 139