]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
venice: lpddr4_timing_imx8mm: add 4gb single die support
authorTim Harvey <tharvey@gateworks.com>
Mon, 14 Jul 2025 17:23:02 +0000 (10:23 -0700)
committerFabio Estevam <festevam@gmail.com>
Thu, 17 Jul 2025 12:58:42 +0000 (09:58 -0300)
Add dram support for the MT53E1G32D2FW-046 RevC part which is a single die
32Gbit density part vs RevA/B which were dual-die parts:
 - use a previously unused EEPROM byte to denote a variant of the
   base config to be patched
 - add a dram description string
 - return the board struct from eeprom_init and pass it to the
   spl_dram_init function so that it has access to the EEPROM
 - move ddr_init into the spl_dram_init so that it can be patched
   in the per-soc init function

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
board/gateworks/venice/eeprom.c
board/gateworks/venice/eeprom.h
board/gateworks/venice/lpddr4_timing.h
board/gateworks/venice/lpddr4_timing_imx8mm.c
board/gateworks/venice/lpddr4_timing_imx8mn.c
board/gateworks/venice/lpddr4_timing_imx8mp.c
board/gateworks/venice/spl.c

index d9a87193434066f02386858a64e4a7859f26a074..88bbc2e1af8c588fbe5d2ebdf74666444f83280a 100644 (file)
@@ -356,7 +356,7 @@ static int eeprom_info(bool verbose)
        return 0;
 }
 
-int venice_eeprom_init(int quiet)
+struct venice_board_info *venice_eeprom_init(int quiet)
 {
        char rev_pcb;
        int rev_bom;
@@ -466,10 +466,10 @@ int venice_eeprom_init(int quiet)
 
        if (!strncmp(venice_model, "GW7901-SP486", 12) &&
            strcmp(venice_model, "GW7901-SP486-C")) {
-               return 2048;
+               som_info.sdram_size++;
        }
 
-       return (16 << som_info.sdram_size);
+       return &som_info;
 }
 
 void board_gsc_info(void)
index a0f449299aa33843b2eda31ff82ded8114880e3f..817277f62767896c29d73704c3ae461ab0221f74 100644 (file)
@@ -18,13 +18,14 @@ struct venice_board_info {
        u8 sdram_size;  /* 0x2B: (16 << n) MB */
        u8 sdram_speed; /* 0x2C: (33.333 * n) MHz */
        u8 sdram_width; /* 0x2D: (8 << n) bit */
-       u8 res3[2];     /* 0x2E */
+       u8 sdram_variant; /* 0x2E */
+       u8 res3[1];     /* 0x2D */
        char model[16];         /* 0x30: model string */
        u8 config[14];  /* 0x40: model config */
        u8 chksum[2];   /* 0x4E */
 };
 
-int venice_eeprom_init(int quiet);
+struct venice_board_info *venice_eeprom_init(int quiet);
 const char *eeprom_get_model(void);
 const char *eeprom_get_som_model(void);
 const char *eeprom_get_baseboard_model(void);
index 21997f6fb2a168025ada96fa41abea8d60ea8c27..e4aa8b6821c7f7c4c4c77bb366abd672e9725cc1 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef __LPDDR4_TIMING_H__
 #define __LPDDR4_TIMING_H__
 
-extern struct dram_timing_info *spl_dram_init(const char *model, int sizemb);
+struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
+                                      char *dram_desc, size_t sz_desc);
 
 #endif /* __LPDDR4_TIMING_H__ */
index 485649ab4f40a809fb82cc784d7f573c22156100..a6025322e78d8611ea2fcee128438f9cabec468a 100644 (file)
@@ -10,6 +10,8 @@
 #include <asm/arch/ddr.h>
 #include <asm/arch/lpddr4_define.h>
 
