Lines Matching +full:ras +full:- +full:to +full:- +full:cas

1 // SPDX-License-Identifier: GPL-2.0-only
10 * Intel 7300 Chipset Memory Controller Hub (MCH) - Datasheet
16 * This driver uses "csrows" EDAC attribute to represent DIMM slot#
48 * Branch 0 - 2 channels: channels 0 and 1 (FDB0 PCI dev 21.0)
49 * Branch 1 - 2 channels: channels 2 and 3 (FDB1 PCI dev 22.0)
50 * Each channel can have to 8 DIMM sets (called as SLOTS)
115 /* FIXME: Why do we need to have this static? */
150 * Note: Other Intel EDAC drivers use AMBPRESENT to identify if the available
151 * memory. From datasheet item 7.3.1 (FB-DIMM technology & organization), it
153 * Each memory slot may have up to 2 AMB interfaces, one for income and another
154 * for outcome interface to the next slot.
156 * the MTR info to detect memory.
157 * Datasheet is also not clear about how to map each AMBPRESENT registers to
169 * Defines to extract the vaious fields from the
170 * MTRx - Memory Technology Registers
192 [22] = "Non-Redundant Fast Reset Timeout",
195 [0] = "Memory Write error on non-redundant retry or "
203 [24] = "DIMM-Spare Copy Completed",
204 [23] = "DIMM-Spare Copy Initiated",
210 [15] = "Correctable Resilver- or Spare-Copy Data ECC",
212 [13] = "Correctable Non-Mirrored Demand Data ECC",
216 [8] = "Non-Aliased Uncorrectable Patrol Data ECC",
217 [7] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
218 [6] = "Non-Aliased Uncorrectable Mirrored Demand Data ECC",
219 [5] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC",
221 [3] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
223 [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
274 [15] = "Internal MCH Non-Fatal Error",
276 [13] = "FSB1 Non-Fatal Error",
277 [12] = "FSB 0 Non-Fatal Error",
278 [11] = "FBD Channel 3 Non-Fatal Error",
279 [10] = "FBD Channel 2 Non-Fatal Error",
280 [9] = "FBD Channel 1 Non-Fatal Error",
281 [8] = "FBD Channel 0 Non-Fatal Error",
282 [7] = "PCI Express Device 7 Non-Fatal Error",
283 [6] = "PCI Express Device 6 Non-Fatal Error",
284 [5] = "PCI Express Device 5 Non-Fatal Error",
285 [4] = "PCI Express Device 4 Non-Fatal Error",
286 [3] = "PCI Express Device 3 Non-Fatal Error",
287 [2] = "PCI Express Device 2 Non-Fatal Error",
288 [1] = "PCI Express Device 1 Non-Fatal Error",
289 [0] = "ESI Non-Fatal Error",
316 * i7300 Functions related to error detection
320 * get_err_from_table() - Gets the error message from a table
323 * @pos: position of the element to be returned
325 * This is a small routine that gets the pos-th element of a table. If the
327 * Instead of calling it directly, the better is to call via the macro
346 * i7300_process_error_global() - Retrieve the hardware error information from
348 * sends it to dmesg
359 pvt = mci->pvt_info; in i7300_process_error_global()
362 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
372 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
378 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
388 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
401 * i7300_process_fbd_error() - Retrieve the hardware error information from
411 unsigned branch, channel, bank, rank, cas, ras; in i7300_process_fbd_error() local
418 pvt = mci->pvt_info; in i7300_process_fbd_error()
421 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
430 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
435 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
438 cas = NRECMEMB_CAS(value); in i7300_process_fbd_error()
439 ras = NRECMEMB_RAS(value); in i7300_process_fbd_error()
442 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
445 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, in i7300_process_fbd_error()
446 "Bank=%d RAS=%d CAS=%d Err=0x%lx (%s))", in i7300_process_fbd_error()
447 bank, ras, cas, errors, specific); in i7300_process_fbd_error()
450 branch, -1, rank, in i7300_process_fbd_error()
452 pvt->tmp_prt_buffer); in i7300_process_fbd_error()
456 /* read in the 1st NON-FATAL error register */ in i7300_process_fbd_error()
457 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
466 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
469 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
474 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
477 cas = RECMEMB_CAS(value); in i7300_process_fbd_error()
478 ras = RECMEMB_RAS(value); in i7300_process_fbd_error()
480 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
488 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
492 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, in i7300_process_fbd_error()
493 "DRAM-Bank=%d RAS=%d CAS=%d, Err=0x%lx (%s))", in i7300_process_fbd_error()
494 bank, ras, cas, errors, specific); in i7300_process_fbd_error()
500 pvt->tmp_prt_buffer); in i7300_process_fbd_error()
506 * i7300_check_error() - Calls the error checking subroutines
516 * i7300_clear_error() - Clears the error registers
521 struct i7300_pvt *pvt = mci->pvt_info; in i7300_clear_error()
524 * All error values are RWC - we need to read and write 1 to the in i7300_clear_error()
525 * bit that we want to cleanup in i7300_clear_error()
529 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
531 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
534 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
536 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
540 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
542 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
545 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
547 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
552 * i7300_enable_error_reporting() - Enable the memory reporting logic at the
558 struct i7300_pvt *pvt = mci->pvt_info; in i7300_enable_error_reporting()
562 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_enable_error_reporting()
568 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_enable_error_reporting()
573 * i7300 Functions related to memory enumberation
577 * decode_mtr() - Decodes the MTR descriptor, filling the edac structs
578 * @pvt: pointer to the private data struct used by i7300 driver
579 * @slot: DIMM slot (0 to 7)
582 * @dinfo: Pointer to DIMM info where dimm size is stored
583 * @dimm: Pointer to the struct dimm_info that corresponds to that element
594 mtr = pvt->mtr[slot][branch]; in decode_mtr()
615 addrBits -= 20; /* divide by 2^^20 */ in decode_mtr()
616 addrBits -= 3; /* 8 bits per bytes */ in decode_mtr()
618 dinfo->megabytes = 1 << addrBits; in decode_mtr()
629 MTR_DIMM_ROWS(mtr) == 0 ? "8,192 - 13 rows" : in decode_mtr()
630 MTR_DIMM_ROWS(mtr) == 1 ? "16,384 - 14 rows" : in decode_mtr()
631 MTR_DIMM_ROWS(mtr) == 2 ? "32,768 - 15 rows" : in decode_mtr()
632 "65,536 - 16 rows"); in decode_mtr()
634 MTR_DIMM_COLS(mtr) == 0 ? "1,024 - 10 columns" : in decode_mtr()
635 MTR_DIMM_COLS(mtr) == 1 ? "2,048 - 11 columns" : in decode_mtr()
636 MTR_DIMM_COLS(mtr) == 2 ? "4,096 - 12 columns" : in decode_mtr()
638 edac_dbg(2, "\t\tSIZE: %d MB\n", dinfo->megabytes); in decode_mtr()
643 * socket 0, channel 0, it uses 8-byte-over-32-byte SECDED+ code. in decode_mtr()
646 * See datasheet Sections 7.3.6 to 7.3.8 in decode_mtr()
649 dimm->nr_pages = MiB_TO_PAGES(dinfo->megabytes); in decode_mtr()
650 dimm->grain = 8; in decode_mtr()
651 dimm->mtype = MEM_FB_DDR2; in decode_mtr()
652 if (IS_SINGLE_MODE(pvt->mc_settings_a)) { in decode_mtr()
653 dimm->edac_mode = EDAC_SECDED; in decode_mtr()
654 edac_dbg(2, "\t\tECC code is 8-byte-over-32-byte SECDED+ code\n"); in decode_mtr()
658 dimm->edac_mode = EDAC_S8ECD8ED; in decode_mtr()
660 dimm->edac_mode = EDAC_S4ECD4ED; in decode_mtr()
666 IS_SCRBALGO_ENHANCED(pvt->mc_settings) ? in decode_mtr()
669 dimm->dtype = DEV_X8; in decode_mtr()
671 dimm->dtype = DEV_X4; in decode_mtr()
677 * print_dimm_size() - Prints dump of the memory organization
678 * @pvt: pointer to the private data struct used by i7300 driver
691 p = pvt->tmp_prt_buffer; in print_dimm_size()
695 space -= n; in print_dimm_size()
699 space -= n; in print_dimm_size()
701 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
702 p = pvt->tmp_prt_buffer; in print_dimm_size()
704 n = snprintf(p, space, "-------------------------------" in print_dimm_size()
705 "------------------------------"); in print_dimm_size()
707 space -= n; in print_dimm_size()
708 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
709 p = pvt->tmp_prt_buffer; in print_dimm_size()
715 space -= n; in print_dimm_size()
718 dinfo = &pvt->dimm_info[slot][channel]; in print_dimm_size()
719 n = snprintf(p, space, "%4d MB | ", dinfo->megabytes); in print_dimm_size()
721 space -= n; in print_dimm_size()
724 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
725 p = pvt->tmp_prt_buffer; in print_dimm_size()
729 n = snprintf(p, space, "-------------------------------" in print_dimm_size()
730 "------------------------------"); in print_dimm_size()
732 space -= n; in print_dimm_size()
733 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
734 p = pvt->tmp_prt_buffer; in print_dimm_size()
740 * i7300_init_csrows() - Initialize the 'csrows' table within
749 int rc = -ENODEV; in i7300_init_csrows()
754 pvt = mci->pvt_info; in i7300_init_csrows()
758 if (IS_SINGLE_MODE(pvt->mc_settings_a)) { in i7300_init_csrows()
770 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
772 &pvt->ambpresent[channel]); in i7300_init_csrows()
773 edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", in i7300_init_csrows()
774 channel, pvt->ambpresent[channel]); in i7300_init_csrows()
780 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
782 &pvt->ambpresent[channel]); in i7300_init_csrows()
783 edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", in i7300_init_csrows()
784 channel, pvt->ambpresent[channel]); in i7300_init_csrows()
787 /* Get the set of MTR[0-7] regs by each branch */ in i7300_init_csrows()
791 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
793 &pvt->mtr[slot][branch]); in i7300_init_csrows()
799 dinfo = &pvt->dimm_info[slot][channel]; in i7300_init_csrows()
818 * decode_mir() - Decodes Memory Interleave Register (MIR) info
819 * @mir_no: number of the MIR register to decode
833 * i7300_get_mc_regs() - Get the contents of the MC enumeration registers
844 pvt = mci->pvt_info; in i7300_get_mc_regs()
846 pci_read_config_dword(pvt->pci_dev_16_0_fsb_ctlr, AMBASE, in i7300_get_mc_regs()
847 (u32 *) &pvt->ambase); in i7300_get_mc_regs()
849 edac_dbg(2, "AMBASE= 0x%lx\n", (long unsigned int)pvt->ambase); in i7300_get_mc_regs()
852 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, TOLM, &pvt->tolm); in i7300_get_mc_regs()
853 pvt->tolm >>= 12; in i7300_get_mc_regs()
855 pvt->tolm, pvt->tolm); in i7300_get_mc_regs()
857 actual_tolm = (u32) ((1000l * pvt->tolm) >> (30 - 28)); in i7300_get_mc_regs()
859 actual_tolm/1000, actual_tolm % 1000, pvt->tolm << 28); in i7300_get_mc_regs()
862 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS, in i7300_get_mc_regs()
863 &pvt->mc_settings); in i7300_get_mc_regs()
864 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS_A, in i7300_get_mc_regs()
865 &pvt->mc_settings_a); in i7300_get_mc_regs()
867 if (IS_SINGLE_MODE(pvt->mc_settings_a)) in i7300_get_mc_regs()
871 IS_MIRRORED(pvt->mc_settings) ? "" : "non-"); in i7300_get_mc_regs()
874 IS_ECC_ENABLED(pvt->mc_settings) ? "enabled" : "disabled"); in i7300_get_mc_regs()
876 IS_RETRY_ENABLED(pvt->mc_settings) ? "enabled" : "disabled"); in i7300_get_mc_regs()
879 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR0, in i7300_get_mc_regs()
880 &pvt->mir[0]); in i7300_get_mc_regs()
881 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR1, in i7300_get_mc_regs()
882 &pvt->mir[1]); in i7300_get_mc_regs()
883 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR2, in i7300_get_mc_regs()
884 &pvt->mir[2]); in i7300_get_mc_regs()
888 decode_mir(i, pvt->mir); in i7300_get_mc_regs()
902 * i7300 Functions related to device probe/release
906 * i7300_put_devices() - Release the PCI devices
914 pvt = mci->pvt_info; in i7300_put_devices()
918 pci_dev_put(pvt->pci_dev_2x_0_fbd_branch[branch]); in i7300_put_devices()
919 pci_dev_put(pvt->pci_dev_16_2_fsb_err_regs); in i7300_put_devices()
920 pci_dev_put(pvt->pci_dev_16_1_fsb_addr_map); in i7300_put_devices()
924 * i7300_get_devices() - Find and perform 'get' operation on the MCH's
925 * device/functions we want to reference for this driver
939 pvt = mci->pvt_info; in i7300_get_devices()
941 /* Attempt to 'get' the MCH register we want */ in i7300_get_devices()
947 switch (PCI_FUNC(pdev->devfn)) { in i7300_get_devices()
949 if (!pvt->pci_dev_16_1_fsb_addr_map) in i7300_get_devices()
950 pvt->pci_dev_16_1_fsb_addr_map = in i7300_get_devices()
954 if (!pvt->pci_dev_16_2_fsb_err_regs) in i7300_get_devices()
955 pvt->pci_dev_16_2_fsb_err_regs = in i7300_get_devices()
961 if (!pvt->pci_dev_16_1_fsb_addr_map || in i7300_get_devices()
962 !pvt->pci_dev_16_2_fsb_err_regs) { in i7300_get_devices()
972 edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
973 pci_name(pvt->pci_dev_16_0_fsb_ctlr), in i7300_get_devices()
974 pvt->pci_dev_16_0_fsb_ctlr->vendor, in i7300_get_devices()
975 pvt->pci_dev_16_0_fsb_ctlr->device); in i7300_get_devices()
976 edac_dbg(1, "Branchmap, control and errors - PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
977 pci_name(pvt->pci_dev_16_1_fsb_addr_map), in i7300_get_devices()
978 pvt->pci_dev_16_1_fsb_addr_map->vendor, in i7300_get_devices()
979 pvt->pci_dev_16_1_fsb_addr_map->device); in i7300_get_devices()
980 edac_dbg(1, "FSB Error Regs - PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
981 pci_name(pvt->pci_dev_16_2_fsb_err_regs), in i7300_get_devices()
982 pvt->pci_dev_16_2_fsb_err_regs->vendor, in i7300_get_devices()
983 pvt->pci_dev_16_2_fsb_err_regs->device); in i7300_get_devices()
985 pvt->pci_dev_2x_0_fbd_branch[0] = pci_get_device(PCI_VENDOR_ID_INTEL, in i7300_get_devices()
988 if (!pvt->pci_dev_2x_0_fbd_branch[0]) { in i7300_get_devices()
996 pvt->pci_dev_2x_0_fbd_branch[1] = pci_get_device(PCI_VENDOR_ID_INTEL, in i7300_get_devices()
999 if (!pvt->pci_dev_2x_0_fbd_branch[1]) { in i7300_get_devices()
1013 return -ENODEV; in i7300_get_devices()
1017 * i7300_init_one() - Probe for one instance of the device
1019 * @id: struct pci_device_id pointer - currently unused
1030 if (rc == -EIO) in i7300_init_one()
1034 pdev->bus->number, in i7300_init_one()
1035 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); in i7300_init_one()
1038 if (PCI_FUNC(pdev->devfn) != 0) in i7300_init_one()
1039 return -ENODEV; in i7300_init_one()
1053 return -ENOMEM; in i7300_init_one()
1057 mci->pdev = &pdev->dev; /* record ptr to the generic device */ in i7300_init_one()
1059 pvt = mci->pvt_info; in i7300_init_one()
1060 pvt->pci_dev_16_0_fsb_ctlr = pdev; /* Record this device in our private */ in i7300_init_one()
1062 pvt->tmp_prt_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); in i7300_init_one()
1063 if (!pvt->tmp_prt_buffer) { in i7300_init_one()
1065 return -ENOMEM; in i7300_init_one()
1068 /* 'get' the pci devices we want to reserve for our use */ in i7300_init_one()
1072 mci->mc_idx = 0; in i7300_init_one()
1073 mci->mtype_cap = MEM_FLAG_FB_DDR2; in i7300_init_one()
1074 mci->edac_ctl_cap = EDAC_FLAG_NONE; in i7300_init_one()
1075 mci->edac_cap = EDAC_FLAG_NONE; in i7300_init_one()
1076 mci->mod_name = "i7300_edac.c"; in i7300_init_one()
1077 mci->ctl_name = i7300_devs[0].ctl_name; in i7300_init_one()
1078 mci->dev_name = pci_name(pdev); in i7300_init_one()
1079 mci->ctl_page_to_phys = NULL; in i7300_init_one()
1081 /* Set the function pointer to an actual operation function */ in i7300_init_one()
1082 mci->edac_check = i7300_check_error; in i7300_init_one()
1087 …edac_dbg(0, "MC: Setting mci->edac_cap to EDAC_FLAG_NONE because i7300_init_csrows() returned nonz… in i7300_init_one()
1088 mci->edac_cap = EDAC_FLAG_NONE; /* no csrows found */ in i7300_init_one()
1094 /* add this new MC control structure to EDAC's list of MCs */ in i7300_init_one()
1106 i7300_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); in i7300_init_one()
1109 "%s(): Unable to create PCI control\n", in i7300_init_one()
1124 kfree(pvt->tmp_prt_buffer); in i7300_init_one()
1126 return -ENODEV; in i7300_init_one()
1130 * i7300_remove_one() - Remove the driver
1143 mci = edac_mc_del_mc(&pdev->dev); in i7300_remove_one()
1147 tmp = ((struct i7300_pvt *)mci->pvt_info)->tmp_prt_buffer; in i7300_remove_one()
1149 /* retrieve references to resources, and free those resources */ in i7300_remove_one()
1179 * i7300_init() - Registers the driver
1196 * i7300_exit() - Unregisters the driver
1210 MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - "