Add PPC440GX L2C error handler
PATCH 1/1 Add PPC440GX L2C error handler
This patch adds an L2-Cache error handler. In addition, it reenables setup of the L2 cache based on erratum L2C0_1 now that we have been reassured that there are no more faulty parts being shipped. If there is a problem, the error handler will report it.
Signed-off-by Eugene Surovegin <[email protected]>
Signed-off-by Matt Porter <[email protected]>
===== arch/ppc/syslib/ibm440gx_common.c 1.2 vs edited =====
arch/ppc/syslib/ibm440gx_common.c +54 -9
@@ -4,7 +4,7 @@* PPC440GX system library * * Eugene Surovegin <[email protected]> or <[email protected]> -* Copyright (c) 2003 Zultys Technologies +* Copyright (c) 2003, 2004 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
@@ -14,6 +14,7 @@*/ #include <linux/config.h> #include <linux/kernel.h> +#include <linux/interrupt.h> #include <asm/ibm44x.h> #include <asm/mmu.h> #include <asm/processor.h>
@@ -97,10 +98,51 @@ p->uart1 = p->plb /__fix_zero (uart1 &0xff ,256 ); } -/* Enable L2 cache (call with IRQs disabled) */ +/* Issue L2C diagnostic command */ +static inline u32 l2c_diag (u32 addr) +{ +mtdcr (DCRN_L2C0_ADDR , addr); +mtdcr (DCRN_L2C0_CMD ,L2C_CMD_DIAG ); +while (!(mfdcr (DCRN_L2C0_SR ) &L2C_SR_CC )) ; +return mfdcr (DCRN_L2C0_DATA ); +} + +static irqreturn_t l2c_error_handler (int irq,void * dev,struct pt_regs * regs) +{ +u32 sr =mfdcr (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 (DCRN_L2C0_ADDR ,0 ); +mtdcr (DCRN_L2C0_CMD ,L2C_CMD_CCP |L2C_CMD_CTE ); + }else +printk (KERN_EMERG "L2C: LRU error\n" ); + +return IRQ_HANDLED ; +} + +/* Enable L2 cache */ void __init ibm440gx_l2c_enable (void ){u32 r; - +unsigned long flags; + +/* Install error handler */ +if (request_irq (87 , l2c_error_handler,SA_INTERRUPT ,"L2C" ,0 ) <0 ){ +printk (KERN_ERR "Cannot install L2C error handler, cache is not enabled\n" ); +return ; + } + +local_irq_save (flags); asmvolatile ("sync" :::"memory" );/* Disable SRAM */
@@ -137,20 +179,22 @@/* Enable ICU/DCU ports */ r =mfdcr (DCRN_L2C0_CFG ); - r &= ~(L2C_CFG_DCW_MASK |L2C_CFG_CPIM |L2C_CFG_TPIM |L2C_CFG_LIM - |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_SMCM ; + 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 ;mtdcr (DCRN_L2C0_CFG , r); asmvolatile ("sync; isync" :::"memory" ); +local_irq_restore (flags); } -/* Disable L2 cache (call with IRQs disabled) */ +/* Disable L2 cache */ void __init ibm440gx_l2c_disable (void ){u32 r; +unsigned long flags; +local_irq_save (flags); asmvolatile ("sync" :::"memory" );/* Disable L2C mode */
@@ -169,6 +213,7 @@ SRAM_SBCR_BAS3 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW); asmvolatile ("sync; isync" :::"memory" ); +local_irq_restore (flags); }void __init ibm440gx_l2c_setup (struct ibm44x_clocks * p)
===== arch/ppc/platforms/4xx/ocotea.c 1.10 vs edited =====
arch/ppc/platforms/4xx/ocotea.c +14 -9
@@ -145,13 +145,13 @@ }#define PCIX_READW (offset) \ - (readw((u32)pcix_reg_base+offset)) + (readw(pcix_reg_base+offset))#define PCIX_WRITEW (value, offset) \ - (writew(value, (u32)pcix_reg_base+offset)) + (writew(value, pcix_reg_base+offset))#define PCIX_WRITEL (value, offset) \ - (writel(value, (u32)pcix_reg_base+offset)) + (writel(value, pcix_reg_base+offset))/* * FIXME: This is only here to "make it work". This will move
@@ -321,6 +321,11 @@printk ("IBM Ocotea port (MontaVista Software, Inc. <[email protected]>)\n" ); } +static void __init ocotea_init (void ) +{ +ibm440gx_l2c_setup (&clocks); +} +void __init platform_init (unsigned long r3,unsigned long r4,unsigned long r5,unsigned long r6,unsigned long r7) {
@@ -341,13 +346,12 @@*/ ibm440gx_get_clocks (&clocks,33333333 ,6 *1843200 ); ocp_sys_info.opb_bus_freq = clocks.opb; - -/* -* Always disable L2 cache. All revs/speeds of silicon -* have parity error problems despite errata claims to -* the contrary. + +/* XXX Fix L2C IRQ triggerring setting (edge-sensitive). +* Firmware (at least PIBS v1.72 OCT/28/2003) sets it incorrectly +* --ebs */ -ibm440gx_l2c_disable (); +mtdcr (DCRN_UIC_TR (UIC2 ),mfdcr (DCRN_UIC_TR (UIC2 )) |0x00000100 );ibm44x_platform_init ();
@@ -365,4 +369,5 @@#ifdef CONFIG_KGDB ppc_md.early_serial_map = ocotea_early_serial_map;#endif + ppc_md.init = ocotea_init; }