/*
 * Copyright (C) 2009 Broadcom Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/pfn.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/highmem.h>

#include <asm/barrier.h>
#include <asm/bcache.h>
#include <asm/bootinfo.h>
#include <asm/cache.h>
#include <asm/cacheops.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/r4kcache.h>
#include <asm/mmu_context.h>
#include <asm/war.h>
#include <asm/cacheflush.h>
#include <linux/brcmstb/brcmstb.h>
#include <dma-coherence.h>

/*
 * R4K-style cache flush functions
 *
 * BMIPS5000 uses an optimized implementation from this file
 * Everything uses uses a mostly-stock c-r4k.c
 */

#if !defined(CONFIG_CPU_BMIPS5000)
#include "c-r4k.c"
#else /* !defined(CONFIG_CPU_BMIPS5000) */

static unsigned long icache_size __read_mostly;
static unsigned long dcache_size __read_mostly;
static unsigned long scache_size __read_mostly;

/*
 * Dummy cache handling routines for machines without boardcaches
 */
static void cache_noop(void) {}

static struct bcache_ops no_sc_ops = {
	.bc_enable = (void *)cache_noop,
	.bc_disable = (void *)cache_noop,
	.bc_wback_inv = (void *)cache_noop,
	.bc_inv = (void *)cache_noop,
};

struct bcache_ops *bcops = &no_sc_ops;

static void (* r4k_blast_dcache_page)(unsigned long addr);
static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
static void (* r4k_blast_icache_page)(unsigned long addr);
static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
static void (* r4k_blast_scache_page)(unsigned long addr);
static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
static void (* r4k_blast_scache)(void);

void (* r4k_blast_dcache)(void);
EXPORT_SYMBOL(r4k_blast_dcache);

void (* r4k_blast_icache)(void);
EXPORT_SYMBOL(r4k_blast_icache);

static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
{
	blast_dcache32_page(addr);
}

static void r4k___flush_cache_all(void)
{
	/* L2 flush implicitly flushes L1 */
	r4k_blast_scache();
	__sync();
}

static void r4k_noop(void)
{
}

static void r4k_instruction_hazard(void)
{
	__sync();
	__sync();
	__asm__ __volatile__(
	"	nop; nop; nop; nop; nop; nop; nop; nop\n"
	"	nop; nop; nop; nop; nop; nop; nop; nop\n"
	"	nop; nop; nop; nop; nop; nop; nop; nop\n"
	"	nop; nop; nop; nop; nop; nop; nop; nop\n"
	: : : "memory");
}

static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{
	/* Catch bad driver code */
	BUG_ON(size == 0);

	/* L2 flush implicitly flushes L1 */
	if (size >= scache_size)
		r4k_blast_scache();
	else
		bc_wback_inv(addr, size);

	__sync();
}

static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
};

static void __cpuinit probe_pcache(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;
	unsigned int config = read_c0_config();
	unsigned long config1;
	unsigned int lsize;

	switch (c->cputype) {
	default:
		if (!(config & MIPS_CONF_M))
			panic("Don't know how to probe P-caches on this cpu.");

		/*
		 * So we seem to be a MIPS32 or MIPS64 CPU
		 * So let's probe the I-cache ...
		 */
		config1 = read_c0_config1();

		if ((lsize = ((config1 >> 19) & 7)))
			c->icache.linesz = 2 << lsize;
		else
			c->icache.linesz = lsize;
		c->icache.sets = 64 << ((config1 >> 22) & 7);
		c->icache.ways = 1 + ((config1 >> 16) & 7);

		icache_size = c->icache.sets *
		              c->icache.ways *
		              c->icache.linesz;
		c->icache.waybit = __ffs(icache_size/c->icache.ways);

		if (config & 0x8)		/* VI bit */
			c->icache.flags |= MIPS_CACHE_VTAG;

		/*
		 * Now probe the MIPS32 / MIPS64 data cache.
		 */
		c->dcache.flags = 0;

		if ((lsize = ((config1 >> 10) & 7)))
			c->dcache.linesz = 2 << lsize;
		else
			c->dcache.linesz= lsize;
		c->dcache.sets = 64 << ((config1 >> 13) & 7);
		c->dcache.ways = 1 + ((config1 >> 7) & 7);

		dcache_size = c->dcache.sets *
		              c->dcache.ways *
		              c->dcache.linesz;
		c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);

		c->options |= MIPS_CPU_PREFETCH;
		break;
	}

	/* compute a couple of other cache variables */
	c->icache.waysize = icache_size / c->icache.ways;
	c->dcache.waysize = dcache_size / c->dcache.ways;

	c->icache.sets = c->icache.linesz ?
		icache_size / (c->icache.linesz * c->icache.ways) : 0;
	c->dcache.sets = c->dcache.linesz ?
		dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;

	printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
	       icache_size >> 10,
	       cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
	       way_string[c->icache.ways], c->icache.linesz);

	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
	       dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);
}

extern int mips_sc_init(void);

