cache-sh2.c 2.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 * arch/sh/mm/cache-sh2.c
 *
 * Copyright (C) 2002 Paul Mundt
Y
Yoshinori Sato 已提交
5
 * Copyright (C) 2008 Yoshinori Sato
L
Linus Torvalds 已提交
6 7 8
 *
 * Released under the terms of the GNU GPL v2.0.
 */
9

L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18
#include <linux/init.h>
#include <linux/mm.h>

#include <asm/cache.h>
#include <asm/addrspace.h>
#include <asm/processor.h>
#include <asm/cacheflush.h>
#include <asm/io.h>

19
void __flush_wback_region(void *start, int size)
L
Linus Torvalds 已提交
20
{
21 22 23 24 25 26 27
	unsigned long v;
	unsigned long begin, end;

	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
		& ~(L1_CACHE_BYTES-1);
	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
Y
Yoshinori Sato 已提交
28 29 30 31 32 33 34 35 36
		unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0);
		int way;
		for (way = 0; way < 4; way++) {
			unsigned long data =  ctrl_inl(addr | (way << 12));
			if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
				data &= ~SH_CACHE_UPDATED;
				ctrl_outl(data, addr | (way << 12));
			}
		}
37 38 39 40 41 42 43 44 45 46 47
	}
}

void __flush_purge_region(void *start, int size)
{
	unsigned long v;
	unsigned long begin, end;

	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
		& ~(L1_CACHE_BYTES-1);
Y
Yoshinori Sato 已提交
48 49 50 51

	for (v = begin; v < end; v+=L1_CACHE_BYTES)
		ctrl_outl((v & CACHE_PHYSADDR_MASK),
			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
52 53 54 55
}

void __flush_invalidate_region(void *start, int size)
{
Y
Yoshinori Sato 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#ifdef CONFIG_CACHE_WRITEBACK
	/*
	 * SH-2 does not support individual line invalidation, only a
	 * global invalidate.
	 */
	unsigned long ccr;
	unsigned long flags;
	local_irq_save(flags);
	jump_to_uncached();

	ccr = ctrl_inl(CCR);
	ccr |= CCR_CACHE_INVALIDATE;
	ctrl_outl(ccr, CCR);

	back_to_cached();
	local_irq_restore(flags);
#else
73 74 75 76 77 78
	unsigned long v;
	unsigned long begin, end;

	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
		& ~(L1_CACHE_BYTES-1);
L
Linus Torvalds 已提交
79

Y
Yoshinori Sato 已提交
80 81 82 83 84
	for (v = begin; v < end; v+=L1_CACHE_BYTES)
		ctrl_outl((v & CACHE_PHYSADDR_MASK),
			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
#endif
}