• Home
  • Raw
  • Download

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

9  * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
13 * can not reflect this configuration so instead the chip-select
15 * the first half belonging to channel 0, the second half belonging
16 * to channel 1.
18 * This driver is for DDR2 DIMMs, and it uses chip select to select among the
70 #define I5100_NERR_NF_MEM 0xa4 /* MC Next Non-Fatal Errors */
82 #define I5100_MTR_0 0x154 /* Memory Technology Registers 0-3 */
85 #define I5100_NRECMEMA 0x190 /* Non-Recoverable Memory Error Log Reg A */
86 #define I5100_NRECMEMB 0x194 /* Non-Recoverable Memory Error Log Reg B */
127 return a & ((1 << 8) - 1); in i5100_spddata_data()
133 return ((dti & ((1 << 4) - 1)) << 28) | in i5100_spdcmd_create()
135 ((sa & ((1 << 3) - 1)) << 24) | in i5100_spdcmd_create()
136 ((ba & ((1 << 8) - 1)) << 16) | in i5100_spdcmd_create()
137 ((data & ((1 << 8) - 1)) << 8) | in i5100_spdcmd_create()
143 return a >> 12 & ((1 << 4) - 1); in i5100_tolm_tolm()
148 return a >> 4 & ((1 << 12) - 1); in i5100_mir_limit()
178 return a >> 16 & ((1 << 11) - 1); in i5100_dmir_limit()
183 return a >> (4 * i) & ((1 << 2) - 1); in i5100_dmir_rank()
208 return a >> 2 & ((1 << 2) - 1); in i5100_mtr_numrow()
213 return a & ((1 << 2) - 1); in i5100_mtr_numcol()
234 return a >> 15 & ((1 << 5) - 1); in i5100_nrecmema_merr()
239 return a >> 12 & ((1 << 3) - 1); in i5100_nrecmema_bank()
244 return a >> 8 & ((1 << 3) - 1); in i5100_nrecmema_rank()
249 return a & ((1 << 8) - 1); in i5100_nrecmema_dm_buf_id()
254 return a >> 16 & ((1 << 13) - 1); in i5100_nrecmemb_cas()
259 return a & ((1 << 16) - 1); in i5100_nrecmemb_ras()
291 #define I5100_DIMM_ADDR_LINES (6 - 3) /* 64 bits / 8 bits per byte */
298 /* ranks on each dimm -- 0 maps to not present -- obtained via SPD */
302 * mainboard chip select map -- maps i5100 chip selects to
305 * we map -1 -> NC and assume both channels use the same
360 /* map a rank/chan to a slot number on the mainboard */
364 const struct i5100_priv *priv = mci->pvt_info; in i5100_rank_to_slot()
369 const int numrank = priv->dimm_numrank[chan][i]; in i5100_rank_to_slot()
372 if (priv->dimm_csmap[i][j] == rank) in i5100_rank_to_slot()
376 return -1; in i5100_rank_to_slot()
387 "aliased uncorrectable spare-copy data ECC", /* 5 */ in i5100_err_msg()
392 "non-aliased uncorrectable demand data ECC", /* 10 */ in i5100_err_msg()
393 "non-aliased uncorrectable spare-copy data ECC", /* 11 */ in i5100_err_msg()
394 "non-aliased uncorrectable patrol data ECC", /* 12 */ in i5100_err_msg()
397 "correctable spare-copy data ECC", /* 15 */ in i5100_err_msg()
414 /* convert csrow index into a rank (per channel -- 0..5) */
418 const struct i5100_priv *priv = mci->pvt_info; in i5100_csrow_to_rank()
420 return csrow % priv->ranksperchan; in i5100_csrow_to_rank()
427 const struct i5100_priv *priv = mci->pvt_info; in i5100_csrow_to_chan()
429 return csrow / priv->ranksperchan; in i5100_csrow_to_chan()
437 unsigned cas, in i5100_handle_ce() argument
438 unsigned ras, in i5100_handle_ce() argument
445 "bank %u, cas %u, ras %u\n", in i5100_handle_ce()
446 bank, cas, ras); in i5100_handle_ce()
450 chan, rank, -1, in i5100_handle_ce()
459 unsigned cas, in i5100_handle_ue() argument
460 unsigned ras, in i5100_handle_ue() argument
467 "bank %u, cas %u, ras %u\n", in i5100_handle_ue()
468 bank, cas, ras); in i5100_handle_ue()
472 chan, rank, -1, in i5100_handle_ue()
479 struct i5100_priv *priv = mci->pvt_info; in i5100_read_log()
480 struct pci_dev *pdev = (chan) ? priv->ch1mm : priv->ch0mm; in i5100_read_log()
487 unsigned cas; in i5100_read_log() local
488 unsigned ras; in i5100_read_log() local
507 cas = i5100_recmemb_cas(dw2); in i5100_read_log()
508 ras = i5100_recmemb_ras(dw2); in i5100_read_log()
517 i5100_handle_ce(mci, chan, bank, rank, syndrome, cas, ras, msg); in i5100_read_log()
529 cas = i5100_nrecmemb_cas(dw2); in i5100_read_log()
530 ras = i5100_nrecmemb_ras(dw2); in i5100_read_log()
539 i5100_handle_ue(mci, chan, bank, rank, syndrome, cas, ras, msg); in i5100_read_log()
547 struct i5100_priv *priv = mci->pvt_info; in i5100_check_error()
550 pci_read_config_dword(priv->mc, I5100_FERR_NF_MEM, &dw); in i5100_check_error()
553 pci_read_config_dword(priv->mc, I5100_NERR_NF_MEM, &dw2); in i5100_check_error()
559 pci_write_config_dword(priv->mc, I5100_NERR_NF_MEM, dw2); in i5100_check_error()
561 pci_write_config_dword(priv->mc, I5100_FERR_NF_MEM, dw); in i5100_check_error()
566 * delayed work to a workqueue, checking every few minutes if
578 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_refresh_scrubbing()
580 if (priv->scrub_enable) { in i5100_refresh_scrubbing()
582 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_refresh_scrubbing()
586 pci_write_config_dword(priv->mc, I5100_MC, dw); in i5100_refresh_scrubbing()
587 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_refresh_scrubbing()
590 schedule_delayed_work(&(priv->i5100_scrubbing), in i5100_refresh_scrubbing()
595 * The bandwidth is based on experimentation, feel free to refine it.
599 struct i5100_priv *priv = mci->pvt_info; in i5100_set_scrub_rate()
602 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_set_scrub_rate()
604 priv->scrub_enable = 1; in i5100_set_scrub_rate()
606 schedule_delayed_work(&(priv->i5100_scrubbing), in i5100_set_scrub_rate()
609 priv->scrub_enable = 0; in i5100_set_scrub_rate()
611 cancel_delayed_work(&(priv->i5100_scrubbing)); in i5100_set_scrub_rate()
613 pci_write_config_dword(priv->mc, I5100_MC, dw); in i5100_set_scrub_rate()
615 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_set_scrub_rate()
624 struct i5100_priv *priv = mci->pvt_info; in i5100_get_scrub_rate()
627 pci_read_config_dword(priv->mc, I5100_MC, &dw); in i5100_get_scrub_rate()
644 if (PCI_FUNC(ret->devfn) == func) in pci_get_device_func()
653 struct i5100_priv *priv = mci->pvt_info; in i5100_npages()
659 if (!priv->mtr[chan][chan_rank].present) in i5100_npages()
664 priv->mtr[chan][chan_rank].numcol + in i5100_npages()
665 priv->mtr[chan][chan_rank].numrow + in i5100_npages()
666 priv->mtr[chan][chan_rank].numbank; in i5100_npages()
674 struct i5100_priv *priv = mci->pvt_info; in i5100_init_mtr()
675 struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm }; in i5100_init_mtr()
685 I5100_MTR_4 + (j - 4) * 2; in i5100_init_mtr()
690 priv->mtr[i][j].present = i5100_mtr_present(w); in i5100_init_mtr()
691 priv->mtr[i][j].ethrottle = i5100_mtr_ethrottle(w); in i5100_init_mtr()
692 priv->mtr[i][j].width = 4 + 4 * i5100_mtr_width(w); in i5100_init_mtr()
693 priv->mtr[i][j].numbank = 2 + i5100_mtr_numbank(w); in i5100_init_mtr()
694 priv->mtr[i][j].numrow = 13 + i5100_mtr_numrow(w); in i5100_init_mtr()
695 priv->mtr[i][j].numcol = 10 + i5100_mtr_numcol(w); in i5100_init_mtr()
701 * FIXME: make this into a real i2c adapter (so that dimm-decode
707 struct i5100_priv *priv = mci->pvt_info; in i5100_read_spd_byte()
710 pci_read_config_word(priv->mc, I5100_SPDDATA, &w); in i5100_read_spd_byte()
712 return -1; in i5100_read_spd_byte()
714 pci_write_config_dword(priv->mc, I5100_SPDCMD, in i5100_read_spd_byte()
718 /* wait up to 100ms */ in i5100_read_spd_byte()
721 pci_read_config_word(priv->mc, I5100_SPDDATA, &w); in i5100_read_spd_byte()
728 return -1; in i5100_read_spd_byte()
739 * o not the only way to may chip selects to dimm slots
740 * o investigate if there is some way to obtain this map from the bios
744 struct i5100_priv *priv = mci->pvt_info; in i5100_init_dimm_csmap()
751 priv->dimm_csmap[i][j] = -1; /* default NC */ in i5100_init_dimm_csmap()
755 if (priv->ranksperchan == 4) { in i5100_init_dimm_csmap()
756 priv->dimm_csmap[0][0] = 0; in i5100_init_dimm_csmap()
757 priv->dimm_csmap[0][1] = 3; in i5100_init_dimm_csmap()
758 priv->dimm_csmap[1][0] = 1; in i5100_init_dimm_csmap()
759 priv->dimm_csmap[1][1] = 2; in i5100_init_dimm_csmap()
760 priv->dimm_csmap[2][0] = 2; in i5100_init_dimm_csmap()
761 priv->dimm_csmap[3][0] = 3; in i5100_init_dimm_csmap()
763 priv->dimm_csmap[0][0] = 0; in i5100_init_dimm_csmap()
764 priv->dimm_csmap[0][1] = 1; in i5100_init_dimm_csmap()
765 priv->dimm_csmap[1][0] = 2; in i5100_init_dimm_csmap()
766 priv->dimm_csmap[1][1] = 3; in i5100_init_dimm_csmap()
767 priv->dimm_csmap[2][0] = 4; in i5100_init_dimm_csmap()
768 priv->dimm_csmap[2][1] = 5; in i5100_init_dimm_csmap()
775 struct i5100_priv *priv = mci->pvt_info; in i5100_init_dimm_layout()
785 priv->dimm_numrank[i][j] = 0; in i5100_init_dimm_layout()
787 priv->dimm_numrank[i][j] = (rank & 3) + 1; in i5100_init_dimm_layout()
799 struct i5100_priv *priv = mci->pvt_info; in i5100_init_interleaving()
800 struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm }; in i5100_init_interleaving()
804 priv->tolm = (u64) i5100_tolm_tolm(w) * 256 * 1024 * 1024; in i5100_init_interleaving()
807 priv->mir[0].limit = (u64) i5100_mir_limit(w) << 28; in i5100_init_interleaving()
808 priv->mir[0].way[1] = i5100_mir_way1(w); in i5100_init_interleaving()
809 priv->mir[0].way[0] = i5100_mir_way0(w); in i5100_init_interleaving()
812 priv->mir[1].limit = (u64) i5100_mir_limit(w) << 28; in i5100_init_interleaving()
813 priv->mir[1].way[1] = i5100_mir_way1(w); in i5100_init_interleaving()
814 priv->mir[1].way[0] = i5100_mir_way0(w); in i5100_init_interleaving()
817 priv->amir[0] = w; in i5100_init_interleaving()
819 priv->amir[1] = w; in i5100_init_interleaving()
829 priv->dmir[i][j].limit = in i5100_init_interleaving()
832 priv->dmir[i][j].rank[k] = in i5100_init_interleaving()
842 struct i5100_priv *priv = mci->pvt_info; in i5100_init_csrows()
846 const unsigned long npages = i5100_npages(mci, dimm->idx); in i5100_init_csrows()
847 const unsigned int chan = i5100_csrow_to_chan(mci, dimm->idx); in i5100_init_csrows()
848 const unsigned int rank = i5100_csrow_to_rank(mci, dimm->idx); in i5100_init_csrows()
853 dimm->nr_pages = npages; in i5100_init_csrows()
854 dimm->grain = 32; in i5100_init_csrows()
855 dimm->dtype = (priv->mtr[chan][rank].width == 4) ? in i5100_init_csrows()
857 dimm->mtype = MEM_RDDR2; in i5100_init_csrows()
858 dimm->edac_mode = EDAC_SECDED; in i5100_init_csrows()
859 snprintf(dimm->label, sizeof(dimm->label), "DIMM%u", in i5100_init_csrows()
873 struct i5100_priv *priv = mci->pvt_info; in i5100_do_inject()
878 * 31 - ADDRMATCHEN in i5100_do_inject()
879 * 29:28 - HLINESEL in i5100_do_inject()
884 * 27 - EINJEN in i5100_do_inject()
885 * 25:19 - XORMASK1 for deviceptr1 in i5100_do_inject()
886 * 9:5 - SEC2RAM for deviceptr2 in i5100_do_inject()
887 * 4:0 - FIR2RAM for deviceptr1 in i5100_do_inject()
889 mask0 = ((priv->inject_hlinesel & 0x3) << 28) | in i5100_do_inject()
891 ((priv->inject_eccmask1 & 0xffff) << 10) | in i5100_do_inject()
892 ((priv->inject_deviceptr2 & 0x1f) << 5) | in i5100_do_inject()
893 (priv->inject_deviceptr1 & 0x1f); in i5100_do_inject()
896 * 15:0 - XORMASK2 for deviceptr2 in i5100_do_inject()
898 mask1 = priv->inject_eccmask2; in i5100_do_inject()
900 if (priv->inject_channel == 0) { in i5100_do_inject()
901 pci_write_config_dword(priv->mc, I5100_MEM0EINJMSK0, mask0); in i5100_do_inject()
902 pci_write_config_word(priv->mc, I5100_MEM0EINJMSK1, mask1); in i5100_do_inject()
904 pci_write_config_dword(priv->mc, I5100_MEM1EINJMSK0, mask0); in i5100_do_inject()
905 pci_write_config_word(priv->mc, I5100_MEM1EINJMSK1, mask1); in i5100_do_inject()
913 * which appears to be accurate for the i5100 in this area. in i5100_do_inject()
916 * The register needs to be flipped off then on else the hardware in i5100_do_inject()
920 * 1010 - Stop after one injection in i5100_do_inject()
921 * 1011 - Never stop injecting faults in i5100_do_inject()
924 * 1010 - Never start in i5100_do_inject()
925 * 1011 - Start immediately in i5100_do_inject()
927 pci_write_config_byte(priv->einj, I5100_DINJ0, 0xaa); in i5100_do_inject()
928 pci_write_config_byte(priv->einj, I5100_DINJ0, 0xab); in i5100_do_inject()
935 struct device *dev = file->private_data; in inject_enable_write()
951 struct i5100_priv *priv = mci->pvt_info; in i5100_setup_debugfs()
954 return -ENODEV; in i5100_setup_debugfs()
956 priv->debugfs = edac_debugfs_create_dir_at(mci->bus->name, i5100_debugfs); in i5100_setup_debugfs()
958 if (!priv->debugfs) in i5100_setup_debugfs()
959 return -ENOMEM; in i5100_setup_debugfs()
961 edac_debugfs_create_x8("inject_channel", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
962 &priv->inject_channel); in i5100_setup_debugfs()
963 edac_debugfs_create_x8("inject_hlinesel", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
964 &priv->inject_hlinesel); in i5100_setup_debugfs()
965 edac_debugfs_create_x8("inject_deviceptr1", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
966 &priv->inject_deviceptr1); in i5100_setup_debugfs()
967 edac_debugfs_create_x8("inject_deviceptr2", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
968 &priv->inject_deviceptr2); in i5100_setup_debugfs()
969 edac_debugfs_create_x16("inject_eccmask1", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
970 &priv->inject_eccmask1); in i5100_setup_debugfs()
971 edac_debugfs_create_x16("inject_eccmask2", S_IRUGO | S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
972 &priv->inject_eccmask2); in i5100_setup_debugfs()
973 edac_debugfs_create_file("inject_enable", S_IWUSR, priv->debugfs, in i5100_setup_debugfs()
974 &mci->dev, &i5100_inject_enable_fops); in i5100_setup_debugfs()
991 if (PCI_FUNC(pdev->devfn) != 1) in i5100_init_one()
992 return -ENODEV; in i5100_init_one()
1004 ret = -ENODEV; in i5100_init_one()
1021 ret = -ENODEV; in i5100_init_one()
1035 ret = -ENODEV; in i5100_init_one()
1054 ret = -ENOMEM; in i5100_init_one()
1063 ret = -ENODEV; in i5100_init_one()
1073 mci->pdev = &pdev->dev; in i5100_init_one()
1075 priv = mci->pvt_info; in i5100_init_one()
1076 priv->ranksperchan = ranksperch; in i5100_init_one()
1077 priv->mc = pdev; in i5100_init_one()
1078 priv->ch0mm = ch0mm; in i5100_init_one()
1079 priv->ch1mm = ch1mm; in i5100_init_one()
1080 priv->einj = einj; in i5100_init_one()
1082 INIT_DELAYED_WORK(&(priv->i5100_scrubbing), i5100_refresh_scrubbing); in i5100_init_one()
1087 priv->scrub_enable = 1; in i5100_init_one()
1088 schedule_delayed_work(&(priv->i5100_scrubbing), in i5100_init_one()
1095 mci->mtype_cap = MEM_FLAG_FB_DDR2; in i5100_init_one()
1096 mci->edac_ctl_cap = EDAC_FLAG_SECDED; in i5100_init_one()
1097 mci->edac_cap = EDAC_FLAG_SECDED; in i5100_init_one()
1098 mci->mod_name = "i5100_edac.c"; in i5100_init_one()
1099 mci->ctl_name = "i5100"; in i5100_init_one()
1100 mci->dev_name = pci_name(pdev); in i5100_init_one()
1101 mci->ctl_page_to_phys = NULL; in i5100_init_one()
1103 mci->edac_check = i5100_check_error; in i5100_init_one()
1104 mci->set_sdram_scrub_rate = i5100_set_scrub_rate; in i5100_init_one()
1105 mci->get_sdram_scrub_rate = i5100_get_scrub_rate; in i5100_init_one()
1107 priv->inject_channel = 0; in i5100_init_one()
1108 priv->inject_hlinesel = 0; in i5100_init_one()
1109 priv->inject_deviceptr1 = 0; in i5100_init_one()
1110 priv->inject_deviceptr2 = 0; in i5100_init_one()
1111 priv->inject_eccmask1 = 0; in i5100_init_one()
1112 priv->inject_eccmask2 = 0; in i5100_init_one()
1116 /* this strange construction seems to be in every driver, dunno why */ in i5100_init_one()
1127 ret = -ENODEV; in i5100_init_one()
1136 priv->scrub_enable = 0; in i5100_init_one()
1137 cancel_delayed_work_sync(&(priv->i5100_scrubbing)); in i5100_init_one()
1170 mci = edac_mc_del_mc(&pdev->dev); in i5100_remove_one()
1175 priv = mci->pvt_info; in i5100_remove_one()
1177 edac_debugfs_remove_recursive(priv->debugfs); in i5100_remove_one()
1179 priv->scrub_enable = 0; in i5100_remove_one()
1180 cancel_delayed_work_sync(&(priv->i5100_scrubbing)); in i5100_remove_one()
1183 pci_disable_device(priv->ch0mm); in i5100_remove_one()
1184 pci_disable_device(priv->ch1mm); in i5100_remove_one()
1185 pci_disable_device(priv->einj); in i5100_remove_one()
1186 pci_dev_put(priv->ch0mm); in i5100_remove_one()
1187 pci_dev_put(priv->ch1mm); in i5100_remove_one()
1188 pci_dev_put(priv->einj); in i5100_remove_one()