Home | History | Annotate | Download | only in sh4
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2016 Vladimir Zapolskiy <vz (at) mleia.com>
      4  * (C) Copyright 2007 Nobuhiro Iwamatsu <iwamatsu (at) nigauri.org>
      5  */
      6 
      7 #include <common.h>
      8 #include <command.h>
      9 #include <asm/io.h>
     10 #include <asm/processor.h>
     11 #include <asm/system.h>
     12 
     13 #define CACHE_VALID       1
     14 #define CACHE_UPDATED     2
     15 
     16 static inline void cache_wback_all(void)
     17 {
     18 	unsigned long addr, data, i, j;
     19 
     20 	for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++) {
     21 		for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
     22 			addr = CACHE_OC_ADDRESS_ARRAY
     23 				| (j << CACHE_OC_WAY_SHIFT)
     24 				| (i << CACHE_OC_ENTRY_SHIFT);
     25 			data = inl(addr);
     26 			if (data & CACHE_UPDATED) {
     27 				data &= ~CACHE_UPDATED;
     28 				outl(data, addr);
     29 			}
     30 		}
     31 	}
     32 }
     33 
     34 #define CACHE_ENABLE      0
     35 #define CACHE_DISABLE     1
     36 
     37 static int cache_control(unsigned int cmd)
     38 {
     39 	unsigned long ccr;
     40 
     41 	jump_to_P2();
     42 	ccr = inl(CCR);
     43 
     44 	if (ccr & CCR_CACHE_ENABLE)
     45 		cache_wback_all();
     46 
     47 	if (cmd == CACHE_DISABLE)
     48 		outl(CCR_CACHE_STOP, CCR);
     49 	else
     50 		outl(CCR_CACHE_INIT, CCR);
     51 	back_to_P1();
     52 
     53 	return 0;
     54 }
     55 
     56 void flush_dcache_range(unsigned long start, unsigned long end)
     57 {
     58 	u32 v;
     59 
     60 	start &= ~(L1_CACHE_BYTES - 1);
     61 	for (v = start; v < end; v += L1_CACHE_BYTES) {
     62 		asm volatile ("ocbp     %0" :	/* no output */
     63 			      : "m" (__m(v)));
     64 	}
     65 }
     66 
     67 void invalidate_dcache_range(unsigned long start, unsigned long end)
     68 {
     69 	u32 v;
     70 
     71 	start &= ~(L1_CACHE_BYTES - 1);
     72 	for (v = start; v < end; v += L1_CACHE_BYTES) {
     73 		asm volatile ("ocbi     %0" :	/* no output */
     74 			      : "m" (__m(v)));
     75 	}
     76 }
     77 
     78 void flush_cache(unsigned long addr, unsigned long size)
     79 {
     80 	flush_dcache_range(addr , addr + size);
     81 }
     82 
     83 void icache_enable(void)
     84 {
     85 	cache_control(CACHE_ENABLE);
     86 }
     87 
     88 void icache_disable(void)
     89 {
     90 	cache_control(CACHE_DISABLE);
     91 }
     92 
     93 int icache_status(void)
     94 {
     95 	return 0;
     96 }
     97 
     98 void dcache_enable(void)
     99 {
    100 }
    101 
    102 void dcache_disable(void)
    103 {
    104 }
    105 
    106 int dcache_status(void)
    107 {
    108 	return 0;
    109 }
    110