Skip to content

Commit

Permalink
Merge branches 'edac-spr', 'edac-igen6' and 'edac-misc' into edac-upd…
Browse files Browse the repository at this point in the history
…ates-for-v5.11

Signed-off-by: Borislav Petkov <bp@suse.de>
  • Loading branch information
suryasaimadhu committed Dec 14, 2020
4 parents 0385979 + 479f58d + 77429ee + 706657b commit f84b799
Show file tree
Hide file tree
Showing 27 changed files with 1,099 additions and 67 deletions.
11 changes: 9 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -2474,7 +2474,7 @@ F: drivers/clk/socfpga/
ARM/SOCFPGA EDAC SUPPORT
M: Dinh Nguyen <dinguyen@kernel.org>
S: Maintained
F: drivers/edac/altera_edac.
F: drivers/edac/altera_edac.[ch]

ARM/SPREADTRUM SoC SUPPORT
M: Orson Zhai <orsonzhai@gmail.com>
Expand Down Expand Up @@ -6351,6 +6351,13 @@ L: linux-edac@vger.kernel.org
S: Maintained
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
M: Johannes Thumshirn <morbidrsa@gmail.com>
L: linux-edac@vger.kernel.org
Expand Down Expand Up @@ -6400,7 +6407,7 @@ EDAC-SKYLAKE
M: Tony Luck <tony.luck@intel.com>
L: linux-edac@vger.kernel.org
S: Maintained
F: drivers/edac/skx_*.c
F: drivers/edac/skx_*.[ch]

EDAC-TI
M: Tero Kristo <t-kristo@ti.com>
Expand Down
9 changes: 9 additions & 0 deletions drivers/edac/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,15 @@ config EDAC_PND2
first used on the Apollo Lake platform and Denverton
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
bool "Freescale MPC83xx / MPC85xx"
depends on FSL_SOC && EDAC=y
Expand Down
1 change: 1 addition & 0 deletions drivers/edac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ obj-$(CONFIG_EDAC_I7300) += i7300_edac.o
obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
obj-$(CONFIG_EDAC_SBRIDGE) += sb_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_E752X) += e752x_edac.o
obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o
Expand Down
34 changes: 14 additions & 20 deletions drivers/edac/amd64_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ static struct amd64_family_type *fam_type;
/* Per-node stuff */
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
* bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
Expand Down Expand Up @@ -2461,14 +2464,11 @@ static int map_err_sym_to_channel(int err_sym, int sym_size)
case 0x20:
case 0x21:
return 0;
break;
case 0x22:
case 0x23:
return 1;
break;
default:
return err_sym >> 4;
break;
}
/* x8 symbols */
else
Expand All @@ -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",
err_sym);
return -1;
break;

case 0x11:
return 0;
break;
case 0x12:
return 1;
break;
default:
return err_sym >> 3;
break;
}
return -1;
}
Expand Down Expand Up @@ -2683,6 +2678,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2)
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, "F3: %s\n", pci_name(pvt->F3));
edac_dbg(1, "F6: %s\n", pci_name(pvt->F6));
Expand All @@ -2707,6 +2705,9 @@ reserve_mc_sibling_devs(struct amd64_pvt *pvt, u16 pci_id1, u16 pci_id2)
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, "F2: %s\n", pci_name(pvt->F2));
edac_dbg(1, "F3: %s\n", pci_name(pvt->F3));
Expand Down Expand Up @@ -3623,21 +3624,10 @@ static void remove_one_instance(unsigned int nid)

static void setup_pci_device(void)
{
struct mem_ctl_info *mci;
struct amd64_pvt *pvt;

if (pci_ctl)
return;

mci = edac_mc_find(0);
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);
pci_ctl = edac_pci_create_generic_ctl(pci_ctl_dev, EDAC_MOD_STR);
if (!pci_ctl) {
pr_warn("%s(): Unable to create PCI control\n", __func__);
pr_warn("%s(): PCI error report via EDAC not set\n", __func__);
Expand Down Expand Up @@ -3716,6 +3706,8 @@ static int __init amd64_edac_init(void)
return 0;

err_pci:
pci_ctl_dev = NULL;

msrs_free(msrs);
msrs = NULL;

Expand Down Expand Up @@ -3745,6 +3737,8 @@ static void __exit amd64_edac_exit(void)
kfree(ecc_stngs);
ecc_stngs = NULL;

pci_ctl_dev = NULL;

msrs_free(msrs);
msrs = NULL;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/edac/amd76x_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ static int amd76x_process_error_info(struct mem_ctl_info *mci,
static void amd76x_check(struct mem_ctl_info *mci)
{
struct amd76x_error_info info;
edac_dbg(3, "\n");
amd76x_get_error_info(mci, &info);
amd76x_process_error_info(mci, &info, 1);
}
Expand Down
1 change: 0 additions & 1 deletion drivers/edac/e752x_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,6 @@ static void e752x_check(struct mem_ctl_info *mci)
{
struct e752x_error_info info;

edac_dbg(3, "\n");
e752x_get_error_info(mci, &info);
e752x_process_error_info(mci, &info, 1);
}
Expand Down
1 change: 0 additions & 1 deletion drivers/edac/e7xxx_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci)
{
struct e7xxx_error_info info;

edac_dbg(3, "\n");
e7xxx_get_error_info(mci, &info);
e7xxx_process_error_info(mci, &info, 1);
}
Expand Down
11 changes: 5 additions & 6 deletions drivers/edac/edac_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
* 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 structure.
*
Expand All @@ -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);

