/*
 * IBM/AMCC PPC4xx SoC setup code
 *
 * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
 *
 * L2 cache routines cloned from arch/ppc/syslib/ibm440gx_common.c which is:
 *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *   Copyright (c) 2003 - 2006 Zultys Technologies
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/of_platform.h>

#include <asm/dcr.h>
#include <asm/dcr-regs.h>
#include <asm/reg.h>

static u32 dcrbase_l2c;

/*
 * L2-cache
 */

/* Issue L2C diagnostic command */
static inline u32 l2c_diag(u32 addr)
{
	mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, addr);
	mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_DIAG);
	while (!(mfdcr(dcrbase_l2c + DCRN_L2C0_SR) & L2C_SR_CC))
		;

	return mfdcr(dcrbase_l2c + DCRN_L2C0_DATA);
}

static irqreturn_t l2c_error_handler(int irq, void *dev)
{
	u32 sr = mfdcr(dcrbase_l2c + DCRN_L2C0_SR);

	if (sr & L2C_SR_CPE) {
		/* Read cache trapped address */
		u32 addr = l2c_diag(0x42000000);
		printk(KERN_EMERG "L2C: Cache Parity Error, addr[16:26] = 0x%08x\n",
		       addr);
	}
	if (sr & L2C_SR_TPE) {
		/* Read tag trapped address */
		u32 addr = l2c_diag(0x82000000) >> 16;
		printk(KERN_EMERG "L2C: Tag Parity Error, addr[16:26] = 0x%08x\n",
		       addr);
	}

	/* Clear parity errors */
	if (sr & (L2C_SR_CPE | L2C_SR_TPE)){
		mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, 0);
		mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);
	} else {
		printk(KERN_EMERG "L2C: LRU error\n");
	}

	return IRQ_HANDLED;
}

static int __init ppc4xx_l2c_probe(void)
{
	struct device_node *np;
	u32 r;
	unsigned long flags;
	int irq;
	const u32 *dcrreg;
	u32 dcrbase_isram;
	int len;
	const u32 *prop;
	u32 l2_size;

	np = of_find_compatible_node(NULL, NULL, "ibm,l2-cache");
	if (!np)
		return 0;

	/* Get l2 cache size */
	prop = of_get_property(np, "cache-size", NULL);
	if (prop == NULL) {
		printk(KERN_ERR "%s: Can't get cache-size!\n", np->full_name);
		of_node_put(np);
		return -ENODEV;
	}
	l2_size = prop[0];

	/* Map DCRs */
	dcrreg = of_get_property(np, "dcr-reg", &len);
	if (!dcrreg || (len != 4 * sizeof(u32))) {
		printk(KERN_ERR "%s: Can't get DCR register base !",
		       np->full_name);
		of_node_put(np);
		return -ENODEV;
	}
	dcrbase_isram = dcrreg[0];
	dcrbase_l2c = dcrreg[2];

	/* Get and map irq number from device tree */
	irq = irq_of_parse_and_map(np, 0);
	if (irq == NO_IRQ) {
		printk(KERN_ERR "irq_of_parse_and_map failed\n");
		of_node_put(np);
		return -ENODEV;
	}

	/* Install error handler */
	if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) {
		printk(KERN_ERR "Cannot install L2C error handler"
		       ", cache is not enabled\n");
		of_node_put(np);
		return -ENODEV;
	}

	local_irq_save(flags);
	asm volatile ("sync" ::: "memory");

	/* Disable SRAM */
	mtdcr(dcrbase_isram + DCRN_SRAM0_DPC,
	      mfdcr(dcrbase_isram + DCRN_SRAM0_DPC) & ~SRAM_DPC_ENABLE);
	mtdcr(dcrbase_isram + DCRN_SRAM0_SB0CR,
	      mfdcr(dcrbase_isram + DCRN_SRAM0_SB0CR) & ~SRAM_SBCR_BU_MASK);
	mtdcr(dcrbase_isram + DCRN_SRAM0_SB1CR,
	      mfdcr(dcrbase_isram + DCRN_SRAM0_SB1CR) & ~SRAM_SBCR_BU_MASK);
	mtdcr(dcrbase_isram + DCRN_SRAM0_SB2CR,
	      mfdcr(dcrbase_isram + DCRN_SRAM0_SB2CR) & ~SRAM_SBCR_BU_MASK);
	mtdcr(dcrbase_isram + DCRN_SRAM0_SB3CR,
	      mfdcr(dcrbase_isram + DCRN_SRAM0_SB3CR) & ~SRAM_SBCR_BU_MASK);

	/* Enable L2_MODE without ICU/DCU */
	r = mfdcr(dcrbase_l2c + DCRN_L2C0_CFG) &
		~(L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_SS_MASK);
	r |= L2C_CFG_L2M | L2C_CFG_SS_256;
	mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r);

	mtdcr(dcrbase_l2c + DCRN_L2C0_ADDR, 0);

	/* Hardware Clear Command */
	mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_HCC);
	while (!(mfdcr(dcrbase_l2c + DCRN_L2C0_SR) & L2C_SR_CC))
		;

	/* Clear Cache Parity and Tag Errors */
	mtdcr(dcrbase_l2c + DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);

	/* Enable 64G snoop region starting at 0 */
	r = mfdcr(dcrbase_l2c + DCRN_L2C0_SNP0) &
		~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK);
	r |= L2C_SNP_SSR_32G | L2C_SNP_ESR;
	mtdcr(dcrbase_l2c + DCRN_L2C0_SNP0, r);

	r = mfdcr(dcrbase_l2c + DCRN_L2C0_SNP1) &
		~(L2C_SNP_BA_MASK | L2C_SNP_SSR_MASK);
	r |= 0x80000000 | L2C_SNP_SSR_32G | L2C_SNP_ESR;
	mtdcr(dcrbase_l2c + DCRN_L2C0_SNP1, r);

	asm volatile ("sync" ::: "memory");

	/* Enable ICU/DCU ports */
	r = mfdcr(dcrbase_l2c + DCRN_L2C0_CFG);
	r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM
	       | L2C_CFG_TPEI | L2C_CFG_CPEI | L2C_CFG_NAM | L2C_CFG_NBRM);
	r |= L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_TPC | L2C_CFG_CPC | L2C_CFG_FRAN
		| L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;

	/* Check for 460EX/GT special handling */
	if (of_device_is_compatible(np, "ibm,l2-cache-460ex"))
		r |= L2C_CFG_RDBW;

	mtdcr(dcrbase_l2c + DCRN_L2C0_CFG, r);

	asm volatile ("sync; isync" ::: "memory");
	local_irq_restore(flags);

	printk(KERN_INFO "%dk L2-cache enabled\n", l2_size >> 10);

	of_node_put(np);
	return 0;
}
arch_initcall(ppc4xx_l2c_probe);

/*
 * At present, this routine just applies a system reset.
 */
void ppc4xx_reset_system(char *cmd)
{
	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_RST_SYSTEM);
	while (1)
		;	/* Just in case the reset doesn't work */
}
