mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
- i10nm:
- switch to use scnprintf() - Add Granite Rapids-D support - synopsys: Make sure ECC error and counter registers are cleared during init/probing to avoid reporting stale errors - igen6: Add Wildcat Lake SoCs support - Make sure scrub features sysfs attributes are initialized properly - Allocate memory repair sysfs attributes statically to reduce stack usage - Fix DIMM module size computation for DIMMs with total capacity which is a non power-of-two number, in amd64_edac - Do not be too dramatic when reporting disabled memory controllers in igen6_edac - Add support to ie31200_edac for the following SoCs: - Core i5-14[67]00 - Bartless Lake-S SoCs - Raptor Lake-HX -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmiHeDcACgkQEsHwGGHe VUrnzhAAryFKu8xWuwOE3eGaMW6oJhjKF8wPxLiCxxi6ZdQ/1uudFVnzwgozmkXo l10h41A3yc1ZdJqdqn54gF8PxbQ0E1MvbXfmBqZ/U+V+dv6zMwu9TygoPRIJ60ST aIxTBq2zoSii7ucGCBjbqClMTF3ZcH/Q2FzZoFbZyZd84snWSz0B9+S+937mtMhl 9Y55sAgQuigQDQ71YZymAGyWi9E9J20wFk76vIHEboRIa5sS0iCU88Wb4PT+5iKf Qc/1gyqnd+6FO9O9ddrYpeDcaIicLShuGVNZNlJalD/JyTIOcP6XdEDa5J7TYp27 7IcmfHSYmZ5eL0vrJfrIwbauEpRL9ZjWXS+uQjj8/K/gkPUsH/Sdldgldkd50GHV 6L79XSzpy4yhlAr3BXU0o917qRVWOpbxr9E7l6VAFGBpLl5ewtZiV3W7/Su4rPd2 zpUGBZvjxO8jmNQn49IPs/XotVQ2L+mT+KSxUMZAO2pV+dztSJELMFQQC0uAXiZc ApcrSkQxa4fsxU2Ukc1dLOJNkwxEC1ECcPsl2I9EE1cFoix7NP2E+G92D/V52VoZ QeVkxM7LHZCTH9tH1nrCZ+WJr8S2vZ+uY8jRl42P12xU4kcd3RWEtna18bX5oe++ RlgchnXwutEPSgHYZVPocuaDD7C6eIvYzpaVezVl9dgbRLLx8u4= =PBTf -----END PGP SIGNATURE----- Merge tag 'edac_updates_for_v6.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras Pull EDAC updates from Borislav Petkov: - i10nm: - switch to using scnprintf() - Add Granite Rapids-D support - synopsys: Make sure ECC error and counter registers are cleared during init/probing to avoid reporting stale errors - igen6: Add Wildcat Lake SoCs support - Make sure scrub features sysfs attributes are initialized properly - Allocate memory repair sysfs attributes statically to reduce stack usage - Fix DIMM module size computation for DIMMs with total capacity which is a non power-of-two number, in amd64_edac - Do not be too dramatic when reporting disabled memory controllers in igen6_edac - Add support to ie31200_edac for the following SoCs: - Core i5-14[67]00 - Bartless Lake-S SoCs - Raptor Lake-HX * tag 'edac_updates_for_v6.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/{skx_common,i10nm}: Use scnprintf() for safer buffer handling EDAC/synopsys: Clear the ECC counters on init EDAC/ie31200: Add Intel Raptor Lake-HX SoCs support EDAC/igen6: Add Intel Wildcat Lake SoCs support EDAC/i10nm: Add Intel Granite Rapids-D support EDAC/mem_repair: Reduce stack usage in edac_mem_repair_get_desc() EDAC/igen6: Reduce log level to debug for absent memory controllers EDAC/ie31200: Document which CPUs correspond to each Raptor Lake-S device ID EDAC/ie31200: Enable support for Core i5-14600 and i7-14700 ie31200/EDAC: Add Intel Bartlett Lake-S SoCs support
This commit is contained in:
commit
d7223aed30
6 changed files with 138 additions and 100 deletions
|
@ -62,6 +62,7 @@
|
||||||
((GET_BITFIELD(reg, 0, 10) << 12) + 0x140000)
|
((GET_BITFIELD(reg, 0, 10) << 12) + 0x140000)
|
||||||
|
|
||||||
#define I10NM_GNR_IMC_MMIO_OFFSET 0x24c000
|
#define I10NM_GNR_IMC_MMIO_OFFSET 0x24c000
|
||||||
|
#define I10NM_GNR_D_IMC_MMIO_OFFSET 0x206000
|
||||||
#define I10NM_GNR_IMC_MMIO_SIZE 0x4000
|
#define I10NM_GNR_IMC_MMIO_SIZE 0x4000
|
||||||
#define I10NM_HBM_IMC_MMIO_SIZE 0x9000
|
#define I10NM_HBM_IMC_MMIO_SIZE 0x9000
|
||||||
#define I10NM_DDR_IMC_CH_CNT(reg) GET_BITFIELD(reg, 21, 24)
|
#define I10NM_DDR_IMC_CH_CNT(reg) GET_BITFIELD(reg, 21, 24)
|
||||||
|
@ -343,7 +344,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
|
||||||
|
|
||||||
status_mask = rrl->over_mask | rrl->uc_mask | rrl->v_mask;
|
status_mask = rrl->over_mask | rrl->uc_mask | rrl->v_mask;
|
||||||
|
|
||||||
n = snprintf(msg, len, " retry_rd_err_log[");
|
n = scnprintf(msg, len, " retry_rd_err_log[");
|
||||||
for (i = 0; i < rrl->set_num; i++) {
|
for (i = 0; i < rrl->set_num; i++) {
|
||||||
scrub = (rrl->modes[i] == FRE_SCRUB || rrl->modes[i] == LRE_SCRUB);
|
scrub = (rrl->modes[i] == FRE_SCRUB || rrl->modes[i] == LRE_SCRUB);
|
||||||
if (scrub_err != scrub)
|
if (scrub_err != scrub)
|
||||||
|
@ -355,9 +356,9 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
|
||||||
log = read_imc_reg(imc, ch, offset, width);
|
log = read_imc_reg(imc, ch, offset, width);
|
||||||
|
|
||||||
if (width == 4)
|
if (width == 4)
|
||||||
n += snprintf(msg + n, len - n, "%.8llx ", log);
|
n += scnprintf(msg + n, len - n, "%.8llx ", log);
|
||||||
else
|
else
|
||||||
n += snprintf(msg + n, len - n, "%.16llx ", log);
|
n += scnprintf(msg + n, len - n, "%.16llx ", log);
|
||||||
|
|
||||||
/* Clear RRL status if RRL in Linux control mode. */
|
/* Clear RRL status if RRL in Linux control mode. */
|
||||||
if (retry_rd_err_log == 2 && !j && (log & status_mask))
|
if (retry_rd_err_log == 2 && !j && (log & status_mask))
|
||||||
|
@ -367,10 +368,10 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
|
||||||
|
|
||||||
/* Move back one space. */
|
/* Move back one space. */
|
||||||
n--;
|
n--;
|
||||||
n += snprintf(msg + n, len - n, "]");
|
n += scnprintf(msg + n, len - n, "]");
|
||||||
|
|
||||||
if (len - n > 0) {
|
if (len - n > 0) {
|
||||||
n += snprintf(msg + n, len - n, " correrrcnt[");
|
n += scnprintf(msg + n, len - n, " correrrcnt[");
|
||||||
for (i = 0; i < rrl->cecnt_num && len - n > 0; i++) {
|
for (i = 0; i < rrl->cecnt_num && len - n > 0; i++) {
|
||||||
offset = rrl->cecnt_offsets[i];
|
offset = rrl->cecnt_offsets[i];
|
||||||
width = rrl->cecnt_widths[i];
|
width = rrl->cecnt_widths[i];
|
||||||
|
@ -378,20 +379,20 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
|
||||||
|
|
||||||
/* CPUs {ICX,SPR} encode two counters per 4-byte CORRERRCNT register. */
|
/* CPUs {ICX,SPR} encode two counters per 4-byte CORRERRCNT register. */
|
||||||
if (res_cfg->type <= SPR) {
|
if (res_cfg->type <= SPR) {
|
||||||
n += snprintf(msg + n, len - n, "%.4llx %.4llx ",
|
n += scnprintf(msg + n, len - n, "%.4llx %.4llx ",
|
||||||
corr & 0xffff, corr >> 16);
|
corr & 0xffff, corr >> 16);
|
||||||
} else {
|
} else {
|
||||||
/* CPUs {GNR} encode one counter per CORRERRCNT register. */
|
/* CPUs {GNR} encode one counter per CORRERRCNT register. */
|
||||||
if (width == 4)
|
if (width == 4)
|
||||||
n += snprintf(msg + n, len - n, "%.8llx ", corr);
|
n += scnprintf(msg + n, len - n, "%.8llx ", corr);
|
||||||
else
|
else
|
||||||
n += snprintf(msg + n, len - n, "%.16llx ", corr);
|
n += scnprintf(msg + n, len - n, "%.16llx ", corr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move back one space. */
|
/* Move back one space. */
|
||||||
n--;
|
n--;
|
||||||
n += snprintf(msg + n, len - n, "]");
|
n += scnprintf(msg + n, len - n, "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,6 +688,14 @@ static struct pci_dev *get_gnr_mdev(struct skx_dev *d, int logical_idx, int *phy
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 get_gnr_imc_mmio_offset(void)
|
||||||
|
{
|
||||||
|
if (boot_cpu_data.x86_vfm == INTEL_GRANITERAPIDS_D)
|
||||||
|
return I10NM_GNR_D_IMC_MMIO_OFFSET;
|
||||||
|
|
||||||
|
return I10NM_GNR_IMC_MMIO_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_ddr_munit() - Get the resource of the i-th DDR memory controller.
|
* get_ddr_munit() - Get the resource of the i-th DDR memory controller.
|
||||||
*
|
*
|
||||||
|
@ -715,7 +724,7 @@ static struct pci_dev *get_ddr_munit(struct skx_dev *d, int i, u32 *offset, unsi
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*offset = I10NM_GET_IMC_MMIO_OFFSET(reg) +
|
*offset = I10NM_GET_IMC_MMIO_OFFSET(reg) +
|
||||||
I10NM_GNR_IMC_MMIO_OFFSET +
|
get_gnr_imc_mmio_offset() +
|
||||||
physical_idx * I10NM_GNR_IMC_MMIO_SIZE;
|
physical_idx * I10NM_GNR_IMC_MMIO_SIZE;
|
||||||
*size = I10NM_GNR_IMC_MMIO_SIZE;
|
*size = I10NM_GNR_IMC_MMIO_SIZE;
|
||||||
|
|
||||||
|
@ -1030,6 +1039,7 @@ static const struct x86_cpu_id i10nm_cpuids[] = {
|
||||||
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_cfg),
|
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_cfg),
|
||||||
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_cfg),
|
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &spr_cfg),
|
||||||
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_cfg),
|
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &gnr_cfg),
|
||||||
|
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &gnr_cfg),
|
||||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_cfg),
|
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_cfg),
|
||||||
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_cfg),
|
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &gnr_cfg),
|
||||||
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_cfg),
|
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &gnr_cfg),
|
||||||
|
|
|
@ -87,14 +87,31 @@
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10 0x3eca
|
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10 0x3eca
|
||||||
|
|
||||||
/* Raptor Lake-S */
|
/* Raptor Lake-S */
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_1 0xa703
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_1 0xa703 /* 8P+8E, e.g. i7-13700 */
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2 0x4640
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2 0x4640 /* 6P+8E, e.g. i5-13500, i5-13600, i5-14500 */
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3 0x4630
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3 0x4630 /* 4P+0E, e.g. i3-13100E */
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4 0xa700
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4 0xa700 /* 8P+16E, e.g. i9-13900, i9-14900 */
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_5 0xa740 /* 8P+12E, e.g. i7-14700 */
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_6 0xa704 /* 6P+8E, e.g. i5-14600 */
|
||||||
|
|
||||||
|
/* Raptor Lake-HX */
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_HX_1 0xa702 /* 8P+16E, e.g. i9-13950HX */
|
||||||
|
|
||||||
/* Alder Lake-S */
|
/* Alder Lake-S */
|
||||||
#define PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1 0x4660
|
#define PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1 0x4660
|
||||||
|
|
||||||
|
/* Bartlett Lake-S */
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_1 0x4639
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_2 0x463c
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_3 0x4642
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_4 0x4643
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_5 0xa731
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_6 0xa732
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_7 0xa733
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_8 0xa741
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_9 0xa744
|
||||||
|
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_10 0xa745
|
||||||
|
|
||||||
#define IE31200_RANKS_PER_CHANNEL 8
|
#define IE31200_RANKS_PER_CHANNEL 8
|
||||||
#define IE31200_DIMMS_PER_CHANNEL 2
|
#define IE31200_DIMMS_PER_CHANNEL 2
|
||||||
#define IE31200_CHANNELS 2
|
#define IE31200_CHANNELS 2
|
||||||
|
@ -740,7 +757,20 @@ static const struct pci_device_id ie31200_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2), (kernel_ulong_t)&rpl_s_cfg},
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3), (kernel_ulong_t)&rpl_s_cfg},
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4), (kernel_ulong_t)&rpl_s_cfg},
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_5), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_6), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_HX_1), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1), (kernel_ulong_t)&rpl_s_cfg},
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_1), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_2), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_3), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_4), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_5), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_6), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_7), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_8), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_9), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
|
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_10), (kernel_ulong_t)&rpl_s_cfg},
|
||||||
{ 0, } /* 0 terminated list. */
|
{ 0, } /* 0 terminated list. */
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);
|
||||||
|
|
|
@ -275,6 +275,9 @@ static struct work_struct ecclog_work;
|
||||||
#define DID_PTL_H_SKU2 0xb001
|
#define DID_PTL_H_SKU2 0xb001
|
||||||
#define DID_PTL_H_SKU3 0xb002
|
#define DID_PTL_H_SKU3 0xb002
|
||||||
|
|
||||||
|
/* Compute die IDs for Wildcat Lake with IBECC */
|
||||||
|
#define DID_WCL_SKU1 0xfd00
|
||||||
|
|
||||||
static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
|
static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
|
@ -569,6 +572,17 @@ static struct res_config mtl_p_cfg = {
|
||||||
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
|
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct res_config wcl_cfg = {
|
||||||
|
.machine_check = true,
|
||||||
|
.num_imc = 1,
|
||||||
|
.imc_base = 0xd800,
|
||||||
|
.ibecc_base = 0xd400,
|
||||||
|
.ibecc_error_log_offset = 0x170,
|
||||||
|
.ibecc_available = mtl_p_ibecc_available,
|
||||||
|
.err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
|
||||||
|
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
|
||||||
|
};
|
||||||
|
|
||||||
static struct pci_device_id igen6_pci_tbl[] = {
|
static struct pci_device_id igen6_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg },
|
{ PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg },
|
||||||
{ PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg },
|
{ PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg },
|
||||||
|
@ -622,6 +636,7 @@ static struct pci_device_id igen6_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&mtl_p_cfg },
|
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&mtl_p_cfg },
|
||||||
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&mtl_p_cfg },
|
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&mtl_p_cfg },
|
||||||
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&mtl_p_cfg },
|
{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&mtl_p_cfg },
|
||||||
|
{ PCI_VDEVICE(INTEL, DID_WCL_SKU1), (kernel_ulong_t)&wcl_cfg },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
|
||||||
|
@ -1351,7 +1366,7 @@ static int igen6_register_mcis(struct pci_dev *pdev, u64 mchbar)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lmc < res_cfg->num_imc) {
|
if (lmc < res_cfg->num_imc) {
|
||||||
igen6_printk(KERN_WARNING, "Expected %d mcs, but only %d detected.",
|
igen6_printk(KERN_DEBUG, "Expected %d mcs, but only %d detected.",
|
||||||
res_cfg->num_imc, lmc);
|
res_cfg->num_imc, lmc);
|
||||||
res_cfg->num_imc = lmc;
|
res_cfg->num_imc = lmc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,17 +286,26 @@ static umode_t mem_repair_attr_visible(struct kobject *kobj, struct attribute *a
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MR_ATTR_RO(_name, _instance) \
|
static const struct device_attribute mem_repair_dev_attr[] = {
|
||||||
((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_RO(_name), \
|
[MR_TYPE] = __ATTR_RO(repair_type),
|
||||||
.instance = _instance })
|
[MR_PERSIST_MODE] = __ATTR_RW(persist_mode),
|
||||||
|
[MR_SAFE_IN_USE] = __ATTR_RO(repair_safe_when_in_use),
|
||||||
#define MR_ATTR_WO(_name, _instance) \
|
[MR_HPA] = __ATTR_RW(hpa),
|
||||||
((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_WO(_name), \
|
[MR_MIN_HPA] = __ATTR_RO(min_hpa),
|
||||||
.instance = _instance })
|
[MR_MAX_HPA] = __ATTR_RO(max_hpa),
|
||||||
|
[MR_DPA] = __ATTR_RW(dpa),
|
||||||
#define MR_ATTR_RW(_name, _instance) \
|
[MR_MIN_DPA] = __ATTR_RO(min_dpa),
|
||||||
((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_RW(_name), \
|
[MR_MAX_DPA] = __ATTR_RO(max_dpa),
|
||||||
.instance = _instance })
|
[MR_NIBBLE_MASK] = __ATTR_RW(nibble_mask),
|
||||||
|
[MR_BANK_GROUP] = __ATTR_RW(bank_group),
|
||||||
|
[MR_BANK] = __ATTR_RW(bank),
|
||||||
|
[MR_RANK] = __ATTR_RW(rank),
|
||||||
|
[MR_ROW] = __ATTR_RW(row),
|
||||||
|
[MR_COLUMN] = __ATTR_RW(column),
|
||||||
|
[MR_CHANNEL] = __ATTR_RW(channel),
|
||||||
|
[MR_SUB_CHANNEL] = __ATTR_RW(sub_channel),
|
||||||
|
[MEM_DO_REPAIR] = __ATTR_WO(repair)
|
||||||
|
};
|
||||||
|
|
||||||
static int mem_repair_create_desc(struct device *dev,
|
static int mem_repair_create_desc(struct device *dev,
|
||||||
const struct attribute_group **attr_groups,
|
const struct attribute_group **attr_groups,
|
||||||
|
@ -305,34 +314,13 @@ static int mem_repair_create_desc(struct device *dev,
|
||||||
struct edac_mem_repair_context *ctx;
|
struct edac_mem_repair_context *ctx;
|
||||||
struct attribute_group *group;
|
struct attribute_group *group;
|
||||||
int i;
|
int i;
|
||||||
struct edac_mem_repair_dev_attr dev_attr[] = {
|
|
||||||
[MR_TYPE] = MR_ATTR_RO(repair_type, instance),
|
|
||||||
[MR_PERSIST_MODE] = MR_ATTR_RW(persist_mode, instance),
|
|
||||||
[MR_SAFE_IN_USE] = MR_ATTR_RO(repair_safe_when_in_use, instance),
|
|
||||||
[MR_HPA] = MR_ATTR_RW(hpa, instance),
|
|
||||||
[MR_MIN_HPA] = MR_ATTR_RO(min_hpa, instance),
|
|
||||||
[MR_MAX_HPA] = MR_ATTR_RO(max_hpa, instance),
|
|
||||||
[MR_DPA] = MR_ATTR_RW(dpa, instance),
|
|
||||||
[MR_MIN_DPA] = MR_ATTR_RO(min_dpa, instance),
|
|
||||||
[MR_MAX_DPA] = MR_ATTR_RO(max_dpa, instance),
|
|
||||||
[MR_NIBBLE_MASK] = MR_ATTR_RW(nibble_mask, instance),
|
|
||||||
[MR_BANK_GROUP] = MR_ATTR_RW(bank_group, instance),
|
|
||||||
[MR_BANK] = MR_ATTR_RW(bank, instance),
|
|
||||||
[MR_RANK] = MR_ATTR_RW(rank, instance),
|
|
||||||
[MR_ROW] = MR_ATTR_RW(row, instance),
|
|
||||||
[MR_COLUMN] = MR_ATTR_RW(column, instance),
|
|
||||||
[MR_CHANNEL] = MR_ATTR_RW(channel, instance),
|
|
||||||
[MR_SUB_CHANNEL] = MR_ATTR_RW(sub_channel, instance),
|
|
||||||
[MEM_DO_REPAIR] = MR_ATTR_WO(repair, instance)
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < MR_MAX_ATTRS; i++) {
|
for (i = 0; i < MR_MAX_ATTRS; i++) {
|
||||||
memcpy(&ctx->mem_repair_dev_attr[i],
|
ctx->mem_repair_dev_attr[i].dev_attr = mem_repair_dev_attr[i];
|
||||||
&dev_attr[i], sizeof(dev_attr[i]));
|
ctx->mem_repair_dev_attr[i].instance = instance;
|
||||||
sysfs_attr_init(&ctx->mem_repair_dev_attr[i].dev_attr.attr);
|
sysfs_attr_init(&ctx->mem_repair_dev_attr[i].dev_attr.attr);
|
||||||
ctx->mem_repair_attrs[i] =
|
ctx->mem_repair_attrs[i] =
|
||||||
&ctx->mem_repair_dev_attr[i].dev_attr.attr;
|
&ctx->mem_repair_dev_attr[i].dev_attr.attr;
|
||||||
|
|
|
@ -670,12 +670,12 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res->decoded_by_adxl) {
|
if (res->decoded_by_adxl) {
|
||||||
len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
|
len = scnprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
|
||||||
overflow ? " OVERFLOW" : "",
|
overflow ? " OVERFLOW" : "",
|
||||||
(uncorrected_error && recoverable) ? " recoverable" : "",
|
(uncorrected_error && recoverable) ? " recoverable" : "",
|
||||||
mscod, errcode, adxl_msg);
|
mscod, errcode, adxl_msg);
|
||||||
} else {
|
} else {
|
||||||
len = snprintf(skx_msg, MSG_SIZE,
|
len = scnprintf(skx_msg, MSG_SIZE,
|
||||||
"%s%s err_code:0x%04x:0x%04x ProcessorSocketId:0x%x MemoryControllerId:0x%x PhysicalRankId:0x%x Row:0x%x Column:0x%x Bank:0x%x BankGroup:0x%x",
|
"%s%s err_code:0x%04x:0x%04x ProcessorSocketId:0x%x MemoryControllerId:0x%x PhysicalRankId:0x%x Row:0x%x Column:0x%x Bank:0x%x BankGroup:0x%x",
|
||||||
overflow ? " OVERFLOW" : "",
|
overflow ? " OVERFLOW" : "",
|
||||||
(uncorrected_error && recoverable) ? " recoverable" : "",
|
(uncorrected_error && recoverable) ? " recoverable" : "",
|
||||||
|
|
|
@ -332,20 +332,26 @@ struct synps_edac_priv {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum synps_platform_type {
|
||||||
|
ZYNQ,
|
||||||
|
ZYNQMP,
|
||||||
|
SYNPS,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct synps_platform_data - synps platform data structure.
|
* struct synps_platform_data - synps platform data structure.
|
||||||
|
* @platform: Identifies the target hardware platform
|
||||||
* @get_error_info: Get EDAC error info.
|
* @get_error_info: Get EDAC error info.
|
||||||
* @get_mtype: Get mtype.
|
* @get_mtype: Get mtype.
|
||||||
* @get_dtype: Get dtype.
|
* @get_dtype: Get dtype.
|
||||||
* @get_ecc_state: Get ECC state.
|
|
||||||
* @get_mem_info: Get EDAC memory info
|
* @get_mem_info: Get EDAC memory info
|
||||||
* @quirks: To differentiate IPs.
|
* @quirks: To differentiate IPs.
|
||||||
*/
|
*/
|
||||||
struct synps_platform_data {
|
struct synps_platform_data {
|
||||||
|
enum synps_platform_type platform;
|
||||||
int (*get_error_info)(struct synps_edac_priv *priv);
|
int (*get_error_info)(struct synps_edac_priv *priv);
|
||||||
enum mem_type (*get_mtype)(const void __iomem *base);
|
enum mem_type (*get_mtype)(const void __iomem *base);
|
||||||
enum dev_type (*get_dtype)(const void __iomem *base);
|
enum dev_type (*get_dtype)(const void __iomem *base);
|
||||||
bool (*get_ecc_state)(void __iomem *base);
|
|
||||||
#ifdef CONFIG_EDAC_DEBUG
|
#ifdef CONFIG_EDAC_DEBUG
|
||||||
u64 (*get_mem_info)(struct synps_edac_priv *priv);
|
u64 (*get_mem_info)(struct synps_edac_priv *priv);
|
||||||
#endif
|
#endif
|
||||||
|
@ -720,51 +726,38 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base)
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static bool get_ecc_state(struct synps_edac_priv *priv)
|
||||||
* zynq_get_ecc_state - Return the controller ECC enable/disable status.
|
|
||||||
* @base: DDR memory controller base address.
|
|
||||||
*
|
|
||||||
* Get the ECC enable/disable status of the controller.
|
|
||||||
*
|
|
||||||
* Return: true if enabled, otherwise false.
|
|
||||||
*/
|
|
||||||
static bool zynq_get_ecc_state(void __iomem *base)
|
|
||||||
{
|
{
|
||||||
|
u32 ecctype, clearval;
|
||||||
enum dev_type dt;
|
enum dev_type dt;
|
||||||
u32 ecctype;
|
|
||||||
|
|
||||||
dt = zynq_get_dtype(base);
|
if (priv->p_data->platform == ZYNQ) {
|
||||||
if (dt == DEV_UNKNOWN)
|
dt = zynq_get_dtype(priv->baseaddr);
|
||||||
return false;
|
if (dt == DEV_UNKNOWN)
|
||||||
|
return false;
|
||||||
|
|
||||||
ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
|
ecctype = readl(priv->baseaddr + SCRUB_OFST) & SCRUB_MODE_MASK;
|
||||||
if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
|
if (ecctype == SCRUB_MODE_SECDED && dt == DEV_X2) {
|
||||||
return true;
|
clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_UE_ERR;
|
||||||
|
writel(clearval, priv->baseaddr + ECC_CTRL_OFST);
|
||||||
|
writel(0x0, priv->baseaddr + ECC_CTRL_OFST);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dt = zynqmp_get_dtype(priv->baseaddr);
|
||||||
|
if (dt == DEV_UNKNOWN)
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
ecctype = readl(priv->baseaddr + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
|
||||||
}
|
if (ecctype == SCRUB_MODE_SECDED &&
|
||||||
|
(dt == DEV_X2 || dt == DEV_X4 || dt == DEV_X8)) {
|
||||||
/**
|
clearval = readl(priv->baseaddr + ECC_CLR_OFST) |
|
||||||
* zynqmp_get_ecc_state - Return the controller ECC enable/disable status.
|
ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
|
||||||
* @base: DDR memory controller base address.
|
ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
|
||||||
*
|
writel(clearval, priv->baseaddr + ECC_CLR_OFST);
|
||||||
* Get the ECC enable/disable status for the controller.
|
return true;
|
||||||
*
|
}
|
||||||
* Return: a ECC status boolean i.e true/false - enabled/disabled.
|
}
|
||||||
*/
|
|
||||||
static bool zynqmp_get_ecc_state(void __iomem *base)
|
|
||||||
{
|
|
||||||
enum dev_type dt;
|
|
||||||
u32 ecctype;
|
|
||||||
|
|
||||||
dt = zynqmp_get_dtype(base);
|
|
||||||
if (dt == DEV_UNKNOWN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
|
|
||||||
if ((ecctype == SCRUB_MODE_SECDED) &&
|
|
||||||
((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -934,18 +927,18 @@ static int setup_irq(struct mem_ctl_info *mci,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct synps_platform_data zynq_edac_def = {
|
static const struct synps_platform_data zynq_edac_def = {
|
||||||
|
.platform = ZYNQ,
|
||||||
.get_error_info = zynq_get_error_info,
|
.get_error_info = zynq_get_error_info,
|
||||||
.get_mtype = zynq_get_mtype,
|
.get_mtype = zynq_get_mtype,
|
||||||
.get_dtype = zynq_get_dtype,
|
.get_dtype = zynq_get_dtype,
|
||||||
.get_ecc_state = zynq_get_ecc_state,
|
|
||||||
.quirks = 0,
|
.quirks = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct synps_platform_data zynqmp_edac_def = {
|
static const struct synps_platform_data zynqmp_edac_def = {
|
||||||
|
.platform = ZYNQMP,
|
||||||
.get_error_info = zynqmp_get_error_info,
|
.get_error_info = zynqmp_get_error_info,
|
||||||
.get_mtype = zynqmp_get_mtype,
|
.get_mtype = zynqmp_get_mtype,
|
||||||
.get_dtype = zynqmp_get_dtype,
|
.get_dtype = zynqmp_get_dtype,
|
||||||
.get_ecc_state = zynqmp_get_ecc_state,
|
|
||||||
#ifdef CONFIG_EDAC_DEBUG
|
#ifdef CONFIG_EDAC_DEBUG
|
||||||
.get_mem_info = zynqmp_get_mem_info,
|
.get_mem_info = zynqmp_get_mem_info,
|
||||||
#endif
|
#endif
|
||||||
|
@ -957,10 +950,10 @@ static const struct synps_platform_data zynqmp_edac_def = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct synps_platform_data synopsys_edac_def = {
|
static const struct synps_platform_data synopsys_edac_def = {
|
||||||
|
.platform = SYNPS,
|
||||||
.get_error_info = zynqmp_get_error_info,
|
.get_error_info = zynqmp_get_error_info,
|
||||||
.get_mtype = zynqmp_get_mtype,
|
.get_mtype = zynqmp_get_mtype,
|
||||||
.get_dtype = zynqmp_get_dtype,
|
.get_dtype = zynqmp_get_dtype,
|
||||||
.get_ecc_state = zynqmp_get_ecc_state,
|
|
||||||
.quirks = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
|
.quirks = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
|
||||||
#ifdef CONFIG_EDAC_DEBUG
|
#ifdef CONFIG_EDAC_DEBUG
|
||||||
| DDR_ECC_DATA_POISON_SUPPORT
|
| DDR_ECC_DATA_POISON_SUPPORT
|
||||||
|
@ -1390,10 +1383,6 @@ static int mc_probe(struct platform_device *pdev)
|
||||||
if (!p_data)
|
if (!p_data)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!p_data->get_ecc_state(baseaddr)) {
|
|
||||||
edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
|
|
||||||
return -ENXIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
|
layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
|
||||||
layers[0].size = SYNPS_EDAC_NR_CSROWS;
|
layers[0].size = SYNPS_EDAC_NR_CSROWS;
|
||||||
|
@ -1413,6 +1402,12 @@ static int mc_probe(struct platform_device *pdev)
|
||||||
priv = mci->pvt_info;
|
priv = mci->pvt_info;
|
||||||
priv->baseaddr = baseaddr;
|
priv->baseaddr = baseaddr;
|
||||||
priv->p_data = p_data;
|
priv->p_data = p_data;
|
||||||
|
if (!get_ecc_state(priv)) {
|
||||||
|
edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
|
||||||
|
rc = -ENODEV;
|
||||||
|
goto free_edac_mc;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_init(&priv->reglock);
|
spin_lock_init(&priv->reglock);
|
||||||
|
|
||||||
mc_init(mci, pdev);
|
mc_init(mci, pdev);
|
||||||
|
|
Loading…
Add table
Reference in a new issue