static void __cpuinit setup_scache(void)
{
	struct cpuinfo_mips *c = &current_cpu_data;

	if (mips_sc_init ()) {
		scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
		printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",
		       scache_size >> 10,
		       way_string[c->scache.ways], c->scache.linesz);
	} else {
		panic("c-r4k cache functions require L2 enabled");
	}
	return;
}

static int __cpuinitdata cca = -1;

static int __init cca_setup(char *str)
{
	get_option(&str, &cca);

	return 1;
}

__setup("cca=", cca_setup);

static void __cpuinit coherency_setup(void)
{
	if (cca < 0 || cca > 7)
		cca = read_c0_config() & CONF_CM_CMASK;
	_page_cachable_default = cca << _CACHE_SHIFT;

	pr_debug("Using cache attribute %d\n", cca);
	change_c0_config(CONF_CM_CMASK, cca);
}

void __cpuinit r4k_cache_init(void)
{
	extern void build_clear_page(void);
	extern void build_copy_page(void);
	extern char except_vec2_generic;

	/* Default cache error handler for R4000 and R5000 family */
	set_uncached_handler (0x100, &except_vec2_generic, 0x80);

	probe_pcache();
	setup_scache();

	BUG_ON(cpu_icache_line_size() != 64);
	BUG_ON(cpu_dcache_line_size() != 32);
	BUG_ON(cpu_scache_line_size() != 128);

	r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
	r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
	r4k_blast_dcache = blast_dcache32;
	r4k_blast_icache_page = blast_icache64_page;
	r4k_blast_icache_page_indexed = blast_icache64_page_indexed;
	r4k_blast_icache = blast_icache64;
	r4k_blast_scache_page = blast_scache128_page;
	r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
	r4k_blast_scache = blast_scache128;

	/* SWLINUX-2630: align to the way size (8KB) on Zephyr */
	shm_align_mask = max_t(unsigned long,
			       current_cpu_data.dcache.waysize, PAGE_SIZE) - 1;

	__flush_cache_vmap	= r4k___flush_cache_all;
	__flush_cache_vunmap	= r4k___flush_cache_all;

	flush_cache_all		= (void *)r4k_noop;
	__flush_cache_all	= r4k___flush_cache_all;
	flush_cache_mm		= (void *)r4k_noop;
	flush_cache_page	= (void *)r4k_instruction_hazard;
	flush_cache_range	= (void *)r4k_instruction_hazard;

	flush_cache_sigtramp	= (void *)r4k_noop;
	flush_icache_all	= (void *)r4k_noop;
	local_flush_data_cache_page	= (void *)r4k_instruction_hazard;
	flush_data_cache_page	= (void *)r4k_instruction_hazard;
	flush_icache_range	= (void *)r4k_instruction_hazard;
	local_flush_icache_range	= (void *)r4k_instruction_hazard;

	_dma_cache_wback_inv	= r4k_dma_cache_wback_inv;
	_dma_cache_wback	= r4k_dma_cache_wback_inv;
	_dma_cache_inv		= r4k_dma_cache_wback_inv;

	build_clear_page();
	build_copy_page();
	r4k___flush_cache_all();
	coherency_setup();
}

#endif /* !defined(CONFIG_CPU_BMIPS5000) */

/*
 * Fine-grained cacheflush() syscall for usermode Nexus
 */
int brcm_cacheflush(unsigned long addr, unsigned long bytes,
	unsigned int cache)
{
#if !defined(CONFIG_BRCM_ZSCM_L2)
	/* partial RAC invalidate is not supported */
	if (cache == RACACHE) {
		brcm_inv_prefetch(0, 0);
		return 0;
	}
#else
	/*
	 * SWLINUX-2607, BMIPS5000_5200-ES100-R: Flush JTB and CRS on
	 * user-initiated invalidations, in case a JIT buffer with mixed
	 * code+data is getting rewritten.  This helps prevent a possible
	 * CPU hang from prefetching invalid instructions.
	 */
	write_c0_brcm_action(4 << 16); /* reset JTB this thread */
	write_c0_brcm_action(5 << 16); /* reset JTB other thread */
	write_c0_brcm_action(6 << 16); /* reset CRS this thread */
	write_c0_brcm_action(7 << 16); /* reset CRS other thread */
#endif
	/* ICACHE/BCACHE is handled by the standard implementation */
	if (cache & ICACHE) {
		flush_icache_range(addr, addr + bytes);
		return 0;
	}

	/* New DCACHE implementation flushes D$/L2 out to RAM for DMA */
	if (cache & DCACHE) {
		unsigned long pg = addr & PAGE_MASK, end = addr + bytes;

		if (bytes == 0 || (bytes >= dcache_size)) {
			preempt_disable();
			r4k_blast_dcache();
			r4k_blast_scache();
			preempt_enable();
			__sync();
			return 0;
		}

		down_read(&current->mm->mmap_sem);
		while (pg < end) {
			pgd_t *pgdp = pgd_offset(current->mm, pg);
			pud_t *pudp = pud_offset(pgdp, pg);
			pmd_t *pmdp = pmd_offset(pudp, pg);
			pte_t *ptep = pte_offset(pmdp, pg);

			if (!(pte_val(*ptep) & _PAGE_PRESENT)) {
				up_read(&current->mm->mmap_sem);
				return -EFAULT;
			}

#if !defined(CONFIG_BRCM_ZSCM_L2)
			r4k_blast_dcache_page(pg);
#endif
			r4k_blast_scache_page(pg);
			pg += PAGE_SIZE;
		}
		up_read(&current->mm->mmap_sem);
	}

	if (cache & RACACHE)
		brcm_inv_prefetch(addr, bytes);

	__sync();
	return 0;
}
EXPORT_SYMBOL(brcm_cacheflush);

