aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 14:58:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 14:58:50 -0500
commit709d9f09b6aee5828cb8f168f63030608176cd0e (patch)
treefeb2690c528eee4cf91885dfe4e4e7e889810c12 /drivers/edac
parent2183a58803c2bbd87c2d0057eed6779ec4718d4d (diff)
parentfec53af531dd040e41fe358abe00b33747af2688 (diff)
Merge tag 'edac/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac
Pull edac updates from Mauro Carvalho Chehab: - Broadwell-DE support on sb-edac driver - Some fixes at sb-edac driver * tag 'edac/v3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac: sb_edac: Fix typo computing number of banks sb_edac: Add support for Broadwell-DE processor sb_edac: Fix discovery of top-of-low-memory for Haswell sb_edac: Fix erroneous bytes->gigabytes conversion sb_edac: Fix off-by-one error in number of channels
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_mc_sysfs.c2
-rw-r--r--drivers/edac/sb_edac.c208
2 files changed, 182 insertions, 28 deletions
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index a6cd36100663..670d2829c547 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -372,7 +372,7 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
372{ 372{
373 int err, chan; 373 int err, chan;
374 374
375 if (csrow->nr_channels >= EDAC_NR_CHANNELS) 375 if (csrow->nr_channels > EDAC_NR_CHANNELS)
376 return -ENODEV; 376 return -ENODEV;
377 377
378 csrow->dev.type = &csrow_attr_type; 378 csrow->dev.type = &csrow_attr_type;
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index e9bb1af67c8d..63aa6730e89e 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -135,6 +135,7 @@ static inline int sad_pkg(const struct interleave_pkg *table, u32 reg,
135 135
136#define TOLM 0x80 136#define TOLM 0x80
137#define TOHM 0x84 137#define TOHM 0x84
138#define HASWELL_TOLM 0xd0
138#define HASWELL_TOHM_0 0xd4 139#define HASWELL_TOHM_0 0xd4
139#define HASWELL_TOHM_1 0xd8 140#define HASWELL_TOHM_1 0xd8
140 141
@@ -261,6 +262,7 @@ enum type {
261 SANDY_BRIDGE, 262 SANDY_BRIDGE,
262 IVY_BRIDGE, 263 IVY_BRIDGE,
263 HASWELL, 264 HASWELL,
265 BROADWELL,
264}; 266};
265 267
266struct sbridge_pvt; 268struct sbridge_pvt;
@@ -445,7 +447,7 @@ static const struct pci_id_table pci_dev_descr_ibridge_table[] = {
445 * - each SMI channel interfaces with a scalable memory buffer 447 * - each SMI channel interfaces with a scalable memory buffer
446 * - each scalable memory buffer supports 4 DDR3/DDR4 channels, 3 DPC 448 * - each scalable memory buffer supports 4 DDR3/DDR4 channels, 3 DPC
447 */ 449 */
448#define HASWELL_DDRCRCLKCONTROLS 0xa10 450#define HASWELL_DDRCRCLKCONTROLS 0xa10 /* Ditto on Broadwell */
449#define HASWELL_HASYSDEFEATURE2 0x84 451#define HASWELL_HASYSDEFEATURE2 0x84
450#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_VTD_MISC 0x2f28 452#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_VTD_MISC 0x2f28
451#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0 0x2fa0 453#define PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0 0x2fa0
@@ -497,12 +499,53 @@ static const struct pci_id_table pci_dev_descr_haswell_table[] = {
497}; 499};
498 500
499/* 501/*
502 * Broadwell support
503 *
504 * DE processor:
505 * - 1 IMC
506 * - 2 DDR3 channels, 2 DPC per channel
507 */
508#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_VTD_MISC 0x6f28
509#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0 0x6fa0
510#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA 0x6fa8
511#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_THERMAL 0x6f71
512#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD0 0x6ffc
513#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD1 0x6ffd
514#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD0 0x6faa
515#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD1 0x6fab
516#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD2 0x6fac
517#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD3 0x6fad
518#define PCI_DEVICE_ID_INTEL_BROADWELL_IMC_DDRIO0 0x6faf
519
520static const struct pci_id_descr pci_dev_descr_broadwell[] = {
521 /* first item must be the HA */
522 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0, 0) },
523
524 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD0, 0) },
525 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD1, 0) },
526
527 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA, 0) },
528 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_THERMAL, 0) },
529 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD0, 0) },
530 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD1, 0) },
531 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD2, 0) },
532 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD3, 0) },
533 { PCI_DESCR(PCI_DEVICE_ID_INTEL_BROADWELL_IMC_DDRIO0, 1) },
534};
535
536static const struct pci_id_table pci_dev_descr_broadwell_table[] = {
537 PCI_ID_TABLE_ENTRY(pci_dev_descr_broadwell),
538 {0,} /* 0 terminated list. */
539};
540
541/*
500 * pci_device_id table for which devices we are looking for 542 * pci_device_id table for which devices we are looking for
501 */ 543 */
502static const struct pci_device_id sbridge_pci_tbl[] = { 544static const struct pci_device_id sbridge_pci_tbl[] = {
503 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0)}, 545 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_HA0)},
504 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)}, 546 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA)},
505 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0)}, 547 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0)},
548 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0)},
506 {0,} /* 0 terminated list. */ 549 {0,} /* 0 terminated list. */
507}; 550};
508 551
@@ -706,8 +749,8 @@ static u64 haswell_get_tolm(struct sbridge_pvt *pvt)
706{ 749{
707 u32 reg; 750 u32 reg;
708 751
709 pci_read_config_dword(pvt->info.pci_vtd, TOLM, &reg); 752 pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOLM, &reg);
710 return (GET_BITFIELD(reg, 26, 31) << 26) | 0x1ffffff; 753 return (GET_BITFIELD(reg, 26, 31) << 26) | 0x3ffffff;
711} 754}
712 755
713static u64 haswell_get_tohm(struct sbridge_pvt *pvt) 756static u64 haswell_get_tohm(struct sbridge_pvt *pvt)
@@ -767,12 +810,22 @@ static int check_if_ecc_is_active(const u8 bus, enum type type)
767 struct pci_dev *pdev = NULL; 810 struct pci_dev *pdev = NULL;
768 u32 mcmtr, id; 811 u32 mcmtr, id;
769 812
770 if (type == IVY_BRIDGE) 813 switch (type) {
814 case IVY_BRIDGE:
771 id = PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA; 815 id = PCI_DEVICE_ID_INTEL_IBRIDGE_IMC_HA0_TA;
772 else if (type == HASWELL) 816 break;
817 case HASWELL:
773 id = PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA; 818 id = PCI_DEVICE_ID_INTEL_HASWELL_IMC_HA0_TA;
774 else 819 break;
820 case SANDY_BRIDGE:
775 id = PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA; 821 id = PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TA;
822 break;
823 case BROADWELL:
824 id = PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA;
825 break;
826 default:
827 return -ENODEV;
828 }
776 829
777 pdev = get_pdev_same_bus(bus, id); 830 pdev = get_pdev_same_bus(bus, id);
778 if (!pdev) { 831 if (!pdev) {
@@ -800,7 +853,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
800 enum edac_type mode; 853 enum edac_type mode;
801 enum mem_type mtype; 854 enum mem_type mtype;
802 855
803 if (pvt->info.type == HASWELL) 856 if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL)
804 pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, &reg); 857 pci_read_config_dword(pvt->pci_sad1, SAD_TARGET, &reg);
805 else 858 else
806 pci_read_config_dword(pvt->pci_br0, SAD_TARGET, &reg); 859 pci_read_config_dword(pvt->pci_br0, SAD_TARGET, &reg);
@@ -848,7 +901,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
848 else 901 else
849 edac_dbg(0, "Memory is unregistered\n"); 902 edac_dbg(0, "Memory is unregistered\n");
850 903
851 if (mtype == MEM_DDR4 || MEM_RDDR4) 904 if (mtype == MEM_DDR4 || mtype == MEM_RDDR4)
852 banks = 16; 905 banks = 16;
853 else 906 else
854 banks = 8; 907 banks = 8;
@@ -909,7 +962,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
909 u32 reg; 962 u32 reg;
910 u64 limit, prv = 0; 963 u64 limit, prv = 0;
911 u64 tmp_mb; 964 u64 tmp_mb;
912 u32 mb, kb; 965 u32 gb, mb;
913 u32 rir_way; 966 u32 rir_way;
914 967
915 /* 968 /*
@@ -919,15 +972,17 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
919 pvt->tolm = pvt->info.get_tolm(pvt); 972 pvt->tolm = pvt->info.get_tolm(pvt);
920 tmp_mb = (1 + pvt->tolm) >> 20; 973 tmp_mb = (1 + pvt->tolm) >> 20;
921 974
922 mb = div_u64_rem(tmp_mb, 1000, &kb); 975 gb = div_u64_rem(tmp_mb, 1024, &mb);
923 edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm); 976 edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n",
977 gb, (mb*1000)/1024, (u64)pvt->tolm);
924 978
925 /* Address range is already 45:25 */ 979 /* Address range is already 45:25 */
926 pvt->tohm = pvt->info.get_tohm(pvt); 980 pvt->tohm = pvt->info.get_tohm(pvt);
927 tmp_mb = (1 + pvt->tohm) >> 20; 981 tmp_mb = (1 + pvt->tohm) >> 20;
928 982
929 mb = div_u64_rem(tmp_mb, 1000, &kb); 983 gb = div_u64_rem(tmp_mb, 1024, &mb);
930 edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tohm); 984 edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n",
985 gb, (mb*1000)/1024, (u64)pvt->tohm);
931 986
932 /* 987 /*
933 * Step 2) Get SAD range and SAD Interleave list 988 * Step 2) Get SAD range and SAD Interleave list
@@ -949,11 +1004,11 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
949 break; 1004 break;
950 1005
951 tmp_mb = (limit + 1) >> 20; 1006 tmp_mb = (limit + 1) >> 20;
952 mb = div_u64_rem(tmp_mb, 1000, &kb); 1007 gb = div_u64_rem(tmp_mb, 1024, &mb);
953 edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n", 1008 edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n",
954 n_sads, 1009 n_sads,
955 get_dram_attr(reg), 1010 get_dram_attr(reg),
956 mb, kb, 1011 gb, (mb*1000)/1024,
957 ((u64)tmp_mb) << 20L, 1012 ((u64)tmp_mb) << 20L,
958 INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]", 1013 INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]",
959 reg); 1014 reg);
@@ -984,9 +1039,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
984 break; 1039 break;
985 tmp_mb = (limit + 1) >> 20; 1040 tmp_mb = (limit + 1) >> 20;
986 1041
987 mb = div_u64_rem(tmp_mb, 1000, &kb); 1042 gb = div_u64_rem(tmp_mb, 1024, &mb);
988 edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n", 1043 edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n",
989 n_tads, mb, kb, 1044 n_tads, gb, (mb*1000)/1024,
990 ((u64)tmp_mb) << 20L, 1045 ((u64)tmp_mb) << 20L,
991 (u32)TAD_SOCK(reg), 1046 (u32)TAD_SOCK(reg),
992 (u32)TAD_CH(reg), 1047 (u32)TAD_CH(reg),
@@ -1009,10 +1064,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
1009 tad_ch_nilv_offset[j], 1064 tad_ch_nilv_offset[j],
1010 &reg); 1065 &reg);
1011 tmp_mb = TAD_OFFSET(reg) >> 20; 1066 tmp_mb = TAD_OFFSET(reg) >> 20;
1012 mb = div_u64_rem(tmp_mb, 1000, &kb); 1067 gb = div_u64_rem(tmp_mb, 1024, &mb);
1013 edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n", 1068 edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n",
1014 i, j, 1069 i, j,
1015 mb, kb, 1070 gb, (mb*1000)/1024,
1016 ((u64)tmp_mb) << 20L, 1071 ((u64)tmp_mb) << 20L,
1017 reg); 1072 reg);
1018 } 1073 }
@@ -1034,10 +1089,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
1034 1089
1035 tmp_mb = pvt->info.rir_limit(reg) >> 20; 1090 tmp_mb = pvt->info.rir_limit(reg) >> 20;
1036 rir_way = 1 << RIR_WAY(reg); 1091 rir_way = 1 << RIR_WAY(reg);
1037 mb = div_u64_rem(tmp_mb, 1000, &kb); 1092 gb = div_u64_rem(tmp_mb, 1024, &mb);
1038 edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", 1093 edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n",
1039 i, j, 1094 i, j,
1040 mb, kb, 1095 gb, (mb*1000)/1024,
1041 ((u64)tmp_mb) << 20L, 1096 ((u64)tmp_mb) << 20L,
1042 rir_way, 1097 rir_way,
1043 reg); 1098 reg);
@@ -1048,10 +1103,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
1048 &reg); 1103 &reg);
1049 tmp_mb = RIR_OFFSET(reg) << 6; 1104 tmp_mb = RIR_OFFSET(reg) << 6;
1050 1105
1051 mb = div_u64_rem(tmp_mb, 1000, &kb); 1106 gb = div_u64_rem(tmp_mb, 1024, &mb);
1052 edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n", 1107 edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
1053 i, j, k, 1108 i, j, k,
1054 mb, kb, 1109 gb, (mb*1000)/1024,
1055 ((u64)tmp_mb) << 20L, 1110 ((u64)tmp_mb) << 20L,
1056 (u32)RIR_RNK_TGT(reg), 1111 (u32)RIR_RNK_TGT(reg),
1057 reg); 1112 reg);
@@ -1089,7 +1144,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
1089 u8 ch_way, sck_way, pkg, sad_ha = 0; 1144 u8 ch_way, sck_way, pkg, sad_ha = 0;
1090 u32 tad_offset; 1145 u32 tad_offset;
1091 u32 rir_way; 1146 u32 rir_way;
1092 u32 mb, kb; 1147 u32 mb, gb;
1093 u64 ch_addr, offset, limit = 0, prv = 0; 1148 u64 ch_addr, offset, limit = 0, prv = 0;
1094 1149
1095 1150
@@ -1179,7 +1234,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
1179 *socket = sad_interleave[idx]; 1234 *socket = sad_interleave[idx];
1180 edac_dbg(0, "SAD interleave index: %d (wayness %d) = CPU socket %d\n", 1235 edac_dbg(0, "SAD interleave index: %d (wayness %d) = CPU socket %d\n",
1181 idx, sad_way, *socket); 1236 idx, sad_way, *socket);
1182 } else if (pvt->info.type == HASWELL) { 1237 } else if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
1183 int bits, a7mode = A7MODE(dram_rule); 1238 int bits, a7mode = A7MODE(dram_rule);
1184 1239
1185 if (a7mode) { 1240 if (a7mode) {
@@ -1358,10 +1413,10 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
1358 continue; 1413 continue;
1359 1414
1360 limit = pvt->info.rir_limit(reg); 1415 limit = pvt->info.rir_limit(reg);
1361 mb = div_u64_rem(limit >> 20, 1000, &kb); 1416 gb = div_u64_rem(limit >> 20, 1024, &mb);
1362 edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", 1417 edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n",
1363 n_rir, 1418 n_rir,
1364 mb, kb, 1419 gb, (mb*1000)/1024,
1365 limit, 1420 limit,
1366 1 << RIR_WAY(reg)); 1421 1 << RIR_WAY(reg));
1367 if (ch_addr <= limit) 1422 if (ch_addr <= limit)
@@ -1828,6 +1883,82 @@ enodev:
1828 return -ENODEV; 1883 return -ENODEV;
1829} 1884}
1830 1885
1886static int broadwell_mci_bind_devs(struct mem_ctl_info *mci,
1887 struct sbridge_dev *sbridge_dev)
1888{
1889 struct sbridge_pvt *pvt = mci->pvt_info;
1890 struct pci_dev *pdev;
1891 int i;
1892
1893 /* there's only one device per system; not tied to any bus */
1894 if (pvt->info.pci_vtd == NULL)
1895 /* result will be checked later */
1896 pvt->info.pci_vtd = pci_get_device(PCI_VENDOR_ID_INTEL,
1897 PCI_DEVICE_ID_INTEL_BROADWELL_IMC_VTD_MISC,
1898 NULL);
1899
1900 for (i = 0; i < sbridge_dev->n_devs; i++) {
1901 pdev = sbridge_dev->pdev[i];
1902 if (!pdev)
1903 continue;
1904
1905 switch (pdev->device) {
1906 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD0:
1907 pvt->pci_sad0 = pdev;
1908 break;
1909 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_CBO_SAD1:
1910 pvt->pci_sad1 = pdev;
1911 break;
1912 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0:
1913 pvt->pci_ha0 = pdev;
1914 break;
1915 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TA:
1916 pvt->pci_ta = pdev;
1917 break;
1918 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_THERMAL:
1919 pvt->pci_ras = pdev;
1920 break;
1921 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD0:
1922 pvt->pci_tad[0] = pdev;
1923 break;
1924 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD1:
1925 pvt->pci_tad[1] = pdev;
1926 break;
1927 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD2:
1928 pvt->pci_tad[2] = pdev;
1929 break;
1930 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0_TAD3:
1931 pvt->pci_tad[3] = pdev;
1932 break;
1933 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_DDRIO0:
1934 pvt->pci_ddrio = pdev;
1935 break;
1936 default:
1937 break;
1938 }
1939
1940 edac_dbg(0, "Associated PCI %02x.%02d.%d with dev = %p\n",
1941 sbridge_dev->bus,
1942 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1943 pdev);
1944 }
1945
1946 /* Check if everything were registered */
1947 if (!pvt->pci_sad0 || !pvt->pci_ha0 || !pvt->pci_sad1 ||
1948 !pvt->pci_ras || !pvt->pci_ta || !pvt->info.pci_vtd)
1949 goto enodev;
1950
1951 for (i = 0; i < NUM_CHANNELS; i++) {
1952 if (!pvt->pci_tad[i])
1953 goto enodev;
1954 }
1955 return 0;
1956
1957enodev:
1958 sbridge_printk(KERN_ERR, "Some needed devices are missing\n");
1959 return -ENODEV;
1960}
1961
1831/**************************************************************************** 1962/****************************************************************************
1832 Error check routines 1963 Error check routines
1833 ****************************************************************************/ 1964 ****************************************************************************/
@@ -2240,6 +2371,25 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev, enum type type)
2240 if (unlikely(rc < 0)) 2371 if (unlikely(rc < 0))
2241 goto fail0; 2372 goto fail0;
2242 break; 2373 break;
2374 case BROADWELL:
2375 /* rankcfgr isn't used */
2376 pvt->info.get_tolm = haswell_get_tolm;
2377 pvt->info.get_tohm = haswell_get_tohm;
2378 pvt->info.dram_rule = ibridge_dram_rule;
2379 pvt->info.get_memory_type = haswell_get_memory_type;
2380 pvt->info.get_node_id = haswell_get_node_id;
2381 pvt->info.rir_limit = haswell_rir_limit;
2382 pvt->info.max_sad = ARRAY_SIZE(ibridge_dram_rule);
2383 pvt->info.interleave_list = ibridge_interleave_list;
2384 pvt->info.max_interleave = ARRAY_SIZE(ibridge_interleave_list);
2385 pvt->info.interleave_pkg = ibridge_interleave_pkg;
2386 mci->ctl_name = kasprintf(GFP_KERNEL, "Broadwell Socket#%d", mci->mc_idx);
2387
2388 /* Store pci devices at mci for faster access */
2389 rc = broadwell_mci_bind_devs(mci, sbridge_dev);
2390 if (unlikely(rc < 0))
2391 goto fail0;
2392 break;
2243 } 2393 }
2244 2394
2245 /* Get dimm basic config and the memory layout */ 2395 /* Get dimm basic config and the memory layout */
@@ -2305,6 +2455,10 @@ static int sbridge_probe(struct pci_dev *pdev, const struct pci_device_id *id)
2305 rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_haswell_table); 2455 rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_haswell_table);
2306 type = HASWELL; 2456 type = HASWELL;
2307 break; 2457 break;
2458 case PCI_DEVICE_ID_INTEL_BROADWELL_IMC_HA0:
2459 rc = sbridge_get_all_devices(&num_mc, pci_dev_descr_broadwell_table);
2460 type = BROADWELL;
2461 break;
2308 } 2462 }
2309 if (unlikely(rc < 0)) 2463 if (unlikely(rc < 0))
2310 goto fail0; 2464 goto fail0;