diff options
author | Marek Vasut <marex@denx.de> | 2023-12-07 18:50:32 +0100 |
---|---|---|
committer | Fabio Estevam <festevam@denx.de> | 2023-12-14 15:29:08 -0300 |
commit | cfdbdf78428bdb1e91c39b8916627fbc22ea2540 (patch) | |
tree | 07b55c753480f8a08f1a7a533b66e893eb76aae9 /board/data_modul/common/common.c | |
parent | c4cc14433dcdb9480eb496541dc7960f7eb718c0 (diff) |
ARM: imx: Update DRAM timings with inline ECC on Data Modul i.MX8M Plus eDM SBC
Import DRAM timings generated by the DDR tool 3.31 which introduce assorted
tweaks to the DRAM controller settings. Furthermore, enable DBI to improve
noise resilience of the DRAM bus by reducing the number of bit changes on
the bus.
Reduce the DRAM rate to 3600 MTps to remove all remaining correctable errors
reported by EDAC . It is not entirely clear why the slightly faster setting
does produce sporadic correctable errors, while this one does not, but this
could be related to simpler PLL setting at 3600 MTps.
Enable inline ECC which is necessary to detect ECC errors and collect
statistics by the EDAC driver in Linux. This reduces the DRAM size by
64 MiB for each 512 MiB of DRAM, so for a 4 GiB device the available
DRAM size becomes 3.5 GiB .
Signed-off-by: Marek Vasut <marex@denx.de>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Diffstat (limited to 'board/data_modul/common/common.c')
-rw-r--r-- | board/data_modul/common/common.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/board/data_modul/common/common.c b/board/data_modul/common/common.c index bf9a11472d..a6761c21d4 100644 --- a/board/data_modul/common/common.c +++ b/board/data_modul/common/common.c @@ -30,6 +30,8 @@ DECLARE_GLOBAL_DATA_PTR; #define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE) +#define DDRC_ECCCFG0_ECC_MODE_MASK 0x7 + u8 dmo_get_memcfg(void) { struct gpio_desc gpio[4]; @@ -58,8 +60,16 @@ u8 dmo_get_memcfg(void) int board_phys_sdram_size(phys_size_t *size) { u8 memcfg = dmo_get_memcfg(); + u8 ecc = 0; + + *size = 4ULL >> ((memcfg >> 1) & 0x3); + + if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) { + /* 896 MiB, i.e. 1 GiB without 12.5% reserved for in-band ECC */ + ecc = readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK; + } - *size = (4ULL >> ((memcfg >> 1) & 0x3)) * SZ_1G; + *size *= SZ_1G - (ecc ? (SZ_1G / 8) : 0); return 0; } @@ -100,6 +110,12 @@ static void spl_dram_init(struct dram_timing_info *dram_timing_info[8]) } ddr_init(dram_timing_info[memcfg]); + + if (IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)) { + printf("DDR: Inline ECC %sabled\n", + (readl(DDRC_ECCCFG0(0)) & DDRC_ECCCFG0_ECC_MODE_MASK) ? + "en" : "dis"); + } } void dmo_board_init_f(const iomux_v3_cfg_t wdog_pad, |