Re: [PATCH v3 2/2] edac: xilinx: Added EDAC support for Xilinx DDR controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 02, 2023 at 05:24:16AM +0000, Datta, Shubhrajyoti wrote:
> > > +
> > > +#define PCSR_UNLOCK_VAL                              0xF9E8D7C6
> > > +#define XDDR_ERR_TYPE_CE                     0
> > > +#define XDDR_ERR_TYPE_UE                     1
> > > +
> > > +#define XILINX_DRAM_SIZE_4G                  0
> > > +#define XILINX_DRAM_SIZE_6G                  1
> > > +#define XILINX_DRAM_SIZE_8G                  2
> > > +#define XILINX_DRAM_SIZE_12G                 3
> > > +#define XILINX_DRAM_SIZE_16G                 4
> > > +#define XILINX_DRAM_SIZE_32G                 5
> > 
> > Oh wow, that's a *lot* of defines!
> > 
> > How about unifying them?
> > 
> > All those rank masks look the same.
> I did not understand the comment. Could you please clarify.
> The size difference is not uniform so a offset jump strategy may not work.

$ grep -E "GENMASK\(5, 0\)" drivers/edac/xilinx_ddrmc_edac.c
#define RANK_0_MASK                             GENMASK(5, 0)
#define ROW_0_MASK                              GENMASK(5, 0)
#define ROW_5_MASK                              GENMASK(5, 0)
#define ROW_10_MASK                             GENMASK(5, 0)
#define ROW_15_MASK                             GENMASK(5, 0)
#define COL_1_MASK                              GENMASK(5, 0)
#define COL_6_MASK                              GENMASK(5, 0)
#define BANK_1_MASK                             GENMASK(5, 0)

Ditto for the other ones.

Can't you use a single

#define MASK_0					GENMASK(5, 0)

and then use MASK_0 everywhere?

And the same for the other ones?

Better yet, you can define a function which does that repeated block:

        priv->row_bit[0] = regval & ROW_0_MASK;
        priv->row_bit[1] = (regval & ROW_1_MASK) >> ROW_1_SHIFT;
        priv->row_bit[2] = (regval & ROW_2_MASK) >> ROW_2_SHIFT;
        priv->row_bit[3] = (regval & ROW_3_MASK) >> ROW_3_SHIFT;
        priv->row_bit[4] = (regval & ROW_4_MASK) >> ROW_4_SHIFT;

in one:

static inline void process_bit(priv, unsigned int start, ... regval)
{
	priv->row_bit[start]	 =  regval & MASK_0;
	priv->row_bit[start + 1] = (regval & MASK_1) >> ROW_1_SHIFT;
	...
}

and then you don't have to define the same masks for every 5 bits but
have the function do it for ya, for each group of 5 bits?


> 
> <snip>
> > > +     ulong err_addr = 0;
> > > +     u32 index;
> > > +
> > > +     for (index = 0; index < XDDR_MAX_ROW_CNT; index++) {
> > > +             err_addr |= (pinf.row & BIT(0)) << priv->row_bit[index];
> > > +             pinf.row >>= 1;
> > > +     }
> > > +
> > > +     for (index = 0; index < XDDR_MAX_COL_CNT; index++) {
> > > +             err_addr |= (pinf.col & BIT(0)) << priv->col_bit[index];
> > > +             pinf.col >>= 1;
> > > +     }
> > > +
> > > +     for (index = 0; index < XDDR_MAX_BANK_CNT; index++) {
> > > +             err_addr |= (pinf.bank & BIT(0)) << priv->bank_bit[index];
> > > +             pinf.bank >>= 1;
> > > +     }
> > > +
> > > +     for (index = 0; index < XDDR_MAX_GRP_CNT; index++) {
> > > +             err_addr |= (pinf.group & BIT(0)) << priv->grp_bit[index];
> > > +             pinf.group >>= 1;
> > > +     }
> > > +
> > > +     for (index = 0; index < XDDR_MAX_RANK_CNT; index++) {
> > > +             err_addr |= (pinf.rank & BIT(0)) << priv->rank_bit[index];
> > > +             pinf.rank >>= 1;
> > > +     }
> > > +
> > > +     for (index = 0; index < XDDR_MAX_LRANK_CNT; index++) {
> > > +             err_addr |= (pinf.lrank & BIT(0)) << priv->lrank_bit[index];
> > > +             pinf.lrank >>= 1;
> > > +     }
> > 
> > Oh wow, 6 loops!
> > 
> > I'm wondering if you could "unroll" those loops and work on each component
> > with a single mask and such...
> 
> I did not understand this one . The loop are running for different indixes.

Let's take the first one. Isn't what you're doing equivalent to simply:

	err_addr = pinf.row & GENMASK_ULL(0, XDDR_MAX_ROW_CNT);
	err_addr <<= XDDR_MAX_ROW_CNT;

?

You basically stick in the error address each segment one after the
other...

err_addr = [XDDR_MAX_ROW_CNT ... XDDR_MAX_COL_CNT ... XDDR_MAX_BANK_CNT .. ]

and so on?

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux