All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz
  2022-06-21 10:07 [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
@ 2022-06-21 10:07 ` Lee Jones
  2022-07-01 12:05   ` Kever Yang
  2022-07-04 10:01   ` Xavier Drudis Ferran
  0 siblings, 2 replies; 8+ messages in thread
From: Lee Jones @ 2022-06-21 10:07 UTC (permalink / raw)
  To: lee.jones, sjg, philipp.tomsich, kever.yang; +Cc: cym, u-boot

Currently the default initialisation frequency is 50MHz.  Although
this does appear to be suitable for some LPDDR4 RAM chips, training at
this low frequency has been seen to cause Column errors, leading to
Capacity check errors on others.

Here we force RAM initialisation to happen at 400MHz before ramping up
to the final value running value of 800MHz after everything has been
successfully configured.

Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/
Suggested-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 34d6c93f95..b05c5925d5 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
 	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
 				   struct rk3399_sdram_params *sdram);
 	int (*set_rate_index)(struct dram_info *dram,
-			      struct rk3399_sdram_params *params);
+			      struct rk3399_sdram_params *params, u32 ctl_fn);
 	void (*modify_param)(const struct chan_info *chan,
 			     struct rk3399_sdram_params *params);
 	struct rk3399_sdram_params *
@@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
 }
 
 static int switch_to_phy_index1(struct dram_info *dram,
-				struct rk3399_sdram_params *params)
+				struct rk3399_sdram_params *params,
+				u32 unused)
 {
 	u32 channel;
 	u32 *denali_phy;
@@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
 }
 
 static int lpddr4_set_rate(struct dram_info *dram,
-			   struct rk3399_sdram_params *params)
+			    struct rk3399_sdram_params *params,
+			    u32 ctl_fn)
 {
-	u32 ctl_fn;
 	u32 phy_fn;
 
-	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
-		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
+	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
 
-		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
-		lpddr4_set_ctl(dram, params, ctl_fn,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
+	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+	lpddr4_set_ctl(dram, params, ctl_fn,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
 
-		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
-			printf("%s: change freq to %dMHz %d, %d\n", __func__,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
-			       ctl_fn, phy_fn);
-	}
+	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
+		printf("%s: change freq to %dMHz %d, %d\n", __func__,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
+		       ctl_fn, phy_fn);
 
 	return 0;
 }
+
 #endif /* CONFIG_RAM_RK3399_LPDDR4 */
 
 /* CS0,n=1
@@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
 		params->ch[ch].cap_info.rank = rank;
 	}
 
+#if defined(CONFIG_RAM_RK3399_LPDDR4)
+	/* LPDDR4 needs to be trained at 400MHz */
+	lpddr4_set_rate(dram, params, 0);
+	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
+#endif
+
 	params->base.num_channels = 0;
 	for (channel = 0; channel < 2; channel++) {
 		const struct chan_info *chan = &dram->chan[channel];
@@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram,
 	params->base.stride = calculate_stride(params);
 	dram_all_config(dram, params);
 
-	ret = dram->ops->set_rate_index(dram, params);
+	ret = dram->ops->set_rate_index(dram, params, 1);
 	if (ret)
 		return ret;
 
-- 
2.37.0.rc0.104.g0611611a94-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz
  2022-06-21 10:07 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
@ 2022-07-01 12:05   ` Kever Yang
  2022-07-04 10:01   ` Xavier Drudis Ferran
  1 sibling, 0 replies; 8+ messages in thread
From: Kever Yang @ 2022-07-01 12:05 UTC (permalink / raw)
  To: Lee Jones, sjg, philipp.tomsich; +Cc: cym, u-boot


On 2022/6/21 18:07, Lee Jones wrote:
> Currently the default initialisation frequency is 50MHz.  Although
> this does appear to be suitable for some LPDDR4 RAM chips, training at
> this low frequency has been seen to cause Column errors, leading to
> Capacity check errors on others.
>
> Here we force RAM initialisation to happen at 400MHz before ramping up
> to the final value running value of 800MHz after everything has been
> successfully configured.
>
> Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/
> Suggested-by: YouMin Chen <cym@rock-chips.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++------------
>   1 file changed, 21 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
> index 34d6c93f95..b05c5925d5 100644
> --- a/drivers/ram/rockchip/sdram_rk3399.c
> +++ b/drivers/ram/rockchip/sdram_rk3399.c
> @@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
>   	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
>   				   struct rk3399_sdram_params *sdram);
>   	int (*set_rate_index)(struct dram_info *dram,
> -			      struct rk3399_sdram_params *params);
> +			      struct rk3399_sdram_params *params, u32 ctl_fn);
>   	void (*modify_param)(const struct chan_info *chan,
>   			     struct rk3399_sdram_params *params);
>   	struct rk3399_sdram_params *
> @@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
>   }
>   
>   static int switch_to_phy_index1(struct dram_info *dram,
> -				struct rk3399_sdram_params *params)
> +				struct rk3399_sdram_params *params,
> +				u32 unused)
>   {
>   	u32 channel;
>   	u32 *denali_phy;
> @@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
>   }
>   
>   static int lpddr4_set_rate(struct dram_info *dram,
> -			   struct rk3399_sdram_params *params)
> +			    struct rk3399_sdram_params *params,
> +			    u32 ctl_fn)
>   {
> -	u32 ctl_fn;
>   	u32 phy_fn;
>   
> -	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
> -		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
> +	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
>   
> -		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> -		lpddr4_set_ctl(dram, params, ctl_fn,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
> +	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> +	lpddr4_set_ctl(dram, params, ctl_fn,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
>   
> -		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> -			printf("%s: change freq to %dMHz %d, %d\n", __func__,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> -			       ctl_fn, phy_fn);
> -	}
> +	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> +		printf("%s: change freq to %dMHz %d, %d\n", __func__,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> +		       ctl_fn, phy_fn);
>   
>   	return 0;
>   }
> +
>   #endif /* CONFIG_RAM_RK3399_LPDDR4 */
>   
>   /* CS0,n=1
> @@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
>   		params->ch[ch].cap_info.rank = rank;
>   	}
>   
> +#if defined(CONFIG_RAM_RK3399_LPDDR4)
> +	/* LPDDR4 needs to be trained at 400MHz */
> +	lpddr4_set_rate(dram, params, 0);
> +	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
> +#endif
> +
>   	params->base.num_channels = 0;
>   	for (channel = 0; channel < 2; channel++) {
>   		const struct chan_info *chan = &dram->chan[channel];
> @@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram,
>   	params->base.stride = calculate_stride(params);
>   	dram_all_config(dram, params);
>   
> -	ret = dram->ops->set_rate_index(dram, params);
> +	ret = dram->ops->set_rate_index(dram, params, 1);
>   	if (ret)
>   		return ret;
>   

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz
  2022-06-21 10:07 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
  2022-07-01 12:05   ` Kever Yang
@ 2022-07-04 10:01   ` Xavier Drudis Ferran
  1 sibling, 0 replies; 8+ messages in thread
From: Xavier Drudis Ferran @ 2022-07-04 10:01 UTC (permalink / raw)
  To: Lee Jones; +Cc: sjg, philipp.tomsich, kever.yang, cym, u-boot

El Tue, Jun 21, 2022 at 10:07:29AM +0000, Lee Jones deia:
> Currently the default initialisation frequency is 50MHz.  Although
> this does appear to be suitable for some LPDDR4 RAM chips, training at
> this low frequency has been seen to cause Column errors, leading to
> Capacity check errors on others.
> 
> Here we force RAM initialisation to happen at 400MHz before ramping up
> to the final value running value of 800MHz after everything has been
> successfully configured.
> 
> Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/
> Suggested-by: YouMin Chen <cym@rock-chips.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>

My board doesn't suffer with the issue resolved by this series,
however I did apply it and nothing regressed.

Tested-by: Xavier Drudis Ferran <xdrudis@tinet.cat>

> ---
>  drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++------------
>  1 file changed, 21 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
> index 34d6c93f95..b05c5925d5 100644
> --- a/drivers/ram/rockchip/sdram_rk3399.c
> +++ b/drivers/ram/rockchip/sdram_rk3399.c
> @@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
>  	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
>  				   struct rk3399_sdram_params *sdram);
>  	int (*set_rate_index)(struct dram_info *dram,
> -			      struct rk3399_sdram_params *params);
> +			      struct rk3399_sdram_params *params, u32 ctl_fn);
>  	void (*modify_param)(const struct chan_info *chan,
>  			     struct rk3399_sdram_params *params);
>  	struct rk3399_sdram_params *
> @@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
>  }
>  
>  static int switch_to_phy_index1(struct dram_info *dram,
> -				struct rk3399_sdram_params *params)
> +				struct rk3399_sdram_params *params,
> +				u32 unused)
>  {
>  	u32 channel;
>  	u32 *denali_phy;
> @@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
>  }
>  
>  static int lpddr4_set_rate(struct dram_info *dram,
> -			   struct rk3399_sdram_params *params)
> +			    struct rk3399_sdram_params *params,
> +			    u32 ctl_fn)
>  {
> -	u32 ctl_fn;
>  	u32 phy_fn;
>  
> -	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
> -		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
> +	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
>  
> -		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> -		lpddr4_set_ctl(dram, params, ctl_fn,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
> +	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> +	lpddr4_set_ctl(dram, params, ctl_fn,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
>  
> -		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> -			printf("%s: change freq to %dMHz %d, %d\n", __func__,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> -			       ctl_fn, phy_fn);
> -	}
> +	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> +		printf("%s: change freq to %dMHz %d, %d\n", __func__,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> +		       ctl_fn, phy_fn);
>  
>  	return 0;
>  }
> +
>  #endif /* CONFIG_RAM_RK3399_LPDDR4 */
>  
>  /* CS0,n=1
> @@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
>  		params->ch[ch].cap_info.rank = rank;
>  	}
>  
> +#if defined(CONFIG_RAM_RK3399_LPDDR4)
> +	/* LPDDR4 needs to be trained at 400MHz */
> +	lpddr4_set_rate(dram, params, 0);
> +	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
> +#endif
> +
>  	params->base.num_channels = 0;
>  	for (channel = 0; channel < 2; channel++) {
>  		const struct chan_info *chan = &dram->chan[channel];
> @@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram,
>  	params->base.stride = calculate_stride(params);
>  	dram_all_config(dram, params);
>  
> -	ret = dram->ops->set_rate_index(dram, params);
> +	ret = dram->ops->set_rate_index(dram, params, 1);
>  	if (ret)
>  		return ret;
>  
> -- 
> 2.37.0.rc0.104.g0611611a94-goog
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 0/3] rockchip: Fix RAM training on RK3399 based platforms (Rock Pi 4)
@ 2022-08-11  7:58 Lee Jones
  2022-08-11  7:58 ` [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Lee Jones @ 2022-08-11  7:58 UTC (permalink / raw)
  To: u-boot, sjg, philipp.tomsich, kever.yang; +Cc: Lee Jones

This set fixes several issues found on the Rock Pi 4.

For full context, please see this initial bug report:

 "There appear to be a number of issues with the Rockchip rk3399 DDR RAM                      
  initialisation sequence in Mainline.  Specifically, I'm seeing                              
  consistent failures on the Rock Pi 4+ during early boot.  A typical                         
  failure looks something like this:                                                          
                                                                                              
    U-Boot TPL 2022.07-rc3-00005-g1b04a961c6 (May 25 2022 - 11:09:19)                         
    Channel 0: LPDDR4, 50MHz                                                                  
    BW=32 Col=10 Bk=8 CS0 Row=16/15 CS=1 Die BW=16 Size=2048MB                                
    Channel 1: col error                                                                      
    Cap error!                                                                                
    256B stride                                                                               
    lpddr4_set_rate: change freq to 400000000 mhz 0, 1                                        
    lpddr4_set_rate: change freq to 800000000 mhz 1, 0                                        
    Trying to boot from BOOTROM                                                               
    Returning to boot ROM...                                                                  
                                                                                              
  Even when the system boots to a terminal, which happens very                                
  infrequently, the LPDDR4 RAM chip at Channel 1 can have conflicting                         
  discovery information printed during TPL.  The following 3 lines were                       
  printed during successive reboots using the same SD card with no                            
  changes:                                                                                    
                                                                                              
    # Boot 1:                                                                                 
    BW=32 Col=9 Bk=4 CS0 Row=16/15 CS=1 Die BW=16 Size=384MB                                  
                                                                                              
    # Boot 2:                                                                                 
    BW=32 Col=10 Bk=4 CS0 Row=16/15 CS=1 Die BW=16 Size=768MB                                 
                                                                                              
    # Boot 3:                                                                                 
    BW=32 Col=10 Bk=4 CS0 Row=15 CS=1 Die BW=16 Size=512MB                                    
                                                                                              
  The story changes when I build the idbloader.img image with Rockchip's                      
  TBL (?) binary blob [0].  With that built in, presumably in place of                        
  the upstream TBL, both RAM chips are successfully enumerated and boot                       
  succeeds with 100% success rate:                                                            
                                                                                              
    tools/mkimage -n rk3399 -T rksd -d \                                                      
      rk3399_ddr_933MHz_v1.25.bin:spl/u-boot-spl.bin idbloader.img                            
                                                                                              
  Another thing that is very different between the 2 is the initial                           
  frequency the LPDDR4 chips are clocked at.  Using the upstream TBL                          
  version, the default is 50Mhz, which seems very low.  If using the                          
  Rockchip supplied binary blob file, this is increased to a respectable                      
  416MHz:                                                                                     
                                                                                              
    # Mainline                                                                                
    Channel 0: LPDDR4, 50MHz                                                                  
                                                                                              
    # Rockchip TBL blob                                                                       
    Channel 0: LPDDR4,416MHz                                                                  
                                                                                              
  One thing I did try was to load in the 400Mhz configuration settings                        
  from drivers/ram/rockchip/sdram-rk3399-lpddr4-400.inc as the default                        
  initial values, instead of the 50MHz default taken from                                     
  arch/arm/dts/rk3399-sdram-lpddr4-100.dtsi, but this failed in a number                      
  of ways:                                                                                    
                                                                                              
    Setting clock: Freq: 400MHz (400000000)                                                   
    Calling SDRAM init: 2 Channels                                                            
    Starting SDRAM initialization...                                                          
      mr5:0  mr12:0  mr14:0                                                                   
      Training failed for rank 2, ch 0 (ret: -22)                                             
      mr5:0  mr12:0  mr14:0                                                                   
      Training failed for rank 1, ch 0 (ret: -22)                                             
      mr5:0  mr12:0  mr14:0                                                                   
      Training failed for rank 2, ch 1 (ret: -22)                                             
      mr5:0  mr12:0  mr14:0                                                                   
      Training failed for rank 1, ch 1 (ret: -22)                                             
      Rank for Channel 1 is 0x0                                                               
      Rank for Channel 0 is 0x0                                                               
      Rank for Channel 1 is 0x0                                                               
    sdram_init: LPDDR4 - 400MHz failed!                                                       
    rk3399_dmc_init DRAM init failed -22                                                      
                                                                                              
  So my question is; does Rockchip, or anyone else for that matter, have                      
  any plans on updating Mainline U-Boot with the upgraded/working LPDDR4                      
  initialisation sequence?"

Lee Jones (3):
  ram: rk3399: Fix .set_rate_index() error handling
  ram: rk3399: Fix faulty frequency change reports
  ram: rk3399: Conduct memory training at 400MHz

 drivers/ram/rockchip/sdram_rk3399.c | 38 +++++++++++++++++------------
 1 file changed, 23 insertions(+), 15 deletions(-)

 -- 
 2.37.1.559.g78731f0fdb-goog
 
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling
  2022-08-11  7:58 [PATCH 0/3] rockchip: Fix RAM training on RK3399 based platforms (Rock Pi 4) Lee Jones
@ 2022-08-11  7:58 ` Lee Jones
  2022-08-11  7:58 ` [PATCH 2/3] ram: rk3399: Fix faulty frequency change reports Lee Jones
  2022-08-11  7:58 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
  2 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2022-08-11  7:58 UTC (permalink / raw)
  To: u-boot, sjg, philipp.tomsich, kever.yang; +Cc: Lee Jones, Xavier Drudis Ferran

Functions pointed to by this op pointer can return non-zero values
indicating an error.  Ensure any error value is propagated back up the
call-chain.

Signed-off-by: Lee Jones <lee@kernel.org>
Tested-by: Xavier Drudis Ferran <xdrudis@tinet.cat>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
 drivers/ram/rockchip/sdram_rk3399.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index c0a06dcaed..0af0fa9e7b 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -3005,7 +3005,9 @@ static int sdram_init(struct dram_info *dram,
 	params->base.stride = calculate_stride(params);
 	dram_all_config(dram, params);
 
-	dram->ops->set_rate_index(dram, params);
+	ret = dram->ops->set_rate_index(dram, params);
+	if (ret)
+		return ret;
 
 	debug("Finish SDRAM initialization...\n");
 	return 0;
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3] ram: rk3399: Fix faulty frequency change reports
  2022-08-11  7:58 [PATCH 0/3] rockchip: Fix RAM training on RK3399 based platforms (Rock Pi 4) Lee Jones
  2022-08-11  7:58 ` [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
@ 2022-08-11  7:58 ` Lee Jones
  2022-08-11  7:58 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
  2 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2022-08-11  7:58 UTC (permalink / raw)
  To: u-boot, sjg, philipp.tomsich, kever.yang; +Cc: Lee Jones, Xavier Drudis Ferran

Frequency changes to 400MHz are presently reported as:

  lpddr4_set_rate_0: change freq to 400000000 mhz 0, 1

This is obviously wrong by 6 orders of magnitude.

Ensure frequency changes are reported accurately.

Signed-off-by: Lee Jones <lee@kernel.org>
Tested-by: Xavier Drudis Ferran <xdrudis@tinet.cat>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
 drivers/ram/rockchip/sdram_rk3399.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 0af0fa9e7b..34d6c93f95 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -2552,8 +2552,8 @@ static int lpddr4_set_rate(struct dram_info *dram,
 			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
 
 		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
-			printf("%s: change freq to %d mhz %d, %d\n", __func__,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq,
+			printf("%s: change freq to %dMHz %d, %d\n", __func__,
+			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
 			       ctl_fn, phy_fn);
 	}
 
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz
  2022-08-11  7:58 [PATCH 0/3] rockchip: Fix RAM training on RK3399 based platforms (Rock Pi 4) Lee Jones
  2022-08-11  7:58 ` [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
  2022-08-11  7:58 ` [PATCH 2/3] ram: rk3399: Fix faulty frequency change reports Lee Jones
@ 2022-08-11  7:58 ` Lee Jones
  2022-08-11 14:38   ` Michal Suchánek
  2 siblings, 1 reply; 8+ messages in thread
From: Lee Jones @ 2022-08-11  7:58 UTC (permalink / raw)
  To: u-boot, sjg, philipp.tomsich, kever.yang
  Cc: Lee Jones, YouMin Chen, Xavier Drudis Ferran

Currently the default initialisation frequency is 50MHz.  Although
this does appear to be suitable for some LPDDR4 RAM chips, training at
this low frequency has been seen to cause Column errors, leading to
Capacity check errors on others.

Here we force RAM initialisation to happen at 400MHz before ramping up
to the final value running value of 800MHz after everything has been
successfully configured.

Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/
Suggested-by: YouMin Chen <cym@rock-chips.com>
Signed-off-by: Lee Jones <lee@kernel.org>
Tested-by: Xavier Drudis Ferran <xdrudis@tinet.cat>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
 drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 34d6c93f95..b05c5925d5 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
 	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
 				   struct rk3399_sdram_params *sdram);
 	int (*set_rate_index)(struct dram_info *dram,
-			      struct rk3399_sdram_params *params);
+			      struct rk3399_sdram_params *params, u32 ctl_fn);
 	void (*modify_param)(const struct chan_info *chan,
 			     struct rk3399_sdram_params *params);
 	struct rk3399_sdram_params *
@@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
 }
 
 static int switch_to_phy_index1(struct dram_info *dram,
-				struct rk3399_sdram_params *params)
+				struct rk3399_sdram_params *params,
+				u32 unused)
 {
 	u32 channel;
 	u32 *denali_phy;
@@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
 }
 
 static int lpddr4_set_rate(struct dram_info *dram,
-			   struct rk3399_sdram_params *params)
+			    struct rk3399_sdram_params *params,
+			    u32 ctl_fn)
 {
-	u32 ctl_fn;
 	u32 phy_fn;
 
-	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
-		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
+	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
 
-		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
-		lpddr4_set_ctl(dram, params, ctl_fn,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
+	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
+	lpddr4_set_ctl(dram, params, ctl_fn,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
 
-		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
-			printf("%s: change freq to %dMHz %d, %d\n", __func__,
-			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
-			       ctl_fn, phy_fn);
-	}
+	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
+		printf("%s: change freq to %dMHz %d, %d\n", __func__,
+		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
+		       ctl_fn, phy_fn);
 
 	return 0;
 }
+
 #endif /* CONFIG_RAM_RK3399_LPDDR4 */
 
 /* CS0,n=1
@@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
 		params->ch[ch].cap_info.rank = rank;
 	}
 
+#if defined(CONFIG_RAM_RK3399_LPDDR4)
+	/* LPDDR4 needs to be trained at 400MHz */
+	lpddr4_set_rate(dram, params, 0);
+	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
+#endif
+
 	params->base.num_channels = 0;
 	for (channel = 0; channel < 2; channel++) {
 		const struct chan_info *chan = &dram->chan[channel];
@@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram,
 	params->base.stride = calculate_stride(params);
 	dram_all_config(dram, params);
 
-	ret = dram->ops->set_rate_index(dram, params);
+	ret = dram->ops->set_rate_index(dram, params, 1);
 	if (ret)
 		return ret;
 
-- 
2.37.1.559.g78731f0fdb-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz
  2022-08-11  7:58 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
@ 2022-08-11 14:38   ` Michal Suchánek
  0 siblings, 0 replies; 8+ messages in thread
From: Michal Suchánek @ 2022-08-11 14:38 UTC (permalink / raw)
  To: Lee Jones
  Cc: u-boot, sjg, philipp.tomsich, kever.yang, YouMin Chen,
	Xavier Drudis Ferran

On Thu, Aug 11, 2022 at 08:58:48AM +0100, Lee Jones wrote:
> Currently the default initialisation frequency is 50MHz.  Although
> this does appear to be suitable for some LPDDR4 RAM chips, training at
> this low frequency has been seen to cause Column errors, leading to
> Capacity check errors on others.
> 
> Here we force RAM initialisation to happen at 400MHz before ramping up
> to the final value running value of 800MHz after everything has been
> successfully configured.
> 
> Link: https://lore.kernel.org/u-boot/Yo4v3jUeHXTovjOH@google.com/
> Suggested-by: YouMin Chen <cym@rock-chips.com>
> Signed-off-by: Lee Jones <lee@kernel.org>
> Tested-by: Xavier Drudis Ferran <xdrudis@tinet.cat>

Also does not cause any regression on a Pinebook Pro

Tested-by: Michal Suchánek <msuchanek@suse.de>

Thanks

Michal

> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>  drivers/ram/rockchip/sdram_rk3399.c | 36 +++++++++++++++++------------
>  1 file changed, 21 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
> index 34d6c93f95..b05c5925d5 100644
> --- a/drivers/ram/rockchip/sdram_rk3399.c
> +++ b/drivers/ram/rockchip/sdram_rk3399.c
> @@ -85,7 +85,7 @@ struct sdram_rk3399_ops {
>  	int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank,
>  				   struct rk3399_sdram_params *sdram);
>  	int (*set_rate_index)(struct dram_info *dram,
> -			      struct rk3399_sdram_params *params);
> +			      struct rk3399_sdram_params *params, u32 ctl_fn);
>  	void (*modify_param)(const struct chan_info *chan,
>  			     struct rk3399_sdram_params *params);
>  	struct rk3399_sdram_params *
> @@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
>  }
>  
>  static int switch_to_phy_index1(struct dram_info *dram,
> -				struct rk3399_sdram_params *params)
> +				struct rk3399_sdram_params *params,
> +				u32 unused)
>  {
>  	u32 channel;
>  	u32 *denali_phy;
> @@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram,
>  }
>  
>  static int lpddr4_set_rate(struct dram_info *dram,
> -			   struct rk3399_sdram_params *params)
> +			    struct rk3399_sdram_params *params,
> +			    u32 ctl_fn)
>  {
> -	u32 ctl_fn;
>  	u32 phy_fn;
>  
> -	for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) {
> -		phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
> +	phy_fn = lpddr4_get_phy_fn(params, ctl_fn);
>  
> -		lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> -		lpddr4_set_ctl(dram, params, ctl_fn,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
> +	lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]);
> +	lpddr4_set_ctl(dram, params, ctl_fn,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq);
>  
> -		if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> -			printf("%s: change freq to %dMHz %d, %d\n", __func__,
> -			       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> -			       ctl_fn, phy_fn);
> -	}
> +	if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
> +		printf("%s: change freq to %dMHz %d, %d\n", __func__,
> +		       dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz,
> +		       ctl_fn, phy_fn);
>  
>  	return 0;
>  }
> +
>  #endif /* CONFIG_RAM_RK3399_LPDDR4 */
>  
>  /* CS0,n=1
> @@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram,
>  		params->ch[ch].cap_info.rank = rank;
>  	}
>  
> +#if defined(CONFIG_RAM_RK3399_LPDDR4)
> +	/* LPDDR4 needs to be trained at 400MHz */
> +	lpddr4_set_rate(dram, params, 0);
> +	params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz;
> +#endif
> +
>  	params->base.num_channels = 0;
>  	for (channel = 0; channel < 2; channel++) {
>  		const struct chan_info *chan = &dram->chan[channel];
> @@ -3005,7 +3011,7 @@ static int sdram_init(struct dram_info *dram,
>  	params->base.stride = calculate_stride(params);
>  	dram_all_config(dram, params);
>  
> -	ret = dram->ops->set_rate_index(dram, params);
> +	ret = dram->ops->set_rate_index(dram, params, 1);
>  	if (ret)
>  		return ret;
>  
> -- 
> 2.37.1.559.g78731f0fdb-goog
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-08-11 14:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-11  7:58 [PATCH 0/3] rockchip: Fix RAM training on RK3399 based platforms (Rock Pi 4) Lee Jones
2022-08-11  7:58 ` [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
2022-08-11  7:58 ` [PATCH 2/3] ram: rk3399: Fix faulty frequency change reports Lee Jones
2022-08-11  7:58 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
2022-08-11 14:38   ` Michal Suchánek
  -- strict thread matches above, loose matches on Subject: below --
2022-06-21 10:07 [PATCH 1/3] ram: rk3399: Fix .set_rate_index() error handling Lee Jones
2022-06-21 10:07 ` [PATCH 3/3] ram: rk3399: Conduct memory training at 400MHz Lee Jones
2022-07-01 12:05   ` Kever Yang
2022-07-04 10:01   ` Xavier Drudis Ferran

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.