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#
49 * Branch 0 - 2 channels: channels 0 and 1 (FDB0 PCI dev 21.0)
50 * Branch 1 - 2 channels: channels 2 and 3 (FDB1 PCI dev 22.0)
51 * Each channel can have to 8 DIMM sets (called as SLOTS)
116 /* FIXME: Why do we need to have this static? */
151 * Note: Other Intel EDAC drivers use AMBPRESENT to identify if the available
152 * memory. From datasheet item 7.3.1 (FB-DIMM technology & organization), it
154 * Each memory slot may have up to 2 AMB interfaces, one for income and another
155 * for outcome interface to the next slot.
157 * the MTR info to detect memory.
158 * Datasheet is also not clear about how to map each AMBPRESENT registers to
170 * Defines to extract the vaious fields from the
171 * MTRx - Memory Technology Registers
193 [22] = "Non-Redundant Fast Reset Timeout",
196 [0] = "Memory Write error on non-redundant retry or "
204 [24] = "DIMM-Spare Copy Completed",
205 [23] = "DIMM-Spare Copy Initiated",
211 [15] = "Correctable Resilver- or Spare-Copy Data ECC",
213 [13] = "Correctable Non-Mirrored Demand Data ECC",
217 [8] = "Non-Aliased Uncorrectable Patrol Data ECC",
218 [7] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
219 [6] = "Non-Aliased Uncorrectable Mirrored Demand Data ECC",
220 [5] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC",
222 [3] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
224 [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
275 [15] = "Internal MCH Non-Fatal Error",
277 [13] = "FSB1 Non-Fatal Error",
278 [12] = "FSB 0 Non-Fatal Error",
279 [11] = "FBD Channel 3 Non-Fatal Error",
280 [10] = "FBD Channel 2 Non-Fatal Error",
281 [9] = "FBD Channel 1 Non-Fatal Error",
282 [8] = "FBD Channel 0 Non-Fatal Error",
283 [7] = "PCI Express Device 7 Non-Fatal Error",
284 [6] = "PCI Express Device 6 Non-Fatal Error",
285 [5] = "PCI Express Device 5 Non-Fatal Error",
286 [4] = "PCI Express Device 4 Non-Fatal Error",
287 [3] = "PCI Express Device 3 Non-Fatal Error",
288 [2] = "PCI Express Device 2 Non-Fatal Error",
289 [1] = "PCI Express Device 1 Non-Fatal Error",
290 [0] = "ESI Non-Fatal Error",
317 * i7300 Functions related to error detection
321 * get_err_from_table() - Gets the error message from a table
324 * @pos: position of the element to be returned
326 * This is a small routine that gets the pos-th element of a table. If the
328 * Instead of calling it directly, the better is to call via the macro
347 * i7300_process_error_global() - Retrieve the hardware error information from
349 * sends it to dmesg
360 pvt = mci->pvt_info; in i7300_process_error_global()
363 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
373 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
379 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
389 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_process_error_global()
402 * i7300_process_fbd_error() - Retrieve the hardware error information from
412 unsigned branch, channel, bank, rank, cas, ras; in i7300_process_fbd_error() local
419 pvt = mci->pvt_info; in i7300_process_fbd_error()
422 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
431 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
436 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
439 cas = NRECMEMB_CAS(value); in i7300_process_fbd_error()
440 ras = NRECMEMB_RAS(value); in i7300_process_fbd_error()
443 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
446 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, in i7300_process_fbd_error()
447 "Bank=%d RAS=%d CAS=%d Err=0x%lx (%s))", in i7300_process_fbd_error()
448 bank, ras, cas, errors, specific); in i7300_process_fbd_error()
451 branch, -1, rank, in i7300_process_fbd_error()
453 pvt->tmp_prt_buffer); in i7300_process_fbd_error()
457 /* read in the 1st NON-FATAL error register */ in i7300_process_fbd_error()
458 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
467 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
470 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
475 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
478 cas = RECMEMB_CAS(value); in i7300_process_fbd_error()
479 ras = RECMEMB_RAS(value); in i7300_process_fbd_error()
481 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
489 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_process_fbd_error()
493 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, in i7300_process_fbd_error()
494 "DRAM-Bank=%d RAS=%d CAS=%d, Err=0x%lx (%s))", in i7300_process_fbd_error()
495 bank, ras, cas, errors, specific); in i7300_process_fbd_error()
501 pvt->tmp_prt_buffer); in i7300_process_fbd_error()
507 * i7300_check_error() - Calls the error checking subroutines
517 * i7300_clear_error() - Clears the error registers
522 struct i7300_pvt *pvt = mci->pvt_info; in i7300_clear_error()
525 * All error values are RWC - we need to read and write 1 to the in i7300_clear_error()
526 * bit that we want to cleanup in i7300_clear_error()
530 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
532 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
535 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
537 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, in i7300_clear_error()
541 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
543 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
546 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
548 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_clear_error()
553 * i7300_enable_error_reporting() - Enable the memory reporting logic at the
559 struct i7300_pvt *pvt = mci->pvt_info; in i7300_enable_error_reporting()
563 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_enable_error_reporting()
569 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, in i7300_enable_error_reporting()
574 * i7300 Functions related to memory enumberation
578 * decode_mtr() - Decodes the MTR descriptor, filling the edac structs
579 * @pvt: pointer to the private data struct used by i7300 driver
580 * @slot: DIMM slot (0 to 7)
583 * @dinfo: Pointer to DIMM info where dimm size is stored
584 * @dimm: Pointer to the struct dimm_info that corresponds to that element
595 mtr = pvt->mtr[slot][branch]; in decode_mtr()
616 addrBits -= 20; /* divide by 2^^20 */ in decode_mtr()
617 addrBits -= 3; /* 8 bits per bytes */ in decode_mtr()
619 dinfo->megabytes = 1 << addrBits; in decode_mtr()
630 MTR_DIMM_ROWS(mtr) == 0 ? "8,192 - 13 rows" : in decode_mtr()
631 MTR_DIMM_ROWS(mtr) == 1 ? "16,384 - 14 rows" : in decode_mtr()
632 MTR_DIMM_ROWS(mtr) == 2 ? "32,768 - 15 rows" : in decode_mtr()
633 "65,536 - 16 rows"); in decode_mtr()
635 MTR_DIMM_COLS(mtr) == 0 ? "1,024 - 10 columns" : in decode_mtr()
636 MTR_DIMM_COLS(mtr) == 1 ? "2,048 - 11 columns" : in decode_mtr()
637 MTR_DIMM_COLS(mtr) == 2 ? "4,096 - 12 columns" : in decode_mtr()
639 edac_dbg(2, "\t\tSIZE: %d MB\n", dinfo->megabytes); in decode_mtr()
644 * socket 0, channel 0, it uses 8-byte-over-32-byte SECDED+ code. in decode_mtr()
647 * See datasheet Sections 7.3.6 to 7.3.8 in decode_mtr()
650 dimm->nr_pages = MiB_TO_PAGES(dinfo->megabytes); in decode_mtr()
651 dimm->grain = 8; in decode_mtr()
652 dimm->mtype = MEM_FB_DDR2; in decode_mtr()
653 if (IS_SINGLE_MODE(pvt->mc_settings_a)) { in decode_mtr()
654 dimm->edac_mode = EDAC_SECDED; in decode_mtr()
655 edac_dbg(2, "\t\tECC code is 8-byte-over-32-byte SECDED+ code\n"); in decode_mtr()
659 dimm->edac_mode = EDAC_S8ECD8ED; in decode_mtr()
661 dimm->edac_mode = EDAC_S4ECD4ED; in decode_mtr()
667 IS_SCRBALGO_ENHANCED(pvt->mc_settings) ? in decode_mtr()
670 dimm->dtype = DEV_X8; in decode_mtr()
672 dimm->dtype = DEV_X4; in decode_mtr()
678 * print_dimm_size() - Prints dump of the memory organization
679 * @pvt: pointer to the private data struct used by i7300 driver
692 p = pvt->tmp_prt_buffer; in print_dimm_size()
696 space -= n; in print_dimm_size()
700 space -= n; in print_dimm_size()
702 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
703 p = pvt->tmp_prt_buffer; in print_dimm_size()
705 n = snprintf(p, space, "-------------------------------" in print_dimm_size()
706 "------------------------------"); in print_dimm_size()
708 space -= n; in print_dimm_size()
709 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
710 p = pvt->tmp_prt_buffer; in print_dimm_size()
716 space -= n; in print_dimm_size()
719 dinfo = &pvt->dimm_info[slot][channel]; in print_dimm_size()
720 n = snprintf(p, space, "%4d MB | ", dinfo->megabytes); in print_dimm_size()
722 space -= n; in print_dimm_size()
725 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
726 p = pvt->tmp_prt_buffer; in print_dimm_size()
730 n = snprintf(p, space, "-------------------------------" in print_dimm_size()
731 "------------------------------"); in print_dimm_size()
733 space -= n; in print_dimm_size()
734 edac_dbg(2, "%s\n", pvt->tmp_prt_buffer); in print_dimm_size()
735 p = pvt->tmp_prt_buffer; in print_dimm_size()
741 * i7300_init_csrows() - Initialize the 'csrows' table within
750 int rc = -ENODEV; in i7300_init_csrows()
755 pvt = mci->pvt_info; in i7300_init_csrows()
759 if (IS_SINGLE_MODE(pvt->mc_settings_a)) { in i7300_init_csrows()
771 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
773 &pvt->ambpresent[channel]); in i7300_init_csrows()
774 edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", in i7300_init_csrows()
775 channel, pvt->ambpresent[channel]); in i7300_init_csrows()
781 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
783 &pvt->ambpresent[channel]); in i7300_init_csrows()
784 edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", in i7300_init_csrows()
785 channel, pvt->ambpresent[channel]); in i7300_init_csrows()
788 /* Get the set of MTR[0-7] regs by each branch */ in i7300_init_csrows()
792 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], in i7300_init_csrows()
794 &pvt->mtr[slot][branch]); in i7300_init_csrows()
800 dinfo = &pvt->dimm_info[slot][channel]; in i7300_init_csrows()
819 * decode_mir() - Decodes Memory Interleave Register (MIR) info
820 * @mir_no: number of the MIR register to decode
834 * i7300_get_mc_regs() - Get the contents of the MC enumeration registers
845 pvt = mci->pvt_info; in i7300_get_mc_regs()
847 pci_read_config_dword(pvt->pci_dev_16_0_fsb_ctlr, AMBASE, in i7300_get_mc_regs()
848 (u32 *) &pvt->ambase); in i7300_get_mc_regs()
850 edac_dbg(2, "AMBASE= 0x%lx\n", (long unsigned int)pvt->ambase); in i7300_get_mc_regs()
853 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, TOLM, &pvt->tolm); in i7300_get_mc_regs()
854 pvt->tolm >>= 12; in i7300_get_mc_regs()
856 pvt->tolm, pvt->tolm); in i7300_get_mc_regs()
858 actual_tolm = (u32) ((1000l * pvt->tolm) >> (30 - 28)); in i7300_get_mc_regs()
860 actual_tolm/1000, actual_tolm % 1000, pvt->tolm << 28); in i7300_get_mc_regs()
863 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS, in i7300_get_mc_regs()
864 &pvt->mc_settings); in i7300_get_mc_regs()
865 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS_A, in i7300_get_mc_regs()
866 &pvt->mc_settings_a); in i7300_get_mc_regs()
868 if (IS_SINGLE_MODE(pvt->mc_settings_a)) in i7300_get_mc_regs()
872 IS_MIRRORED(pvt->mc_settings) ? "" : "non-"); in i7300_get_mc_regs()
875 str_enabled_disabled(IS_ECC_ENABLED(pvt->mc_settings))); in i7300_get_mc_regs()
877 str_enabled_disabled(IS_RETRY_ENABLED(pvt->mc_settings))); in i7300_get_mc_regs()
880 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR0, in i7300_get_mc_regs()
881 &pvt->mir[0]); in i7300_get_mc_regs()
882 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR1, in i7300_get_mc_regs()
883 &pvt->mir[1]); in i7300_get_mc_regs()
884 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR2, in i7300_get_mc_regs()
885 &pvt->mir[2]); in i7300_get_mc_regs()
889 decode_mir(i, pvt->mir); in i7300_get_mc_regs()
903 * i7300 Functions related to device probe/release
907 * i7300_put_devices() - Release the PCI devices
915 pvt = mci->pvt_info; in i7300_put_devices()
919 pci_dev_put(pvt->pci_dev_2x_0_fbd_branch[branch]); in i7300_put_devices()
920 pci_dev_put(pvt->pci_dev_16_2_fsb_err_regs); in i7300_put_devices()
921 pci_dev_put(pvt->pci_dev_16_1_fsb_addr_map); in i7300_put_devices()
925 * i7300_get_devices() - Find and perform 'get' operation on the MCH's
926 * device/functions we want to reference for this driver
940 pvt = mci->pvt_info; in i7300_get_devices()
942 /* Attempt to 'get' the MCH register we want */ in i7300_get_devices()
948 switch (PCI_FUNC(pdev->devfn)) { in i7300_get_devices()
950 if (!pvt->pci_dev_16_1_fsb_addr_map) in i7300_get_devices()
951 pvt->pci_dev_16_1_fsb_addr_map = in i7300_get_devices()
955 if (!pvt->pci_dev_16_2_fsb_err_regs) in i7300_get_devices()
956 pvt->pci_dev_16_2_fsb_err_regs = in i7300_get_devices()
962 if (!pvt->pci_dev_16_1_fsb_addr_map || in i7300_get_devices()
963 !pvt->pci_dev_16_2_fsb_err_regs) { in i7300_get_devices()
973 edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
974 pci_name(pvt->pci_dev_16_0_fsb_ctlr), in i7300_get_devices()
975 pvt->pci_dev_16_0_fsb_ctlr->vendor, in i7300_get_devices()
976 pvt->pci_dev_16_0_fsb_ctlr->device); in i7300_get_devices()
977 edac_dbg(1, "Branchmap, control and errors - PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
978 pci_name(pvt->pci_dev_16_1_fsb_addr_map), in i7300_get_devices()
979 pvt->pci_dev_16_1_fsb_addr_map->vendor, in i7300_get_devices()
980 pvt->pci_dev_16_1_fsb_addr_map->device); in i7300_get_devices()
981 edac_dbg(1, "FSB Error Regs - PCI Bus ID: %s %x:%x\n", in i7300_get_devices()
982 pci_name(pvt->pci_dev_16_2_fsb_err_regs), in i7300_get_devices()
983 pvt->pci_dev_16_2_fsb_err_regs->vendor, in i7300_get_devices()
984 pvt->pci_dev_16_2_fsb_err_regs->device); in i7300_get_devices()
986 pvt->pci_dev_2x_0_fbd_branch[0] = pci_get_device(PCI_VENDOR_ID_INTEL, in i7300_get_devices()
989 if (!pvt->pci_dev_2x_0_fbd_branch[0]) { in i7300_get_devices()
997 pvt->pci_dev_2x_0_fbd_branch[1] = pci_get_device(PCI_VENDOR_ID_INTEL, in i7300_get_devices()
1000 if (!pvt->pci_dev_2x_0_fbd_branch[1]) { in i7300_get_devices()
1014 return -ENODEV; in i7300_get_devices()
1018 * i7300_init_one() - Probe for one instance of the device
1020 * @id: struct pci_device_id pointer - currently unused
1031 if (rc == -EIO) in i7300_init_one()
1035 pdev->bus->number, in i7300_init_one()
1036 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); in i7300_init_one()
1039 if (PCI_FUNC(pdev->devfn) != 0) in i7300_init_one()
1040 return -ENODEV; in i7300_init_one()
1054 return -ENOMEM; in i7300_init_one()
1058 mci->pdev = &pdev->dev; /* record ptr to the generic device */ in i7300_init_one()
1060 pvt = mci->pvt_info; in i7300_init_one()
1061 pvt->pci_dev_16_0_fsb_ctlr = pdev; /* Record this device in our private */ in i7300_init_one()
1063 pvt->tmp_prt_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); in i7300_init_one()
1064 if (!pvt->tmp_prt_buffer) { in i7300_init_one()
1066 return -ENOMEM; in i7300_init_one()
1069 /* 'get' the pci devices we want to reserve for our use */ in i7300_init_one()
1073 mci->mc_idx = 0; in i7300_init_one()
1074 mci->mtype_cap = MEM_FLAG_FB_DDR2; in i7300_init_one()
1075 mci->edac_ctl_cap = EDAC_FLAG_NONE; in i7300_init_one()
1076 mci->edac_cap = EDAC_FLAG_NONE; in i7300_init_one()
1077 mci->mod_name = "i7300_edac.c"; in i7300_init_one()
1078 mci->ctl_name = i7300_devs[0].ctl_name; in i7300_init_one()
1079 mci->dev_name = pci_name(pdev); in i7300_init_one()
1080 mci->ctl_page_to_phys = NULL; in i7300_init_one()
1082 /* Set the function pointer to an actual operation function */ in i7300_init_one()
1083 mci->edac_check = i7300_check_error; in i7300_init_one()
1088 …edac_dbg(0, "MC: Setting mci->edac_cap to EDAC_FLAG_NONE because i7300_init_csrows() returned nonz… in i7300_init_one()
1089 mci->edac_cap = EDAC_FLAG_NONE; /* no csrows found */ in i7300_init_one()
1095 /* add this new MC control structure to EDAC's list of MCs */ in i7300_init_one()
1107 i7300_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); in i7300_init_one()
1110 "%s(): Unable to create PCI control\n", in i7300_init_one()
1125 kfree(pvt->tmp_prt_buffer); in i7300_init_one()
1127 return -ENODEV; in i7300_init_one()
1131 * i7300_remove_one() - Remove the driver
1144 mci = edac_mc_del_mc(&pdev->dev); in i7300_remove_one()
1148 tmp = ((struct i7300_pvt *)mci->pvt_info)->tmp_prt_buffer; in i7300_remove_one()
1150 /* retrieve references to resources, and free those resources */ in i7300_remove_one()
1180 * i7300_init() - Registers the driver
1197 * i7300_exit() - Unregisters the driver
1211 MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - "