[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