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 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation; either version 2 of
   8 * the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 * MA 02111-1307 USA
  19 */
  20
  21#include <common.h>
  22#include <asm/system.h>
  23
  24void flush_dcache_range(unsigned long addr, unsigned long stop)
  25{
  26        ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  27
  28        while (addr < stop) {
  29                mtspr(SPR_DCBFR, addr);
  30                addr += block_size;
  31        }
  32}
  33
  34void invalidate_dcache_range(unsigned long addr, unsigned long stop)
  35{
  36        ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  37
  38        while (addr < stop) {
  39                mtspr(SPR_DCBIR, addr);
  40                addr += block_size;
  41        }
  42}
  43
  44static void invalidate_icache_range(unsigned long addr, unsigned long stop)
  45{
  46        ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
  47
  48        while (addr < stop) {
  49                mtspr(SPR_ICBIR, addr);
  50                addr += block_size;
  51        }
  52}
  53
  54void flush_cache(unsigned long addr, unsigned long size)
  55{
  56        flush_dcache_range(addr, addr + size);
  57        invalidate_icache_range(addr, addr + size);
  58}
  59
  60int icache_status(void)
  61{
  62        return mfspr(SPR_SR) & SPR_SR_ICE;
  63}
  64
  65int checkicache(void)
  66{
  67        unsigned long iccfgr;
  68        unsigned long cache_set_size;
  69        unsigned long cache_ways;
  70        unsigned long cache_block_size;
  71
  72        iccfgr = mfspr(SPR_ICCFGR);
  73        cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
  74        cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
  75        cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
  76
  77        return cache_set_size * cache_ways * cache_block_size;
  78}
  79
  80int dcache_status(void)
  81{
  82        return mfspr(SPR_SR) & SPR_SR_DCE;
  83}
  84
  85int checkdcache(void)
  86{
  87        unsigned long dccfgr;
  88        unsigned long cache_set_size;
  89        unsigned long cache_ways;
  90        unsigned long cache_block_size;
  91
  92        dccfgr = mfspr(SPR_DCCFGR);
  93        cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
  94        cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
  95        cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
  96
  97        return cache_set_size * cache_ways * cache_block_size;
  98}
  99
 100void dcache_enable(void)
 101{
 102        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
 103        asm volatile("l.nop");
 104        asm volatile("l.nop");
 105        asm volatile("l.nop");
 106        asm volatile("l.nop");
 107        asm volatile("l.nop");
 108        asm volatile("l.nop");
 109        asm volatile("l.nop");
 110        asm volatile("l.nop");
 111}
 112
 113void dcache_disable(void)
 114{
 115        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
 116}
 117
 118void icache_enable(void)
 119{
 120        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
 121        asm volatile("l.nop");
 122        asm volatile("l.nop");
 123        asm volatile("l.nop");
 124        asm volatile("l.nop");
 125        asm volatile("l.nop");
 126        asm volatile("l.nop");
 127        asm volatile("l.nop");
 128        asm volatile("l.nop");
 129}
 130
 131void icache_disable(void)
 132{
 133        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
 134}
 135
 136int cache_init(void)
 137{
 138        if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
 139                icache_disable();
 140                invalidate_icache_range(0, checkicache());
 141                icache_enable();
 142        }
 143
 144        if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
 145                dcache_disable();
 146                invalidate_dcache_range(0, checkdcache());
 147                dcache_enable();
 148        }
 149
 150        return 0;
 151}
 152