Message ID | 20200306111355.6.Id09f75f6aa43a345f0eccb009481c6423933358b@changeid |
---|---|
State | Accepted |
Commit | 8c9ce0807545976c4080621be80dfb02b4ead400 |
Headers | show |
Series | ram: stm32mp1: fixes | expand |
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 <patrick.delaunay at st.com> > --- > > 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 <patrice.chotard at st.com> Thanks Patrice
Hi, > From: Patrick DELAUNAY <patrick.delaunay at st.com> > Sent: vendredi 6 mars 2020 11:14 > > 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 at st.com> > --- Applied to u-boot-stm/next, thanks! Regards Patrick
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()) {
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 at st.com> --- drivers/ram/stm32mp1/stm32mp1_tuning.c | 151 +++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 9 deletions(-)