diff options
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd64_edac.c | 65 | ||||
-rw-r--r-- | drivers/edac/amd64_edac.h | 4 | ||||
-rw-r--r-- | drivers/edac/i7300_edac.c | 19 | ||||
-rw-r--r-- | drivers/edac/sb_edac.c | 53 |
4 files changed, 111 insertions, 30 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index e1d13c463c90..8b6a0343c220 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -98,6 +98,7 @@ int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset, | |||
98 | * | 98 | * |
99 | * F15h: we select which DCT we access using F1x10C[DctCfgSel] | 99 | * F15h: we select which DCT we access using F1x10C[DctCfgSel] |
100 | * | 100 | * |
101 | * F16h: has only 1 DCT | ||
101 | */ | 102 | */ |
102 | static int k8_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, | 103 | static int k8_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, |
103 | const char *func) | 104 | const char *func) |
@@ -340,6 +341,27 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct, | |||
340 | base_bits = GENMASK(21, 31) | GENMASK(9, 15); | 341 | base_bits = GENMASK(21, 31) | GENMASK(9, 15); |
341 | mask_bits = GENMASK(21, 29) | GENMASK(9, 15); | 342 | mask_bits = GENMASK(21, 29) | GENMASK(9, 15); |
342 | addr_shift = 4; | 343 | addr_shift = 4; |
344 | |||
345 | /* | ||
346 | * F16h needs two addr_shift values: 8 for high and 6 for low | ||
347 | * (cf. F16h BKDG). | ||
348 | */ | ||
349 | } else if (boot_cpu_data.x86 == 0x16) { | ||
350 | csbase = pvt->csels[dct].csbases[csrow]; | ||
351 | csmask = pvt->csels[dct].csmasks[csrow >> 1]; | ||
352 | |||
353 | *base = (csbase & GENMASK(5, 15)) << 6; | ||
354 | *base |= (csbase & GENMASK(19, 30)) << 8; | ||
355 | |||
356 | *mask = ~0ULL; | ||
357 | /* poke holes for the csmask */ | ||
358 | *mask &= ~((GENMASK(5, 15) << 6) | | ||
359 | (GENMASK(19, 30) << 8)); | ||
360 | |||
361 | *mask |= (csmask & GENMASK(5, 15)) << 6; | ||
362 | *mask |= (csmask & GENMASK(19, 30)) << 8; | ||
363 | |||
364 | return; | ||
343 | } else { | 365 | } else { |
344 | csbase = pvt->csels[dct].csbases[csrow]; | 366 | csbase = pvt->csels[dct].csbases[csrow]; |
345 | csmask = pvt->csels[dct].csmasks[csrow >> 1]; | 367 | csmask = pvt->csels[dct].csmasks[csrow >> 1]; |
@@ -1150,6 +1172,21 @@ static int f15_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | |||
1150 | return ddr3_cs_size(cs_mode, false); | 1172 | return ddr3_cs_size(cs_mode, false); |
1151 | } | 1173 | } |
1152 | 1174 | ||
1175 | /* | ||
1176 | * F16h has only limited cs_modes | ||
1177 | */ | ||
1178 | static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, | ||
1179 | unsigned cs_mode) | ||
1180 | { | ||
1181 | WARN_ON(cs_mode > 12); | ||
1182 | |||
1183 | if (cs_mode == 6 || cs_mode == 8 || | ||
1184 | cs_mode == 9 || cs_mode == 12) | ||
1185 | return -1; | ||
1186 | else | ||
1187 | return ddr3_cs_size(cs_mode, false); | ||
1188 | } | ||
1189 | |||
1153 | static void read_dram_ctl_register(struct amd64_pvt *pvt) | 1190 | static void read_dram_ctl_register(struct amd64_pvt *pvt) |
1154 | { | 1191 | { |
1155 | 1192 | ||
@@ -1587,6 +1624,17 @@ static struct amd64_family_type amd64_family_types[] = { | |||
1587 | .read_dct_pci_cfg = f15_read_dct_pci_cfg, | 1624 | .read_dct_pci_cfg = f15_read_dct_pci_cfg, |
1588 | } | 1625 | } |
1589 | }, | 1626 | }, |
1627 | [F16_CPUS] = { | ||
1628 | .ctl_name = "F16h", | ||
1629 | .f1_id = PCI_DEVICE_ID_AMD_16H_NB_F1, | ||
1630 | .f3_id = PCI_DEVICE_ID_AMD_16H_NB_F3, | ||
1631 | .ops = { | ||
1632 | .early_channel_count = f1x_early_channel_count, | ||
1633 | .map_sysaddr_to_csrow = f1x_map_sysaddr_to_csrow, | ||
1634 | .dbam_to_cs = f16_dbam_to_chip_select, | ||
1635 | .read_dct_pci_cfg = f10_read_dct_pci_cfg, | ||
1636 | } | ||
1637 | }, | ||
1590 | }; | 1638 | }; |
1591 | 1639 | ||
1592 | /* | 1640 | /* |
@@ -1939,7 +1987,9 @@ static void read_mc_regs(struct amd64_pvt *pvt) | |||
1939 | 1987 | ||
1940 | if (c->x86 >= 0x10) { | 1988 | if (c->x86 >= 0x10) { |
1941 | amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp); | 1989 | amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp); |
1942 | amd64_read_dct_pci_cfg(pvt, DBAM1, &pvt->dbam1); | 1990 | if (c->x86 != 0x16) |
1991 | /* F16h has only DCT0 */ | ||
1992 | amd64_read_dct_pci_cfg(pvt, DBAM1, &pvt->dbam1); | ||
1943 | 1993 | ||
1944 | /* F10h, revD and later can do x8 ECC too */ | 1994 | /* F10h, revD and later can do x8 ECC too */ |
1945 | if ((c->x86 > 0x10 || c->x86_model > 7) && tmp & BIT(25)) | 1995 | if ((c->x86 > 0x10 || c->x86_model > 7) && tmp & BIT(25)) |
@@ -2356,6 +2406,11 @@ static struct amd64_family_type *amd64_per_family_init(struct amd64_pvt *pvt) | |||
2356 | pvt->ops = &amd64_family_types[F15_CPUS].ops; | 2406 | pvt->ops = &amd64_family_types[F15_CPUS].ops; |
2357 | break; | 2407 | break; |
2358 | 2408 | ||
2409 | case 0x16: | ||
2410 | fam_type = &amd64_family_types[F16_CPUS]; | ||
2411 | pvt->ops = &amd64_family_types[F16_CPUS].ops; | ||
2412 | break; | ||
2413 | |||
2359 | default: | 2414 | default: |
2360 | amd64_err("Unsupported family!\n"); | 2415 | amd64_err("Unsupported family!\n"); |
2361 | return NULL; | 2416 | return NULL; |
@@ -2581,6 +2636,14 @@ static DEFINE_PCI_DEVICE_TABLE(amd64_pci_table) = { | |||
2581 | .class = 0, | 2636 | .class = 0, |
2582 | .class_mask = 0, | 2637 | .class_mask = 0, |
2583 | }, | 2638 | }, |
2639 | { | ||
2640 | .vendor = PCI_VENDOR_ID_AMD, | ||
2641 | .device = PCI_DEVICE_ID_AMD_16H_NB_F2, | ||
2642 | .subvendor = PCI_ANY_ID, | ||
2643 | .subdevice = PCI_ANY_ID, | ||
2644 | .class = 0, | ||
2645 | .class_mask = 0, | ||
2646 | }, | ||
2584 | 2647 | ||
2585 | {0, } | 2648 | {0, } |
2586 | }; | 2649 | }; |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 35637d83f235..2c6f113bae2b 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -172,7 +172,8 @@ | |||
172 | */ | 172 | */ |
173 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 | 173 | #define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 |
174 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 | 174 | #define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 |
175 | 175 | #define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531 | |
176 | #define PCI_DEVICE_ID_AMD_16H_NB_F2 0x1532 | ||
176 | 177 | ||
177 | /* | 178 | /* |
178 | * Function 1 - Address Map | 179 | * Function 1 - Address Map |
@@ -296,6 +297,7 @@ enum amd_families { | |||
296 | K8_CPUS = 0, | 297 | K8_CPUS = 0, |
297 | F10_CPUS, | 298 | F10_CPUS, |
298 | F15_CPUS, | 299 | F15_CPUS, |
300 | F16_CPUS, | ||
299 | NUM_FAMILIES, | 301 | NUM_FAMILIES, |
300 | }; | 302 | }; |
301 | 303 | ||
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 087c27bc5d42..9004c64b169e 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
@@ -750,15 +750,23 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) | |||
750 | struct i7300_dimm_info *dinfo; | 750 | struct i7300_dimm_info *dinfo; |
751 | int rc = -ENODEV; | 751 | int rc = -ENODEV; |
752 | int mtr; | 752 | int mtr; |
753 | int ch, branch, slot, channel; | 753 | int ch, branch, slot, channel, max_channel, max_branch; |
754 | struct dimm_info *dimm; | 754 | struct dimm_info *dimm; |
755 | 755 | ||
756 | pvt = mci->pvt_info; | 756 | pvt = mci->pvt_info; |
757 | 757 | ||
758 | edac_dbg(2, "Memory Technology Registers:\n"); | 758 | edac_dbg(2, "Memory Technology Registers:\n"); |
759 | 759 | ||
760 | if (IS_SINGLE_MODE(pvt->mc_settings_a)) { | ||
761 | max_branch = 1; | ||
762 | max_channel = 1; | ||
763 | } else { | ||
764 | max_branch = MAX_BRANCHES; | ||
765 | max_channel = MAX_CH_PER_BRANCH; | ||
766 | } | ||
767 | |||
760 | /* Get the AMB present registers for the four channels */ | 768 | /* Get the AMB present registers for the four channels */ |
761 | for (branch = 0; branch < MAX_BRANCHES; branch++) { | 769 | for (branch = 0; branch < max_branch; branch++) { |
762 | /* Read and dump branch 0's MTRs */ | 770 | /* Read and dump branch 0's MTRs */ |
763 | channel = to_channel(0, branch); | 771 | channel = to_channel(0, branch); |
764 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], | 772 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], |
@@ -767,6 +775,9 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) | |||
767 | edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", | 775 | edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", |
768 | channel, pvt->ambpresent[channel]); | 776 | channel, pvt->ambpresent[channel]); |
769 | 777 | ||
778 | if (max_channel == 1) | ||
779 | continue; | ||
780 | |||
770 | channel = to_channel(1, branch); | 781 | channel = to_channel(1, branch); |
771 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], | 782 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], |
772 | AMBPRESENT_1, | 783 | AMBPRESENT_1, |
@@ -778,11 +789,11 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) | |||
778 | /* Get the set of MTR[0-7] regs by each branch */ | 789 | /* Get the set of MTR[0-7] regs by each branch */ |
779 | for (slot = 0; slot < MAX_SLOTS; slot++) { | 790 | for (slot = 0; slot < MAX_SLOTS; slot++) { |
780 | int where = mtr_regs[slot]; | 791 | int where = mtr_regs[slot]; |
781 | for (branch = 0; branch < MAX_BRANCHES; branch++) { | 792 | for (branch = 0; branch < max_branch; branch++) { |
782 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], | 793 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], |
783 | where, | 794 | where, |
784 | &pvt->mtr[slot][branch]); | 795 | &pvt->mtr[slot][branch]); |
785 | for (ch = 0; ch < MAX_CH_PER_BRANCH; ch++) { | 796 | for (ch = 0; ch < max_channel; ch++) { |
786 | int channel = to_channel(ch, branch); | 797 | int channel = to_channel(ch, branch); |
787 | 798 | ||
788 | dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, | 799 | dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, |
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 57244f995614..e04462b60756 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c | |||
@@ -331,30 +331,31 @@ struct sbridge_pvt { | |||
331 | u64 tolm, tohm; | 331 | u64 tolm, tohm; |
332 | }; | 332 | }; |
333 | 333 | ||
334 | #define PCI_DESCR(device, function, device_id) \ | 334 | #define PCI_DESCR(device, function, device_id, opt) \ |
335 | .dev = (device), \ | 335 | .dev = (device), \ |
336 | .func = (function), \ | 336 | .func = (function), \ |
337 | .dev_id = (device_id) | 337 | .dev_id = (device_id), \ |
338 | .optional = opt | ||
338 | 339 | ||
339 | static const struct pci_id_descr pci_dev_descr_sbridge[] = { | 340 | static const struct pci_id_descr pci_dev_descr_sbridge[] = { |
340 | /* Processor Home Agent */ | 341 | /* Processor Home Agent */ |
341 | { PCI_DESCR(14, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0) }, | 342 | { PCI_DESCR(14, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0, 0) }, |
342 | 343 | ||
343 | /* Memory controller */ | 344 | /* Memory controller */ |
344 | { PCI_DESCR(15, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA) }, | 345 | { PCI_DESCR(15, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA, 0) }, |
345 | { PCI_DESCR(15, 1, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS) }, | 346 | { PCI_DESCR(15, 1, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS, 0) }, |
346 | { PCI_DESCR(15, 2, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0) }, | 347 | { PCI_DESCR(15, 2, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD0, 0) }, |
347 | { PCI_DESCR(15, 3, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1) }, | 348 | { PCI_DESCR(15, 3, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1, 0) }, |
348 | { PCI_DESCR(15, 4, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2) }, | 349 | { PCI_DESCR(15, 4, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2, 0) }, |
349 | { PCI_DESCR(15, 5, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3) }, | 350 | { PCI_DESCR(15, 5, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3, 0) }, |
350 | { PCI_DESCR(17, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO) }, | 351 | { PCI_DESCR(17, 0, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO, 1) }, |
351 | 352 | ||
352 | /* System Address Decoder */ | 353 | /* System Address Decoder */ |
353 | { PCI_DESCR(12, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0) }, | 354 | { PCI_DESCR(12, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0, 0) }, |
354 | { PCI_DESCR(12, 7, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1) }, | 355 | { PCI_DESCR(12, 7, PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1, 0) }, |
355 | 356 | ||
356 | /* Broadcast Registers */ | 357 | /* Broadcast Registers */ |
357 | { PCI_DESCR(13, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_BR) }, | 358 | { PCI_DESCR(13, 6, PCI_DEVICE_ID_INTEL_SBRIDGE_BR, 0) }, |
358 | }; | 359 | }; |
359 | 360 | ||
360 | #define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) } | 361 | #define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) } |
@@ -556,14 +557,19 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
556 | pvt->is_close_pg = false; | 557 | pvt->is_close_pg = false; |
557 | } | 558 | } |
558 | 559 | ||
559 | pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); | 560 | if (pvt->pci_ddrio) { |
560 | if (IS_RDIMM_ENABLED(reg)) { | 561 | pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); |
561 | /* FIXME: Can also be LRDIMM */ | 562 | if (IS_RDIMM_ENABLED(reg)) { |
562 | edac_dbg(0, "Memory is registered\n"); | 563 | /* FIXME: Can also be LRDIMM */ |
563 | mtype = MEM_RDDR3; | 564 | edac_dbg(0, "Memory is registered\n"); |
565 | mtype = MEM_RDDR3; | ||
566 | } else { | ||
567 | edac_dbg(0, "Memory is unregistered\n"); | ||
568 | mtype = MEM_DDR3; | ||
569 | } | ||
564 | } else { | 570 | } else { |
565 | edac_dbg(0, "Memory is unregistered\n"); | 571 | edac_dbg(0, "Cannot determine memory type\n"); |
566 | mtype = MEM_DDR3; | 572 | mtype = MEM_UNKNOWN; |
567 | } | 573 | } |
568 | 574 | ||
569 | /* On all supported DDR3 DIMM types, there are 8 banks available */ | 575 | /* On all supported DDR3 DIMM types, there are 8 banks available */ |
@@ -1303,8 +1309,7 @@ static int mci_bind_devs(struct mem_ctl_info *mci, | |||
1303 | 1309 | ||
1304 | /* Check if everything were registered */ | 1310 | /* Check if everything were registered */ |
1305 | if (!pvt->pci_sad0 || !pvt->pci_sad1 || !pvt->pci_ha0 || | 1311 | if (!pvt->pci_sad0 || !pvt->pci_sad1 || !pvt->pci_ha0 || |
1306 | !pvt-> pci_tad || !pvt->pci_ras || !pvt->pci_ta || | 1312 | !pvt-> pci_tad || !pvt->pci_ras || !pvt->pci_ta) |
1307 | !pvt->pci_ddrio) | ||
1308 | goto enodev; | 1313 | goto enodev; |
1309 | 1314 | ||
1310 | for (i = 0; i < NUM_CHANNELS; i++) { | 1315 | for (i = 0; i < NUM_CHANNELS; i++) { |