On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Update the BIST config to compute the real use mask for the real
> bank, row and col of the used DDR. The values are get from addrmap
> register value.
>
> Signed-off-by: Patrick Delaunay <[email protected]>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 151 +++++++++++++++++++++++--
>  1 file changed, 142 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c 
> b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index 37d3ec8fef..07d57d496c 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -8,6 +8,7 @@
>  #include <ram.h>
>  #include <reset.h>
>  #include <asm/io.h>
> +#include <linux/bitops.h>
>  #include <linux/iopoll.h>
>  
>  #include "stm32mp1_ddr_regs.h"
> @@ -76,6 +77,133 @@ static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl)
>       return nb_bytes;
>  }
>  
> +static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl)
> +{
> +     /* Count bank address bits */
> +     u8 bits = 0;
> +     u32 reg, val;
> +
> +     reg = readl(&ctl->addrmap1);
> +     /* addrmap1.addrmap_bank_b1 */
> +     val = (reg & GENMASK(5, 0)) >> 0;
> +     if (val <= 31)
> +             bits++;
> +     /* addrmap1.addrmap_bank_b2 */
> +     val = (reg & GENMASK(13, 8)) >> 8;
> +     if (val <= 31)
> +             bits++;
> +     /* addrmap1.addrmap_bank_b3 */
> +     val = (reg & GENMASK(21, 16)) >> 16;
> +     if (val <= 31)
> +             bits++;
> +
> +     return bits;
> +}
> +
> +static u8 get_nb_col(struct stm32mp1_ddrctl *ctl)
> +{
> +     u8 bits;
> +     u32 reg, val;
> +
> +     /* Count column address bits, start at 2 for b0 and b1 (fixed) */
> +     bits = 2;
> +
> +     reg = readl(&ctl->addrmap2);
> +     /* addrmap2.addrmap_col_b2 */
> +     val = (reg & GENMASK(3, 0)) >> 0;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap2.addrmap_col_b3 */
> +     val = (reg & GENMASK(11, 8)) >> 8;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap2.addrmap_col_b4 */
> +     val = (reg & GENMASK(19, 16)) >> 16;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap2.addrmap_col_b5 */
> +     val = (reg & GENMASK(27, 24)) >> 24;
> +     if (val <= 7)
> +             bits++;
> +
> +     reg = readl(&ctl->addrmap3);
> +     /* addrmap3.addrmap_col_b6 */
> +     val = (reg & GENMASK(3, 0)) >> 0;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap3.addrmap_col_b7 */
> +     val = (reg & GENMASK(11, 8)) >> 8;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap3.addrmap_col_b8 */
> +     val = (reg & GENMASK(19, 16)) >> 16;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap3.addrmap_col_b9 */
> +     val = (reg & GENMASK(27, 24)) >> 24;
> +     if (val <= 7)
> +             bits++;
> +
> +     reg = readl(&ctl->addrmap4);
> +     /* addrmap4.addrmap_col_b10 */
> +     val = (reg & GENMASK(3, 0)) >> 0;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap4.addrmap_col_b11 */
> +     val = (reg & GENMASK(11, 8)) >> 8;
> +     if (val <= 7)
> +             bits++;
> +
> +     return bits;
> +}
> +
> +static u8 get_nb_row(struct stm32mp1_ddrctl *ctl)
> +{
> +     /* Count row address bits */
> +     u8 bits = 0;
> +     u32 reg, val;
> +
> +     reg = readl(&ctl->addrmap5);
> +     /* addrmap5.addrmap_row_b0 */
> +     val = (reg & GENMASK(3, 0)) >> 0;
> +     if (val <= 11)
> +             bits++;
> +     /* addrmap5.addrmap_row_b1 */
> +     val = (reg & GENMASK(11, 8)) >> 8;
> +     if (val <= 11)
> +             bits++;
> +     /* addrmap5.addrmap_row_b2_10 */
> +     val = (reg & GENMASK(19, 16)) >> 16;
> +     if (val <= 11)
> +             bits += 9;
> +     else
> +             printf("warning: addrmap5.addrmap_row_b2_10 not supported\n");
> +     /* addrmap5.addrmap_row_b11 */
> +     val = (reg & GENMASK(27, 24)) >> 24;
> +     if (val <= 11)
> +             bits++;
> +
> +     reg = readl(&ctl->addrmap6);
> +     /* addrmap6.addrmap_row_b12 */
> +     val = (reg & GENMASK(3, 0)) >> 0;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap6.addrmap_row_b13 */
> +     val = (reg & GENMASK(11, 8)) >> 8;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap6.addrmap_row_b14 */
> +     val = (reg & GENMASK(19, 16)) >> 16;
> +     if (val <= 7)
> +             bits++;
> +     /* addrmap6.addrmap_row_b15 */
> +     val = (reg & GENMASK(27, 24)) >> 24;
> +     if (val <= 7)
> +             bits++;
> +
> +     return bits;
> +}
> +
>  static void itm_soft_reset(struct stm32mp1_ddrphy *phy)
>  {
>       stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
> @@ -170,8 +298,13 @@ static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy,
>  }
>  
>  /* Basic BIST configuration for data lane tests. */
> -static void config_BIST(struct stm32mp1_ddrphy *phy)
> +static void config_BIST(struct stm32mp1_ddrctl *ctl,
> +                     struct stm32mp1_ddrphy *phy)
>  {
> +     u8 nb_bank = get_nb_bank(ctl);
> +     u8 nb_row = get_nb_row(ctl);
> +     u8 nb_col = get_nb_col(ctl);
> +
>       /* Selects the SDRAM bank address to be used during BIST. */
>       u32 bbank = 0;
>       /* Selects the SDRAM row address to be used during BIST. */
> @@ -191,18 +324,20 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
>        * must be 0 with single rank
>        */
>       u32 brank = 0;
> +
>       /* Specifies the maximum SDRAM bank address to be used during
>        * BIST before the address & increments to the next rank.
>        */
> -     u32 bmbank = 1;
> +     u32 bmbank = (1 << nb_bank) - 1;
>       /* Specifies the maximum SDRAM row address to be used during
>        * BIST before the address & increments to the next bank.
>        */
> -     u32 bmrow = 0x7FFF; /* To check */
> +     u32 bmrow = (1 << nb_row) - 1;
>       /* Specifies the maximum SDRAM column address to be used during
>        * BIST before the address & increments to the next row.
>        */
> -     u32 bmcol = 0x3FF;  /* To check */
> +     u32 bmcol = (1 << nb_col) - 1;
> +
>       u32 bmode_conf = 0x00000001;  /* DRam mode */
>       u32 bdxen_conf = 0x00000001;  /* BIST on Data byte */
>       u32 bdpat_conf = 0x00000002;  /* Select LFSR pattern */
> @@ -224,8 +359,6 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
>  
>       writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0);
>       writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1);
> -
> -     /* To check this line : */
>       writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2);
>  }
>  
> @@ -399,7 +532,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl 
> *ctl,
>       clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>       /* Config the BIST block */
> -     config_BIST(phy);
> +     config_BIST(ctl, phy);
>       pr_debug("BIST Config done.\n");
>  
>       /* Train each byte */
> @@ -812,7 +945,7 @@ static enum test_result eye_training(struct 
> stm32mp1_ddrctl *ctl,
>       clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>       /* Config the BIST block */
> -     config_BIST(phy);
> +     config_BIST(ctl, phy);
>  
>       for (byte = 0; byte < nb_bytes; byte++) {
>               if (ctrlc()) {
> @@ -1234,7 +1367,7 @@ static enum test_result read_dqs_gating(struct 
> stm32mp1_ddrctl *ctl,
>       clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>       /* config the bist block */
> -     config_BIST(phy);
> +     config_BIST(ctl, phy);
>  
>       for (byte = 0; byte < nb_bytes; byte++) {
>               if (ctrlc()) {


Acked-by: Patrice Chotard <[email protected]>

Thanks

Patrice

Reply via email to