Skip to content

Commit

Permalink
EDAC/ie31200: Make struct dimm_data contain decoded information
Browse files Browse the repository at this point in the history
The current dimm_data structure contains encoded DIMM information,
which needs to be decoded for a given SoC when it is used. Make it
contain decoded information when it's initialized so that the places
where it is used do not need to decode it again, thereby simplifying
the code.

No functional changes intended.

Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Tested-by: Gary Wang <gary.c.wang@intel.com>
Link: https://lore.kernel.org/r/20250310011411.31685-8-qiuxu.zhuo@intel.com
  • Loading branch information
Qiuxu Zhuo authored and Tony Luck committed Mar 10, 2025
1 parent 2a52cce commit afdbc36
Showing 1 changed file with 19 additions and 43 deletions.
62 changes: 19 additions & 43 deletions drivers/edac/ie31200_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,6 @@
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_9 0x3ec6
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10 0x3eca

/* Test if HB is for Skylake or later. */
#define DEVICE_ID_SKYLAKE_OR_LATER(did) \
(((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_8) || \
((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_9) || \
((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_10) || \
((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_11) || \
((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_12) || \
(((did) & PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK) == \
PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK))

#define IE31200_RANKS_PER_CHANNEL 4
#define IE31200_DIMMS_PER_CHANNEL 2
#define IE31200_CHANNELS 2
Expand All @@ -118,10 +108,6 @@
#define IE31200_CAPID0_DDPCD BIT(6)
#define IE31200_CAPID0_ECC BIT(1)

/* Skylake reports 1GB increments, everything else is 256MB */
#define IE31200_PAGES(n, skl) \
(n << (28 + (2 * skl) - PAGE_SHIFT))

/* Non-constant mask variant of FIELD_GET() */
#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))

Expand All @@ -141,6 +127,7 @@ struct res_config {
u64 reg_eccerrlog_rank_mask;
u64 reg_eccerrlog_syndrome_mask;
/* DIMM characteristics register */
u64 reg_mad_dimm_size_granularity;
u64 reg_mad_dimm_offset[IE31200_CHANNELS];
u32 reg_mad_dimm_size_mask[IE31200_DIMMS_PER_CHANNEL];
u32 reg_mad_dimm_rank_mask[IE31200_DIMMS_PER_CHANNEL];
Expand Down Expand Up @@ -175,9 +162,9 @@ static const struct ie31200_dev_info ie31200_devs[] = {
};

struct dimm_data {
u8 size; /* in multiples of 256MB, except Skylake is 1GB */
u8 dual_rank : 1,
x16_width : 2; /* 0 means x8 width */
u64 size; /* in bytes */
u8 ranks;
enum dev_type dtype;
};

static int how_many_channels(struct pci_dev *pdev)
Expand Down Expand Up @@ -340,26 +327,20 @@ static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev, struct res_config
static void populate_dimm_info(struct dimm_data *dd, u32 addr_decode, int dimm,
struct res_config *cfg)
{
dd->size = field_get(cfg->reg_mad_dimm_size_mask[dimm], addr_decode);
dd->dual_rank = field_get(cfg->reg_mad_dimm_rank_mask[dimm], addr_decode);
dd->x16_width = field_get(cfg->reg_mad_dimm_width_mask[dimm], addr_decode);
dd->size = field_get(cfg->reg_mad_dimm_size_mask[dimm], addr_decode) * cfg->reg_mad_dimm_size_granularity;
dd->ranks = field_get(cfg->reg_mad_dimm_rank_mask[dimm], addr_decode) + 1;
dd->dtype = field_get(cfg->reg_mad_dimm_width_mask[dimm], addr_decode) + DEV_X8;
}

static int ie31200_probe1(struct pci_dev *pdev, struct res_config *cfg)
{
int i, j, ret;
int i, j, k, ret;
struct mem_ctl_info *mci = NULL;
struct edac_mc_layer layers[2];
void __iomem *window;
struct ie31200_priv *priv;
u32 addr_decode[IE31200_CHANNELS];

/*
* Kaby Lake, Coffee Lake seem to work like Skylake. Please re-visit
* this logic when adding new CPU support.
*/
bool skl = DEVICE_ID_SKYLAKE_OR_LATER(pdev->device);

edac_dbg(0, "MC:\n");

if (!ecc_capable(pdev)) {
Expand Down Expand Up @@ -419,32 +400,25 @@ static int ie31200_probe1(struct pci_dev *pdev, struct res_config *cfg)
unsigned long nr_pages;

populate_dimm_info(&dimm_info, addr_decode[j], i, cfg);
edac_dbg(0, "size: 0x%x, rank: %d, width: %d\n",
dimm_info.size,
dimm_info.dual_rank,
dimm_info.x16_width);
edac_dbg(0, "channel: %d, dimm: %d, size: %lld MiB, ranks: %d, DRAM chip type: %d\n",
j, i, dimm_info.size >> 20,
dimm_info.ranks,
dimm_info.dtype);

nr_pages = IE31200_PAGES(dimm_info.size, skl);
nr_pages = MiB_TO_PAGES(dimm_info.size >> 20);
if (nr_pages == 0)
continue;

if (dimm_info.dual_rank) {
nr_pages = nr_pages / 2;
dimm = edac_get_dimm(mci, (i * 2) + 1, j, 0);
nr_pages = nr_pages / dimm_info.ranks;
for (k = 0; k < dimm_info.ranks; k++) {
dimm = edac_get_dimm(mci, (i * dimm_info.ranks) + k, j, 0);
dimm->nr_pages = nr_pages;
edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
dimm->grain = 8; /* just a guess */
dimm->mtype = cfg->mtype;
dimm->dtype = DEV_UNKNOWN;
dimm->dtype = dimm_info.dtype;
dimm->edac_mode = EDAC_UNKNOWN;
}
dimm = edac_get_dimm(mci, i * 2, j, 0);
dimm->nr_pages = nr_pages;
edac_dbg(0, "set nr pages: 0x%lx\n", nr_pages);
dimm->grain = 8; /* same guess */
dimm->mtype = cfg->mtype;
dimm->dtype = DEV_UNKNOWN;
dimm->edac_mode = EDAC_UNKNOWN;
}
}

Expand Down Expand Up @@ -510,6 +484,7 @@ static struct res_config snb_cfg = {
.reg_eccerrlog_ue_mask = BIT_ULL(1),
.reg_eccerrlog_rank_mask = GENMASK_ULL(28, 27),
.reg_eccerrlog_syndrome_mask = GENMASK_ULL(23, 16),
.reg_mad_dimm_size_granularity = BIT_ULL(28),
.reg_mad_dimm_offset[0] = 0x5004,
.reg_mad_dimm_offset[1] = 0x5008,
.reg_mad_dimm_size_mask[0] = GENMASK(7, 0),
Expand All @@ -530,6 +505,7 @@ static struct res_config skl_cfg = {
.reg_eccerrlog_ue_mask = BIT_ULL(1),
.reg_eccerrlog_rank_mask = GENMASK_ULL(28, 27),
.reg_eccerrlog_syndrome_mask = GENMASK_ULL(23, 16),
.reg_mad_dimm_size_granularity = BIT_ULL(30),
.reg_mad_dimm_offset[0] = 0x500c,
.reg_mad_dimm_offset[1] = 0x5010,
.reg_mad_dimm_size_mask[0] = GENMASK(5, 0),
Expand Down

0 comments on commit afdbc36

Please sign in to comment.