Linux EDAC development
 help / color / mirror / Atom feed
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
To: Tony Luck <tony.luck@intel.com>, Borislav Petkov <bp@alien8.de>
Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com>, Yi Lai <yi1.lai@intel.com>,
	linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 8/8] EDAC/imh: Add RRL support for Intel Diamond Rapids server
Date: Thu, 21 May 2026 15:31:12 +0800	[thread overview]
Message-ID: <20260521073112.3881223-9-qiuxu.zhuo@intel.com> (raw)
In-Reply-To: <20260521073112.3881223-1-qiuxu.zhuo@intel.com>

Compared to previous generations, Diamond Rapids RRL (Retry Read error Log)
operates at DDR sub-channel granularity and adds an extra register per set.
It also increases the CORRERRCNT register width from 4 to 8 bytes while
reducing the number of registers from 8 to 4.

Add the Diamond Rapids RRL register configuration table and enable support.

Tested-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
---
 drivers/edac/imh_base.c   | 52 +++++++++++++++++++++++++++++++++++++++
 drivers/edac/skx_common.h |  2 +-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c
index dfdcfa127ce7..6ca0df031bf5 100644
--- a/drivers/edac/imh_base.c
+++ b/drivers/edac/imh_base.c
@@ -71,6 +71,39 @@ struct local_reg {
 		.width	= (cfg)->ip_name##_reg_##reg_name##_width,		\
 	}
 
