18beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek/*
28beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * Cache control for MicroBlaze cache memories
38beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek *
48beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
58beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * Copyright (C) 2007-2009 PetaLogix
62ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek * Copyright (C) 2007-2009 John Williams <john.williams@petalogix.com>
78beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek *
88beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * This file is subject to the terms and conditions of the GNU General
98beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * Public License. See the file COPYING in the main directory of this
108beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek * archive for more details.
118beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek */
128beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
138beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek#include <asm/cacheflush.h>
148beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek#include <linux/cache.h>
158beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek#include <asm/cpuinfo.h>
162ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#include <asm/pvr.h>
178beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
182ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __enable_icache_msr(void)
198beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
202ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	msrset	r0, %0;		\
212ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
222ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			: : "i" (MSR_ICE) : "memory");
232ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
242ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
252ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __disable_icache_msr(void)
262ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
272ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	msrclr	r0, %0;		\
282ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
292ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			: : "i" (MSR_ICE) : "memory");
302ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
312ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
322ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __enable_dcache_msr(void)
332ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	msrset	r0, %0;		\
352ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_DCE)		\
388beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek				: "memory");
398beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
408beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
412ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __disable_dcache_msr(void)
428beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
432ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	msrclr	r0, %0;		\
442ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
452ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
462ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_DCE)		\
478beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek				: "memory");
482ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
492ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __enable_icache_nomsr(void)
512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop;			\
542ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				ori	r12, r12, %0;	\
552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mts	rmsr, r12;	\
562ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
572ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
582ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_ICE)		\
598beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek				: "memory", "r12");
608beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
618beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
622ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __disable_icache_nomsr(void)
638beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
642ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
652ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop;			\
662ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				andi	r12, r12, ~%0;	\
672ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mts	rmsr, r12;	\
682ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
692ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
702ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_ICE)		\
712ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "memory", "r12");
728beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
738beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
742ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __enable_dcache_nomsr(void)
758beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
762ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
772ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop;			\
782ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				ori	r12, r12, %0;	\
792ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mts	rmsr, r12;	\
802ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
812ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
822ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_DCE)		\
838beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek				: "memory", "r12");
848beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
858beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
862ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic inline void __disable_dcache_nomsr(void)
878beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
882ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ ("	mfs	r12, rmsr;	\
892ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop;			\
902ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				andi	r12, r12, ~%0;	\
912ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mts	rmsr, r12;	\
922ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				nop; "			\
932ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				:			\
942ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				: "i" (MSR_DCE)		\
958beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek				: "memory", "r12");
968beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
978beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
982ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
993274c5707c22221574b396d140d0db3480a2027aMichal Simek/* Helper macro for computing the limits of cache range loops
1003274c5707c22221574b396d140d0db3480a2027aMichal Simek *
1013274c5707c22221574b396d140d0db3480a2027aMichal Simek * End address can be unaligned which is OK for C implementation.
1023274c5707c22221574b396d140d0db3480a2027aMichal Simek * ASM implementation align it in ASM macros
1033274c5707c22221574b396d140d0db3480a2027aMichal Simek */
1042ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)	\
1052ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekdo {									\
1062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	int align = ~(cache_line_length - 1);				\
1072ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	end = min(start + cache_size, end);				\
1082ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	start &= align;							\
1092ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek} while (0);
1102ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
1112ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/*
1122ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek * Helper macro to loop over the specified cache_size/line_length and
1132ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek * execute 'op' on that cacheline
1142ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek */
1152ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CACHE_ALL_LOOP(cache_size, line_length, op)			\
1162ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekdo {									\
1173274c5707c22221574b396d140d0db3480a2027aMichal Simek	unsigned int len = cache_size - line_length;			\
1182ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	int step = -line_length;					\
1193274c5707c22221574b396d140d0db3480a2027aMichal Simek	WARN_ON(step >= 0);						\
1202ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek									\
1212ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__asm__ __volatile__ (" 1:      " #op " %0, r0;			\
1222ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					bgtid   %0, 1b;			\
1232ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					addk    %0, %0, %1;		\
1242ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					" : : "r" (len), "r" (step)	\
1252ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					: "memory");			\
1262ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek} while (0);
1272ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
1283274c5707c22221574b396d140d0db3480a2027aMichal Simek/* Used for wdc.flush/clear which can use rB for offset which is not possible
1293274c5707c22221574b396d140d0db3480a2027aMichal Simek * to use for simple wdc or wic.
1303274c5707c22221574b396d140d0db3480a2027aMichal Simek *
1313274c5707c22221574b396d140d0db3480a2027aMichal Simek * start address is cache aligned
13225985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * end address is not aligned, if end is aligned then I have to subtract
1333274c5707c22221574b396d140d0db3480a2027aMichal Simek * cacheline length because I can't flush/invalidate the next cacheline.
1343274c5707c22221574b396d140d0db3480a2027aMichal Simek * If is not, I align it because I will flush/invalidate whole line.
1353274c5707c22221574b396d140d0db3480a2027aMichal Simek */
1362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CACHE_RANGE_LOOP_2(start, end, line_length, op)			\
1372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekdo {									\
1382ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	int step = -line_length;					\
1393274c5707c22221574b396d140d0db3480a2027aMichal Simek	int align = ~(line_length - 1);					\
140ddfbc935eae68294834dc29998f93147a5422a0dMichal Simek	int count;							\
1413274c5707c22221574b396d140d0db3480a2027aMichal Simek	end = ((end & align) == end) ? end - line_length : end & align;	\
142ddfbc935eae68294834dc29998f93147a5422a0dMichal Simek	count = end - start;						\
1433274c5707c22221574b396d140d0db3480a2027aMichal Simek	WARN_ON(count < 0);						\
1442ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek									\
14522607a28213068af113b46862eafa785f00a482eMichal Simek	__asm__ __volatile__ (" 1:	" #op "	%0, %1;			\
14622607a28213068af113b46862eafa785f00a482eMichal Simek					bgtid	%1, 1b;			\
14722607a28213068af113b46862eafa785f00a482eMichal Simek					addk	%1, %1, %2;		\
1482ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					" : : "r" (start), "r" (count),	\
1492ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek					"r" (step) : "memory");		\
1502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek} while (0);
1512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
1522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* It is used only first parameter for OP - for wic, wdc */
1532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CACHE_RANGE_LOOP_1(start, end, line_length, op)			\
1542ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekdo {									\
1550d670b24729be268eba98b3920b8571f60798d8dMichal Simek	int volatile temp;						\
1563274c5707c22221574b396d140d0db3480a2027aMichal Simek	int align = ~(line_length - 1);					\
1573274c5707c22221574b396d140d0db3480a2027aMichal Simek	end = ((end & align) == end) ? end - line_length : end & align;	\
1583274c5707c22221574b396d140d0db3480a2027aMichal Simek	WARN_ON(end - start < 0);					\
1592ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek									\
16022607a28213068af113b46862eafa785f00a482eMichal Simek	__asm__ __volatile__ (" 1:	" #op "	%1, r0;			\
1610d670b24729be268eba98b3920b8571f60798d8dMichal Simek					cmpu	%0, %1, %2;		\
1620d670b24729be268eba98b3920b8571f60798d8dMichal Simek					bgtid	%0, 1b;			\
1630d670b24729be268eba98b3920b8571f60798d8dMichal Simek					addk	%1, %1, %3;		\
1640d670b24729be268eba98b3920b8571f60798d8dMichal Simek				" : : "r" (temp), "r" (start), "r" (end),\
1650d670b24729be268eba98b3920b8571f60798d8dMichal Simek					"r" (line_length) : "memory");	\
1662ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek} while (0);
1672ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
16822607a28213068af113b46862eafa785f00a482eMichal Simek#define ASM_LOOP
16922607a28213068af113b46862eafa785f00a482eMichal Simek
1702ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
1718beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
1722ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
17322607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
17422607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
17522607a28213068af113b46862eafa785f00a482eMichal Simek#endif
1762ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
1772ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
1782ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
1792ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
1802ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.icache_line_length, cpuinfo.icache_size);
1812ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
1822ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
1832ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_icache_msr();
1842ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
18522607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
1862ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
18722607a28213068af113b46862eafa785f00a482eMichal Simek#else
18822607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = start; i < end; i += cpuinfo.icache_line_length)
18922607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wic	%0, r0;"	\
19022607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
19122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
1922ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_icache_msr();
1932ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
1948beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
1958beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
1962ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_range_nomsr_irq(unsigned long start,
1972ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				unsigned long end)
1988beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
1992ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
20022607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
20122607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
20222607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2032ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
2042ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
2058beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
2062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
2072ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.icache_line_length, cpuinfo.icache_size);
2088beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
2092ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
2102ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_icache_nomsr();
2112ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
21222607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
2132ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
21422607a28213068af113b46862eafa785f00a482eMichal Simek#else
21522607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = start; i < end; i += cpuinfo.icache_line_length)
21622607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wic	%0, r0;"	\
21722607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
21822607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2192ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2202ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_icache_nomsr();
2212ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
2228beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
2238beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
2242ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_range_noirq(unsigned long start,
2252ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				unsigned long end)
2268beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
22722607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
22822607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
22922607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2302ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
2312ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
2322ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2332ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
2342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.icache_line_length, cpuinfo.icache_size);
23522607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
2362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic);
23722607a28213068af113b46862eafa785f00a482eMichal Simek#else
23822607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = start; i < end; i += cpuinfo.icache_line_length)
23922607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wic	%0, r0;"	\
24022607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
24122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2422ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
2432ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2442ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_all_msr_irq(void)
2452ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
2462ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
24722607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
24822607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
24922607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
2512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
2532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_icache_msr();
25422607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
2552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
25622607a28213068af113b46862eafa785f00a482eMichal Simek#else
25722607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.icache_size;
25822607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.icache_line_length)
25922607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wic	%0, r0;" \
26022607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
26122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2622ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_icache_msr();
2632ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
2642ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
2652ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2662ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_all_nomsr_irq(void)
2672ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
2682ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
26922607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
27022607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
27122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2722ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
2732ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
2742ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
2752ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_icache_nomsr();
27622607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
2772ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
27822607a28213068af113b46862eafa785f00a482eMichal Simek#else
27922607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.icache_size;
28022607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.icache_line_length)
28122607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wic	%0, r0;" \
28222607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
28322607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2842ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_icache_nomsr();
2852ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
2868beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
2878beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
2882ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_icache_all_noirq(void)
2898beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
29022607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
29122607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
29222607a28213068af113b46862eafa785f00a482eMichal Simek#endif
2932ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
29422607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
2952ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic);
29622607a28213068af113b46862eafa785f00a482eMichal Simek#else
29722607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.icache_size;
29822607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.icache_line_length)
29922607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wic	%0, r0;" \
30022607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
30122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3028beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
3038beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
3042ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_all_msr_irq(void)
3058beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
3062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
30722607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
30822607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
30922607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3102ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
3112ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
3122ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
3132ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_dcache_msr();
31422607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
3152ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
31622607a28213068af113b46862eafa785f00a482eMichal Simek#else
31722607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.dcache_size;
31822607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.dcache_line_length)
31922607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wdc	%0, r0;" \
32022607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
32122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3222ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_dcache_msr();
3232ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
3248beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
3258beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
3262ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_all_nomsr_irq(void)
3278beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
3282ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
32922607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
33022607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
33122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3322ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
3332ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
3342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
3352ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_dcache_nomsr();
33622607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
3372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
33822607a28213068af113b46862eafa785f00a482eMichal Simek#else
33922607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.dcache_size;
34022607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.dcache_line_length)
34122607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wdc	%0, r0;" \
34222607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
34322607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3442ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_dcache_nomsr();
3452ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
3468beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
3478beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
3482ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_all_noirq_wt(void)
3498beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
35022607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
35122607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
35222607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
35422607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
3552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
35622607a28213068af113b46862eafa785f00a482eMichal Simek#else
35722607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.dcache_size;
35822607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.dcache_line_length)
35922607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wdc	%0, r0;" \
36022607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
36122607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3628beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
3638beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
3643274c5707c22221574b396d140d0db3480a2027aMichal Simek/* FIXME It is blindly invalidation as is expected
3653274c5707c22221574b396d140d0db3480a2027aMichal Simek * but can't be called on noMMU in microblaze_cache_init below
3663274c5707c22221574b396d140d0db3480a2027aMichal Simek *
3673274c5707c22221574b396d140d0db3480a2027aMichal Simek * MS: noMMU kernel won't boot if simple wdc is used
3683274c5707c22221574b396d140d0db3480a2027aMichal Simek * The reason should be that there are discared data which kernel needs
3693274c5707c22221574b396d140d0db3480a2027aMichal Simek */
3702ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_all_wb(void)
3718beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
37222607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
37322607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
37422607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3752ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
37622607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
3773274c5707c22221574b396d140d0db3480a2027aMichal Simek	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
3783274c5707c22221574b396d140d0db3480a2027aMichal Simek					wdc)
37922607a28213068af113b46862eafa785f00a482eMichal Simek#else
38022607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.dcache_size;
38122607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.dcache_line_length)
3823274c5707c22221574b396d140d0db3480a2027aMichal Simek			__asm__ __volatile__ ("wdc	%0, r0;" \
38322607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
38422607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3852ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
3862ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
3872ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_range_wb(unsigned long start,
3882ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek						unsigned long end)
3892ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
39022607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
39122607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
39222607a28213068af113b46862eafa785f00a482eMichal Simek#endif
3932ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
3942ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
3952ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
3962ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
3972ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
39822607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
3992ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
40022607a28213068af113b46862eafa785f00a482eMichal Simek#else
401c17e1a1cedb723d48d4822cae1af1c010b608b5cMichal Simek	for (i = start; i < end; i += cpuinfo.dcache_line_length)
40222607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wdc.clear	%0, r0;"	\
40322607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
40422607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4052ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
4062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4072ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_range_nomsr_wt(unsigned long start,
4082ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek							unsigned long end)
4092ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
41022607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
41122607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
41222607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4132ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
4142ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
4152ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
4162ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
4172ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
41822607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
4192ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
42022607a28213068af113b46862eafa785f00a482eMichal Simek#else
421c17e1a1cedb723d48d4822cae1af1c010b608b5cMichal Simek	for (i = start; i < end; i += cpuinfo.dcache_line_length)
42222607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wdc	%0, r0;"	\
42322607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
42422607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4258beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
4268beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
4272ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
4282ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek							unsigned long end)
4298beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
4302ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
43122607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
43222607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
43322607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
4352ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
4362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
4372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
4382ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4392ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
4402ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_dcache_msr();
4412ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
44222607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
4432ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
44422607a28213068af113b46862eafa785f00a482eMichal Simek#else
445c17e1a1cedb723d48d4822cae1af1c010b608b5cMichal Simek	for (i = start; i < end; i += cpuinfo.dcache_line_length)
44622607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wdc	%0, r0;"	\
44722607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
44822607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4492ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_dcache_msr();
4512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
4522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
4532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4542ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __invalidate_dcache_range_nomsr_irq(unsigned long start,
4552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek							unsigned long end)
4562ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
4572ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	unsigned long flags;
45822607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
45922607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
46022607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4612ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
4622ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
4632ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4642ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
4652ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
4662ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4672ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_save(flags);
4682ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__disable_dcache_nomsr();
4692ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
47022607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
4712ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
47222607a28213068af113b46862eafa785f00a482eMichal Simek#else
473c17e1a1cedb723d48d4822cae1af1c010b608b5cMichal Simek	for (i = start; i < end; i += cpuinfo.dcache_line_length)
47422607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wdc	%0, r0;"	\
47522607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
47622607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4772ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4782ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	__enable_dcache_nomsr();
4792ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	local_irq_restore(flags);
4802ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
4812ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
4822ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_dcache_all_wb(void)
4832ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
48422607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
48522607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
48622607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4872ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s\n", __func__);
48822607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
4892ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
4902ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				wdc.flush);
49122607a28213068af113b46862eafa785f00a482eMichal Simek#else
49222607a28213068af113b46862eafa785f00a482eMichal Simek	for (i = 0; i < cpuinfo.dcache_size;
49322607a28213068af113b46862eafa785f00a482eMichal Simek		 i += cpuinfo.dcache_line_length)
49422607a28213068af113b46862eafa785f00a482eMichal Simek			__asm__ __volatile__ ("wdc.flush	%0, r0;" \
49522607a28213068af113b46862eafa785f00a482eMichal Simek					: : "r" (i));
49622607a28213068af113b46862eafa785f00a482eMichal Simek#endif
4978beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
4988beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek
4992ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstatic void __flush_dcache_range_wb(unsigned long start, unsigned long end)
5008beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek{
50122607a28213068af113b46862eafa785f00a482eMichal Simek#ifndef ASM_LOOP
50222607a28213068af113b46862eafa785f00a482eMichal Simek	int i;
50322607a28213068af113b46862eafa785f00a482eMichal Simek#endif
5042ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	pr_debug("%s: start 0x%x, end 0x%x\n", __func__,
5052ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				(unsigned int)start, (unsigned int) end);
5062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5072ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_LOOP_LIMITS(start, end,
5082ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			cpuinfo.dcache_line_length, cpuinfo.dcache_size);
50922607a28213068af113b46862eafa785f00a482eMichal Simek#ifdef ASM_LOOP
5102ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
51122607a28213068af113b46862eafa785f00a482eMichal Simek#else
512c17e1a1cedb723d48d4822cae1af1c010b608b5cMichal Simek	for (i = start; i < end; i += cpuinfo.dcache_line_length)
51322607a28213068af113b46862eafa785f00a482eMichal Simek		__asm__ __volatile__ ("wdc.flush	%0, r0;"	\
51422607a28213068af113b46862eafa785f00a482eMichal Simek				: : "r" (i));
51522607a28213068af113b46862eafa785f00a482eMichal Simek#endif
5162ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek}
5172ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5182ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* struct for wb caches and for wt caches */
5192ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekstruct scache *mbc;
5202ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5212ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* new wb cache model */
522954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wb_msr = {
5232ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_msr,
5242ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_msr,
5252ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_noirq,
5262ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_noirq,
5272ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_noirq,
5282ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_noirq,
5292ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_msr,
5302ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_msr,
5312ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __flush_dcache_all_wb,
5322ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __flush_dcache_range_wb,
5332ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_wb,
5342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_wb,
5352ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
5362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* There is only difference in ie, id, de, dd functions */
538954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wb_nomsr = {
5392ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_nomsr,
5402ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_nomsr,
5412ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_noirq,
5422ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_noirq,
5432ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_noirq,
5442ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_noirq,
5452ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_nomsr,
5462ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_nomsr,
5472ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __flush_dcache_all_wb,
5482ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __flush_dcache_range_wb,
5492ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_wb,
5502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_wb,
5512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
5522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* Old wt cache model with disabling irq and turn off cache */
554954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wt_msr = {
5552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_msr,
5562ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_msr,
5572ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_msr_irq,
5582ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_msr_irq,
5592ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_msr_irq,
5602ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_msr_irq,
5612ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_msr,
5622ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_msr,
5632ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __invalidate_dcache_all_msr_irq,
5642ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __invalidate_dcache_range_msr_irq_wt,
5652ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_msr_irq,
5662ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_msr_irq_wt,
5672ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
5682ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
569954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wt_nomsr = {
5702ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_nomsr,
5712ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_nomsr,
5722ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_nomsr_irq,
5732ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_nomsr_irq,
5742ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_nomsr_irq,
5752ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_nomsr_irq,
5762ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_nomsr,
5772ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_nomsr,
5782ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __invalidate_dcache_all_nomsr_irq,
5792ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __invalidate_dcache_range_nomsr_irq,
5802ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_nomsr_irq,
5812ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_nomsr_irq,
5822ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
5832ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
5842ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* New wt cache model for newer Microblaze versions */
585954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wt_msr_noirq = {
5862ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_msr,
5872ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_msr,
5882ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_noirq,
5892ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_noirq,
5902ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_noirq,
5912ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_noirq,
5922ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_msr,
5932ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_msr,
5942ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __invalidate_dcache_all_noirq_wt,
5952ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __invalidate_dcache_range_nomsr_wt,
5962ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_noirq_wt,
5972ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_nomsr_wt,
5982ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
5992ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
600954e8b9599d64a959fe81cfaa8b0e0ee6387271cMichal Simekstatic const struct scache wt_nomsr_noirq = {
6012ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ie = __enable_icache_nomsr,
6022ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.id = __disable_icache_nomsr,
6032ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.ifl = __flush_icache_all_noirq,
6042ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iflr = __flush_icache_range_noirq,
6052ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iin = __flush_icache_all_noirq,
6062ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.iinr = __flush_icache_range_noirq,
6072ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.de = __enable_dcache_nomsr,
6082ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dd = __disable_dcache_nomsr,
6092ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dfl = __invalidate_dcache_all_noirq_wt,
6102ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dflr = __invalidate_dcache_range_nomsr_wt,
6112ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.din = __invalidate_dcache_all_noirq_wt,
6122ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	.dinr = __invalidate_dcache_range_nomsr_wt,
6132ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek};
6142ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
6152ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek/* CPU version code for 7.20.c - see arch/microblaze/kernel/cpu/cpuinfo.c */
6162ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CPUVER_7_20_A	0x0c
6172ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek#define CPUVER_7_20_D	0x0f
6182ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
6194c912c1a33abb67aefecb5ed8bd73d91887c4977Frans Pop#define INFO(s)	printk(KERN_INFO "cache: " s "\n");
6202ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek
6212ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simekvoid microblaze_cache_init(void)
6222ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek{
6232ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
6242ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		if (cpuinfo.dcache_wb) {
6252ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			INFO("wb_msr");
6262ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			mbc = (struct scache *)&wb_msr;
627b9dc9e7781f1c3e85e0d1b8044021fa8974422b1Michal Simek			if (cpuinfo.ver_code <= CPUVER_7_20_D) {
6282ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				/* MS: problem with signal handling - hw bug */
6292ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("WB won't work properly");
6302ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			}
6312ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		} else {
6322ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
6332ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("wt_msr_noirq");
6342ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mbc = (struct scache *)&wt_msr_noirq;
6352ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			} else {
6362ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("wt_msr");
6372ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mbc = (struct scache *)&wt_msr;
6382ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			}
6392ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		}
6402ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	} else {
6412ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		if (cpuinfo.dcache_wb) {
6422ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			INFO("wb_nomsr");
6432ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			mbc = (struct scache *)&wb_nomsr;
644b9dc9e7781f1c3e85e0d1b8044021fa8974422b1Michal Simek			if (cpuinfo.ver_code <= CPUVER_7_20_D) {
6452ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				/* MS: problem with signal handling - hw bug */
6462ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("WB won't work properly");
6472ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			}
6482ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		} else {
6492ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			if (cpuinfo.ver_code >= CPUVER_7_20_A) {
6502ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("wt_nomsr_noirq");
6512ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mbc = (struct scache *)&wt_nomsr_noirq;
6522ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			} else {
6532ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				INFO("wt_nomsr");
6542ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek				mbc = (struct scache *)&wt_nomsr;
6552ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek			}
6562ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek		}
6572ee2ff875a4d3bdb941e2bb1173cd927c09d5a67Michal Simek	}
6583274c5707c22221574b396d140d0db3480a2027aMichal Simek/* FIXME Invalidation is done in U-BOOT
6593274c5707c22221574b396d140d0db3480a2027aMichal Simek * WT cache: Data is already written to main memory
6603274c5707c22221574b396d140d0db3480a2027aMichal Simek * WB cache: Discard data on noMMU which caused that kernel doesn't boot
6613274c5707c22221574b396d140d0db3480a2027aMichal Simek */
6623274c5707c22221574b396d140d0db3480a2027aMichal Simek	/* invalidate_dcache(); */
663407c1da07d5afa001ed0fdb8f379c00bbd09990aMichal Simek	enable_dcache();
664407c1da07d5afa001ed0fdb8f379c00bbd09990aMichal Simek
665407c1da07d5afa001ed0fdb8f379c00bbd09990aMichal Simek	invalidate_icache();
666407c1da07d5afa001ed0fdb8f379c00bbd09990aMichal Simek	enable_icache();
6678beb8503bfa305cd7d9efa590517a9c01e2f97b4Michal Simek}
668