]> www.infradead.org Git - linux.git/commitdiff
EDAC/{skx_common,i10nm}: Structure the per-channel RRL registers
authorQiuxu Zhuo <qiuxu.zhuo@intel.com>
Thu, 17 Apr 2025 15:07:21 +0000 (23:07 +0800)
committerTony Luck <tony.luck@intel.com>
Thu, 17 Apr 2025 17:28:09 +0000 (10:28 -0700)
As the number of RRL (retry_rd_err_log) registers per memory channel
increases, the positions of the RRL control bits and the widths of the
RRL registers vary across different CPU generations. Adding RRL support
for a new CPU requires handling these differences throughout the
RRL-related code.

Structure the offsets, widths, control bit positions, set numbers, modes,
etc., of the per-channel RRL registers and make them configurable to
facilitate easier RRL support for new CPUs.

No functional changes are intended.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Feng Xu <feng.f.xu@intel.com>
Link: https://lore.kernel.org/r/20250417150724.1170168-5-qiuxu.zhuo@intel.com
drivers/edac/i10nm_base.c
drivers/edac/skx_common.h

index 50a16ce0aa22f87fd01a33dab86aff9b8906ff93..b47da970510c9065328f8f9c5c7f021e9929e269 100644 (file)
@@ -86,15 +86,38 @@ static int retry_rd_err_log;
 static int decoding_via_mca;
 static bool mem_cfg_2lm;
 
-static u32 offsets_scrub_icx[]  = {0x22c60, 0x22c54, 0x22c5c, 0x22c58, 0x22c28, 0x20ed8};
-static u32 offsets_scrub_spr[]  = {0x22c60, 0x22c54, 0x22f08, 0x22c58, 0x22c28, 0x20ed8};
-static u32 offsets_scrub_spr_hbm0[]  = {0x2860, 0x2854, 0x2b08, 0x2858, 0x2828, 0x0ed8};
-static u32 offsets_scrub_spr_hbm1[]  = {0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8};
-static u32 offsets_demand_icx[] = {0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0};
-static u32 offsets_demand_spr[] = {0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0};
-static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10};
-static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0};
-static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0};
+static struct reg_rrl icx_reg_rrl_ddr = {
+       .set_num = 2,
+       .offsets = {
+               {0x22c60, 0x22c54, 0x22c5c, 0x22c58, 0x22c28, 0x20ed8},
+               {0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0},
+       },
+};
+
+static struct reg_rrl spr_reg_rrl_ddr = {
+       .set_num = 3,
+       .offsets = {
+               {0x22c60, 0x22c54, 0x22f08, 0x22c58, 0x22c28, 0x20ed8},
+               {0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0},
+               {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10},
+       },
+};
+
+static struct reg_rrl spr_reg_rrl_hbm_pch0 = {
+       .set_num = 2,
+       .offsets = {
+               {0x2860, 0x2854, 0x2b08, 0x2858, 0x2828, 0x0ed8},
+               {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0},
+       },
+};
+
+static struct reg_rrl spr_reg_rrl_hbm_pch1 = {
+       .set_num = 2,
+       .offsets = {
+               {0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8},
+               {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0},
+       },
+};
 
 static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable, u32 *rrl_ctl,
                                      u32 *offsets_scrub, u32 *offsets_demand,
@@ -185,9 +208,11 @@ static void enable_retry_rd_err_log(bool enable)
                        chan = d->imc[i].chan;
                        for (j = 0; j < chan_num; j++)
                                __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
-                                                         res_cfg->offsets_scrub,
-                                                         res_cfg->offsets_demand,
-                                                         res_cfg->offsets_demand2);
+                                                         res_cfg->reg_rrl_ddr->offsets[0],
+                                                         res_cfg->reg_rrl_ddr->offsets[1],
+                                                         res_cfg->reg_rrl_ddr->set_num > 2 ?
+                                                         res_cfg->reg_rrl_ddr->offsets[2] : NULL);
+
                }
 
                imc_num += res_cfg->hbm_imc_num;
@@ -201,12 +226,12 @@ static void enable_retry_rd_err_log(bool enable)
                        chan = d->imc[i].chan;
                        for (j = 0; j < chan_num; j++) {
                                __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[0],
-                                                         res_cfg->offsets_scrub_hbm0,
-                                                         res_cfg->offsets_demand_hbm0,
+                                                         res_cfg->reg_rrl_hbm[0]->offsets[0],
+                                                         res_cfg->reg_rrl_hbm[0]->offsets[1],
                                                          NULL);
                                __enable_retry_rd_err_log(imc, j, enable, chan[j].rrl_ctl[1],
-                                                         res_cfg->offsets_scrub_hbm1,
-                                                         res_cfg->offsets_demand_hbm1,
+                                                         res_cfg->reg_rrl_hbm[1]->offsets[0],
+                                                         res_cfg->reg_rrl_hbm[1]->offsets[1],
                                                          NULL);
                        }
                }
@@ -233,17 +258,18 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
                pch = res->cs & 1;
 
                if (pch)
-                       offsets = scrub_err ? res_cfg->offsets_scrub_hbm1 :
-                                             res_cfg->offsets_demand_hbm1;
+                       offsets = scrub_err ? res_cfg->reg_rrl_hbm[1]->offsets[0] :
+                                             res_cfg->reg_rrl_hbm[1]->offsets[1];
                else