+static struct res_config *res_cfg;
+static int retry_rd_err_log;
+
+#define REG_RRL_DEFINE(a0, a1, a2, a3, a4, a5, a6, b0, b1, b2, b3)	\
+	{								\
+		.set_num = 4,						\
+		.reg_num = 7,						\
+		.sources = {RRL_SRC_FRE_SCRUB, RRL_SRC_FRE_DEMAND, RRL_SRC_LRE_SCRUB, RRL_SRC_LRE_DEMAND},	\
+		.offsets = {									\
+			{a0,      a1,      a2,      a3,      a4,      a5,      a6},		\
+			{a0 + 4,  a1 + 4,  a2 + 8,  a3 + 4,  a4 + 4,  a5 + 8,  a6 + 8},		\
+			{a0 + 8,  a1 + 8,  a2 + 16, a3 + 8,  a4 + 8,  a5 + 16, a6 + 16},	\
+			{a0 + 12, a1 + 12, a2 + 24, a3 + 12, a4 + 12, a5 + 24, a6 + 24},	\
+		},										\
+		.widths		= {4, 4, 8, 4, 4, 8, 8},		\
+		.v_mask		= BIT(0),				\
+		.uc_mask	= BIT(1),				\
+		.over_mask	= BIT(2),				\
+		.en_mask	= BIT(12),				\
+		.en_patspr_mask	= BIT(14),				\
+		.noover_mask	= BIT(15),				\
+		.cecnt_num	= 4,					\
+		.cecnt_offsets	= {b0, b1, b2, b3},			\
+		.cecnt_widths	= {8, 8, 8, 8},				\
+}
+
+static struct reg_rrl dmr_reg_rrl_ddr_subch0 = REG_RRL_DEFINE(
+	0x2dc0, 0x2dd0, 0x2de0, 0x2e00, 0x2e10, 0x2f70, 0x0200,
+	0x2c10, 0x2c18, 0x2c20, 0x2c28);
+static struct reg_rrl dmr_reg_rrl_ddr_subch1 = REG_RRL_DEFINE(
+	0x6dc0, 0x6dd0, 0x6de0, 0x6e00, 0x6e10, 0x6f70, 0x4200,
+	0x6c10, 0x6c18, 0x6c20, 0x6c28);
+
 static void __read_local_reg(void *reg)
 {
 	struct local_reg *r = (struct local_reg *)reg;
@@ -480,6 +513,8 @@ static struct res_config dmr_cfg = {
 	.ha_size			= 0x1000,
 	.ha_reg_mode_offset		= 0x4a0,
 	.ha_reg_mode_width		= 4,
+	.reg_rrl_ddr[0]			= &dmr_reg_rrl_ddr_subch0,
+	.reg_rrl_ddr[1]			= &dmr_reg_rrl_ddr_subch1,
 };
 
 static const struct x86_cpu_id imh_cpuids[] = {
@@ -519,6 +554,7 @@ static int __init imh_init(void)
 		return -ENODEV;
 	cfg = (struct res_config *)id->driver_data;
 	skx_set_res_cfg(cfg);
+	res_cfg = cfg;
 
 	if (!imh_get_tolm_tohm(cfg, &tolm, &tohm))
 		return -ENODEV;
@@ -553,6 +589,13 @@ static int __init imh_init(void)
 	mce_register_decode_chain(&imh_mce_dec);
 	skx_setup_debug("imh_test");
 
+	cfg->rrl_ctrl_mode = retry_rd_err_log;
+	if (retry_rd_err_log && cfg->reg_rrl_ddr[0]) {
+		skx_set_show_rrl(skx_show_rrl);
+		if (retry_rd_err_log == RRL_CTRL_LINUX)
+			skx_enable_rrl(true);
+	}
+
 	imh_printk(KERN_INFO, "%s\n", IMH_REVISION);
 
 	return 0;
@@ -565,6 +608,12 @@ static void __exit imh_exit(void)
 {
 	edac_dbg(2, "\n");
 
+	if (retry_rd_err_log && res_cfg->reg_rrl_ddr[0]) {
+		if (retry_rd_err_log == RRL_CTRL_LINUX)
+			skx_enable_rrl(false);
+		skx_set_show_rrl(NULL);
+	}
+
 	skx_teardown_debug();
 	mce_unregister_decode_chain(&imh_mce_dec);
 	skx_adxl_put();
@@ -574,6 +623,9 @@ static void __exit imh_exit(void)
 module_init(imh_init);
 module_exit(imh_exit);
 
+module_param(retry_rd_err_log, int, 0444);
+MODULE_PARM_DESC(retry_rd_err_log, "retry_rd_err_log: 0=off(default), 1=bios(Linux doesn't reset any control bits, but just reports values.), 2=linux(Linux tries to take control and resets mode bits, clear valid/UC bits after reading.)");
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Qiuxu Zhuo");
 MODULE_DESCRIPTION("MC Driver for Intel servers using IMH-based memory controller");
diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
index 6d4cf0dd412a..777252cca809 100644
--- a/drivers/edac/skx_common.h
+++ b/drivers/edac/skx_common.h
@@ -77,7 +77,7 @@
 /* Max RRL register sets per {,sub-,pseudo-}channel. */
 #define NUM_RRL_SET		4
 /* Max RRL registers per set. */
-#define NUM_RRL_REG		6
+#define NUM_RRL_REG		7
 /* Max correctable error count registers. */
 #define NUM_CECNT_REG		8
 
-- 
2.43.0


  parent reply	other threads:[~2026-05-21  7:40 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-21  7:31 [PATCH 0/8] EDAC: Add RRL support for Intel Diamond Rapids servers Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 1/8] EDAC/{skx_common,i10nm,imh}: Move MC register access helpers to skx_common Qiuxu Zhuo
2026-06-15  2:26   ` Borislav Petkov
2026-06-16  2:02     ` Zhuo, Qiuxu
2026-05-21  7:31 ` [PATCH 2/8] EDAC/{skx_common,skx,i10nm}: Split skx_set_decode() Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 3/8] EDAC/{skx_common,i10nm}: Rename rrl_mode to rrl_source_type Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 4/8] EDAC/{skx_common,i10nm}: Introduce rrl_ctrl_mode Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 5/8] EDAC/{skx_common,i10nm}: Move RRL handling to common code Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 6/8] EDAC/skx_common: Add SubChannel support to ADXL decode Qiuxu Zhuo
2026-05-21  7:31 ` [PATCH 7/8] EDAC/{skx_common,i10nm}: Prepare RRL for sub-channel granularity Qiuxu Zhuo
2026-05-21  7:31 ` Qiuxu Zhuo [this message]
2026-05-27 16:18 ` [PATCH 0/8] EDAC: Add RRL support for Intel Diamond Rapids servers Luck, Tony

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260521073112.3881223-9-qiuxu.zhuo@intel.com \
    --to=qiuxu.zhuo@intel.com \
    --cc=bp@alien8.de \
    --cc=linux-edac@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tony.luck@intel.com \
    --cc=yi1.lai@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox