aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/mpc85xx_edac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/mpc85xx_edac.c')
-rw-r--r--drivers/edac/mpc85xx_edac.c163
1 files changed, 151 insertions, 12 deletions
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index ecd5928d7110..94cac0aacea3 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -239,16 +239,15 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
239 /* we only need the error registers */ 239 /* we only need the error registers */
240 r.start += 0xe00; 240 r.start += 0xe00;
241 241
242 if (!devm_request_mem_region(&op->dev, r.start, 242 if (!devm_request_mem_region(&op->dev, r.start, resource_size(&r),
243 r.end - r.start + 1, pdata->name)) { 243 pdata->name)) {
244 printk(KERN_ERR "%s: Error while requesting mem region\n", 244 printk(KERN_ERR "%s: Error while requesting mem region\n",
245 __func__); 245 __func__);
246 res = -EBUSY; 246 res = -EBUSY;
247 goto err; 247 goto err;
248 } 248 }
249 249
250 pdata->pci_vbase = devm_ioremap(&op->dev, r.start, 250 pdata->pci_vbase = devm_ioremap(&op->dev, r.start, resource_size(&r));
251 r.end - r.start + 1);
252 if (!pdata->pci_vbase) { 251 if (!pdata->pci_vbase) {
253 printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); 252 printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
254 res = -ENOMEM; 253 res = -ENOMEM;
@@ -668,15 +667,125 @@ static struct of_platform_driver mpc85xx_l2_err_driver = {
668 667
669/**************************** MC Err device ***************************/ 668/**************************** MC Err device ***************************/
670 669
670/*
671 * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the
672 * MPC8572 User's Manual. Each line represents a syndrome bit column as a
673 * 64-bit value, but split into an upper and lower 32-bit chunk. The labels
674 * below correspond to Freescale's manuals.
675 */
676static unsigned int ecc_table[16] = {
677 /* MSB LSB */
678 /* [0:31] [32:63] */
679 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */
680 0x00ff00ff, 0x00fff0ff,
681 0x0f0f0f0f, 0x0f0fff00,
682 0x11113333, 0x7777000f,
683 0x22224444, 0x8888222f,
684 0x44448888, 0xffff4441,
685 0x8888ffff, 0x11118882,
686 0xffff1111, 0x22221114, /* Syndrome bit 0 */
687};
688
689/*
690 * Calculate the correct ECC value for a 64-bit value specified by high:low
691 */
692static u8 calculate_ecc(u32 high, u32 low)
693{
694 u32 mask_low;
695 u32 mask_high;
696 int bit_cnt;
697 u8 ecc = 0;
698 int i;
699 int j;
700
701 for (i = 0; i < 8; i++) {
702 mask_high = ecc_table[i * 2];
703 mask_low = ecc_table[i * 2 + 1];
704 bit_cnt = 0;
705
706 for (j = 0; j < 32; j++) {
707 if ((mask_high >> j) & 1)
708 bit_cnt ^= (high >> j) & 1;
709 if ((mask_low >> j) & 1)
710 bit_cnt ^= (low >> j) & 1;
711 }
712
713 ecc |= bit_cnt << i;
714 }
715
716 return ecc;
717}
718
719/*
720 * Create the syndrome code which is generated if the data line specified by
721 * 'bit' failed. Eg generate an 8-bit codes seen in Table 8-55 in the MPC8641
722 * User's Manual and 9-61 in the MPC8572 User's Manual.
723 */
724static u8 syndrome_from_bit(unsigned int bit) {
725 int i;
726 u8 syndrome = 0;
727
728 /*
729 * Cycle through the upper or lower 32-bit portion of each value in
730 * ecc_table depending on if 'bit' is in the upper or lower half of
731 * 64-bit data.
732 */
733 for (i = bit < 32; i < 16; i += 2)
734 syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
735
736 return syndrome;
737}
738
739/*
740 * Decode data and ecc syndrome to determine what went wrong
741 * Note: This can only decode single-bit errors
742 */
743static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc,
744 int *bad_data_bit, int *bad_ecc_bit)
745{
746 int i;
747 u8 syndrome;
748
749 *bad_data_bit = -1;
750 *bad_ecc_bit = -1;
751
752 /*
753 * Calculate the ECC of the captured data and XOR it with the captured
754 * ECC to find an ECC syndrome value we can search for
755 */
756 syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc;
757
758 /* Check if a data line is stuck... */
759 for (i = 0; i < 64; i++) {
760 if (syndrome == syndrome_from_bit(i)) {
761 *bad_data_bit = i;
762 return;
763 }
764 }
765
766 /* If data is correct, check ECC bits for errors... */
767 for (i = 0; i < 8; i++) {
768 if ((syndrome >> i) & 0x1) {
769 *bad_ecc_bit = i;
770 return;
771 }
772 }
773}
774
671static void mpc85xx_mc_check(struct mem_ctl_info *mci) 775static void mpc85xx_mc_check(struct mem_ctl_info *mci)
672{ 776{
673 struct mpc85xx_mc_pdata *pdata = mci->pvt_info; 777 struct mpc85xx_mc_pdata *pdata = mci->pvt_info;
674 struct csrow_info *csrow; 778 struct csrow_info *csrow;
779 u32 bus_width;
675 u32 err_detect; 780 u32 err_detect;
676 u32 syndrome; 781 u32 syndrome;
677 u32 err_addr; 782 u32 err_addr;
678 u32 pfn; 783 u32 pfn;
679 int row_index; 784 int row_index;
785 u32 cap_high;
786 u32 cap_low;
787 int bad_data_bit;
788 int bad_ecc_bit;
680 789
681 err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT); 790 err_detect = in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DETECT);
682 if (!err_detect) 791 if (!err_detect)
@@ -692,6 +801,15 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
692 } 801 }
693 802
694 syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC); 803 syndrome = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ECC);
804
805 /* Mask off appropriate bits of syndrome based on bus width */
806 bus_width = (in_be32(pdata->mc_vbase + MPC85XX_MC_DDR_SDRAM_CFG) &
807 DSC_DBW_MASK) ? 32 : 64;
808 if (bus_width == 64)
809 syndrome &= 0xff;
810 else
811 syndrome &= 0xffff;
812
695 err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS); 813 err_addr = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_ADDRESS);
696 pfn = err_addr >> PAGE_SHIFT; 814 pfn = err_addr >> PAGE_SHIFT;
697 815
@@ -701,14 +819,35 @@ static void mpc85xx_mc_check(struct mem_ctl_info *mci)
701 break; 819 break;
702 } 820 }
703 821
704 mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data High: %#8.8x\n", 822 cap_high = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_HI);
705 in_be32(pdata->mc_vbase + 823 cap_low = in_be32(pdata->mc_vbase + MPC85XX_MC_CAPTURE_DATA_LO);
706 MPC85XX_MC_CAPTURE_DATA_HI)); 824
707 mpc85xx_mc_printk(mci, KERN_ERR, "Capture Data Low: %#8.8x\n", 825 /*
708 in_be32(pdata->mc_vbase + 826 * Analyze single-bit errors on 64-bit wide buses
709 MPC85XX_MC_CAPTURE_DATA_LO)); 827 * TODO: Add support for 32-bit wide buses
710 mpc85xx_mc_printk(mci, KERN_ERR, "syndrome: %#8.8x\n", syndrome); 828 */
711 mpc85xx_mc_printk(mci, KERN_ERR, "err addr: %#8.8x\n", err_addr); 829 if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
830 sbe_ecc_decode(cap_high, cap_low, syndrome,
831 &bad_data_bit, &bad_ecc_bit);
832
833 if (bad_data_bit != -1)
834 mpc85xx_mc_printk(mci, KERN_ERR,
835 "Faulty Data bit: %d\n", bad_data_bit);
836 if (bad_ecc_bit != -1)
837 mpc85xx_mc_printk(mci, KERN_ERR,
838 "Faulty ECC bit: %d\n", bad_ecc_bit);
839
840 mpc85xx_mc_printk(mci, KERN_ERR,
841 "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
842 cap_high ^ (1 << (bad_data_bit - 32)),
843 cap_low ^ (1 << bad_data_bit),
844 syndrome ^ (1 << bad_ecc_bit));
845 }
846
847 mpc85xx_mc_printk(mci, KERN_ERR,
848 "Captured Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
849 cap_high, cap_low, syndrome);
850 mpc85xx_mc_printk(mci, KERN_ERR, "Err addr: %#8.8x\n", err_addr);
712 mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn); 851 mpc85xx_mc_printk(mci, KERN_ERR, "PFN: %#8.8x\n", pfn);
713 852
714 /* we are out of range */ 853 /* we are out of range */