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 1/8] EDAC/{skx_common,i10nm,imh}: Move MC register access helpers to skx_common
Date: Thu, 21 May 2026 15:31:05 +0800	[thread overview]
Message-ID: <20260521073112.3881223-2-qiuxu.zhuo@intel.com> (raw)
In-Reply-To: <20260521073112.3881223-1-qiuxu.zhuo@intel.com>

Both i10nm_basic.c and imh_basic.c use identical helpers for accessing
memory controller MMIO-based registers. Move these helpers to skx_common.c
to eliminate code duplication. This change also prepares for an upcoming
patch that will move RRL(retry_rd_err_log) code from i10nm_basic.c to
skx_common.c, which requires these helpers to be available in skx_common.c.

Additionally, prefix these function names with 'skx_' to maintain naming
consistency within the file.

No functional changes intended.

Tested-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
---
 drivers/edac/i10nm_base.c | 39 ++++--------------------------
 drivers/edac/imh_base.c   | 33 ++++----------------------
 drivers/edac/skx_common.c | 50 +++++++++++++++++++++++++++++++++++++++
 drivers/edac/skx_common.h |  3 +++
 4 files changed, 63 insertions(+), 62 deletions(-)

diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
index de6c52dbd9d2..0a0236583eb7 100644
--- a/drivers/edac/i10nm_base.c
+++ b/drivers/edac/i10nm_base.c
@@ -47,12 +47,6 @@
 	readl((m)->mbase + ((m)->hbm_mc ? 0xef8 :	\
 	(res_cfg->type == GNR ? 0xaf8 : 0x20ef8)) +	\
 	(i) * (m)->chan_mmio_sz)
-#define I10NM_GET_REG32(m, i, offset)	\
-	readl((m)->mbase + (i) * (m)->chan_mmio_sz + (offset))
-#define I10NM_GET_REG64(m, i, offset)	\
-	readq((m)->mbase + (i) * (m)->chan_mmio_sz + (offset))
-#define I10NM_SET_REG32(m, i, offset, v)	\
-	writel(v, (m)->mbase + (i) * (m)->chan_mmio_sz + (offset))
 
 #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)
@@ -189,29 +183,6 @@ static struct reg_rrl gnr_reg_rrl_ddr = {
 	.cecnt_widths	= {4, 4, 4, 4, 4, 4, 4, 4},
 };
 
