[PATCH 6/9] ram: stm32mp1: update BIST config for tuning
Patrice CHOTARD
patrice.chotard at st.com
Wed Mar 18 10:45:08 CET 2020
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
More information about the U-Boot
mailing list