Lines Matching +full:spare +full:- +full:regs
18 * Intel 5400 Chipset Memory Controller Hub (MCH) - Datasheet
21 * This Memory Controller manages DDR2 FB-DIMMs. It has 2 branches, each with
22 * 2 channels operating in lockstep no-mirror mode. Each channel can have up to
83 #define FERR_FAT_FBDCHAN (3<<28) /* channel index where the highest-order error occurred */
88 /* Non-fatal error register */
140 * Error masks are according with Table 5-17 of i5400 datasheet
144 EMASK_M1 = 1<<0, /* Memory Write error on non-redundant retry */
145 EMASK_M2 = 1<<1, /* Memory or FB-DIMM configuration CRC read error */
148 EMASK_M5 = 1<<4, /* Aliased Uncorrectable Non-Mirrored Demand Data ECC */
150 EMASK_M7 = 1<<6, /* Aliased Uncorrectable Resilver- or Spare-Copy Data ECC */
152 EMASK_M9 = 1<<8, /* Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC */
154 EMASK_M11 = 1<<10, /* Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC */
155 EMASK_M12 = 1<<11, /* Non-Aliased Uncorrectable Patrol Data ECC */
157 EMASK_M14 = 1<<13, /* FB-DIMM Configuration Write error on first attempt */
158 EMASK_M15 = 1<<14, /* Memory or FB-DIMM configuration CRC read error */
159 EMASK_M16 = 1<<15, /* Channel Failed-Over Occurred */
160 EMASK_M17 = 1<<16, /* Correctable Non-Mirrored Demand Data ECC */
162 EMASK_M19 = 1<<18, /* Correctable Resilver- or Spare-Copy Data ECC */
164 EMASK_M21 = 1<<20, /* FB-DIMM Northbound parity error on FB-DIMM Sync Status */
166 EMASK_M23 = 1<<22, /* Non-Redundant Fast Reset Timeout */
171 EMASK_M28 = 1<<27, /* DIMM-Spare Copy Completed */
172 EMASK_M29 = 1<<28, /* DIMM-Isolation Completed */
179 [0] = "Memory Write error on non-redundant retry",
180 [1] = "Memory or FB-DIMM configuration CRC read error",
183 [4] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
185 [6] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
187 [8] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC",
189 [10] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
190 [11] = "Non-Aliased Uncorrectable Patrol Data ECC",
192 [13] = "FB-DIMM Configuration Write error on first attempt",
193 [14] = "Memory or FB-DIMM configuration CRC read error",
194 [15] = "Channel Failed-Over Occurred",
195 [16] = "Correctable Non-Mirrored Demand Data ECC",
197 [18] = "Correctable Resilver- or Spare-Copy Data ECC",
199 [20] = "FB-DIMM Northbound parity error on FB-DIMM Sync Status",
201 [22] = "Non-Redundant Fast Reset Timeout",
206 [27] = "DIMM-Spare Copy Completed",
207 [28] = "DIMM-Isolation Completed",
244 /* mask to all non-fatal errors */
262 /* masks for non-fatal error register */
271 (mask & ((1 << 28) - 1) << 3); /* Bits 0 to 27 */ in from_nf_ferr()
283 * MTRx - Memory Technology Registers
297 /* This applies to FERR_NF_FB-DIMM as well as FERR_FAT_FB-DIMM */
361 u32 ferr_nf_fbd; /* First Errors Non-Fatal */
362 u32 nerr_nf_fbd; /* Next Errors Non-Fatal */
369 /* These registers are input ONLY if there was a Non-Rec Error */
370 u16 nrecmema; /* Non-Recoverable Mem log A */
371 u32 nrecmemb; /* Non-Recoverable Mem log B */
379 return ((info->nrecmema) >> 12) & 0x7; in nrec_bank()
383 return ((info->nrecmema) >> 8) & 0xf; in nrec_rank()
387 return ((info->nrecmema)) & 0xff; in nrec_buf_id()
391 return (info->nrecmemb) >> 31; in nrec_rdwr()
401 return ((info->nrecmemb) >> 16) & 0x1fff; in nrec_cas()
405 return (info->nrecmemb) & 0xffff; in nrec_ras()
409 return ((info->recmema) >> 12) & 0x7; in rec_bank()
413 return ((info->recmema) >> 8) & 0xf; in rec_rank()
417 return (info->recmemb) >> 31; in rec_rdwr()
421 return ((info->recmemb) >> 16) & 0x1fff; in rec_cas()
425 return (info->recmemb) & 0xffff; in rec_ras()
441 pvt = mci->pvt_info; in i5400_get_error_info()
444 pci_read_config_dword(pvt->branchmap_werrors, FERR_FAT_FBD, &value); in i5400_get_error_info()
454 info->ferr_fat_fbd = value; in i5400_get_error_info()
457 pci_read_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
458 NERR_FAT_FBD, &info->nerr_fat_fbd); in i5400_get_error_info()
459 pci_read_config_word(pvt->branchmap_werrors, in i5400_get_error_info()
460 NRECMEMA, &info->nrecmema); in i5400_get_error_info()
461 pci_read_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
462 NRECMEMB, &info->nrecmemb); in i5400_get_error_info()
465 pci_write_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
468 info->ferr_fat_fbd = 0; in i5400_get_error_info()
469 info->nerr_fat_fbd = 0; in i5400_get_error_info()
470 info->nrecmema = 0; in i5400_get_error_info()
471 info->nrecmemb = 0; in i5400_get_error_info()
474 /* read in the 1st NON-FATAL error register */ in i5400_get_error_info()
475 pci_read_config_dword(pvt->branchmap_werrors, FERR_NF_FBD, &value); in i5400_get_error_info()
477 /* If there is an error, then read in the 1st NON-FATAL error in i5400_get_error_info()
480 info->ferr_nf_fbd = value; in i5400_get_error_info()
483 pci_read_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
484 NERR_NF_FBD, &info->nerr_nf_fbd); in i5400_get_error_info()
485 pci_read_config_word(pvt->branchmap_werrors, in i5400_get_error_info()
486 RECMEMA, &info->recmema); in i5400_get_error_info()
487 pci_read_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
488 RECMEMB, &info->recmemb); in i5400_get_error_info()
489 pci_read_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
490 REDMEMB, &info->redmemb); in i5400_get_error_info()
493 pci_write_config_dword(pvt->branchmap_werrors, in i5400_get_error_info()
496 info->ferr_nf_fbd = 0; in i5400_get_error_info()
497 info->nerr_nf_fbd = 0; in i5400_get_error_info()
498 info->recmema = 0; in i5400_get_error_info()
499 info->recmemb = 0; in i5400_get_error_info()
500 info->redmemb = 0; in i5400_get_error_info()
534 type = "NON-FATAL uncorrected"; in i5400_proccess_non_recoverable_info()
536 type = "NON-FATAL recoverable"; in i5400_proccess_non_recoverable_info()
540 branch = extract_fbdchan_indx(info->ferr_fat_fbd); in i5400_proccess_non_recoverable_info()
543 /* Use the NON-Recoverable macros to extract data */ in i5400_proccess_non_recoverable_info()
564 branch >> 1, -1, rank, in i5400_proccess_non_recoverable_info()
574 * handle the Intel NON-FATAL errors, if any
590 allErrors = from_nf_ferr(info->ferr_nf_fbd & FERR_NF_MASK); in i5400_process_nonfatal_error_info()
605 branch = extract_fbdchan_indx(info->ferr_nf_fbd); in i5400_process_nonfatal_error_info()
608 if (REC_ECC_LOCATOR_ODD(info->redmemb)) in i5400_process_nonfatal_error_info()
630 "Corrected error (Branch=%d DRAM-Bank=%d RDWR=%s " in i5400_process_nonfatal_error_info()
646 branch = extract_fbdchan_indx(info->ferr_nf_fbd); in i5400_process_nonfatal_error_info()
649 "Non-Fatal misc error (Branch=%d Err=%#lx (%s))", in i5400_process_nonfatal_error_info()
662 allErrors = (info->ferr_fat_fbd & FERR_FAT_MASK); in i5400_process_error_info()
665 /* now handle any non-fatal errors that occurred */ in i5400_process_error_info()
702 pvt = mci->pvt_info; in i5400_put_devices()
705 pci_dev_put(pvt->branch_1); in i5400_put_devices()
706 pci_dev_put(pvt->branch_0); in i5400_put_devices()
707 pci_dev_put(pvt->fsb_error_regs); in i5400_put_devices()
708 pci_dev_put(pvt->branchmap_werrors); in i5400_put_devices()
722 pvt = mci->pvt_info; in i5400_get_devices()
723 pvt->branchmap_werrors = NULL; in i5400_get_devices()
724 pvt->fsb_error_regs = NULL; in i5400_get_devices()
725 pvt->branch_0 = NULL; in i5400_get_devices()
726 pvt->branch_1 = NULL; in i5400_get_devices()
742 return -ENODEV; in i5400_get_devices()
746 if (PCI_FUNC(pdev->devfn) == 1) in i5400_get_devices()
749 pvt->branchmap_werrors = pdev; in i5400_get_devices()
765 pci_dev_put(pvt->branchmap_werrors); in i5400_get_devices()
766 return -ENODEV; in i5400_get_devices()
770 if (PCI_FUNC(pdev->devfn) == 2) in i5400_get_devices()
773 pvt->fsb_error_regs = pdev; in i5400_get_devices()
775 edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", in i5400_get_devices()
776 pci_name(pvt->system_address), in i5400_get_devices()
777 pvt->system_address->vendor, pvt->system_address->device); in i5400_get_devices()
778 edac_dbg(1, "Branchmap, control and errors - PCI Bus ID: %s %x:%x\n", in i5400_get_devices()
779 pci_name(pvt->branchmap_werrors), in i5400_get_devices()
780 pvt->branchmap_werrors->vendor, in i5400_get_devices()
781 pvt->branchmap_werrors->device); in i5400_get_devices()
782 edac_dbg(1, "FSB Error Regs - PCI Bus ID: %s %x:%x\n", in i5400_get_devices()
783 pci_name(pvt->fsb_error_regs), in i5400_get_devices()
784 pvt->fsb_error_regs->vendor, pvt->fsb_error_regs->device); in i5400_get_devices()
786 pvt->branch_0 = pci_get_device(PCI_VENDOR_ID_INTEL, in i5400_get_devices()
788 if (!pvt->branch_0) { in i5400_get_devices()
794 pci_dev_put(pvt->fsb_error_regs); in i5400_get_devices()
795 pci_dev_put(pvt->branchmap_werrors); in i5400_get_devices()
796 return -ENODEV; in i5400_get_devices()
802 if (pvt->maxch < CHANNELS_PER_BRANCH) in i5400_get_devices()
805 pvt->branch_1 = pci_get_device(PCI_VENDOR_ID_INTEL, in i5400_get_devices()
807 if (!pvt->branch_1) { in i5400_get_devices()
815 pci_dev_put(pvt->branch_0); in i5400_get_devices()
816 pci_dev_put(pvt->fsb_error_regs); in i5400_get_devices()
817 pci_dev_put(pvt->branchmap_werrors); in i5400_get_devices()
818 return -ENODEV; in i5400_get_devices()
843 amb_present = pvt->b0_ambpresent1; in determine_amb_present_reg()
845 amb_present = pvt->b0_ambpresent0; in determine_amb_present_reg()
848 amb_present = pvt->b1_ambpresent1; in determine_amb_present_reg()
850 amb_present = pvt->b1_ambpresent0; in determine_amb_present_reg()
866 /* There is one MTR for each slot pair of FB-DIMMs, in determine_mtr()
878 mtr = pvt->b0_mtr[n]; in determine_mtr()
880 mtr = pvt->b1_mtr[n]; in determine_mtr()
907 MTR_DIMM_ROWS(mtr) == 0 ? "8,192 - 13 rows" : in decode_mtr()
908 MTR_DIMM_ROWS(mtr) == 1 ? "16,384 - 14 rows" : in decode_mtr()
909 MTR_DIMM_ROWS(mtr) == 2 ? "32,768 - 15 rows" : in decode_mtr()
910 "65,536 - 16 rows"); in decode_mtr()
912 MTR_DIMM_COLS(mtr) == 0 ? "1,024 - 10 columns" : in decode_mtr()
913 MTR_DIMM_COLS(mtr) == 1 ? "2,048 - 11 columns" : in decode_mtr()
914 MTR_DIMM_COLS(mtr) == 2 ? "4,096 - 12 columns" : in decode_mtr()
942 addrBits -= 20; /* divide by 2^^20 */ in handle_channel()
943 addrBits -= 3; /* 8 bits per bytes */ in handle_channel()
945 dinfo->megabytes = 1 << addrBits; in handle_channel()
978 max_dimms = pvt->maxdimmperch; in calculate_dimm_size()
979 for (dimm = max_dimms - 1; dimm >= 0; dimm--) { in calculate_dimm_size()
984 n = snprintf(p, space, "---------------------------" in calculate_dimm_size()
985 "-------------------------------"); in calculate_dimm_size()
987 space -= n; in calculate_dimm_size()
994 space -= n; in calculate_dimm_size()
996 for (channel = 0; channel < pvt->maxch; channel++) { in calculate_dimm_size()
997 dinfo = &pvt->dimm_info[dimm][channel]; in calculate_dimm_size()
999 n = snprintf(p, space, "%4d MB | ", dinfo->megabytes); in calculate_dimm_size()
1001 space -= n; in calculate_dimm_size()
1009 n = snprintf(p, space, "---------------------------" in calculate_dimm_size()
1010 "-------------------------------"); in calculate_dimm_size()
1012 space -= n; in calculate_dimm_size()
1020 space -= n; in calculate_dimm_size()
1021 for (channel = 0; channel < pvt->maxch; channel++) { in calculate_dimm_size()
1024 space -= n; in calculate_dimm_size()
1027 space -= n; in calculate_dimm_size()
1037 space -= n; in calculate_dimm_size()
1059 pvt = mci->pvt_info; in i5400_get_mc_regs()
1061 pci_read_config_dword(pvt->system_address, AMBASE, in i5400_get_mc_regs()
1062 &pvt->u.ambase_bottom); in i5400_get_mc_regs()
1063 pci_read_config_dword(pvt->system_address, AMBASE + sizeof(u32), in i5400_get_mc_regs()
1064 &pvt->u.ambase_top); in i5400_get_mc_regs()
1066 edac_dbg(2, "AMBASE= 0x%lx MAXCH= %d MAX-DIMM-Per-CH= %d\n", in i5400_get_mc_regs()
1067 (long unsigned int)pvt->ambase, pvt->maxch, pvt->maxdimmperch); in i5400_get_mc_regs()
1069 /* Get the Branch Map regs */ in i5400_get_mc_regs()
1070 pci_read_config_word(pvt->branchmap_werrors, TOLM, &pvt->tolm); in i5400_get_mc_regs()
1071 pvt->tolm >>= 12; in i5400_get_mc_regs()
1073 pvt->tolm, pvt->tolm); in i5400_get_mc_regs()
1075 actual_tolm = (u32) ((1000l * pvt->tolm) >> (30 - 28)); in i5400_get_mc_regs()
1077 actual_tolm/1000, actual_tolm % 1000, pvt->tolm << 28); in i5400_get_mc_regs()
1079 pci_read_config_word(pvt->branchmap_werrors, MIR0, &pvt->mir0); in i5400_get_mc_regs()
1080 pci_read_config_word(pvt->branchmap_werrors, MIR1, &pvt->mir1); in i5400_get_mc_regs()
1082 /* Get the MIR[0-1] regs */ in i5400_get_mc_regs()
1083 limit = (pvt->mir0 >> 4) & 0x0fff; in i5400_get_mc_regs()
1084 way0 = pvt->mir0 & 0x1; in i5400_get_mc_regs()
1085 way1 = pvt->mir0 & 0x2; in i5400_get_mc_regs()
1088 limit = (pvt->mir1 >> 4) & 0xfff; in i5400_get_mc_regs()
1089 way0 = pvt->mir1 & 0x1; in i5400_get_mc_regs()
1090 way1 = pvt->mir1 & 0x2; in i5400_get_mc_regs()
1094 /* Get the set of MTR[0-3] regs by each branch */ in i5400_get_mc_regs()
1099 pci_read_config_word(pvt->branch_0, where, in i5400_get_mc_regs()
1100 &pvt->b0_mtr[slot_row]); in i5400_get_mc_regs()
1103 slot_row, where, pvt->b0_mtr[slot_row]); in i5400_get_mc_regs()
1105 if (pvt->maxch < CHANNELS_PER_BRANCH) { in i5400_get_mc_regs()
1106 pvt->b1_mtr[slot_row] = 0; in i5400_get_mc_regs()
1111 pci_read_config_word(pvt->branch_1, where, in i5400_get_mc_regs()
1112 &pvt->b1_mtr[slot_row]); in i5400_get_mc_regs()
1114 slot_row, where, pvt->b1_mtr[slot_row]); in i5400_get_mc_regs()
1121 decode_mtr(slot_row, pvt->b0_mtr[slot_row]); in i5400_get_mc_regs()
1123 pci_read_config_word(pvt->branch_0, AMBPRESENT_0, in i5400_get_mc_regs()
1124 &pvt->b0_ambpresent0); in i5400_get_mc_regs()
1125 edac_dbg(2, "\t\tAMB-Branch 0-present0 0x%x:\n", pvt->b0_ambpresent0); in i5400_get_mc_regs()
1126 pci_read_config_word(pvt->branch_0, AMBPRESENT_1, in i5400_get_mc_regs()
1127 &pvt->b0_ambpresent1); in i5400_get_mc_regs()
1128 edac_dbg(2, "\t\tAMB-Branch 0-present1 0x%x:\n", pvt->b0_ambpresent1); in i5400_get_mc_regs()
1131 if (pvt->maxch < CHANNELS_PER_BRANCH) { in i5400_get_mc_regs()
1132 pvt->b1_ambpresent0 = 0; in i5400_get_mc_regs()
1133 pvt->b1_ambpresent1 = 0; in i5400_get_mc_regs()
1138 decode_mtr(slot_row, pvt->b1_mtr[slot_row]); in i5400_get_mc_regs()
1140 pci_read_config_word(pvt->branch_1, AMBPRESENT_0, in i5400_get_mc_regs()
1141 &pvt->b1_ambpresent0); in i5400_get_mc_regs()
1142 edac_dbg(2, "\t\tAMB-Branch 1-present0 0x%x:\n", in i5400_get_mc_regs()
1143 pvt->b1_ambpresent0); in i5400_get_mc_regs()
1144 pci_read_config_word(pvt->branch_1, AMBPRESENT_1, in i5400_get_mc_regs()
1145 &pvt->b1_ambpresent1); in i5400_get_mc_regs()
1146 edac_dbg(2, "\t\tAMB-Branch 1-present1 0x%x:\n", in i5400_get_mc_regs()
1147 pvt->b1_ambpresent1); in i5400_get_mc_regs()
1173 pvt = mci->pvt_info; in i5400_init_dimms()
1178 * FIXME: remove pvt->dimm_info[slot][channel] and use the 3 in i5400_init_dimms()
1181 for (channel = 0; channel < mci->layers[0].size * mci->layers[1].size; in i5400_init_dimms()
1183 for (slot = 0; slot < mci->layers[2].size; slot++) { in i5400_init_dimms()
1192 size_mb = pvt->dimm_info[slot][channel].megabytes; in i5400_init_dimms()
1198 dimm->nr_pages = size_mb << 8; in i5400_init_dimms()
1199 dimm->grain = 8; in i5400_init_dimms()
1200 dimm->dtype = MTR_DRAM_WIDTH(mtr) == 8 ? in i5400_init_dimms()
1202 dimm->mtype = MEM_FB_DDR2; in i5400_init_dimms()
1207 dimm->edac_mode = MTR_DRAM_WIDTH(mtr) == 8 ? in i5400_init_dimms()
1215 * With such single-DIMM mode, the SDCC algorithm degrades to SECDEC+. in i5400_init_dimms()
1218 mci->dimms[0]->edac_mode = EDAC_SECDED; in i5400_init_dimms()
1232 pvt = mci->pvt_info; in i5400_enable_error_reporting()
1235 pci_read_config_dword(pvt->branchmap_werrors, EMASK_FBD, in i5400_enable_error_reporting()
1241 pci_write_config_dword(pvt->branchmap_werrors, EMASK_FBD, in i5400_enable_error_reporting()
1259 return -EINVAL; in i5400_probe1()
1262 pdev->bus->number, in i5400_probe1()
1263 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); in i5400_probe1()
1266 if (PCI_FUNC(pdev->devfn) != 0) in i5400_probe1()
1267 return -ENODEV; in i5400_probe1()
1285 return -ENOMEM; in i5400_probe1()
1289 mci->pdev = &pdev->dev; /* record ptr to the generic device */ in i5400_probe1()
1291 pvt = mci->pvt_info; in i5400_probe1()
1292 pvt->system_address = pdev; /* Record this device in our private */ in i5400_probe1()
1293 pvt->maxch = MAX_CHANNELS; in i5400_probe1()
1294 pvt->maxdimmperch = DIMMS_PER_CHANNEL; in i5400_probe1()
1303 mci->mc_idx = 0; in i5400_probe1()
1304 mci->mtype_cap = MEM_FLAG_FB_DDR2; in i5400_probe1()
1305 mci->edac_ctl_cap = EDAC_FLAG_NONE; in i5400_probe1()
1306 mci->edac_cap = EDAC_FLAG_NONE; in i5400_probe1()
1307 mci->mod_name = "i5400_edac.c"; in i5400_probe1()
1308 mci->ctl_name = i5400_devs[dev_idx].ctl_name; in i5400_probe1()
1309 mci->dev_name = pci_name(pdev); in i5400_probe1()
1310 mci->ctl_page_to_phys = NULL; in i5400_probe1()
1313 mci->edac_check = i5400_check_error; in i5400_probe1()
1318 …edac_dbg(0, "MC: Setting mci->edac_cap to EDAC_FLAG_NONE because i5400_init_dimms() returned nonze… in i5400_probe1()
1319 mci->edac_cap = EDAC_FLAG_NONE; /* no dimms found */ in i5400_probe1()
1337 i5400_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); in i5400_probe1()
1356 return -ENODEV; in i5400_probe1()
1378 return i5400_probe1(pdev, id->driver_data); in i5400_init_one()
1394 mci = edac_mc_del_mc(&pdev->dev); in i5400_remove_one()
1464 MODULE_DESCRIPTION("MC Driver for Intel I5400 memory controllers - "