/*
 * sc-rm7k.c: RM7000 cache management functions.
 *
 * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
 */

#undef DEBUG

#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/bitops.h>

#include <asm/addrspace.h>
#include <asm/bcache.h>
#include <asm/cacheops.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/cacheflush.h> /* for run_uncached() */

/* Primary cache parameters. */
#define sc_lsize	32
#define tc_pagesize	(32*128)

/* Secondary cache parameters. */
#define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */

/* Tertiary cache parameters */
#define tc_lsize	32

extern unsigned long icache_way_size, dcache_way_size;
static unsigned long tcache_size;

#include <asm/r4kcache.h>

static int rm7k_tcache_init;

/*
 * Writeback and invalidate the primary cache dcache before DMA.
 * (XXX These need to be fixed ...)
 */
static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size)
{
	unsigned long end, a;

	pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);

	/* Catch bad driver code */
	BUG_ON(size == 0);

	blast_scache_range(addr, addr + size);

	if (!rm7k_tcache_init)
		return;

	a = addr & ~(tc_pagesize - 1);
	end = (addr + size - 1) & ~(tc_pagesize - 1);
	while(1) {
		invalidate_tcache_page(a);	/* Page_Invalidate_T */
		if (a == end)
			break;
		a += tc_pagesize;
	}
}

static void rm7k_sc_inv(unsigned long addr, unsigned long size)
{
	unsigned long end, a;

	pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size);

	/* Catch bad driver code */
	BUG_ON(size == 0);

	blast_inv_scache_range(addr, addr + size);

	if (!rm7k_tcache_init)
		return;

	a = addr & ~(tc_pagesize - 1);
	end = (addr + size - 1) & ~(tc_pagesize - 1);
	while(1) {
		invalidate_tcache_page(a);	/* Page_Invalidate_T */
		if (a == end)
			break;
		a += tc_pagesize;
	}
}

static void blast_rm7k_tcache(void)
{
	unsigned long start = CKSEG0ADDR(0);
	unsigned long end = start + tcache_size;

	write_c0_taglo(0);

	while (start < end) {
		cache_op(Page_Invalidate_T, start);
		start += tc_pagesize;
	}
}

/*
 * This function is executed in uncached address space.
 */
static void __rm7k_tc_enable(void)
{
	int i;

	set_c0_config(RM7K_CONF_TE);

	write_c0_taglo(0);
	write_c0_taghi(0);

	for (i = 0; i < tcache_size; i += tc_lsize)
		cache_op(Index_Store_Tag_T, CKSEG0ADDR(i));
}

static void rm7k_tc_enable(void)
{
	if (read_c0_config() & RM7K_CONF_TE)
		return;

	BUG_ON(tcache_size == 0);

	run_uncached(__rm7k_tc_enable);
}

/*
 * This function is executed in uncached address space.
 */
static void __rm7k_sc_enable(void)
{
	int i;

	set_c0_config(RM7K_CONF_SE);

	write_c0_taglo(0);
	write_c0_taghi(0);

	for (i = 0; i < scache_size; i += sc_lsize)
		cache_op(Index_Store_Tag_SD, CKSEG0ADDR(i));
}

static void rm7k_sc_enable(void)
{
	if (read_c0_config() & RM7K_CONF_SE)
		return;

	pr_info("Enabling secondary cache...\n");
	run_uncached(__rm7k_sc_enable);

	if (rm7k_tcache_init)
		rm7k_tc_enable();
}

static void rm7k_tc_disable(void)
{
	unsigned long flags;

	local_irq_save(flags);
	blast_rm7k_tcache();
	clear_c0_config(RM7K_CONF_TE);
	local_irq_restore(flags);
}

static void rm7k_sc_disable(void)
{
	clear_c0_config(RM7K_CONF_SE);

	if (rm7k_tcache_init)
		rm7k_tc_disable();
}

static struct bcache_ops rm7k_sc_ops = {
	.bc_enable = rm7k_sc_enable,
	.bc_disable = rm7k_sc_disable,
	.bc_wback_inv = rm7k_sc_wback_inv,
	.bc_inv = rm7k_sc_inv
};

/*
 * This is a probing function like the one found in c-r4k.c, we look for the
 * wrap around point with different addresses.
 */
static void __probe_tcache(void)
{
	unsigned long flags, addr, begin, end, pow2;

	begin = (unsigned long) &_stext;
	begin  &= ~((8 * 1024 * 1024) - 1);
	end = begin + (8 * 1024 * 1024);

	local_irq_save(flags);

	set_c0_config(RM7K_CONF_TE);

	/* Fill size-multiple lines with a valid tag */
	pow2 = (256 * 1024);
	for (addr = begin; addr <= end; addr = (begin + pow2)) {
		unsigned long *p = (unsigned long *) addr;
		__asm__ __volatile__("nop" : : "r" (*p));
		pow2 <<= 1;
	}

	/* Load first line with a 0 tag, to check after */
	write_c0_taglo(0);
	write_c0_taghi(0);
	cache_op(Index_Store_Tag_T, begin);

	/* Look for the wrap-around */
	pow2 = (512 * 1024);
	for (addr = begin + (512 * 1024); addr <= end; addr = begin + pow2) {
		cache_op(Index_Load_Tag_T, addr);
		if (!read_c0_taglo())
			break;
		pow2 <<= 1;
	}

	addr -= begin;
	tcache_size = addr;

	clear_c0_config(RM7K_CONF_TE);

	local_irq_restore(flags);
}

void rm7k_sc_init(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;
	unsigned int config = read_c0_config();

	if ((config & RM7K_CONF_SC))
		return;

	c->scache.linesz = sc_lsize;
	c->scache.ways = 4;
	c->scache.waybit= __ffs(scache_size / c->scache.ways);
	c->scache.waysize = scache_size / c->scache.ways;
	c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
	printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
	       (scache_size >> 10), sc_lsize);

	if (!(config & RM7K_CONF_SE))
		rm7k_sc_enable();

	bcops = &rm7k_sc_ops;

	/*
	 * While we're at it let's deal with the tertiary cache.
	 */

	rm7k_tcache_init = 0;
	tcache_size = 0;

	if (config & RM7K_CONF_TC)
		return;

	/*
	 * No efficient way to ask the hardware for the size of the tcache,
	 * so must probe for it.
	 */
	run_uncached(__probe_tcache);
	rm7k_tc_enable();
	rm7k_tcache_init = 1;
	c->tcache.linesz = tc_lsize;
	c->tcache.ways = 1;
	pr_info("Tertiary cache size %ldK.\n", (tcache_size >> 10));
}
