xref: /rk3399_rockchip-uboot/arch/sh/cpu/sh4/cache.c (revision ee47c4cb2b3413b3ee0edd2207de46d715b2628c)
18f0fec74SPeter Tyser /*
28f0fec74SPeter Tyser  * (C) Copyright 2007
38f0fec74SPeter Tyser  * Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
48f0fec74SPeter Tyser  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
68f0fec74SPeter Tyser  */
78f0fec74SPeter Tyser 
88f0fec74SPeter Tyser #include <common.h>
98f0fec74SPeter Tyser #include <command.h>
108f0fec74SPeter Tyser #include <asm/processor.h>
118f0fec74SPeter Tyser #include <asm/io.h>
128f0fec74SPeter Tyser 
138f0fec74SPeter Tyser /*
148f0fec74SPeter Tyser  * Jump to P2 area.
158f0fec74SPeter Tyser  * When handling TLB or caches, we need to do it from P2 area.
168f0fec74SPeter Tyser  */
178f0fec74SPeter Tyser #define jump_to_P2()			\
188f0fec74SPeter Tyser   do {					\
198f0fec74SPeter Tyser     unsigned long __dummy;		\
208f0fec74SPeter Tyser     __asm__ __volatile__(		\
218f0fec74SPeter Tyser 		"mov.l	1f, %0\n\t"	\
228f0fec74SPeter Tyser 		"or	%1, %0\n\t"	\
238f0fec74SPeter Tyser 		"jmp	@%0\n\t"	\
248f0fec74SPeter Tyser 		" nop\n\t"		\
258f0fec74SPeter Tyser 		".balign 4\n"		\
268f0fec74SPeter Tyser 		"1:	.long 2f\n"	\
278f0fec74SPeter Tyser 		"2:"			\
288f0fec74SPeter Tyser 		: "=&r" (__dummy)	\
298f0fec74SPeter Tyser 		: "r" (0x20000000));	\
308f0fec74SPeter Tyser   } while (0)
318f0fec74SPeter Tyser 
328f0fec74SPeter Tyser /*
338f0fec74SPeter Tyser  * Back to P1 area.
348f0fec74SPeter Tyser  */
358f0fec74SPeter Tyser #define back_to_P1()					\
368f0fec74SPeter Tyser   do {							\
378f0fec74SPeter Tyser     unsigned long __dummy;				\
388f0fec74SPeter Tyser     __asm__ __volatile__(				\
398f0fec74SPeter Tyser 		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
408f0fec74SPeter Tyser 		"mov.l	1f, %0\n\t"			\
418f0fec74SPeter Tyser 		"jmp	@%0\n\t"			\
428f0fec74SPeter Tyser 		" nop\n\t"				\
438f0fec74SPeter Tyser 		".balign 4\n"				\
448f0fec74SPeter Tyser 		"1:	.long 2f\n"			\
458f0fec74SPeter Tyser 		"2:"					\
468f0fec74SPeter Tyser 		: "=&r" (__dummy));			\
478f0fec74SPeter Tyser   } while (0)
488f0fec74SPeter Tyser 
498f0fec74SPeter Tyser #define CACHE_VALID       1
508f0fec74SPeter Tyser #define CACHE_UPDATED     2
518f0fec74SPeter Tyser 
528f0fec74SPeter Tyser static inline void cache_wback_all(void)
538f0fec74SPeter Tyser {
548f0fec74SPeter Tyser 	unsigned long addr, data, i, j;
558f0fec74SPeter Tyser 
568f0fec74SPeter Tyser 	jump_to_P2();
578f0fec74SPeter Tyser 	for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){
588f0fec74SPeter Tyser 		for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
598f0fec74SPeter Tyser 			addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT)
608f0fec74SPeter Tyser 				| (i << CACHE_OC_ENTRY_SHIFT);
618f0fec74SPeter Tyser 			data = inl(addr);
628f0fec74SPeter Tyser 			if (data & CACHE_UPDATED) {
638f0fec74SPeter Tyser 				data &= ~CACHE_UPDATED;
648f0fec74SPeter Tyser 				outl(data, addr);
658f0fec74SPeter Tyser 			}
668f0fec74SPeter Tyser 		}
678f0fec74SPeter Tyser 	}
688f0fec74SPeter Tyser 	back_to_P1();
698f0fec74SPeter Tyser }
708f0fec74SPeter Tyser 
718f0fec74SPeter Tyser 
728f0fec74SPeter Tyser #define CACHE_ENABLE      0
738f0fec74SPeter Tyser #define CACHE_DISABLE     1
748f0fec74SPeter Tyser 
758f0fec74SPeter Tyser int cache_control(unsigned int cmd)
768f0fec74SPeter Tyser {
778f0fec74SPeter Tyser 	unsigned long ccr;
788f0fec74SPeter Tyser 
798f0fec74SPeter Tyser 	jump_to_P2();
808f0fec74SPeter Tyser 	ccr = inl(CCR);
818f0fec74SPeter Tyser 
828f0fec74SPeter Tyser 	if (ccr & CCR_CACHE_ENABLE)
838f0fec74SPeter Tyser 		cache_wback_all();
848f0fec74SPeter Tyser 
858f0fec74SPeter Tyser 	if (cmd == CACHE_DISABLE)
868f0fec74SPeter Tyser 		outl(CCR_CACHE_STOP, CCR);
878f0fec74SPeter Tyser 	else
888f0fec74SPeter Tyser 		outl(CCR_CACHE_INIT, CCR);
898f0fec74SPeter Tyser 	back_to_P1();
908f0fec74SPeter Tyser 
918f0fec74SPeter Tyser 	return 0;
928f0fec74SPeter Tyser }
9317210643SMike Frysinger 
94a633a18fSNobuhiro Iwamatsu void flush_dcache_range(unsigned long start, unsigned long end)
9517210643SMike Frysinger {
9617210643SMike Frysinger 	u32 v;
9717210643SMike Frysinger 
9817210643SMike Frysinger 	start &= ~(L1_CACHE_BYTES - 1);
9917210643SMike Frysinger 	for (v = start; v < end; v += L1_CACHE_BYTES) {
100*ee47c4cbSVladimir Zapolskiy 		asm volatile ("ocbp     %0" :	/* no output */
10117210643SMike Frysinger 			      : "m" (__m(v)));
10217210643SMike Frysinger 	}
10317210643SMike Frysinger }
10417210643SMike Frysinger 
105a633a18fSNobuhiro Iwamatsu void invalidate_dcache_range(unsigned long start, unsigned long end)
10617210643SMike Frysinger {
10717210643SMike Frysinger 	u32 v;
10817210643SMike Frysinger 
10917210643SMike Frysinger 	start &= ~(L1_CACHE_BYTES - 1);
11017210643SMike Frysinger 	for (v = start; v < end; v += L1_CACHE_BYTES) {
11117210643SMike Frysinger 		asm volatile ("ocbi     %0" :	/* no output */
11217210643SMike Frysinger 			      : "m" (__m(v)));
11317210643SMike Frysinger 	}
11417210643SMike Frysinger }
115