/*
 * Flush RAC or prefetch lines after DMA from device
 */
void brcm_inv_prefetch(unsigned long addr, unsigned long size)
{
#if defined(CONFIG_CPU_BMIPS3300)
	DEV_SET_RB(__BMIPS_GET_CBR() + BMIPS_RAC_CONFIG, 0x100);
#elif defined(CONFIG_CPU_BMIPS4380)
	DEV_SET_RB(__BMIPS_GET_CBR() + BMIPS_RAC_CONFIG, 0x100);
#elif defined(CONFIG_BRCM_ZSCM_L2)
	unsigned int linesz = cpu_scache_line_size();
	unsigned long addr0 = addr, addr1;

	BUG_ON(size == 0);

	addr0 &= ~(linesz - 1);
	addr1 = (addr0 + size - 1) & ~(linesz - 1);

	protected_writeback_scache_line(addr0);
	if (likely(addr1 != addr0))
		protected_writeback_scache_line(addr1);
	else
		return;

	addr0 += linesz;
	if (likely(addr1 != addr0))
		protected_writeback_scache_line(addr0);
	else
		return;

	addr1 -= linesz;
	if (likely(addr1 > addr0))
		protected_writeback_scache_line(addr0);
#endif
}
EXPORT_SYMBOL(brcm_inv_prefetch);

/*
 * Hooks for extra RAC/prefetch flush after DMA
 */
static inline void __brcm_sync(struct page *page,
	unsigned long offset, size_t size, enum dma_data_direction direction)
{
	size_t left = size;

	if (direction == DMA_TO_DEVICE)
		return;

	do {
		size_t len = left;

		if (PageHighMem(page)) {
			void *addr;

			if (offset + len > PAGE_SIZE) {
				if (offset >= PAGE_SIZE) {
					page += offset >> PAGE_SHIFT;
					offset &= ~PAGE_MASK;
				}
				len = PAGE_SIZE - offset;
			}

			addr = kmap_atomic(page);
			brcm_inv_prefetch((unsigned long)addr + offset, len);
			kunmap_atomic(addr);
		} else
			brcm_inv_prefetch((unsigned long)page_address(page) +
				offset, size);
		offset = 0;
		page++;
		left -= len;
	} while (left);
}

void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
	size_t size, int dir)
{
	unsigned long pa = plat_dma_addr_to_phys(dev, dma_addr);
	__brcm_sync(pfn_to_page(PFN_DOWN(pa)), pa & ~PAGE_MASK, size, dir);
}

static void brcm_dma_sync_single_for_cpu(struct device *dev,
	dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
{
	unsigned long pa = plat_dma_addr_to_phys(dev, dma_handle);
	__brcm_sync(pfn_to_page(PFN_DOWN(pa)), pa & ~PAGE_MASK, size, dir);
}

static void brcm_dma_sync_sg_for_cpu(struct device *dev,
	struct scatterlist *sg, int nelems, enum dma_data_direction direction)
{
	int i;
	for (i = 0; i < nelems; i++, sg++)
		__brcm_sync(sg_page(sg), sg->offset, sg->length, direction);
}

static int __init brcm_setup_dma_ops(void)
{
	mips_dma_map_ops->sync_single_for_cpu = brcm_dma_sync_single_for_cpu;
	mips_dma_map_ops->sync_sg_for_cpu = brcm_dma_sync_sg_for_cpu;
	return 0;
}
core_initcall(brcm_setup_dma_ops);

/*
 * Provide cache details for PI/Nexus
 */
void brcm_get_cache_info(struct brcm_cache_info *info)
{
	info->max_writeback = cpu_scache_line_size() ? : cpu_dcache_line_size();
	info->max_writethrough = 0;
	info->prefetch_enabled = 0;

#if defined(CONFIG_BRCM_ZSCM_L2)
	/* chips with prefetching L2 */
	info->prefetch_enabled = 1;
#elif defined(CONFIG_CPU_BMIPS3300) || defined(CONFIG_CPU_BMIPS4380)
	/* chips with write-through RAC */
	info->max_writethrough = info->max_writeback * 4;
	info->prefetch_enabled = 1;
#endif
}
EXPORT_SYMBOL(brcm_get_cache_info);
