]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
ARM: imx: Update DRAM timings with inline ECC on Data Modul i.MX8M Plus eDM SBC
authorMarek Vasut <marex@denx.de>
Thu, 7 Dec 2023 17:50:32 +0000 (18:50 +0100)
committerFabio Estevam <festevam@denx.de>
Thu, 14 Dec 2023 18:29:08 +0000 (15:29 -0300)
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>
board/data_modul/common/common.c
board/data_modul/imx8mp_edm_sbc/lpddr4_timing_4G_32.c
configs/imx8mp_data_modul_edm_sbc_defconfig

index bf9a11472d116ff1f921d0371481c97abc2047cf..a6761c21d409253b87c7d44bd99f113618e6fabb 100644 (file)
@@ -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,
index 04cef3a8b9fb37c7a905028d5bf66ead06df1c08..0ad40002d4e74cfddcef9f3c636bf54663e2b066 100644 (file)
@@ -19,47 +19,66 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d400030, 0x1 },
        { 0x3d400000, 0xa3080020 },
        { 0x3d400020, 0x1303 },
-       { 0x3d400024, 0x1c79100 },
+       { 0x3d400024, 0x1c7cf80 },
        { 0x3d400064, 0x710106 },
+#if IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)
+       { 0x3d400070, 0x7027fd4 },
+#else
        { 0x3d400070, 0x7027f90 },
+#endif
        { 0x3d400074, 0x790 },
-       { 0x3d4000d0, 0xc0030720 },
+       { 0x3d4000d0, 0xc0030721 },
        { 0x3d4000d4, 0xb80000 },
-       { 0x3d4000dc, 0xe40036 },
-       { 0x3d4000e0, 0x330000 },
+       { 0x3d4000dc, 0xf4003f },
+       { 0x3d4000e0, 0xf30000 },
        { 0x3d4000e8, 0x660048 },
        { 0x3d4000ec, 0x160048 },
-       { 0x3d400100, 0x1e262028 },
-       { 0x3d400104, 0x7073b },
+       { 0x3d400100, 0x1f262028 },
+       { 0x3d400104, 0x8083b },
        { 0x3d40010c, 0xe0e000 },
        { 0x3d400110, 0x11040a11 },
-       { 0x3d400114, 0x2050e0e },
-       { 0x3d400118, 0x1010008 },
-       { 0x3d40011c, 0x501 },
-       { 0x3d400130, 0x20700 },
+       { 0x3d400114, 0x2050f0f },
+       { 0x3d400118, 0x1010009 },
+       { 0x3d40011c, 0x502 },
+       { 0x3d400130, 0x20800 },
        { 0x3d400134, 0xe100002 },
        { 0x3d400138, 0x10d },
        { 0x3d400144, 0xbb005e },
-       { 0x3d400180, 0x3a5001c },
-       { 0x3d400184, 0x2f071e5 },
+       { 0x3d400180, 0x3a6001d },
+       { 0x3d400184, 0x2f071f4 },
        { 0x3d400188, 0x0 },
-       { 0x3d400190, 0x49b820c },
+       { 0x3d400190, 0x4a3820e },
        { 0x3d400194, 0x80303 },
-       { 0x3d4001b4, 0x1b0c },
+       { 0x3d4001b4, 0x230e },
        { 0x3d4001a0, 0xe0400018 },
        { 0x3d4001a4, 0xdf00e4 },
        { 0x3d4001a8, 0x80000000 },
        { 0x3d4001b0, 0x11 },
-       { 0x3d4001c0, 0x1 },
+       { 0x3d4001c0, 0x7 },
        { 0x3d4001c4, 0x1 },
-       { 0x3d4000f4, 0xc99 },
-       { 0x3d400108, 0x810191a },
+       { 0x3d4000f4, 0x799 },
+       { 0x3d400108, 0x9141c1c },
+#if IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)
+       { 0x3d400200, 0x14 },
+#else
        { 0x3d400200, 0x17 },
+#endif
+       { 0x3d400208, 0x0 },
+#if IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)
+       { 0x3d40020c, 0x14141400 },
+#else
        { 0x3d40020c, 0x0 },
+#endif
        { 0x3d400210, 0x1f1f },
+#if IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)
+       { 0x3d400204, 0x50505 },
+       { 0x3d400214, 0x4040404 },
+       { 0x3d400218, 0x4040404 },
+#else
        { 0x3d400204, 0x80808 },
        { 0x3d400214, 0x7070707 },
        { 0x3d400218, 0x7070707 },
+#endif
        { 0x3d40021c, 0xf0f },
        { 0x3d400250, 0x1705 },
        { 0x3d400254, 0x2c },
