On 07/23/2018 10:20 AM, [email protected] wrote:
> From: Tien Fong Chee <[email protected]>
> 
> The SDRAM must first be rewritten by zeroes if ECC is used to initialize
> the ECC metadata. Make the CPU overwrite the DRAM with zeroes in such a
> case. This scrubbing implementation turns the caches on temporarily, then
> overwrites the whole RAM with zeroes, flushes the caches and turns them
> off again. This provides satisfactory performance.
> 
> Signed-off-by: Tien Fong Chee <[email protected]>
> ---
>  drivers/ddr/altera/sdram_s10.c |   44 
> ++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/ddr/altera/sdram_s10.c b/drivers/ddr/altera/sdram_s10.c
> index 48f4f47..cce261f 100644
> --- a/drivers/ddr/altera/sdram_s10.c
> +++ b/drivers/ddr/altera/sdram_s10.c
> @@ -8,6 +8,7 @@
>  #include <errno.h>
>  #include <div64.h>
>  #include <asm/io.h>
> +#include <linux/sizes.h>
>  #include <wait_bit.h>
>  #include <asm/arch/firewall_s10.h>
>  #include <asm/arch/sdram_s10.h>
> @@ -134,6 +135,47 @@ static int poll_hmc_clock_status(void)
>                                SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false);
>  }
>  
> +/* Initialize SDRAM ECC bits to avoid false DBE */
> +static void sdram_init_ecc_bits(unsigned long long size)
> +{
> +     /* 1GB per chunk */
> +     unsigned long long size_byte = SZ_1G;
> +     unsigned long long remaining_size;
> +     unsigned long long dst_addr = 0x8000;
> +     unsigned int start = get_timer(0);
> +
> +     icache_enable();
> +
> +     memset(0, 0, dst_addr);
> +     gd->arch.tlb_addr = 0x4000;
> +     gd->arch.tlb_size = PGTABLE_SIZE;

Are you sure this is valid on arm64 ? It looks like something copies
from arria10.

> +     dcache_enable();
> +
> +     remaining_size = size - dst_addr;
> +     printf("DDRCAL: Scrubbing ECC RAM (%d MiB).\n", (u32)(size >> 20));
> +
> +     while (remaining_size) {
> +             if (remaining_size <= size_byte) {
> +                     memset((void *)dst_addr, 0, remaining_size);
> +                     break;
> +             } else {
> +                     memset((void *)dst_addr, 0, size_byte);
> +                     dst_addr += size_byte;
> +             }
> +
> +             WATCHDOG_RESET();
> +             remaining_size -= size_byte;
> +     }

How long does this take ?

> +     flush_dcache_all();
> +     printf("DDRCAL: Scrubbing ECC RAM done.\n");
> +     dcache_disable();
> +
> +     printf("SDRAM-ECC: Initialized success with %d ms\n",
> +     (unsigned)get_timer(start));
> +}
> +
>  /**
>   * sdram_mmr_init_full() - Function to initialize SDRAM MMR
>   *
> @@ -351,6 +393,8 @@ int sdram_mmr_init_full(unsigned int unused)
>               setbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL2,
>                            (DDR_HMC_ECCCTL2_RMW_EN_SET_MSK |
>                             DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));
> +
> +             sdram_init_ecc_bits(gd->ram_size);
>       } else {
>               clrbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL1,
>                            (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK |
> 


-- 
Best regards,
Marek Vasut
_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to