From: Qiuxu Zhuo Date: Thu, 21 May 2026 07:31:05 +0000 (+0800) Subject: EDAC/{skx_common,i10nm,imh}: Move MC register access helpers to skx_common X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=bebda0aba2cf64271ded37746c48f9ab6652ca31;p=thirdparty%2Fkernel%2Flinux.git EDAC/{skx_common,i10nm,imh}: Move MC register access helpers to skx_common 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. Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck Tested-by: Yi Lai Link: https://patch.msgid.link/20260521073112.3881223-2-qiuxu.zhuo@intel.com --- diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index de6c52dbd9d25..0a0236583eb7c 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 40082ba45e621..dfdcfa127ce74 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 f15de0ea96c87..1c4cc21679bcf 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 f88038e5b18cb..95412459a84fb 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);