@@ -78,7 +97,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d402050, 0x20d000 },
        { 0x3d402064, 0xc001c },
        { 0x3d4020dc, 0x840000 },
-       { 0x3d4020e0, 0x330000 },
+       { 0x3d4020e0, 0xf30000 },
        { 0x3d4020e8, 0x660048 },
        { 0x3d4020ec, 0x160048 },
        { 0x3d402100, 0xa040305 },
@@ -88,7 +107,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d402110, 0x2040202 },
        { 0x3d402114, 0x2030202 },
        { 0x3d402118, 0x1010004 },
-       { 0x3d40211c, 0x301 },
+       { 0x3d40211c, 0x302 },
        { 0x3d402130, 0x20300 },
        { 0x3d402134, 0xa100002 },
        { 0x3d402138, 0x1d },
@@ -97,13 +116,13 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d402190, 0x3818200 },
        { 0x3d402194, 0x80303 },
        { 0x3d4021b4, 0x100 },
-       { 0x3d4020f4, 0xc99 },
+       { 0x3d4020f4, 0x599 },
        { 0x3d403020, 0x1001 },
        { 0x3d403024, 0xc3500 },
        { 0x3d403050, 0x20d000 },
        { 0x3d403064, 0x30007 },
        { 0x3d4030dc, 0x840000 },
-       { 0x3d4030e0, 0x330000 },
+       { 0x3d4030e0, 0xf30000 },
        { 0x3d4030e8, 0x660048 },
        { 0x3d4030ec, 0x160048 },
        { 0x3d403100, 0xa010102 },
@@ -113,7 +132,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d403110, 0x2040202 },
        { 0x3d403114, 0x2030202 },
        { 0x3d403118, 0x1010004 },
-       { 0x3d40311c, 0x301 },
+       { 0x3d40311c, 0x302 },
        { 0x3d403130, 0x20300 },
        { 0x3d403134, 0xa100002 },
        { 0x3d403138, 0x8 },
@@ -122,7 +141,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
        { 0x3d403190, 0x3818200 },
        { 0x3d403194, 0x80303 },
        { 0x3d4031b4, 0x100 },
-       { 0x3d4030f4, 0xc99 },
+       { 0x3d4030f4, 0x599 },
        { 0x3d400028, 0x0 },
 };
 