+#include "eeprom.h"
+
 /* ddr phy trained csr */
 static struct dram_cfg_param lpddr4_ddrphy_trained_csr[] = {
        { 0x200b2, 0x0 },
@@ -3561,9 +3563,36 @@ static struct dram_cfg_param ddr_ddrphy_cfg_alt_patch[] = {
        { 0x120a5, 0x2 },
 };
 
-struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
+/* 4GB single Die patch (MT53E1G32D2FW-046 revC) */
+static struct dram_cfg_param ddr_ddrc_cfg_4gb_single_die_patch[] = {
+       { 0x3d400000, 0xa1080020 },
+       { 0x3d400064, 0x5b011d },
+       { 0x3d40011c, 0x402 },
+       { 0x3d400138, 0x123 },
+       { 0x3d4000f4, 0x699 },
+       { 0x3d400200, 0x1f },
+       { 0x3d40021c, 0xf07 },
+       { 0x3d402064, 0xc0026 },
+       { 0x3d40211c, 0x302 },
+       { 0x3d402138, 0x27 },
+       { 0x3d4020f4, 0x599 },
+       { 0x3d403064, 0x3000a },
+       { 0x3d40311c, 0x302 },
+       { 0x3d403138, 0xa },
+       { 0x3d4030f4, 0x599 }
+};
+
+static struct dram_cfg_param fsp_msg_4gb_single_die_patch[] = {
+       { 0x00054012, 0x110 },
+       { 0x0005402c, 0x1 },
+};
+
+struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
+                                      char *dram_desc, size_t sz_desc)
 {
        struct dram_timing_info *dram_timing;
+       int sizemb = (16 << info->sdram_size);
+       int i;
 
        switch (sizemb) {
        case 512:
@@ -3577,6 +3606,21 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
                break;
        case 4096:
                dram_timing = &dram_timing_4gb;
+               if (info->sdram_variant == 1) {
+                       if (dram_desc)
+                               strlcpy(dram_desc, "single-die", sz_desc);
+                       apply_cfg_patch(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num,
+                                       ddr_ddrc_cfg_4gb_single_die_patch,
+                                       ARRAY_SIZE(ddr_ddrc_cfg_4gb_single_die_patch));
+                       for (i = 0; i < 4; i++) {
+                               apply_cfg_patch(dram_timing->fsp_msg[i].fsp_cfg,
+                                               dram_timing->fsp_msg[i].fsp_cfg_num,
+                                               fsp_msg_4gb_single_die_patch,
+                                               ARRAY_SIZE(fsp_msg_4gb_single_die_patch));
+                       }
+               } else if (dram_desc) {
+                       strlcpy(dram_desc, "dual-die", sz_desc);
+               }
                break;
        default:
                printf("unsupported");
@@ -3596,5 +3640,8 @@ struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
                                ARRAY_SIZE(ddr_ddrphy_cfg_alt_patch));
        }
 
+       if (ddr_init(dram_timing))
+               return NULL;
+
        return dram_timing;
 }
index e7d04822c9cffbd5ca7585f871d222ab4d0b312e..cad4fc0d31ce3a0b9715739656150a8da4348b4b 100644 (file)
@@ -4,6 +4,8 @@
 #include <string.h>
 #include <asm/arch/ddr.h>
 
+#include "eeprom.h"
+
 /*
  * Generated code from MX8M_DDR_tool v3.20 using RPAv15
  */
@@ -2369,26 +2371,36 @@ static struct dram_timing_info dram_timing_2gb_dual_die = {
        .fsp_table = { 3200, 400, 100, },
 };
 
-struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
+struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
+                                      char *dram_desc, size_t sz_desc)
 {
        struct dram_timing_info *dram_timing;
+       int sizemb = (16 << info->sdram_size);
 
        switch (sizemb) {
        case 1024:
                dram_timing = &dram_timing_1gb_single_die;
+               if (dram_desc)
+                       strlcpy(dram_desc, "single-die", sz_desc);
                break;
        case 2048:
                if (!strcmp(model, "GW7902-SP466-A") ||
                    !strcmp(model, "GW7902-SP466-B")) {
                        dram_timing = &dram_timing_2gb_dual_die;
+                       if (dram_desc)
+                               strlcpy(dram_desc, "dual-die", sz_desc);
                } else {
                        dram_timing = &dram_timing_2gb_single_die;
+                       if (dram_desc)
+                               strlcpy(dram_desc, "single-die", sz_desc);
                }
                break;
        default:
                printf("unsupported");
                dram_timing = &dram_timing_2gb_dual_die;
        }
+       if (ddr_init(dram_timing))
+               return NULL;
 
        return dram_timing;
 }