-                       offsets = scrub_err ? res_cfg->offsets_scrub_hbm0 :
-                                             res_cfg->offsets_demand_hbm0;
+                       offsets = scrub_err ? res_cfg->reg_rrl_hbm[0]->offsets[0] :
+                                             res_cfg->reg_rrl_hbm[0]->offsets[1];
        } else {
                if (scrub_err) {
-                       offsets = res_cfg->offsets_scrub;
+                       offsets = res_cfg->reg_rrl_ddr->offsets[0];
                } else {
-                       offsets = res_cfg->offsets_demand;
-                       xffsets = res_cfg->offsets_demand2;
+                       offsets = res_cfg->reg_rrl_ddr->offsets[1];
+                       if (res_cfg->reg_rrl_ddr->set_num > 2)
+                               xffsets = res_cfg->reg_rrl_ddr->offsets[2];
                }
        }
 
@@ -883,8 +909,7 @@ static struct res_config i10nm_cfg0 = {
        .ddr_mdev_bdf           = {0, 12, 0},
        .hbm_mdev_bdf           = {0, 12, 1},
        .sad_all_offset         = 0x108,
-       .offsets_scrub          = offsets_scrub_icx,
-       .offsets_demand         = offsets_demand_icx,
+       .reg_rrl_ddr            = &icx_reg_rrl_ddr,
 };
 
 static struct res_config i10nm_cfg1 = {
@@ -902,8 +927,7 @@ static struct res_config i10nm_cfg1 = {
        .ddr_mdev_bdf           = {0, 12, 0},
        .hbm_mdev_bdf           = {0, 12, 1},
        .sad_all_offset         = 0x108,
-       .offsets_scrub          = offsets_scrub_icx,
-       .offsets_demand         = offsets_demand_icx,
+       .reg_rrl_ddr            = &icx_reg_rrl_ddr,
 };
 
 static struct res_config spr_cfg = {
@@ -926,13 +950,9 @@ static struct res_config spr_cfg = {
        .ddr_mdev_bdf           = {0, 12, 0},
        .hbm_mdev_bdf           = {0, 12, 1},
        .sad_all_offset         = 0x300,
-       .offsets_scrub          = offsets_scrub_spr,
-       .offsets_scrub_hbm0     = offsets_scrub_spr_hbm0,
-       .offsets_scrub_hbm1     = offsets_scrub_spr_hbm1,
-       .offsets_demand         = offsets_demand_spr,
-       .offsets_demand2        = offsets_demand2_spr,
-       .offsets_demand_hbm0    = offsets_demand_spr_hbm0,
-       .offsets_demand_hbm1    = offsets_demand_spr_hbm1,
+       .reg_rrl_ddr            = &spr_reg_rrl_ddr,
+       .reg_rrl_hbm[0]         = &spr_reg_rrl_hbm_pch0,
+       .reg_rrl_hbm[1]         = &spr_reg_rrl_hbm_pch1,
 };
 
 static struct res_config gnr_cfg = {
@@ -1121,7 +1141,7 @@ static int __init i10nm_init(void)
        mce_register_decode_chain(&i10nm_mce_dec);
        skx_setup_debug("i10nm_test");
 
-       if (retry_rd_err_log && res_cfg->offsets_scrub && res_cfg->offsets_demand) {
+       if (retry_rd_err_log && res_cfg->reg_rrl_ddr) {
                skx_set_decode(i10nm_mc_decode, show_retry_rd_err_log);
                if (retry_rd_err_log == 2)
                        enable_retry_rd_err_log(true);
@@ -1141,7 +1161,7 @@ static void __exit i10nm_exit(void)
 {
        edac_dbg(2, "\n");
 
-       if (retry_rd_err_log && res_cfg->offsets_scrub && res_cfg->offsets_demand) {
+       if (retry_rd_err_log && res_cfg->reg_rrl_ddr) {
                skx_set_decode(NULL, NULL);
                if (retry_rd_err_log == 2)
                        enable_retry_rd_err_log(false);
index 5afd425f3b4ff1ae827710cbd2ed46a1c8d2d933..5833fbe7c0fbdc583558ddc10090911d8dbd647a 100644 (file)
 
 /* Max RRL register sets per {,sub-,pseudo-}channel. */
 #define NUM_RRL_SET            3
+/* Max RRL registers per set. */
+#define NUM_RRL_REG            6
+
+/* RRL registers per {,sub-,pseudo-}channel. */
+struct reg_rrl {
+       /* RRL register parts. */
+       int set_num;
+       u32 offsets[NUM_RRL_SET][NUM_RRL_REG];
+};
 
 /*
  * Each cpu socket contains some pci devices that provide global
@@ -237,14 +246,10 @@ struct res_config {
        /* HBM mdev device BDF */
        struct pci_bdf hbm_mdev_bdf;
        int sad_all_offset;
-       /* Offsets of retry_rd_err_log registers */
-       u32 *offsets_scrub;
-       u32 *offsets_scrub_hbm0;
-       u32 *offsets_scrub_hbm1;
-       u32 *offsets_demand;
-       u32 *offsets_demand2;
-       u32 *offsets_demand_hbm0;
-       u32 *offsets_demand_hbm1;
+       /* RRL register sets per DDR channel */
+       struct reg_rrl *reg_rrl_ddr;
+       /* RRL register sets per HBM channel */
+       struct reg_rrl *reg_rrl_hbm[2];
 };
 
 typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci,