|
@@ -1620,66 +1620,17 @@ static void get_source_id(struct mem_ctl_info *mci)
|
|
|
pvt->sbridge_dev->source_id = SOURCE_ID(reg);
|
|
|
}
|
|
|
|
|
|
-static int get_dimm_config(struct mem_ctl_info *mci)
|
|
|
+static void __populate_dimms(struct mem_ctl_info *mci,
|
|
|
+ u64 knl_mc_sizes[KNL_MAX_CHANNELS],
|
|
|
+ enum edac_type mode)
|
|
|
{
|
|
|
struct sbridge_pvt *pvt = mci->pvt_info;
|
|
|
+ int channels = pvt->info.type == KNIGHTS_LANDING ? KNL_MAX_CHANNELS
|
|
|
+ : NUM_CHANNELS;
|
|
|
+ unsigned int i, j, banks, ranks, rows, cols, npages;
|
|
|
struct dimm_info *dimm;
|
|
|
- unsigned i, j, banks, ranks, rows, cols, npages;
|
|
|
- u64 size;
|
|
|
- u32 reg;
|
|
|
- enum edac_type mode;
|
|
|
enum mem_type mtype;
|
|
|
- int channels = pvt->info.type == KNIGHTS_LANDING ?
|
|
|
- KNL_MAX_CHANNELS : NUM_CHANNELS;
|
|
|
- u64 knl_mc_sizes[KNL_MAX_CHANNELS];
|
|
|
-
|
|
|
- if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
|
|
|
- pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, ®);
|
|
|
- pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
|
|
|
- }
|
|
|
- pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
|
|
|
- edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
|
|
|
- pvt->sbridge_dev->mc,
|
|
|
- pvt->sbridge_dev->node_id,
|
|
|
- pvt->sbridge_dev->source_id);
|
|
|
-
|
|
|
- /* KNL doesn't support mirroring or lockstep,
|
|
|
- * and is always closed page
|
|
|
- */
|
|
|
- if (pvt->info.type == KNIGHTS_LANDING) {
|
|
|
- mode = EDAC_S4ECD4ED;
|
|
|
- pvt->is_mirrored = false;
|
|
|
-
|
|
|
- if (knl_get_dimm_capacity(pvt, knl_mc_sizes) != 0)
|
|
|
- return -1;
|
|
|
- } else {
|
|
|
- pci_read_config_dword(pvt->pci_ras, RASENABLES, ®);
|
|
|
- if (IS_MIRROR_ENABLED(reg)) {
|
|
|
- edac_dbg(0, "Memory mirror is enabled\n");
|
|
|
- pvt->is_mirrored = true;
|
|
|
- } else {
|
|
|
- edac_dbg(0, "Memory mirror is disabled\n");
|
|
|
- pvt->is_mirrored = false;
|
|
|
- }
|
|
|
-
|
|
|
- pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
|
|
|
- if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
|
|
|
- edac_dbg(0, "Lockstep is enabled\n");
|
|
|
- mode = EDAC_S8ECD8ED;
|
|
|
- pvt->is_lockstep = true;
|
|
|
- } else {
|
|
|
- edac_dbg(0, "Lockstep is disabled\n");
|
|
|
- mode = EDAC_S4ECD4ED;
|
|
|
- pvt->is_lockstep = false;
|
|
|
- }
|
|
|
- if (IS_CLOSE_PG(pvt->info.mcmtr)) {
|
|
|
- edac_dbg(0, "address map is on closed page mode\n");
|
|
|
- pvt->is_close_pg = true;
|
|
|
- } else {
|
|
|
- edac_dbg(0, "address map is on open page mode\n");
|
|
|
- pvt->is_close_pg = false;
|
|
|
- }
|
|
|
- }
|
|
|
+ u64 size;
|
|
|
|
|
|
mtype = pvt->info.get_memory_type(pvt);
|
|
|
if (mtype == MEM_RDDR3 || mtype == MEM_RDDR4)
|
|
@@ -1710,8 +1661,7 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
|
|
}
|
|
|
|
|
|
for (j = 0; j < max_dimms_per_channel; j++) {
|
|
|
- dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
|
|
|
- i, j, 0);
|
|
|
+ dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0);
|
|
|
if (pvt->info.type == KNIGHTS_LANDING) {
|
|
|
pci_read_config_dword(pvt->knl.pci_channel[i],
|
|
|
knl_mtr_reg, &mtr);
|
|
@@ -1754,6 +1704,64 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+static int get_dimm_config(struct mem_ctl_info *mci)
|
|
|
+{
|
|
|
+ struct sbridge_pvt *pvt = mci->pvt_info;
|
|
|
+ u64 knl_mc_sizes[KNL_MAX_CHANNELS];
|
|
|
+ enum edac_type mode;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ if (pvt->info.type == HASWELL || pvt->info.type == BROADWELL) {
|
|
|
+ pci_read_config_dword(pvt->pci_ha, HASWELL_HASYSDEFEATURE2, ®);
|
|
|
+ pvt->is_chan_hash = GET_BITFIELD(reg, 21, 21);
|
|
|
+ }
|
|
|
+ pvt->sbridge_dev->node_id = pvt->info.get_node_id(pvt);
|
|
|
+ edac_dbg(0, "mc#%d: Node ID: %d, source ID: %d\n",
|
|
|
+ pvt->sbridge_dev->mc,
|
|
|
+ pvt->sbridge_dev->node_id,
|
|
|
+ pvt->sbridge_dev->source_id);
|
|
|
+
|
|
|
+ /* KNL doesn't support mirroring or lockstep,
|
|
|
+ * and is always closed page
|
|
|
+ */
|
|
|
+ if (pvt->info.type == KNIGHTS_LANDING) {
|
|
|
+ mode = EDAC_S4ECD4ED;
|
|
|
+ pvt->is_mirrored = false;
|
|
|
+
|
|
|
+ if (knl_get_dimm_capacity(pvt, knl_mc_sizes) != 0)
|
|
|
+ return -1;
|
|
|
+ } else {
|
|
|
+ pci_read_config_dword(pvt->pci_ras, RASENABLES, ®);
|
|
|
+ if (IS_MIRROR_ENABLED(reg)) {
|
|
|
+ edac_dbg(0, "Memory mirror is enabled\n");
|
|
|
+ pvt->is_mirrored = true;
|
|
|
+ } else {
|
|
|
+ edac_dbg(0, "Memory mirror is disabled\n");
|
|
|
+ pvt->is_mirrored = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ pci_read_config_dword(pvt->pci_ta, MCMTR, &pvt->info.mcmtr);
|
|
|
+ if (IS_LOCKSTEP_ENABLED(pvt->info.mcmtr)) {
|
|
|
+ edac_dbg(0, "Lockstep is enabled\n");
|
|
|
+ mode = EDAC_S8ECD8ED;
|
|
|
+ pvt->is_lockstep = true;
|
|
|
+ } else {
|
|
|
+ edac_dbg(0, "Lockstep is disabled\n");
|
|
|
+ mode = EDAC_S4ECD4ED;
|
|
|
+ pvt->is_lockstep = false;
|
|
|
+ }
|
|
|
+ if (IS_CLOSE_PG(pvt->info.mcmtr)) {
|
|
|
+ edac_dbg(0, "address map is on closed page mode\n");
|
|
|
+ pvt->is_close_pg = true;
|
|
|
+ } else {
|
|
|
+ edac_dbg(0, "address map is on open page mode\n");
|
|
|
+ pvt->is_close_pg = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ __populate_dimms(mci, knl_mc_sizes, mode);
|
|
|
|
|
|
return 0;
|
|
|
}
|