index 36c4cb147e823b5f28c9e7226c973a7bfdad4b3e..f2d5d9ce5659ac0ed7227a00511e8cd27a2c251a 100644 (file)
@@ -1,8 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0+
 
 #include <linux/kernel.h>
+#include <string.h>
 #include <asm/arch/ddr.h>
 
+#include "eeprom.h"
+
 /*
  * Generated code from MX8M_DDR_tool v3.30 using MX8M_Plus RPAv7
  */
@@ -2378,21 +2381,29 @@ static struct dram_timing_info dram_timing_4gb_dual_die = {
        .fsp_table = { 4000, 400, 100, },
 };
 
-struct dram_timing_info *spl_dram_init(const char *model, int sizemb)
+struct dram_timing_info *spl_dram_init(const char *model, struct venice_board_info *info,
+                                      char *dram_desc, size_t sz_desc)
 {
        struct dram_timing_info *dram_timing;
+       int sizemb = (16 << info->sdram_size);
 
        switch (sizemb) {
        case 1024:
                dram_timing = &dram_timing_1gb_single_die;
+               if (dram_desc)
+                       strlcpy(dram_desc, "single-die", sz_desc);
                break;
        case 4096:
                dram_timing = &dram_timing_4gb_dual_die;
+               if (dram_desc)
+                       strlcpy(dram_desc, "dual-die", sz_desc);
                break;
        default:
                printf("unsupported");
                dram_timing = &dram_timing_4gb_dual_die;
        }
+       if (ddr_init(dram_timing))
+               return NULL;
 
        return dram_timing;
 }
index e813f3e763ec1f2baa69962545081004aabd3cf0..d9bc593fa0d575b97be0c15107be32b142994f5c 100644 (file)
@@ -188,9 +188,10 @@ static int power_init_board(const char *model, struct udevice *gsc)
 void board_init_f(ulong dummy)
 {
        struct dram_timing_info *dram_timing;
+       struct venice_board_info *eeprom;
        struct udevice *bus, *dev;
        const char *model;
-       int dram_szmb;
+       char dram_desc[32];
        int i, ret;
 
        arch_cpu_init();
@@ -249,23 +250,31 @@ void board_init_f(ulong dummy)
                        break;
                mdelay(1);
        }
-       dram_szmb = venice_eeprom_init(0);
+       eeprom = venice_eeprom_init(0);
        model = eeprom_get_model();
 
        /* PMIC */
        power_init_board(model, dev);
 
        /* DDR initialization */
-       printf("DRAM    : LPDDR4 ");
-       if (dram_szmb > 512)
-               printf("%d GiB", dram_szmb / 1024);
-       else
-               printf("%d MiB", dram_szmb);
-       dram_timing = spl_dram_init(model, dram_szmb);
-       printf(" %dMT/s %dMHz\n",
-              dram_timing->fsp_msg[0].drate,
-              dram_timing->fsp_msg[0].drate / 2);
-       ddr_init(dram_timing);
+       dram_desc[0] = 0;
+       dram_timing = spl_dram_init(model, eeprom, dram_desc, sizeof(dram_desc));
+       if (dram_timing) {
+               int dram_szmb = (16 << eeprom->sdram_size);
+
+               printf("DRAM    : LPDDR4 ");
+               if (dram_szmb > 512)
+                       printf("%d GiB", dram_szmb / 1024);
+               else
+                       printf("%d MiB", dram_szmb);
+               printf(" %dMT/s %dMHz %s",
+                      dram_timing->fsp_msg[0].drate,
+                      dram_timing->fsp_msg[0].drate / 2,
+                      dram_desc[0] ? dram_desc : "");
+               puts("\n");
+       } else {
+               hang();
+       }
 
        board_init_r(NULL, 0);
 }