@@ -260,16 +279,16 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = {
        { 0x212149, 0xeba },
        { 0x213049, 0xeba },
        { 0x213149, 0xeba },
-       { 0x43, 0xe7 },
-       { 0x1043, 0xe7 },
-       { 0x2043, 0xe7 },
-       { 0x3043, 0xe7 },
-       { 0x4043, 0xe7 },
-       { 0x5043, 0xe7 },
-       { 0x6043, 0xe7 },
-       { 0x7043, 0xe7 },
-       { 0x8043, 0xe7 },
-       { 0x9043, 0xe7 },
+       { 0x43, 0x3ff },
+       { 0x1043, 0x3ff },
+       { 0x2043, 0x3ff },
+       { 0x3043, 0x3ff },
+       { 0x4043, 0x3ff },
+       { 0x5043, 0x3ff },
+       { 0x6043, 0x3ff },
+       { 0x7043, 0x3ff },
+       { 0x8043, 0x3ff },
+       { 0x9043, 0x3ff },
        { 0x20018, 0x3 },
        { 0x20075, 0x4 },
        { 0x20050, 0x0 },
@@ -319,19 +338,15 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = {
        { 0x200f6, 0x0 },
        { 0x200f7, 0xf000 },
        { 0x20025, 0x0 },
-       { 0x2002d, 0x0 },
-       { 0x12002d, 0x0 },
-       { 0x22002d, 0x0 },
+       { 0x2002d, 0x1 },
+       { 0x12002d, 0x1 },
+       { 0x22002d, 0x1 },
        { 0x2007d, 0x212 },
        { 0x12007d, 0x212 },
        { 0x22007d, 0x212 },
        { 0x2007c, 0x61 },
        { 0x12007c, 0x61 },
        { 0x22007c, 0x61 },
-       { 0x1004a, 0x500 },
-       { 0x1104a, 0x500 },
-       { 0x1204a, 0x500 },
-       { 0x1304a, 0x500 },
        { 0x2002c, 0x0 },
 };
 
@@ -1061,7 +1076,7 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = {
 /* P0 message block paremeter for training firmware */
 static struct dram_cfg_param ddr_fsp0_cfg[] = {
        { 0xd0000, 0x0 },
-       { 0x54003, 0xe94 },
+       { 0x54003, 0xe96 },
        { 0x54004, 0x2 },
        { 0x54005, 0x2228 },
        { 0x54006, 0x14 },
@@ -1070,26 +1085,26 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = {
        { 0x5400b, 0x2 },
        { 0x5400f, 0x100 },
        { 0x54012, 0x310 },
-       { 0x54019, 0x36e4 },
-       { 0x5401a, 0x33 },
+       { 0x54019, 0x3ff4 },
+       { 0x5401a, 0xf3 },
        { 0x5401b, 0x4866 },
        { 0x5401c, 0x4800 },
        { 0x5401e, 0x16 },
-       { 0x5401f, 0x36e4 },
-       { 0x54020, 0x33 },
+       { 0x5401f, 0x3ff4 },
+       { 0x54020, 0xf3 },
        { 0x54021, 0x4866 },
        { 0x54022, 0x4800 },
        { 0x54024, 0x16 },
        { 0x5402b, 0x1000 },
        { 0x5402c, 0x3 },
-       { 0x54032, 0xe400 },
-       { 0x54033, 0x3336 },
+       { 0x54032, 0xf400 },
+       { 0x54033, 0xf33f },
        { 0x54034, 0x6600 },
        { 0x54035, 0x48 },
        { 0x54036, 0x48 },
        { 0x54037, 0x1600 },
-       { 0x54038, 0xe400 },
-       { 0x54039, 0x3336 },
+       { 0x54038, 0xf400 },
+       { 0x54039, 0xf33f },
        { 0x5403a, 0x6600 },
        { 0x5403b, 0x48 },
        { 0x5403c, 0x48 },
@@ -1111,25 +1126,25 @@ static struct dram_cfg_param ddr_fsp1_cfg[] = {
        { 0x5400f, 0x100 },
        { 0x54012, 0x310 },
        { 0x54019, 0x84 },
-       { 0x5401a, 0x33 },
+       { 0x5401a, 0xf3 },
        { 0x5401b, 0x4866 },
        { 0x5401c, 0x4800 },
        { 0x5401e, 0x16 },
        { 0x5401f, 0x84 },
-       { 0x54020, 0x33 },
+       { 0x54020, 0xf3 },
        { 0x54021, 0x4866 },
        { 0x54022, 0x4800 },
        { 0x54024, 0x16 },
        { 0x5402b, 0x1000 },
        { 0x5402c, 0x3 },
        { 0x54032, 0x8400 },
-       { 0x54033, 0x3300 },
+       { 0x54033, 0xf300 },
        { 0x54034, 0x6600 },
        { 0x54035, 0x48 },
        { 0x54036, 0x48 },
        { 0x54037, 0x1600 },
        { 0x54038, 0x8400 },
-       { 0x54039, 0x3300 },
+       { 0x54039, 0xf300 },
        { 0x5403a, 0x6600 },
        { 0x5403b, 0x48 },
        { 0x5403c, 0x48 },
@@ -1151,25 +1166,25 @@ static struct dram_cfg_param ddr_fsp2_cfg[] = {
        { 0x5400f, 0x100 },
        { 0x54012, 0x310 },
        { 0x54019, 0x84 },
-       { 0x5401a, 0x33 },
+       { 0x5401a, 0xf3 },
        { 0x5401b, 0x4866 },
        { 0x5401c, 0x4800 },
        { 0x5401e, 0x16 },
        { 0x5401f, 0x84 },
-       { 0x54020, 0x33 },
+       { 0x54020, 0xf3 },
        { 0x54021, 0x4866 },
        { 0x54022, 0x4800 },
        { 0x54024, 0x16 },
        { 0x5402b, 0x1000 },
        { 0x5402c, 0x3 },
        { 0x54032, 0x8400 },
-       { 0x54033, 0x3300 },
+       { 0x54033, 0xf300 },
        { 0x54034, 0x6600 },
        { 0x54035, 0x48 },
        { 0x54036, 0x48 },
        { 0x54037, 0x1600 },
        { 0x54038, 0x8400 },
-       { 0x54039, 0x3300 },
+       { 0x54039, 0xf300 },
        { 0x5403a, 0x6600 },
        { 0x5403b, 0x48 },
        { 0x5403c, 0x48 },
@@ -1180,7 +1195,7 @@ static struct dram_cfg_param ddr_fsp2_cfg[] = {
 /* P0 2D message block paremeter for training firmware */
 static struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
        { 0xd0000, 0x0 },
-       { 0x54003, 0xe94 },
+       { 0x54003, 0xe96 },
        { 0x54004, 0x2 },
        { 0x54005, 0x2228 },
        { 0x54006, 0x14 },
@@ -1190,26 +1205,26 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
        { 0x5400f, 0x100 },
        { 0x54010, 0x1f7f },
        { 0x54012, 0x310 },
-       { 0x54019, 0x36e4 },
-       { 0x5401a, 0x33 },
+       { 0x54019, 0x3ff4 },
+       { 0x5401a, 0xf3 },
        { 0x5401b, 0x4866 },
        { 0x5401c, 0x4800 },
        { 0x5401e, 0x16 },
-       { 0x5401f, 0x36e4 },
-       { 0x54020, 0x33 },
+       { 0x5401f, 0x3ff4 },
+       { 0x54020, 0xf3 },
        { 0x54021, 0x4866 },
        { 0x54022, 0x4800 },
        { 0x54024, 0x16 },
        { 0x5402b, 0x1000 },
        { 0x5402c, 0x3 },
-       { 0x54032, 0xe400 },
-       { 0x54033, 0x3336 },
+       { 0x54032, 0xf400 },
+       { 0x54033, 0xf33f },
        { 0x54034, 0x6600 },
        { 0x54035, 0x48 },
        { 0x54036, 0x48 },
        { 0x54037, 0x1600 },
-       { 0x54038, 0xe400 },
-       { 0x54039, 0x3336 },
+       { 0x54038, 0xf400 },
+       { 0x54039, 0xf33f },
        { 0x5403a, 0x6600 },
        { 0x5403b, 0x48 },
        { 0x5403c, 0x48 },
@@ -1699,9 +1714,9 @@ static struct dram_cfg_param ddr_phy_pie[] = {
        { 0x400d7, 0x20b },
        { 0x2003a, 0x2 },
        { 0x200be, 0x3 },
-       { 0x2000b, 0x419 },
+       { 0x2000b, 0x41a },
        { 0x2000c, 0xe9 },
-       { 0x2000d, 0x91c },
+       { 0x2000d, 0x91d },
        { 0x2000e, 0x2c },
        { 0x12000b, 0x70 },
        { 0x12000c, 0x19 },
@@ -1804,8 +1819,8 @@ static struct dram_cfg_param ddr_phy_pie[] = {
 
 static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
        {
-               /* P0 3733mts 1D */
-               .drate = 3733,
+               /* P0 3600mts 1D */
+               .drate = 3600,
                .fw_type = FW_1D_IMAGE,
                .fsp_cfg = ddr_fsp0_cfg,
                .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg),
@@ -1825,8 +1840,8 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
                .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg),
        },
        {
-               /* P0 3733mts 2D */
-               .drate = 3733,
+               /* P0 3600mts 2D */
+               .drate = 3600,
                .fw_type = FW_2D_IMAGE,
                .fsp_cfg = ddr_fsp0_2d_cfg,
                .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg),
@@ -1845,5 +1860,19 @@ struct dram_timing_info dmo_imx8mp_sbc_dram_timing_32_32 = {
        .ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr),
        .ddrphy_pie = ddr_phy_pie,
        .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
-       .fsp_table = { 3733, 400, 100, },
+       .fsp_table = { 3600, 400, 100, },
 };
+
+#if IS_ENABLED(CONFIG_IMX8M_DRAM_INLINE_ECC)
+void board_dram_ecc_scrub(void)
+{
+       ddrc_inline_ecc_scrub(0x0,0x7ffffff);
+       ddrc_inline_ecc_scrub(0x8000000,0xfffffff);
+       ddrc_inline_ecc_scrub(0x10000000,0x17ffffff);
+       ddrc_inline_ecc_scrub(0x18000000,0x1fffffff);
+       ddrc_inline_ecc_scrub(0x20000000,0x27ffffff);
+       ddrc_inline_ecc_scrub(0x28000000,0x2fffffff);
+       ddrc_inline_ecc_scrub(0x30000000,0x37ffffff);
+       ddrc_inline_ecc_scrub_end(0x0,0x3fffffff);
+}
+#endif
index 30f8636f4d57e907a723d2a1aff237f4be42e4ac..3974e376b85bf98f0e17f914334df52e82e88cd3 100644 (file)
@@ -165,6 +165,7 @@ CONFIG_CLK_COMPOSITE_CCF=y
 CONFIG_SPL_CLK_IMX8MP=y
 CONFIG_CLK_IMX8MP=y
 CONFIG_FSL_CAAM=y
+CONFIG_IMX8M_DRAM_INLINE_ECC=y
 CONFIG_DFU_TFTP=y
 CONFIG_DFU_TIMEOUT=y
 CONFIG_DFU_MMC=y