ram: stm32mp1: update BIST config for tuning
authorPatrick Delaunay <patrick.delaunay@st.com>
Fri, 6 Mar 2020 10:14:08 +0000 (11:14 +0100)
committerPatrick Delaunay <patrick.delaunay@st.com>
Tue, 24 Mar 2020 13:20:50 +0000 (14:20 +0100)
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 <patrick.delaunay@st.com>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
drivers/ram/stm32mp1/stm32mp1_tuning.c

index 37d3ec8fef970215bf7d5ac5995ceef7911fb38e..07d57d496c38eb8320279541dd6cb73e6d940e48 100644 (file)
@@ -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()) {