diff mbox series

[v5,10/11] ram: starfive: Read memory size information from EEPROM

Message ID 20230615093652.23161-11-yanhong.wang@starfivetech.com
State Accepted
Commit 38d900b409199df02a1a26dfcb464d4d2b6e27d2
Delegated to: Andes
Headers show
Series Add ethernet driver for StarFive JH7110 SoC | expand

Commit Message

Yanhong Wang June 15, 2023, 9:36 a.m. UTC
StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of
DDR capacity includes 2G/4G/8G, a DT can not support multiple
capacities, so the capacity size information is recorded to EEPROM, when
DDR initialization required capacity size information is read from
EEPROM.

If there is no information in EEPROM, it is initialized with the default
size defined in DT.

Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
---
 arch/riscv/cpu/jh7110/spl.c         | 32 ++++++++++++++++++++++++++++-
 drivers/ram/starfive/starfive_ddr.c |  2 --
 2 files changed, 31 insertions(+), 3 deletions(-)

Comments

Rick Chen June 21, 2023, 2:11 a.m. UTC | #1
> From: Yanhong Wang <yanhong.wang@starfivetech.com>
> Sent: Thursday, June 15, 2023 5:37 PM
> To: u-boot@lists.denx.de; Rick Jian-Zhi Chen(陳建志) <rick@andestech.com>; Leo Yu-Chi Liang(梁育齊) <ycliang@andestech.com>; Joe Hershberger <joe.hershberger@ni.com>; Ramon Fried <rfried.dev@gmail.com>
> Cc: Yanhong Wang <yanhong.wang@starfivetech.com>; Torsten Duwe <duwe@lst.de>; Leyfoon Tan <leyfoon.tan@starfivetech.com>; samin . guo <samin.guo@starfivetech.com>; Walker Chen <walker.chen@starfivetech.com>; Hal Feng <hal.feng@starfivetech.com>
> Subject: [PATCH v5 10/11] ram: starfive: Read memory size information from EEPROM
>
> StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of DDR capacity includes 2G/4G/8G, a DT can not support multiple capacities, so the capacity size information is recorded to EEPROM, when DDR initialization required capacity size information is read from EEPROM.
>
> If there is no information in EEPROM, it is initialized with the default size defined in DT.
>
> Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
> ---
>  arch/riscv/cpu/jh7110/spl.c         | 32 ++++++++++++++++++++++++++++-
>  drivers/ram/starfive/starfive_ddr.c |  2 --
>  2 files changed, 31 insertions(+), 3 deletions(-)
>
> diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c index 104f0fe949..72adcefa0e 100644
> --- a/arch/riscv/cpu/jh7110/spl.c
> +++ b/arch/riscv/cpu/jh7110/spl.c
> @@ -3,19 +3,49 @@
>   * Copyright (C) 2022 StarFive Technology Co., Ltd.
>   * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
>   */
> -
> +#include <common.h>
> +#include <asm/arch/eeprom.h>
>  #include <asm/csr.h>
>  #include <asm/sections.h>
>  #include <dm.h>
> +#include <linux/sizes.h>
>  #include <log.h>
> +#include <init.h>
>
>  #define CSR_U74_FEATURE_DISABLE        0x7c1
>  #define L2_LIM_MEM_END 0x81FFFFFUL
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static bool check_ddr_size(phys_size_t size) {
> +       switch (size) {
> +       case SZ_2:
> +       case SZ_4:
> +       case SZ_8:
> +       case SZ_16:

In commit message, it describes that "DDR capacity includes 2G/4G/8G".
Is it mismatch here ?

> +               return true;
> +       default:
> +               return false;
> +       }
> +}
> +
>  int spl_soc_init(void)
>  {
>         int ret;
>         struct udevice *dev;
> +       phys_size_t size;
> +
> +       ret = fdtdec_setup_mem_size_base();
> +       if (ret)
> +               return ret;

It maybe unnecessary to add return above. If it fail to parse memory
node from DT, then there
has no chance to get ddr size from eeprom.

Thanks,
Rick

> +
> +       /* Read the definition of the DDR size from eeprom, and if not,
> +        * use the definition in DT
> +        */
> +       size = (get_ddr_size_from_eeprom() >> 16) & 0xFF;
> +       if (check_ddr_size(size))
> +               gd->ram_size = size << 30;
>
>         /* DDR init */
>         ret = uclass_get_device(UCLASS_RAM, 0, &dev); diff --git a/drivers/ram/starfive/starfive_ddr.c b/drivers/ram/starfive/starfive_ddr.c
> index 553f2ce6f4..a0a3d6b33d 100644
> --- a/drivers/ram/starfive/starfive_ddr.c
> +++ b/drivers/ram/starfive/starfive_ddr.c
> @@ -72,8 +72,6 @@ static int starfive_ddr_probe(struct udevice *dev)
>         u64 rate;
>         int ret;
>
> -       /* Read memory base and size from DT */
> -       fdtdec_setup_mem_size_base();
>         priv->info.base = gd->ram_base;
>         priv->info.size = gd->ram_size;
>
> --
> 2.17.1
Leo Liang July 12, 2023, 5:11 a.m. UTC | #2
On Thu, Jun 15, 2023 at 05:36:51PM +0800, Yanhong Wang wrote:
> StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of
> DDR capacity includes 2G/4G/8G, a DT can not support multiple
> capacities, so the capacity size information is recorded to EEPROM, when
> DDR initialization required capacity size information is read from
> EEPROM.
> 
> If there is no information in EEPROM, it is initialized with the default
> size defined in DT.
> 
> Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
> ---
>  arch/riscv/cpu/jh7110/spl.c         | 32 ++++++++++++++++++++++++++++-
>  drivers/ram/starfive/starfive_ddr.c |  2 --
>  2 files changed, 31 insertions(+), 3 deletions(-)

Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Andreas Schwab Oct. 10, 2023, 12:23 p.m. UTC | #3
On Jun 15 2023, Yanhong Wang wrote:

> StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of
> DDR capacity includes 2G/4G/8G, a DT can not support multiple
> capacities, so the capacity size information is recorded to EEPROM, when
> DDR initialization required capacity size information is read from
> EEPROM.

Does that acutally work?  I see that read_eeprom fails in SPL.
Heinrich Schuchardt Oct. 11, 2023, 2:54 a.m. UTC | #4
On 15.06.23 11:36, Yanhong Wang wrote:
> StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of
> DDR capacity includes 2G/4G/8G, a DT can not support multiple
> capacities, so the capacity size information is recorded to EEPROM, when
> DDR initialization required capacity size information is read from
> EEPROM.
> 
> If there is no information in EEPROM, it is initialized with the default
> size defined in DT.
> 
> Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
> ---
>   arch/riscv/cpu/jh7110/spl.c         | 32 ++++++++++++++++++++++++++++-
>   drivers/ram/starfive/starfive_ddr.c |  2 --
>   2 files changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
> index 104f0fe949..72adcefa0e 100644
> --- a/arch/riscv/cpu/jh7110/spl.c
> +++ b/arch/riscv/cpu/jh7110/spl.c
> @@ -3,19 +3,49 @@
>    * Copyright (C) 2022 StarFive Technology Co., Ltd.
>    * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
>    */
> -
> +#include <common.h>
> +#include <asm/arch/eeprom.h>
>   #include <asm/csr.h>
>   #include <asm/sections.h>
>   #include <dm.h>
> +#include <linux/sizes.h>
>   #include <log.h>
> +#include <init.h>
>   
>   #define CSR_U74_FEATURE_DISABLE	0x7c1
>   #define L2_LIM_MEM_END	0x81FFFFFUL
>   
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static bool check_ddr_size(phys_size_t size)
> +{
> +	switch (size) {
> +	case SZ_2:
> +	case SZ_4:
> +	case SZ_8:
> +	case SZ_16:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
>   int spl_soc_init(void)
>   {
>   	int ret;
>   	struct udevice *dev;
> +	phys_size_t size;
> +
> +	ret = fdtdec_setup_mem_size_base();
> +	if (ret)
> +		return ret;
> +
> +	/* Read the definition of the DDR size from eeprom, and if not,
> +	 * use the definition in DT
> +	 */
> +	size = (get_ddr_size_from_eeprom() >> 16) & 0xFF;

On origin/master for a 4 GiB board with a serial number 
VF7110B1-2253-D004E000-4000xxxx this always fails. This results in 
memory reported as 8 GiB and Linux crashing.

i2c_get_chip_for_busnum() returns -EINVAL in read_eeprom() 
[board/starfive/visionfive2/visionfive2-i2c-eeprom.c:335].

Is the driver model really expected to be fully initialized before 
setting up memory?

Best regards

Heinrich

> +	if (check_ddr_size(size))
> +		gd->ram_size = size << 30;
>   
>   	/* DDR init */
>   	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
> diff --git a/drivers/ram/starfive/starfive_ddr.c b/drivers/ram/starfive/starfive_ddr.c
> index 553f2ce6f4..a0a3d6b33d 100644
> --- a/drivers/ram/starfive/starfive_ddr.c
> +++ b/drivers/ram/starfive/starfive_ddr.c
> @@ -72,8 +72,6 @@ static int starfive_ddr_probe(struct udevice *dev)
>   	u64 rate;
>   	int ret;
>   
> -	/* Read memory base and size from DT */
> -	fdtdec_setup_mem_size_base();
>   	priv->info.base = gd->ram_base;
>   	priv->info.size = gd->ram_size;
>
Heinrich Schuchardt Oct. 11, 2023, 4:43 a.m. UTC | #5
On 11.10.23 04:54, Heinrich Schuchardt wrote:
> On 15.06.23 11:36, Yanhong Wang wrote:
>> StarFive VisionFive 2 has two versions, 1.2A and 1.3B, each version of
>> DDR capacity includes 2G/4G/8G, a DT can not support multiple
>> capacities, so the capacity size information is recorded to EEPROM, when
>> DDR initialization required capacity size information is read from
>> EEPROM.
>>
>> If there is no information in EEPROM, it is initialized with the default
>> size defined in DT.
>>
>> Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
>> Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
>> ---
>>   arch/riscv/cpu/jh7110/spl.c         | 32 ++++++++++++++++++++++++++++-
>>   drivers/ram/starfive/starfive_ddr.c |  2 --
>>   2 files changed, 31 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
>> index 104f0fe949..72adcefa0e 100644
>> --- a/arch/riscv/cpu/jh7110/spl.c
>> +++ b/arch/riscv/cpu/jh7110/spl.c
>> @@ -3,19 +3,49 @@
>>    * Copyright (C) 2022 StarFive Technology Co., Ltd.
>>    * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
>>    */
>> -
>> +#include <common.h>
>> +#include <asm/arch/eeprom.h>
>>   #include <asm/csr.h>
>>   #include <asm/sections.h>
>>   #include <dm.h>
>> +#include <linux/sizes.h>
>>   #include <log.h>
>> +#include <init.h>
>>   #define CSR_U74_FEATURE_DISABLE    0x7c1
>>   #define L2_LIM_MEM_END    0x81FFFFFUL
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static bool check_ddr_size(phys_size_t size)
>> +{
>> +    switch (size) {
>> +    case SZ_2:
>> +    case SZ_4:
>> +    case SZ_8:
>> +    case SZ_16:
>> +        return true;
>> +    default:
>> +        return false;
>> +    }
>> +}
>> +
>>   int spl_soc_init(void)
>>   {
>>       int ret;
>>       struct udevice *dev;
>> +    phys_size_t size;
>> +
>> +    ret = fdtdec_setup_mem_size_base();
>> +    if (ret)
>> +        return ret;
>> +
>> +    /* Read the definition of the DDR size from eeprom, and if not,
>> +     * use the definition in DT
>> +     */
>> +    size = (get_ddr_size_from_eeprom() >> 16) & 0xFF;
> 
> On origin/master for a 4 GiB board with a serial number 
> VF7110B1-2253-D004E000-4000xxxx this always fails. This results in 
> memory reported as 8 GiB and Linux crashing.
> 
> i2c_get_chip_for_busnum() returns -EINVAL in read_eeprom() 
> [board/starfive/visionfive2/visionfive2-i2c-eeprom.c:335].
> 
> Is the driver model really expected to be fully initialized before 
> setting up memory?
> 
> Best regards
> 
> Heinrich

The root cause seems to be in dw_i2c_calc_timing(). Probing of the 
i2c_designware device fails with:

dw_i2c: mode 0, ic_clk 1000000, speed 100000, period 10 rise 1 fall 1 
tlow 5 thigh 4 spk 0
dw_i2c: bad counts. hcnt = -4 lcnt = 4
device_probe: i2c@12050000 failed to probe -22

When I change the hcnt timing calculation, by replacing the offset of 7 
to 1, the device is probed correctly and I get the correct memory size 
for my board.

Best regards

Heinrich


> 
>> +    if (check_ddr_size(size))
>> +        gd->ram_size = size << 30;
>>       /* DDR init */
>>       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
>> diff --git a/drivers/ram/starfive/starfive_ddr.c 
>> b/drivers/ram/starfive/starfive_ddr.c
>> index 553f2ce6f4..a0a3d6b33d 100644
>> --- a/drivers/ram/starfive/starfive_ddr.c
>> +++ b/drivers/ram/starfive/starfive_ddr.c
>> @@ -72,8 +72,6 @@ static int starfive_ddr_probe(struct udevice *dev)
>>       u64 rate;
>>       int ret;
>> -    /* Read memory base and size from DT */
>> -    fdtdec_setup_mem_size_base();
>>       priv->info.base = gd->ram_base;
>>       priv->info.size = gd->ram_size;
>
diff mbox series

Patch

diff --git a/arch/riscv/cpu/jh7110/spl.c b/arch/riscv/cpu/jh7110/spl.c
index 104f0fe949..72adcefa0e 100644
--- a/arch/riscv/cpu/jh7110/spl.c
+++ b/arch/riscv/cpu/jh7110/spl.c
@@ -3,19 +3,49 @@ 
  * Copyright (C) 2022 StarFive Technology Co., Ltd.
  * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
  */
-
+#include <common.h>
+#include <asm/arch/eeprom.h>
 #include <asm/csr.h>
 #include <asm/sections.h>
 #include <dm.h>
+#include <linux/sizes.h>
 #include <log.h>
+#include <init.h>
 
 #define CSR_U74_FEATURE_DISABLE	0x7c1
 #define L2_LIM_MEM_END	0x81FFFFFUL
 
+DECLARE_GLOBAL_DATA_PTR;
+
+static bool check_ddr_size(phys_size_t size)
+{
+	switch (size) {
+	case SZ_2:
+	case SZ_4:
+	case SZ_8:
+	case SZ_16:
+		return true;
+	default:
+		return false;
+	}
+}
+
 int spl_soc_init(void)
 {
 	int ret;
 	struct udevice *dev;
+	phys_size_t size;
+
+	ret = fdtdec_setup_mem_size_base();
+	if (ret)
+		return ret;
+
+	/* Read the definition of the DDR size from eeprom, and if not,
+	 * use the definition in DT
+	 */
+	size = (get_ddr_size_from_eeprom() >> 16) & 0xFF;
+	if (check_ddr_size(size))
+		gd->ram_size = size << 30;
 
 	/* DDR init */
 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
diff --git a/drivers/ram/starfive/starfive_ddr.c b/drivers/ram/starfive/starfive_ddr.c
index 553f2ce6f4..a0a3d6b33d 100644
--- a/drivers/ram/starfive/starfive_ddr.c
+++ b/drivers/ram/starfive/starfive_ddr.c
@@ -72,8 +72,6 @@  static int starfive_ddr_probe(struct udevice *dev)
 	u64 rate;
 	int ret;
 
-	/* Read memory base and size from DT */
-	fdtdec_setup_mem_size_base();
 	priv->info.base = gd->ram_base;
 	priv->info.size = gd->ram_size;