/**
* edac_device_del_device:
* Remove sysfs entries for specified edac_device structure and
* then remove edac_device structure from global list
* edac_device_del_device - Remove sysfs entries for specified edac_device
* structure and then remove edac_device structure from global list
*
* @dev:
* Pointer to struct &device representing the edac device
Expand All @@ -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);

/**
* Log correctable errors.
* edac_device_handle_ce_count - Log correctable errors.
*
* @edac_dev: pointer to struct &edac_device_ctl_info
* @inst_nr: number of the instance where the CE error happened
Expand All @@ -299,7 +298,7 @@ void edac_device_handle_ce_count(struct edac_device_ctl_info *edac_dev,
const char *msg);

/**
* Log uncorrectable errors.
* edac_device_handle_ue_count - Log uncorrectable errors.
*
* @edac_dev: pointer to struct &edac_device_ctl_info
* @inst_nr: number of the instance where the CE error happened
Expand Down
4 changes: 4 additions & 0 deletions drivers/edac/edac_mc.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,14 @@ const char * const edac_mem_types[] = {
[MEM_DDR3] = "Unbuffered-DDR3",
[MEM_RDDR3] = "Registered-DDR3",
[MEM_LRDDR3] = "Load-Reduced-DDR3-RAM",
[MEM_LPDDR3] = "Low-Power-DDR3-RAM",
[MEM_DDR4] = "Unbuffered-DDR4",
[MEM_RDDR4] = "Registered-DDR4",
[MEM_LPDDR4] = "Low-Power-DDR4-RAM",
[MEM_LRDDR4] = "Load-Reduced-DDR4-RAM",
[MEM_DDR5] = "Unbuffered-DDR5",
[MEM_NVDIMM] = "Non-volatile-RAM",
[MEM_WIO2] = "Wide-IO-2",
};
EXPORT_SYMBOL_GPL(edac_mem_types);

Expand Down
39 changes: 29 additions & 10 deletions drivers/edac/i10nm_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,32 @@
*/

#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/mce.h>
#include "edac_module.h"
#include "skx_common.h"

#define I10NM_REVISION "v0.0.3"
#define I10NM_REVISION "v0.0.4"
#define EDAC_MOD_STR "i10nm_edac"

/* Debug macros */
#define i10nm_printk(level, 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))
#define I10NM_GET_IMC_BAR(d, i, reg) \
pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
#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) \
(*(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_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12)
Expand Down Expand Up @@ -126,12 +131,22 @@ static struct res_config i10nm_cfg0 = {
.type = I10NM,
.decs_did = 0x3452,
.busno_cfg_offset = 0xcc,
.ddr_chan_mmio_sz = 0x4000,
};

static struct res_config i10nm_cfg1 = {
.type = I10NM,
.decs_did = 0x3452,
.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[] = {
Expand All @@ -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(0x4, 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);
Expand All @@ -148,25 +164,27 @@ static bool i10nm_check_ecc(struct skx_imc *imc, int chan)
{
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);

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_imc *imc = pvt->imc;
u32 mtr, amap, mcddrtcfg;
struct dimm_info *dimm;
u32 mtr, mcddrtcfg;
int i, j, ndimms;

for (i = 0; i < I10NM_NUM_CHANNELS; i++) {
if (!imc->mbase)
continue;

ndimms = 0;
amap = I10NM_GET_AMAP(imc, i);
for (j = 0; j < I10NM_NUM_DIMMS; j++) {
dimm = edac_get_dimm(mci, i, j, 0);
mtr = I10NM_GET_DIMMMTR(imc, i, j);
Expand All @@ -175,8 +193,8 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci)
mtr, mcddrtcfg, imc->mc, i, j);

if (IS_DIMM_PRESENT(mtr))
ndimms += skx_get_dimm_info(mtr, 0, 0, dimm,
imc, i, j);
ndimms += skx_get_dimm_info(mtr, 0, amap, dimm,
imc, i, j, cfg);
else if (IS_NVDIMM_PRESENT(mcddrtcfg, j))
ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
EDAC_MOD_STR);
Expand Down Expand Up @@ -300,10 +318,11 @@ static int __init i10nm_init(void)
d->imc[i].lmc = i;
d->imc[i].src_id = src_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,
"Intel_10nm Socket", EDAC_MOD_STR,
i10nm_get_dimm_config);
i10nm_get_dimm_config, cfg);
if (rc < 0)
goto fail;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/edac/i3000_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ static void i3000_check(struct mem_ctl_info *mci)
{
struct i3000_error_info info;

edac_dbg(1, "MC%d\n", mci->mc_idx);
i3000_get_error_info(mci, &info);
i3000_process_error_info(mci, &info, 1);
}
Expand Down
1 change: 0 additions & 1 deletion drivers/edac/i3200_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ static void i3200_check(struct mem_ctl_info *mci)
{
struct i3200_error_info info;

edac_dbg(1, "MC%d\n", mci->mc_idx);
i3200_get_and_clear_error_info(mci, &info);
i3200_process_error_info(mci, &info);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/edac/i5000_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ static void i5000_clear_error(struct mem_ctl_info *mci)
static void i5000_check_error(struct mem_ctl_info *mci)
{
struct i5000_error_info info;
edac_dbg(4, "MC%d\n", mci->mc_idx);

i5000_get_error_info(mci, &info);
i5000_process_error_info(mci, &info, 1);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/edac/i5400_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ static void i5400_clear_error(struct mem_ctl_info *mci)
static void i5400_check_error(struct mem_ctl_info *mci)
{
struct i5400_error_info info;
edac_dbg(4, "MC%d\n", mci->mc_idx);

i5400_get_error_info(mci, &info);
i5400_process_error_info(mci, &info);
}
Expand Down
Loading

0 comments on commit f84b799

Please sign in to comment.