-static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width)
-{
-	switch (width) {
-	case 4:
-		return I10NM_GET_REG32(imc, chan, offset);
-	case 8:
-		return I10NM_GET_REG64(imc, chan, offset);
-	default:
-		i10nm_printk(KERN_ERR, "Invalid read RRL 0x%x width %d\n", offset, width);
-		return 0;
-	}
-}
-
-static void write_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width, u64 val)
-{
-	switch (width) {
-	case 4:
-		return I10NM_SET_REG32(imc, chan, offset, (u32)val);
-	default:
-		i10nm_printk(KERN_ERR, "Invalid write RRL 0x%x width %d\n", offset, width);
-	}
-}
-
 static void enable_rrl(struct skx_imc *imc, int chan, struct reg_rrl *rrl,
 		       int rrl_set, bool enable, u32 *rrl_ctl)
 {
@@ -225,7 +196,7 @@ static void enable_rrl(struct skx_imc *imc, int chan, struct reg_rrl *rrl,
 	/* Patrol scrub or on-demand read error. */
 	scrub = (mode == FRE_SCRUB || mode == LRE_SCRUB);
 
-	v = read_imc_reg(imc, chan, offset, width);
+	v = skx_read_imc_reg(imc, chan, offset, width);
 
 	if (enable) {
 		/* Save default configurations. */
@@ -268,7 +239,7 @@ static void enable_rrl(struct skx_imc *imc, int chan, struct reg_rrl *rrl,
 			v &= ~rrl->en_mask;
 	}
 
-	write_imc_reg(imc, chan, offset, width, v);
+	skx_write_imc_reg(imc, chan, offset, width, v);
 }
 
 static void enable_rrls(struct skx_imc *imc, int chan, struct reg_rrl *rrl,
@@ -354,7 +325,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
 		for (j = 0; j < rrl->reg_num && len - n > 0; j++) {
 			offset = rrl->offsets[i][j];
 			width = rrl->widths[j];
-			log = read_imc_reg(imc, ch, offset, width);
+			log = skx_read_imc_reg(imc, ch, offset, width);
 
 			if (width == 4)
 				n += scnprintf(msg + n, len - n, "%.8llx ", log);
@@ -363,7 +334,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
 
 			/* Clear RRL status if RRL in Linux control mode. */
 			if (retry_rd_err_log == 2 && !j && (log & status_mask))
-				write_imc_reg(imc, ch, offset, width, log & ~status_mask);
+				skx_write_imc_reg(imc, ch, offset, width, log & ~status_mask);
 		}
 	}
 
@@ -376,7 +347,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
 		for (i = 0; i < rrl->cecnt_num && len - n > 0; i++) {
 			offset = rrl->cecnt_offsets[i];
 			width = rrl->cecnt_widths[i];
-			corr = read_imc_reg(imc, ch, offset, width);
+			corr = skx_read_imc_reg(imc, ch, offset, width);
 
 			/* CPUs {ICX,SPR} encode two counters per 4-byte CORRERRCNT register. */
 			if (res_cfg->type <= SPR) {
diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c
index 40082ba45e62..dfdcfa127ce7 100644
--- a/drivers/edac/imh_base.c
+++ b/drivers/edac/imh_base.c
@@ -71,28 +71,11 @@ struct local_reg {
 		.width	= (cfg)->ip_name##_reg_##reg_name##_width,		\
 	}
 
-static u64 readx(void __iomem *addr, u8 width)
-{
-	switch (width) {
-	case 1:
-		return readb(addr);
-	case 2:
-		return readw(addr);
-	case 4:
-		return readl(addr);
-	case 8:
-		return readq(addr);
-	default:
-		imh_printk(KERN_ERR, "Invalid reg 0x%p width %d\n", addr, width);
-		return 0;
-	}
-}
-
 static void __read_local_reg(void *reg)
 {
 	struct local_reg *r = (struct local_reg *)reg;
 
-	r->val = readx(r->vbase + r->offset, r->width);
+	r->val = skx_readx(r->vbase + r->offset, r->width);
 }
 
 /* Read a local-view register. */
@@ -378,22 +361,16 @@ static bool imh_2lm_enabled(struct res_config *cfg, struct list_head *head)
 	return false;
 }
 
-/* Helpers to read memory controller registers */
-static u64 read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width)
-{
-	return readx(imc->mbase + imc->chan_mmio_sz * chan + offset, width);
-}
-
 static u32 read_imc_mcmtr(struct res_config *cfg, struct skx_imc *imc, int chan)
 {
-	return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_mcmtr_offset, cfg->ddr_reg_mcmtr_width);
+	return (u32)skx_read_imc_reg(imc, chan, cfg->ddr_reg_mcmtr_offset, cfg->ddr_reg_mcmtr_width);
 }
 
 static u32 read_imc_dimmmtr(struct res_config *cfg, struct skx_imc *imc, int chan, int dimm)
 {
-	return (u32)read_imc_reg(imc, chan, cfg->ddr_reg_dimmmtr_offset +
-				 cfg->ddr_reg_dimmmtr_width * dimm,
-				 cfg->ddr_reg_dimmmtr_width);
+	return (u32)skx_read_imc_reg(imc, chan, cfg->ddr_reg_dimmmtr_offset +
+				     cfg->ddr_reg_dimmmtr_width * dimm,
+				     cfg->ddr_reg_dimmmtr_width);
 }
 
 static bool ecc_enabled(u32 mcmtr)
diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c
index f15de0ea96c8..1c4cc21679bc 100644
--- a/drivers/edac/skx_common.c
+++ b/drivers/edac/skx_common.c
@@ -52,6 +52,56 @@ static LIST_HEAD(dev_edac_list);
 static bool skx_mem_cfg_2lm;
 static struct res_config *skx_res_cfg;
 
+u64 skx_readx(void __iomem *addr, u8 width)
+{
+	switch (width) {
+	case 1:
+		return readb(addr);
+	case 2:
+		return readw(addr);
+	case 4:
+		return readl(addr);
+	case 8:
+		return readq(addr);
+	default:
+		skx_printk(KERN_ERR, "Invalid reg 0x%p width %u to read.\n", addr, width);
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(skx_readx);
+
+static void skx_writex(void __iomem *addr, u8 width, u64 val)
+{
+	switch (width) {
+	case 1:
+		writeb((u8)val, addr);
+		return;
+	case 2:
+		writew((u16)val, addr);
+		return;
+	case 4:
+		writel((u32)val, addr);
+		return;
+	case 8:
+		writeq(val, addr);
+		return;
+	default:
+		skx_printk(KERN_ERR, "Invalid reg 0x%p width %u to write 0x%llx.\n", addr, width, val);
+	}
+}
+
+u64 skx_read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width)
+{
+	return skx_readx(imc->mbase + imc->chan_mmio_sz * chan + offset, width);
+}
+EXPORT_SYMBOL_GPL(skx_read_imc_reg);
+
+void skx_write_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width, u64 val)
+{
+	skx_writex(imc->mbase + imc->chan_mmio_sz * chan + offset, width, val);
+}
+EXPORT_SYMBOL_GPL(skx_write_imc_reg);
+
 int skx_adxl_get(void)
 {
 	const char * const *names;
diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h
index f88038e5b18c..95412459a84f 100644
--- a/drivers/edac/skx_common.h
+++ b/drivers/edac/skx_common.h
@@ -326,6 +326,9 @@ typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci,
 typedef bool (*skx_decode_f)(struct decoded_addr *res);
 typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len, bool scrub_err);
 
+u64 skx_readx(void __iomem *addr, u8 width);
+u64 skx_read_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width);
+void skx_write_imc_reg(struct skx_imc *imc, int chan, u32 offset, u8 width, u64 val);
 int skx_adxl_get(void);
 void skx_adxl_put(void);
 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
-- 
2.43.0


  reply	other threads:[~2026-05-21  7:38 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 ` Qiuxu Zhuo [this message]
2026-06-15  2:26   ` [PATCH 1/8] EDAC/{skx_common,i10nm,imh}: Move MC register access helpers to skx_common 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 ` [PATCH 8/8] EDAC/imh: Add RRL support for Intel Diamond Rapids server Qiuxu Zhuo
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-2-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