Commit f84b7999 authored by Borislav Petkov's avatar Borislav Petkov

Merge branches 'edac-spr', 'edac-igen6' and 'edac-misc' into edac-updates-for-v5.11

Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
...@@ -2474,7 +2474,7 @@ F: drivers/clk/socfpga/ ...@@ -2474,7 +2474,7 @@ F: drivers/clk/socfpga/
ARM/SOCFPGA EDAC SUPPORT ARM/SOCFPGA EDAC SUPPORT
M: Dinh Nguyen <dinguyen@kernel.org> M: Dinh Nguyen <dinguyen@kernel.org>
S: Maintained S: Maintained
F: drivers/edac/altera_edac. F: drivers/edac/altera_edac.[ch]
ARM/SPREADTRUM SoC SUPPORT ARM/SPREADTRUM SoC SUPPORT
M: Orson Zhai <orsonzhai@gmail.com> M: Orson Zhai <orsonzhai@gmail.com>
...@@ -6351,6 +6351,13 @@ L: linux-edac@vger.kernel.org ...@@ -6351,6 +6351,13 @@ L: linux-edac@vger.kernel.org
S: Maintained S: Maintained
F: drivers/edac/ie31200_edac.c F: drivers/edac/ie31200_edac.c
EDAC-IGEN6
M: Tony Luck <tony.luck@intel.com>
R: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/igen6_edac.c
EDAC-MPC85XX EDAC-MPC85XX
M: Johannes Thumshirn <morbidrsa@gmail.com> M: Johannes Thumshirn <morbidrsa@gmail.com>
L: linux-edac@vger.kernel.org L: linux-edac@vger.kernel.org
...@@ -6400,7 +6407,7 @@ EDAC-SKYLAKE ...@@ -6400,7 +6407,7 @@ EDAC-SKYLAKE
M: Tony Luck <tony.luck@intel.com> M: Tony Luck <tony.luck@intel.com>
L: linux-edac@vger.kernel.org L: linux-edac@vger.kernel.org
S: Maintained S: Maintained
F: drivers/edac/skx_*.c F: drivers/edac/skx_*.[ch]
EDAC-TI EDAC-TI
M: Tero Kristo <t-kristo@ti.com> M: Tero Kristo <t-kristo@ti.com>
......
...@@ -269,6 +269,15 @@ config EDAC_PND2 ...@@ -269,6 +269,15 @@ config EDAC_PND2
first used on the Apollo Lake platform and Denverton first used on the Apollo Lake platform and Denverton
micro-server but may appear on others in the future. micro-server but may appear on others in the future.
config EDAC_IGEN6
tristate "Intel client SoC Integrated MC"
depends on PCI && X86_64 && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG
help
Support for error detection and correction on the Intel
client SoC Integrated Memory Controller using In-Band ECC IP.
This In-Band ECC is first used on the Elkhart Lake SoC but
may appear on others in the future.
config EDAC_MPC85XX config EDAC_MPC85XX
bool "Freescale MPC83xx / MPC85xx" bool "Freescale MPC83xx / MPC85xx"
depends on FSL_SOC && EDAC=y depends on FSL_SOC && EDAC=y
......
...@@ -32,6 +32,7 @@ obj-$(CONFIG_EDAC_I7300) += i7300_edac.o ...@@ -32,6 +32,7 @@ obj-$(CONFIG_EDAC_I7300) += i7300_edac.o
obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
obj-$(CONFIG_EDAC_SBRIDGE) += sb_edac.o obj-$(CONFIG_EDAC_SBRIDGE) += sb_edac.o
obj-$(CONFIG_EDAC_PND2) += pnd2_edac.o obj-$(CONFIG_EDAC_PND2) += pnd2_edac.o
obj-$(CONFIG_EDAC_IGEN6) += igen6_edac.o
obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
obj-$(CONFIG_EDAC_E752X) += e752x_edac.o obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
......
...@@ -18,6 +18,9 @@ static struct amd64_family_type *fam_type; ...@@ -18,6 +18,9 @@ static struct amd64_family_type *fam_type;
/* Per-node stuff */ /* Per-node stuff */
static struct ecc_settings **ecc_stngs; static struct ecc_settings **ecc_stngs;
/* Device for the PCI component */
static struct device *pci_ctl_dev;
/* /*
* Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
* bandwidth to a valid bit pattern. The 'set' operation finds the 'matching- * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
...@@ -2461,14 +2464,11 @@ static int map_err_sym_to_channel(int err_sym, int sym_size) ...@@ -2461,14 +2464,11 @@ static int map_err_sym_to_channel(int err_sym, int sym_size)
case 0x20: case 0x20:
case 0x21: case 0x21:
return 0; return 0;
break;
case 0x22: case 0x22:
case 0x23: case 0x23:
return 1; return 1;
break;
default: default:
return err_sym >> 4; return err_sym >> 4;
break;
} }
/* x8 symbols */ /* x8 symbols */
else else
...@@ -2478,17 +2478,12 @@ static int map_err_sym_to_channel(int err_sym, int sym_size) ...@@ -2478,17 +2478,12 @@ static int map_err_sym_to_channel(int err_sym, int sym_size)
WARN(1, KERN_ERR "Invalid error symbol: 0x%x\n", WARN(1, KERN_ERR "Invalid error symbol: 0x%x\n",
err_sym); err_sym);
return -1; return -1;
break;
case 0x11: case 0x11:
return 0; return 0;
break;
case 0x12: case 0x12:
return 1; return 1;
break;
default: default:
return err_sym >> 3; return err_sym >> 3;
break;
} }
return -1; return -1;
} }
...@@ -2683,6 +2678,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2) ...@@ -2683,6 +2678,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2)
return -ENODEV; return -ENODEV;
} }
if (!pci_ctl_dev)
pci_ctl_dev = &pvt->F0->dev;
edac_dbg(1, "F0: %s\n", pci_name(pvt->F0)); edac_dbg(1, "F0: %s\n", pci_name(pvt->F0));
edac_dbg(1, "F3: %s\n", pci_name(pvt->F3)); edac_dbg(1, "F3: %s\n", pci_name(pvt->F3));
edac_dbg(1, "F6: %s\n", pci_name(pvt->F6)); edac_dbg(1, "F6: %s\n", pci_name(pvt->F6));
...@@ -2707,6 +2705,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2) ...@@ -2707,6 +2705,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2)
return -ENODEV; return -ENODEV;
} }
if (!pci_ctl_dev)
pci_ctl_dev = &pvt->F2->dev;
edac_dbg(1, "F1: %s\n", pci_name(pvt->F1)); edac_dbg(1, "F1: %s\n", pci_name(pvt->F1));
edac_dbg(1, "F2: %s\n", pci_name(pvt->F2)); edac_dbg(1, "F2: %s\n", pci_name(pvt->F2));
edac_dbg(1, "F3: %s\n", pci_name(pvt->F3)); edac_dbg(1, "F3: %s\n", pci_name(pvt->F3));
...@@ -3623,21 +3624,10 @@ static void remove_one_instance(unsigned int nid) ...@@ -3623,21 +3624,10 @@ static void remove_one_instance(unsigned int nid)
static void setup_pci_device(void) static void setup_pci_device(void)
{ {
struct mem_ctl_info *mci;
struct amd64_pvt *pvt;
if (pci_ctl) if (pci_ctl)
return; return;
mci = edac_mc_find(0); pci_ctl = edac_pci_create_generic_ctl(pci_ctl_dev, EDAC_MOD_STR);
if (!mci)
return;
pvt = mci->pvt_info;
if (pvt->umc)
pci_ctl = edac_pci_create_generic_ctl(&pvt->F0->dev, EDAC_MOD_STR);
else
pci_ctl = edac_pci_create_generic_ctl(&pvt->F2->dev, EDAC_MOD_STR);
if (!pci_ctl) { if (!pci_ctl) {
pr_warn("%s(): Unable to create PCI control\n", __func__); pr_warn("%s(): Unable to create PCI control\n", __func__);
pr_warn("%s(): PCI error report via EDAC not set\n", __func__); pr_warn("%s(): PCI error report via EDAC not set\n", __func__);
...@@ -3716,6 +3706,8 @@ static int __init amd64_edac_init(void) ...@@ -3716,6 +3706,8 @@ static int __init amd64_edac_init(void)
return 0; return 0;
err_pci: err_pci:
pci_ctl_dev = NULL;
msrs_free(msrs); msrs_free(msrs);
msrs = NULL; msrs = NULL;
...@@ -3745,6 +3737,8 @@ static void __exit amd64_edac_exit(void) ...@@ -3745,6 +3737,8 @@ static void __exit amd64_edac_exit(void)
kfree(ecc_stngs); kfree(ecc_stngs);
ecc_stngs = NULL; ecc_stngs = NULL;
pci_ctl_dev = NULL;
msrs_free(msrs); msrs_free(msrs);
msrs = NULL; msrs = NULL;
} }
......
...@@ -179,7 +179,6 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci, ...@@ -179,7 +179,6 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
static void amd76x_check(struct mem_ctl_info *mci) static void amd76x_check(struct mem_ctl_info *mci)
{ {
struct amd76x_error_info info; struct amd76x_error_info info;
edac_dbg(3, "\n");
amd76x_get_error_info(mci, &info); amd76x_get_error_info(mci, &info);
amd76x_process_error_info(mci, &info, 1); amd76x_process_error_info(mci, &info, 1);
} }
......
...@@ -980,7 +980,6 @@ static void e752x_check(struct mem_ctl_info *mci) ...@@ -980,7 +980,6 @@ static void e752x_check(struct mem_ctl_info *mci)
{ {
struct e752x_error_info info; struct e752x_error_info info;
edac_dbg(3, "\n");
e752x_get_error_info(mci, &info); e752x_get_error_info(mci, &info);
e752x_process_error_info(mci, &info, 1); e752x_process_error_info(mci, &info, 1);
} }
......
...@@ -333,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci) ...@@ -333,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci)
{ {
struct e7xxx_error_info info; struct e7xxx_error_info info;
edac_dbg(3, "\n");
e7xxx_get_error_info(mci, &info); e7xxx_get_error_info(mci, &info);
e7xxx_process_error_info(mci, &info, 1); e7xxx_process_error_info(mci, &info, 1);
} }
......
...@@ -258,7 +258,7 @@ extern struct edac_device_ctl_info *edac_device_alloc_ctl_info( ...@@ -258,7 +258,7 @@ extern struct edac_device_ctl_info *edac_device_alloc_ctl_info(
extern void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info); extern void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info);
/** /**
* edac_device_add_device: Insert the 'edac_dev' structure into the * edac_device_add_device - Insert the 'edac_dev' structure into the
* edac_device global list and create sysfs entries associated with * edac_device global list and create sysfs entries associated with
* edac_device structure. * edac_device structure.
* *
...@@ -271,9 +271,8 @@ extern void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info); ...@@ -271,9 +271,8 @@ extern void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info);
extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev); extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev);
/** /**
* edac_device_del_device: * edac_device_del_device - Remove sysfs entries for specified edac_device
* Remove sysfs entries for specified edac_device structure and * structure and then remove edac_device structure from global list
* then remove edac_device structure from global list
* *
* @dev: * @dev:
* Pointer to struct &device representing the edac device * Pointer to struct &device representing the edac device
...@@ -286,7 +285,7 @@ extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev); ...@@ -286,7 +285,7 @@ extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev);
extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev); extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev);
/** /**
* Log correctable errors. * edac_device_handle_ce_count - Log correctable errors.
* *
* @edac_dev: pointer to struct &edac_device_ctl_info * @edac_dev: pointer to struct &edac_device_ctl_info
* @inst_nr: number of the instance where the CE error happened * @inst_nr: number of the instance where the CE error happened
...@@ -299,7 +298,7 @@ void edac_device_handle_ce_count(struct edac_device_ctl_info *edac_dev, ...@@ -299,7 +298,7 @@ void edac_device_handle_ce_count(struct edac_device_ctl_info *edac_dev,
const char *msg); const char *msg);
/** /**
* Log uncorrectable errors. * edac_device_handle_ue_count - Log uncorrectable errors.
* *
* @edac_dev: pointer to struct &edac_device_ctl_info * @edac_dev: pointer to struct &edac_device_ctl_info
* @inst_nr: number of the instance where the CE error happened * @inst_nr: number of the instance where the CE error happened
......
...@@ -158,10 +158,14 @@ const char * const edac_mem_types[] = { ...@@ -158,10 +158,14 @@ const char * const edac_mem_types[] = {
[MEM_DDR3] = "Unbuffered-DDR3", [MEM_DDR3] = "Unbuffered-DDR3",
[MEM_RDDR3] = "Registered-DDR3", [MEM_RDDR3] = "Registered-DDR3",
[MEM_LRDDR3] = "Load-Reduced-DDR3-RAM", [MEM_LRDDR3] = "Load-Reduced-DDR3-RAM",
[MEM_LPDDR3] = "Low-Power-DDR3-RAM",
[MEM_DDR4] = "Unbuffered-DDR4", [MEM_DDR4] = "Unbuffered-DDR4",
[MEM_RDDR4] = "Registered-DDR4", [MEM_RDDR4] = "Registered-DDR4",
[MEM_LPDDR4] = "Low-Power-DDR4-RAM",
[MEM_LRDDR4] = "Load-Reduced-DDR4-RAM", [MEM_LRDDR4] = "Load-Reduced-DDR4-RAM",
[MEM_DDR5] = "Unbuffered-DDR5",
[MEM_NVDIMM] = "Non-volatile-RAM", [MEM_NVDIMM] = "Non-volatile-RAM",
[MEM_WIO2] = "Wide-IO-2",
}; };
EXPORT_SYMBOL_GPL(edac_mem_types); EXPORT_SYMBOL_GPL(edac_mem_types);
......
...@@ -6,27 +6,32 @@ ...@@ -6,27 +6,32 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
#include <asm/intel-family.h> #include <asm/intel-family.h>
#include <asm/mce.h> #include <asm/mce.h>
#include "edac_module.h" #include "edac_module.h"
#include "skx_common.h" #include "skx_common.h"
#define I10NM_REVISION "v0.0.3" #define I10NM_REVISION "v0.0.4"
#define EDAC_MOD_STR "i10nm_edac" #define EDAC_MOD_STR "i10nm_edac"
/* Debug macros */ /* Debug macros */
#define i10nm_printk(level, fmt, arg...) \ #define i10nm_printk(level, fmt, arg...) \
edac_printk(level, "i10nm", fmt, ##arg) edac_printk(level, "i10nm", fmt, ##arg)
#define I10NM_GET_SCK_BAR(d, reg) \ #define I10NM_GET_SCK_BAR(d, reg) \
pci_read_config_dword((d)->uracu, 0xd0, &(reg)) pci_read_config_dword((d)->uracu, 0xd0, &(reg))
#define I10NM_GET_IMC_BAR(d, i, reg) \ #define I10NM_GET_IMC_BAR(d, i, reg) \
pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg)) pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
#define I10NM_GET_DIMMMTR(m, i, j) \ #define I10NM_GET_DIMMMTR(m, i, j) \
(*(u32 *)((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)) readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
#define I10NM_GET_MCDDRTCFG(m, i, j) \ #define I10NM_GET_MCDDRTCFG(m, i, j) \
(*(u32 *)((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4)) readl((m)->mbase + 0x20970 + (i) * (m)->chan_mmio_sz + (j) * 4)
#define I10NM_GET_MCMTR(m, i) \
readl((m)->mbase + 0x20ef8 + (i) * (m)->chan_mmio_sz)
#define I10NM_GET_AMAP(m, i) \
readl((m)->mbase + 0x20814 + (i) * (m)->chan_mmio_sz)
#define I10NM_GET_SCK_MMIO_BASE(reg) (GET_BITFIELD(reg, 0, 28) << 23) #define I10NM_GET_SCK_MMIO_BASE(reg) (GET_BITFIELD(reg, 0, 28) << 23)
#define I10NM_GET_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12) #define I10NM_GET_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12)
...@@ -126,12 +131,22 @@ static struct res_config i10nm_cfg0 = { ...@@ -126,12 +131,22 @@ static struct res_config i10nm_cfg0 = {
.type = I10NM, .type = I10NM,
.decs_did = 0x3452, .decs_did = 0x3452,
.busno_cfg_offset = 0xcc, .busno_cfg_offset = 0xcc,
.ddr_chan_mmio_sz = 0x4000,
}; };
static struct res_config i10nm_cfg1 = { static struct res_config i10nm_cfg1 = {
.type = I10NM, .type = I10NM,
.decs_did = 0x3452, .decs_did = 0x3452,
.busno_cfg_offset = 0xd0, .busno_cfg_offset = 0xd0,
.ddr_chan_mmio_sz = 0x4000,
};
static struct res_config spr_cfg = {
.type = SPR,
.decs_did = 0x3252,
.busno_cfg_offset = 0xd0,
.ddr_chan_mmio_sz = 0x8000,
.support_ddr5 = true,
}; };
static const struct x86_cpu_id i10nm_cpuids[] = { static const struct x86_cpu_id i10nm_cpuids[] = {
...@@ -140,6 +155,7 @@ static const struct x86_cpu_id i10nm_cpuids[] = { ...@@ -140,6 +155,7 @@ static const struct x86_cpu_id i10nm_cpuids[] = {
X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0), X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x0, 0x3), &i10nm_cfg0),
X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1), X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0xf), &i10nm_cfg1),
X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1), X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x0, 0xf), &i10nm_cfg1),
X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SAPPHIRERAPIDS_X, X86_STEPPINGS(0x0, 0xf), &spr_cfg),
{} {}
}; };
MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
...@@ -148,18 +164,19 @@ static bool i10nm_check_ecc(struct skx_imc *imc, int chan) ...@@ -148,18 +164,19 @@ static bool i10nm_check_ecc(struct skx_imc *imc, int chan)
{ {
u32 mcmtr; u32 mcmtr;
mcmtr = *(u32 *)(imc->mbase + 0x20ef8 + chan * 0x4000); mcmtr = I10NM_GET_MCMTR(imc, chan);
edac_dbg(1, "ch%d mcmtr reg %x\n", chan, mcmtr); edac_dbg(1, "ch%d mcmtr reg %x\n", chan, mcmtr);
return !!GET_BITFIELD(mcmtr, 2, 2); return !!GET_BITFIELD(mcmtr, 2, 2);
} }
static int i10nm_get_dimm_config(struct mem_ctl_info *mci) static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
struct res_config *cfg)
{ {
struct skx_pvt *pvt = mci->pvt_info; struct skx_pvt *pvt = mci->pvt_info;
struct skx_imc *imc = pvt->imc; struct skx_imc *imc = pvt->imc;
u32 mtr, amap, mcddrtcfg;
struct dimm_info *dimm; struct dimm_info *dimm;
u32 mtr, mcddrtcfg;
int i, j, ndimms; int i, j, ndimms;
for (i = 0; i < I10NM_NUM_CHANNELS; i++) { for (i = 0; i < I10NM_NUM_CHANNELS; i++) {
...@@ -167,6 +184,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci) ...@@ -167,6 +184,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci)
continue; continue;
ndimms = 0; ndimms = 0;
amap = I10NM_GET_AMAP(imc, i);
for (j = 0; j < I10NM_NUM_DIMMS; j++) { for (j = 0; j < I10NM_NUM_DIMMS; j++) {
dimm = edac_get_dimm(mci, i, j, 0); dimm = edac_get_dimm(mci, i, j, 0);
mtr = I10NM_GET_DIMMMTR(imc, i, j); mtr = I10NM_GET_DIMMMTR(imc, i, j);
...@@ -175,8 +193,8 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci) ...@@ -175,8 +193,8 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci)
mtr, mcddrtcfg, imc->mc, i, j); mtr, mcddrtcfg, imc->mc, i, j);
if (IS_DIMM_PRESENT(mtr)) if (IS_DIMM_PRESENT(mtr))
ndimms += skx_get_dimm_info(mtr, 0, 0, dimm, ndimms += skx_get_dimm_info(mtr, 0, amap, dimm,
imc, i, j); imc, i, j, cfg);
else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) else if (IS_NVDIMM_PRESENT(mcddrtcfg, j))
ndimms += skx_get_nvdimm_info(dimm, imc, i, j, ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
EDAC_MOD_STR); EDAC_MOD_STR);
...@@ -300,10 +318,11 @@ static int __init i10nm_init(void) ...@@ -300,10 +318,11 @@ static int __init i10nm_init(void)
d->imc[i].lmc = i; d->imc[i].lmc = i;
d->imc[i].src_id = src_id; d->imc[i].src_id = src_id;
d->imc[i].node_id = node_id; d->imc[i].node_id = node_id;
d->imc[i].chan_mmio_sz = cfg->ddr_chan_mmio_sz;
rc = skx_register_mci(&d->imc[i], d->imc[i].mdev, rc = skx_register_mci(&d->imc[i], d->imc[i].mdev,
"Intel_10nm Socket", EDAC_MOD_STR, "Intel_10nm Socket", EDAC_MOD_STR,
i10nm_get_dimm_config); i10nm_get_dimm_config, cfg);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
} }
......
...@@ -273,7 +273,6 @@ static void i3000_check(struct mem_ctl_info *mci) ...@@ -273,7 +273,6 @@ static void i3000_check(struct mem_ctl_info *mci)
{ {
struct i3000_error_info info; struct i3000_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i3000_get_error_info(mci, &info); i3000_get_error_info(mci, &info);
i3000_process_error_info(mci, &info, 1); i3000_process_error_info(mci, &info, 1);
} }
......
...@@ -253,7 +253,6 @@ static void i3200_check(struct mem_ctl_info *mci) ...@@ -253,7 +253,6 @@ static void i3200_check(struct mem_ctl_info *mci)
{ {
struct i3200_error_info info; struct i3200_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i3200_get_and_clear_error_info(mci, &info); i3200_get_and_clear_error_info(mci, &info);
i3200_process_error_info(mci, &info); i3200_process_error_info(mci, &info);
} }
......
...@@ -765,7 +765,7 @@ static void i5000_clear_error(struct mem_ctl_info *mci) ...@@ -765,7 +765,7 @@ static void i5000_clear_error(struct mem_ctl_info *mci)
static void i5000_check_error(struct mem_ctl_info *mci) static void i5000_check_error(struct mem_ctl_info *mci)
{ {
struct i5000_error_info info; struct i5000_error_info info;
edac_dbg(4, "MC%d\n", mci->mc_idx);
i5000_get_error_info(mci, &info); i5000_get_error_info(mci, &info);
i5000_process_error_info(mci, &info, 1); i5000_process_error_info(mci, &info, 1);
} }
......
...@@ -686,7 +686,7 @@ static void i5400_clear_error(struct mem_ctl_info *mci) ...@@ -686,7 +686,7 @@ static void i5400_clear_error(struct mem_ctl_info *mci)
static void i5400_check_error(struct mem_ctl_info *mci) static void i5400_check_error(struct mem_ctl_info *mci)
{ {
struct i5400_error_info info; struct i5400_error_info info;
edac_dbg(4, "MC%d\n", mci->mc_idx);
i5400_get_error_info(mci, &info); i5400_get_error_info(mci, &info);
i5400_process_error_info(mci, &info); i5400_process_error_info(mci, &info);
} }
......
...@@ -176,7 +176,6 @@ static void i82443bxgx_edacmc_check(struct mem_ctl_info *mci) ...@@ -176,7 +176,6 @@ static void i82443bxgx_edacmc_check(struct mem_ctl_info *mci)
{ {
struct i82443bxgx_edacmc_error_info info; struct i82443bxgx_edacmc_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i82443bxgx_edacmc_get_error_info(mci, &info); i82443bxgx_edacmc_get_error_info(mci, &info);
i82443bxgx_edacmc_process_error_info(mci, &info, 1); i82443bxgx_edacmc_process_error_info(mci, &info, 1);
} }
......
...@@ -135,7 +135,6 @@ static void i82860_check(struct mem_ctl_info *mci) ...@@ -135,7 +135,6 @@ static void i82860_check(struct mem_ctl_info *mci)
{ {
struct i82860_error_info info; struct i82860_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i82860_get_error_info(mci, &info); i82860_get_error_info(mci, &info);
i82860_process_error_info(mci, &info, 1); i82860_process_error_info(mci, &info, 1);
} }
......
...@@ -262,7 +262,6 @@ static void i82875p_check(struct mem_ctl_info *mci) ...@@ -262,7 +262,6 @@ static void i82875p_check(struct mem_ctl_info *mci)
{ {
struct i82875p_error_info info; struct i82875p_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i82875p_get_error_info(mci, &info); i82875p_get_error_info(mci, &info);
i82875p_process_error_info(mci, &info, 1); i82875p_process_error_info(mci, &info, 1);
} }
......
...@@ -330,7 +330,6 @@ static void i82975x_check(struct mem_ctl_info *mci) ...@@ -330,7 +330,6 @@ static void i82975x_check(struct mem_ctl_info *mci)
{ {
struct i82975x_error_info info; struct i82975x_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
i82975x_get_error_info(mci, &info); i82975x_get_error_info(mci, &info);
i82975x_process_error_info(mci, &info, 1); i82975x_process_error_info(mci, &info, 1);
} }
......
...@@ -333,7 +333,6 @@ static void ie31200_check(struct mem_ctl_info *mci) ...@@ -333,7 +333,6 @@ static void ie31200_check(struct mem_ctl_info *mci)
{ {
struct ie31200_error_info info; struct ie31200_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
ie31200_get_and_clear_error_info(mci, &info); ie31200_get_and_clear_error_info(mci, &info);
ie31200_process_error_info(mci, &info); ie31200_process_error_info(mci, &info);
} }
......
This diff is collapsed.
...@@ -204,7 +204,6 @@ static void r82600_check(struct mem_ctl_info *mci) ...@@ -204,7 +204,6 @@ static void r82600_check(struct mem_ctl_info *mci)
{ {
struct r82600_error_info info; struct r82600_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
r82600_get_error_info(mci, &info); r82600_get_error_info(mci, &info);
r82600_process_error_info(mci, &info, 1); r82600_process_error_info(mci, &info, 1);
} }
......
...@@ -174,7 +174,7 @@ static bool skx_check_ecc(u32 mcmtr) ...@@ -174,7 +174,7 @@ static bool skx_check_ecc(u32 mcmtr)
return !!GET_BITFIELD(mcmtr, 2, 2); return !!GET_BITFIELD(mcmtr, 2, 2);
} }
static int skx_get_dimm_config(struct mem_ctl_info *mci) static int skx_get_dimm_config(struct mem_ctl_info *mci, struct res_config *cfg)
{ {
struct skx_pvt *pvt = mci->pvt_info; struct skx_pvt *pvt = mci->pvt_info;
u32 mtr, mcmtr, amap, mcddrtcfg; u32 mtr, mcmtr, amap, mcddrtcfg;
...@@ -195,7 +195,7 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci) ...@@ -195,7 +195,7 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci)
pci_read_config_dword(imc->chan[i].cdev, pci_read_config_dword(imc->chan[i].cdev,
0x80 + 4 * j, &mtr); 0x80 + 4 * j, &mtr);
if (IS_DIMM_PRESENT(mtr)) { if (IS_DIMM_PRESENT(mtr)) {
ndimms += skx_get_dimm_info(mtr, mcmtr, amap, dimm, imc, i, j); ndimms += skx_get_dimm_info(mtr, mcmtr, amap, dimm, imc, i, j, cfg);
} else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) { } else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) {
ndimms += skx_get_nvdimm_info(dimm, imc, i, j, ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
EDAC_MOD_STR); EDAC_MOD_STR);
...@@ -702,7 +702,7 @@ static int __init skx_init(void) ...@@ -702,7 +702,7 @@ static int __init skx_init(void)
d->imc[i].node_id = node_id; d->imc[i].node_id = node_id;
rc = skx_register_mci(&d->imc[i], d->imc[i].chan[0].cdev, rc = skx_register_mci(&d->imc[i], d->imc[i].chan[0].cdev,
"Skylake Socket", EDAC_MOD_STR, "Skylake Socket", EDAC_MOD_STR,
skx_get_dimm_config); skx_get_dimm_config, cfg);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
} }
......
...@@ -304,15 +304,25 @@ static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, ...@@ -304,15 +304,25 @@ static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add,
#define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols") #define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols")
int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
struct skx_imc *imc, int chan, int dimmno) struct skx_imc *imc, int chan, int dimmno,
struct res_config *cfg)
{ {
int banks = 16, ranks, rows, cols, npages; int banks, ranks, rows, cols, npages;
enum mem_type mtype;
u64 size; u64 size;
ranks = numrank(mtr); ranks = numrank(mtr);
rows = numrow(mtr); rows = numrow(mtr);
cols = numcol(mtr); cols = numcol(mtr);
if (cfg->support_ddr5 && (amap & 0x8)) {
banks = 32;
mtype = MEM_DDR5;
} else {
banks = 16;
mtype = MEM_DDR4;
}
/* /*
* Compute size in 8-byte (2^3) words, then shift to MiB (2^20) * Compute size in 8-byte (2^3) words, then shift to MiB (2^20)
*/ */
...@@ -332,7 +342,7 @@ int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, ...@@ -332,7 +342,7 @@ int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
dimm->nr_pages = npages; dimm->nr_pages = npages;
dimm->grain = 32; dimm->grain = 32;
dimm->dtype = get_width(mtr); dimm->dtype = get_width(mtr);
dimm->mtype = MEM_DDR4; dimm->mtype = mtype;
dimm->edac_mode = EDAC_SECDED; /* likely better than this */ dimm->edac_mode = EDAC_SECDED; /* likely better than this */
snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u", snprintf(dimm->label, sizeof(dimm->label), "CPU_SrcID#%u_MC#%u_Chan#%u_DIMM#%u",
imc->src_id, imc->lmc, chan, dimmno); imc->src_id, imc->lmc, chan, dimmno);
...@@ -390,7 +400,8 @@ int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, ...@@ -390,7 +400,8 @@ int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
const char *ctl_name, const char *mod_str, const char *ctl_name, const char *mod_str,
get_dimm_config_f get_dimm_config) get_dimm_config_f get_dimm_config,
struct res_config *cfg)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct edac_mc_layer layers[2]; struct edac_mc_layer layers[2];
...@@ -425,13 +436,15 @@ int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, ...@@ -425,13 +436,15 @@ int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
} }
mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM; mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_NVDIMM;
if (cfg->support_ddr5)
mci->mtype_cap |= MEM_FLAG_DDR5;
mci->edac_ctl_cap = EDAC_FLAG_NONE; mci->edac_ctl_cap = EDAC_FLAG_NONE;
mci->edac_cap = EDAC_FLAG_NONE; mci->edac_cap = EDAC_FLAG_NONE;
mci->mod_name = mod_str; mci->mod_name = mod_str;
mci->dev_name = pci_name(pdev); mci->dev_name = pci_name(pdev);
mci->ctl_page_to_phys = NULL; mci->ctl_page_to_phys = NULL;
rc = get_dimm_config(mci); rc = get_dimm_config(mci, cfg);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
......
...@@ -59,6 +59,7 @@ struct skx_dev { ...@@ -59,6 +59,7 @@ struct skx_dev {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct pci_dev *mdev; /* for i10nm CPU */ struct pci_dev *mdev; /* for i10nm CPU */
void __iomem *mbase; /* for i10nm CPU */ void __iomem *mbase; /* for i10nm CPU */
int chan_mmio_sz; /* for i10nm CPU */
u8 mc; /* system wide mc# */ u8 mc; /* system wide mc# */
u8 lmc; /* socket relative mc# */ u8 lmc; /* socket relative mc# */
u8 src_id, node_id; u8 src_id, node_id;
...@@ -82,7 +83,8 @@ struct skx_pvt { ...@@ -82,7 +83,8 @@ struct skx_pvt {
enum type { enum type {
SKX, SKX,
I10NM I10NM,
SPR
}; };
enum { enum {
...@@ -118,9 +120,13 @@ struct res_config { ...@@ -118,9 +120,13 @@ struct res_config {
unsigned int decs_did; unsigned int decs_did;
/* Default bus number configuration register offset */ /* Default bus number configuration register offset */
int busno_cfg_offset; int busno_cfg_offset;
/* Per DDR channel memory-mapped I/O size */
int ddr_chan_mmio_sz;
bool support_ddr5;
}; };
typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci,
struct res_config *cfg);
typedef bool (*skx_decode_f)(struct decoded_addr *res); typedef bool (*skx_decode_f)(struct decoded_addr *res);
typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len);
...@@ -136,14 +142,16 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list); ...@@ -136,14 +142,16 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list);
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm);
int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
struct skx_imc *imc, int chan, int dimmno); struct skx_imc *imc, int chan, int dimmno,
struct res_config *cfg);
int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
int chan, int dimmno, const char *mod_str); int chan, int dimmno, const char *mod_str);
int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
const char *ctl_name, const char *mod_str, const char *ctl_name, const char *mod_str,
get_dimm_config_f get_dimm_config); get_dimm_config_f get_dimm_config,
struct res_config *cfg);
int skx_mce_check_error(struct notifier_block *nb, unsigned long val, int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
void *data); void *data);
......
...@@ -1344,7 +1344,8 @@ static int mc_probe(struct platform_device *pdev) ...@@ -1344,7 +1344,8 @@ static int mc_probe(struct platform_device *pdev)
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) { if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) {
if (edac_create_sysfs_attributes(mci)) { rc = edac_create_sysfs_attributes(mci);
if (rc) {
edac_printk(KERN_ERR, EDAC_MC, edac_printk(KERN_ERR, EDAC_MC,
"Failed to create sysfs entries\n"); "Failed to create sysfs entries\n");
goto free_edac_mc; goto free_edac_mc;
......
...@@ -238,7 +238,6 @@ static void x38_check(struct mem_ctl_info *mci) ...@@ -238,7 +238,6 @@ static void x38_check(struct mem_ctl_info *mci)
{ {
struct x38_error_info info; struct x38_error_info info;
edac_dbg(1, "MC%d\n", mci->mc_idx);
x38_get_and_clear_error_info(mci, &info); x38_get_and_clear_error_info(mci, &info);
x38_process_error_info(mci, &info); x38_process_error_info(mci, &info);
} }
......
...@@ -175,11 +175,15 @@ static inline char *mc_event_error_type(const unsigned int err_type) ...@@ -175,11 +175,15 @@ static inline char *mc_event_error_type(const unsigned int err_type)
* @MEM_RDDR3: Registered DDR3 RAM * @MEM_RDDR3: Registered DDR3 RAM
* This is a variant of the DDR3 memories. * This is a variant of the DDR3 memories.
* @MEM_LRDDR3: Load-Reduced DDR3 memory. * @MEM_LRDDR3: Load-Reduced DDR3 memory.
* @MEM_LPDDR3: Low-Power DDR3 memory.
* @MEM_DDR4: Unbuffered DDR4 RAM * @MEM_DDR4: Unbuffered DDR4 RAM
* @MEM_RDDR4: Registered DDR4 RAM * @MEM_RDDR4: Registered DDR4 RAM
* This is a variant of the DDR4 memories. * This is a variant of the DDR4 memories.
* @MEM_LRDDR4: Load-Reduced DDR4 memory. * @MEM_LRDDR4: Load-Reduced DDR4 memory.
* @MEM_LPDDR4: Low-Power DDR4 memory.
* @MEM_DDR5: Unbuffered DDR5 RAM
* @MEM_NVDIMM: Non-volatile RAM * @MEM_NVDIMM: Non-volatile RAM
* @MEM_WIO2: Wide I/O 2.
*/ */
enum mem_type { enum mem_type {
MEM_EMPTY = 0, MEM_EMPTY = 0,
...@@ -200,10 +204,14 @@ enum mem_type { ...@@ -200,10 +204,14 @@ enum mem_type {
MEM_DDR3, MEM_DDR3,
MEM_RDDR3, MEM_RDDR3,
MEM_LRDDR3, MEM_LRDDR3,
MEM_LPDDR3,
MEM_DDR4, MEM_DDR4,
MEM_RDDR4, MEM_RDDR4,
MEM_LRDDR4, MEM_LRDDR4,
MEM_LPDDR4,
MEM_DDR5,
MEM_NVDIMM, MEM_NVDIMM,
MEM_WIO2,
}; };
#define MEM_FLAG_EMPTY BIT(MEM_EMPTY) #define MEM_FLAG_EMPTY BIT(MEM_EMPTY)
...@@ -223,13 +231,17 @@ enum mem_type { ...@@ -223,13 +231,17 @@ enum mem_type {
#define MEM_FLAG_XDR BIT(MEM_XDR) #define MEM_FLAG_XDR BIT(MEM_XDR)
#define MEM_FLAG_DDR3 BIT(MEM_DDR3) #define MEM_FLAG_DDR3 BIT(MEM_DDR3)
#define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) #define MEM_FLAG_RDDR3 BIT(MEM_RDDR3)
#define MEM_FLAG_LPDDR3 BIT(MEM_LPDDR3)
#define MEM_FLAG_DDR4 BIT(MEM_DDR4) #define MEM_FLAG_DDR4 BIT(MEM_DDR4)
#define MEM_FLAG_RDDR4 BIT(MEM_RDDR4) #define MEM_FLAG_RDDR4 BIT(MEM_RDDR4)
#define MEM_FLAG_LRDDR4 BIT(MEM_LRDDR4) #define MEM_FLAG_LRDDR4 BIT(MEM_LRDDR4)
#define MEM_FLAG_LPDDR4 BIT(MEM_LPDDR4)
#define MEM_FLAG_DDR5 BIT(MEM_DDR5)
#define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM) #define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM)
#define MEM_FLAG_WIO2 BIT(MEM_WIO2)
/** /**
* enum edac-type - Error Detection and Correction capabilities and mode * enum edac_type - Error Detection and Correction capabilities and mode
* @EDAC_UNKNOWN: Unknown if ECC is available * @EDAC_UNKNOWN: Unknown if ECC is available
* @EDAC_NONE: Doesn't support ECC * @EDAC_NONE: Doesn't support ECC
* @EDAC_RESERVED: Reserved ECC type * @EDAC_RESERVED: Reserved ECC type
...@@ -309,7 +321,7 @@ enum scrub_type { ...@@ -309,7 +321,7 @@ enum scrub_type {
#define OP_OFFLINE 0x300 #define OP_OFFLINE 0x300
/** /**
* enum edac_mc_layer - memory controller hierarchy layer * enum edac_mc_layer_type - memory controller hierarchy layer
* *
* @EDAC_MC_LAYER_BRANCH: memory layer is named "branch" * @EDAC_MC_LAYER_BRANCH: memory layer is named "branch"
* @EDAC_MC_LAYER_CHANNEL: memory layer is named "channel" * @EDAC_MC_LAYER_CHANNEL: memory layer is named "channel"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment