[PATCH v3 0/3] Add support for all variants of the phyCORE-i.MX93 SOM

The phyCORE-i.MX 93 is available in various variants (e.g. different ram sizes, eMMC HS400 yes/no). It's eeprom contains information which features the existing module supports.
Extend the existing board-code to support all the SOM variants. The spl/u-boot evaluates the eeprom information and enables supported features accordingly. The resulting spl and u-boot binary is able to boot each phyCORE-i.MX 93 SOM variant on each carrier board.
Changes in v3:
patch #1: - none changes
patch #2: - remove unwanted dts node eepromid - correct typo in doc (PHYTEC_IMX93_VOLTAGE_3V3) - improve enum code-style (phytec_imx93_option_index)
patch #3: - add comment about SoM-scope to imx93-phyboard-segin-u-boot.dtsi - rebase to the latest master - adapt doc according to new defconfig
Changes in v2:
patch #1: - remove multiple blank lines - add update of 1GB ram timings to commit message
patch #2: - encapsulate handling of feature flag VOLTAGE into own function - move definition of enum phytec_imx93_ddr_eeprom_code into header file
patch #3: - just rename imx93-phyboard-segin_defconfig and add needed CONFIGs, instead of creating an entirely new second defconfig - remove wrong comment from imx93-phyboard-segin-u-boot.dtsi - improve commit message
Christoph Stoidner (3): board: phytec: phycore-imx93: Add 2GB LPDDR4X RAM timings board: phytec: imx93: Add eeprom-based hardware introspection board: phytec: imx93: Add phyCORE-i.MX 93 support for all SOM variants
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 20 +- arch/arm/mach-imx/imx9/Kconfig | 2 + arch/arm/mach-imx/imx9/soc.c | 2 +- board/phytec/common/Kconfig | 8 + board/phytec/common/Makefile | 1 + board/phytec/common/imx93_som_detection.c | 111 +++ board/phytec/common/imx93_som_detection.h | 51 ++ board/phytec/phycore_imx93/Kconfig | 28 + board/phytec/phycore_imx93/MAINTAINERS | 7 +- board/phytec/phycore_imx93/lpddr4_timing.c | 793 ++++++++++++++++-- board/phytec/phycore_imx93/phycore-imx93.c | 51 ++ board/phytec/phycore_imx93/spl.c | 48 ++ ...egin_defconfig => imx93-phycore_defconfig} | 2 + ...3-phyboard-segin.rst => imx93-phycore.rst} | 8 +- doc/board/phytec/index.rst | 2 +- 15 files changed, 1063 insertions(+), 71 deletions(-) create mode 100644 board/phytec/common/imx93_som_detection.c create mode 100644 board/phytec/common/imx93_som_detection.h rename configs/{imx93-phyboard-segin_defconfig => imx93-phycore_defconfig} (98%) rename doc/board/phytec/{imx93-phyboard-segin.rst => imx93-phycore.rst} (91%)

The phyCORE-i.MX 93 is available with a 1GB ram chip or a 2GB ram chip. Add the ram timings for the 2GB chip, in form of a diff compared to the existing LPDDR4X 1GB timings. With that, the SPL can select the appropriate timings at startup. Update also the 1GB ram timings with new version of the DDR Tool.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de --- Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de --- No changes in v3
Changes in v2: - remove multiple blank lines - add update of 1GB ram timings to commit message
board/phytec/phycore_imx93/lpddr4_timing.c | 793 +++++++++++++++++++-- 1 file changed, 732 insertions(+), 61 deletions(-)
diff --git a/board/phytec/phycore_imx93/lpddr4_timing.c b/board/phytec/phycore_imx93/lpddr4_timing.c index 2111972a40..f1261f6a92 100644 --- a/board/phytec/phycore_imx93/lpddr4_timing.c +++ b/board/phytec/phycore_imx93/lpddr4_timing.c @@ -1,24 +1,24 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2023 NXP - * Copyright (C) 2023 PHYTEC Messtechnik GmbH + * Copyright 2024 NXP + * Copyright (C) 2024 PHYTEC Messtechnik GmbH * Christoph Stoidner c.stoidner@phytec.de * - * Code generated with DDR Tool v1.0.0. + * Code generated with DDR Tool v3.1.0_7.4. */
#include <linux/kernel.h> #include <asm/arch/ddr.h>
+/* Initialize DDRC registers */ static struct dram_cfg_param ddr_ddrc_cfg[] = { - /** Initialize DDRC registers **/ {0x4e300110, 0x44100001}, {0x4e300000, 0x8000bf}, {0x4e300008, 0x0}, {0x4e300080, 0x80000412}, {0x4e300084, 0x0}, {0x4e300114, 0x1002}, - {0x4e300260, 0x4080}, + {0x4e300260, 0x80}, {0x4e300f04, 0x80}, {0x4e300800, 0x43b30002}, {0x4e300804, 0x1f1f1f1f}, @@ -31,18 +31,17 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = { {0x4e301254, 0x0}, {0x4e301258, 0x0}, {0x4e30125c, 0x0}, - };
/* dram fsp cfg */ static struct dram_fsp_cfg ddr_dram_fsp_cfg[] = { { { - {0x4e300100, 0x24A0421B}, + {0x4e300100, 0x24A0321B}, {0x4e300104, 0xF8EE001B}, - {0x4e300108, 0x2F263233}, - {0x4e30010C, 0x0005E18B}, - {0x4e300124, 0x1C770000}, + {0x4e300108, 0x2F2E3233}, + {0x4e30010C, 0x0005C18B}, + {0x4e300124, 0x1C790000}, {0x4e300160, 0x00009102}, {0x4e30016C, 0x35F00000}, {0x4e300170, 0x8B0B0608}, @@ -50,21 +49,73 @@ static struct dram_fsp_cfg ddr_dram_fsp_cfg[] = { {0x4e300254, 0x00FE00FE}, {0x4e300258, 0x00000008}, {0x4e30025C, 0x00000400}, - {0x4e300300, 0x224F2215}, + {0x4e300300, 0x224F2213}, {0x4e300304, 0x00FE2213}, - {0x4e300308, 0x0A3C0E3C}, + {0x4e300308, 0x0A380E3D}, }, { {0x01, 0xE4}, {0x02, 0x36}, - {0x03, 0xF2}, - {0x0b, 0x46}, - {0x0c, 0x11}, - {0x0e, 0x11}, + {0x03, 0x22}, + {0x0b, 0x44}, + {0x0c, 0x1E}, + {0x0e, 0x12}, + {0x16, 0x04}, + }, + 0, + }, + { + { + {0x4e300100, 0x124F2100}, + {0x4e300104, 0xF877000E}, + {0x4e300108, 0x1816E4AA}, + {0x4e30010C, 0x005101E6}, + {0x4e300124, 0x0E3C0000}, + {0x4e300160, 0x00009101}, + {0x4e30016C, 0x30900000}, + {0x4e300170, 0x8A0A0508}, + {0x4e300250, 0x00000014}, + {0x4e300254, 0x007B007B}, + {0x4e300258, 0x00000008}, + {0x4e30025C, 0x00000400}, + }, + { + {0x01, 0xB4}, + {0x02, 0x1B}, + {0x03, 0x22}, + {0x0b, 0x44}, + {0x0c, 0x1E}, + {0x0e, 0x12}, {0x16, 0x04}, }, 0, }, + { + { + {0x4e300100, 0x00051000}, + {0x4e300104, 0xF855000A}, + {0x4e300108, 0x6E620A48}, + {0x4e30010C, 0x0031010D}, + {0x4e300124, 0x04C50000}, + {0x4e300160, 0x00009100}, + {0x4e30016C, 0x30000000}, + {0x4e300170, 0x89090408}, + {0x4e300250, 0x00000007}, + {0x4e300254, 0x00240024}, + {0x4e300258, 0x00000008}, + {0x4e30025C, 0x00000400}, + }, + { + {0x01, 0x94}, + {0x02, 0x9}, + {0x03, 0x22}, + {0x0b, 0x44}, + {0x0c, 0x1E}, + {0x0e, 0x12}, + {0x16, 0x04}, + }, + 1, + },
};
@@ -90,25 +141,65 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x1015f, 0x5ff}, {0x1105f, 0x5ff}, {0x1115f, 0x5ff}, + {0x11005f, 0x5ff}, + {0x11015f, 0x5ff}, + {0x11105f, 0x5ff}, + {0x11115f, 0x5ff}, + {0x21005f, 0x5ff}, + {0x21015f, 0x5ff}, + {0x21105f, 0x5ff}, + {0x21115f, 0x5ff}, {0x55, 0x1ff}, {0x1055, 0x1ff}, {0x2055, 0x1ff}, {0x200c5, 0x19}, + {0x1200c5, 0xb}, + {0x2200c5, 0x7}, {0x2002e, 0x2}, + {0x12002e, 0x2}, + {0x22002e, 0x2}, {0x90204, 0x0}, + {0x190204, 0x0}, + {0x290204, 0x0}, {0x20024, 0x1e3}, {0x2003a, 0x2}, {0x2007d, 0x212}, {0x2007c, 0x61}, + {0x120024, 0x1e3}, + {0x2003a, 0x2}, + {0x12007d, 0x212}, + {0x12007c, 0x61}, + {0x220024, 0x1e3}, + {0x2003a, 0x2}, + {0x22007d, 0x212}, + {0x22007c, 0x61}, {0x20056, 0x3}, + {0x120056, 0x3}, + {0x220056, 0x3}, {0x1004d, 0x600}, {0x1014d, 0x600}, {0x1104d, 0x600}, {0x1114d, 0x600}, - {0x10049, 0xe00}, - {0x10149, 0xe00}, - {0x11049, 0xe00}, - {0x11149, 0xe00}, + {0x11004d, 0x600}, + {0x11014d, 0x600}, + {0x11104d, 0x600}, + {0x11114d, 0x600}, + {0x21004d, 0x600}, + {0x21014d, 0x600}, + {0x21104d, 0x600}, + {0x21114d, 0x600}, + {0x10049, 0x604}, + {0x10149, 0x604}, + {0x11049, 0x604}, + {0x11149, 0x604}, + {0x110049, 0x604}, + {0x110149, 0x604}, + {0x111049, 0x604}, + {0x111149, 0x604}, + {0x210049, 0x604}, + {0x210149, 0x604}, + {0x211049, 0x604}, + {0x211149, 0x604}, {0x43, 0x60}, {0x1043, 0x60}, {0x2043, 0x60}, @@ -117,14 +208,30 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x20050, 0x0}, {0x2009b, 0x2}, {0x20008, 0x3a5}, + {0x120008, 0x1d3}, + {0x220008, 0x9c}, {0x20088, 0x9}, - {0x200b2, 0x10c}, + {0x200b2, 0x104}, {0x10043, 0x5a1}, {0x10143, 0x5a1}, {0x11043, 0x5a1}, {0x11143, 0x5a1}, + {0x1200b2, 0x104}, + {0x110043, 0x5a1}, + {0x110143, 0x5a1}, + {0x111043, 0x5a1}, + {0x111143, 0x5a1}, + {0x2200b2, 0x104}, + {0x210043, 0x5a1}, + {0x210143, 0x5a1}, + {0x211043, 0x5a1}, + {0x211143, 0x5a1}, {0x200fa, 0x2}, + {0x1200fa, 0x2}, + {0x2200fa, 0x2}, {0x20019, 0x1}, + {0x120019, 0x1}, + {0x220019, 0x1}, {0x200f0, 0x600}, {0x200f1, 0x0}, {0x200f2, 0x4444}, @@ -133,42 +240,83 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x200f5, 0x0}, {0x200f6, 0x0}, {0x200f7, 0xf000}, + {0x1004a, 0x500}, + {0x1104a, 0x500}, {0x20025, 0x0}, - {0x2002d, 0x1}, + {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x22002d, 0x0}, {0x2002c, 0x0}, {0x20021, 0x0}, {0x200c7, 0x21}, {0x1200c7, 0x21}, {0x200ca, 0x24}, {0x1200ca, 0x24}, - };
-/* ddr phy trained csr */ +/* PHY trained csr */ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x1005f, 0x0}, {0x1015f, 0x0}, {0x1105f, 0x0}, {0x1115f, 0x0}, + {0x11005f, 0x0}, + {0x11015f, 0x0}, + {0x11105f, 0x0}, + {0x11115f, 0x0}, + {0x21005f, 0x0}, + {0x21015f, 0x0}, + {0x21105f, 0x0}, + {0x21115f, 0x0}, {0x55, 0x0}, {0x1055, 0x0}, {0x2055, 0x0}, {0x200c5, 0x0}, + {0x1200c5, 0x0}, + {0x2200c5, 0x0}, {0x2002e, 0x0}, + {0x12002e, 0x0}, + {0x22002e, 0x0}, {0x90204, 0x0}, + {0x190204, 0x0}, + {0x290204, 0x0}, {0x20024, 0x0}, {0x2003a, 0x0}, {0x2007d, 0x0}, {0x2007c, 0x0}, + {0x120024, 0x0}, + {0x12007d, 0x0}, + {0x12007c, 0x0}, + {0x220024, 0x0}, + {0x22007d, 0x0}, + {0x22007c, 0x0}, {0x20056, 0x0}, + {0x120056, 0x0}, + {0x220056, 0x0}, {0x1004d, 0x0}, {0x1014d, 0x0}, {0x1104d, 0x0}, {0x1114d, 0x0}, + {0x11004d, 0x0}, + {0x11014d, 0x0}, + {0x11104d, 0x0}, + {0x11114d, 0x0}, + {0x21004d, 0x0}, + {0x21014d, 0x0}, + {0x21104d, 0x0}, + {0x21114d, 0x0}, {0x10049, 0x0}, {0x10149, 0x0}, {0x11049, 0x0}, {0x11149, 0x0}, + {0x110049, 0x0}, + {0x110149, 0x0}, + {0x111049, 0x0}, + {0x111149, 0x0}, + {0x210049, 0x0}, + {0x210149, 0x0}, + {0x211049, 0x0}, + {0x211149, 0x0}, {0x43, 0x0}, {0x1043, 0x0}, {0x2043, 0x0}, @@ -177,14 +325,30 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x20050, 0x0}, {0x2009b, 0x0}, {0x20008, 0x0}, + {0x120008, 0x0}, + {0x220008, 0x0}, {0x20088, 0x0}, {0x200b2, 0x0}, {0x10043, 0x0}, {0x10143, 0x0}, {0x11043, 0x0}, {0x11143, 0x0}, + {0x1200b2, 0x0}, + {0x110043, 0x0}, + {0x110143, 0x0}, + {0x111043, 0x0}, + {0x111143, 0x0}, + {0x2200b2, 0x0}, + {0x210043, 0x0}, + {0x210143, 0x0}, + {0x211043, 0x0}, + {0x211143, 0x0}, {0x200fa, 0x0}, + {0x1200fa, 0x0}, + {0x2200fa, 0x0}, {0x20019, 0x0}, + {0x120019, 0x0}, + {0x220019, 0x0}, {0x200f0, 0x0}, {0x200f1, 0x0}, {0x200f2, 0x0}, @@ -193,8 +357,12 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x200f5, 0x0}, {0x200f6, 0x0}, {0x200f7, 0x0}, + {0x1004a, 0x0}, + {0x1104a, 0x0}, {0x20025, 0x0}, {0x2002d, 0x0}, + {0x12002d, 0x0}, + {0x22002d, 0x0}, {0x2002c, 0x0}, {0xd0000, 0x0}, {0x90000, 0x0}, @@ -682,6 +850,14 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x2000c, 0x0}, {0x2000d, 0x0}, {0x2000e, 0x0}, + {0x12000b, 0x0}, + {0x12000c, 0x0}, + {0x12000d, 0x0}, + {0x12000e, 0x0}, + {0x22000b, 0x0}, + {0x22000c, 0x0}, + {0x22000d, 0x0}, + {0x22000e, 0x0}, {0x9000c, 0x0}, {0x9000d, 0x0}, {0x9000e, 0x0}, @@ -692,12 +868,26 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x90013, 0x0}, {0x20010, 0x0}, {0x20011, 0x0}, + {0x120010, 0x0}, + {0x120011, 0x0}, {0x40080, 0x0}, {0x40081, 0x0}, {0x40082, 0x0}, {0x40083, 0x0}, {0x40084, 0x0}, {0x40085, 0x0}, + {0x140080, 0x0}, + {0x140081, 0x0}, + {0x140082, 0x0}, + {0x140083, 0x0}, + {0x140084, 0x0}, + {0x140085, 0x0}, + {0x240080, 0x0}, + {0x240081, 0x0}, + {0x240082, 0x0}, + {0x240083, 0x0}, + {0x240084, 0x0}, + {0x240085, 0x0}, {0x400fd, 0x0}, {0x400f1, 0x0}, {0x10011, 0x0}, @@ -866,6 +1056,160 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x90207, 0x0}, {0x90208, 0x0}, {0x20020, 0x0}, + {0x100080, 0x0}, + {0x101080, 0x0}, + {0x102080, 0x0}, + {0x110020, 0x0}, + {0x110080, 0x0}, + {0x110081, 0x0}, + {0x1100d0, 0x0}, + {0x1100d1, 0x0}, + {0x11008c, 0x0}, + {0x11008d, 0x0}, + {0x110180, 0x0}, + {0x110181, 0x0}, + {0x1101d0, 0x0}, + {0x1101d1, 0x0}, + {0x11018c, 0x0}, + {0x11018d, 0x0}, + {0x1100c0, 0x0}, + {0x1100c1, 0x0}, + {0x1101c0, 0x0}, + {0x1101c1, 0x0}, + {0x1102c0, 0x0}, + {0x1102c1, 0x0}, + {0x1103c0, 0x0}, + {0x1103c1, 0x0}, + {0x1104c0, 0x0}, + {0x1104c1, 0x0}, + {0x1105c0, 0x0}, + {0x1105c1, 0x0}, + {0x1106c0, 0x0}, + {0x1106c1, 0x0}, + {0x1107c0, 0x0}, + {0x1107c1, 0x0}, + {0x1108c0, 0x0}, + {0x1108c1, 0x0}, + {0x1100ae, 0x0}, + {0x1100af, 0x0}, + {0x111020, 0x0}, + {0x111080, 0x0}, + {0x111081, 0x0}, + {0x1110d0, 0x0}, + {0x1110d1, 0x0}, + {0x11108c, 0x0}, + {0x11108d, 0x0}, + {0x111180, 0x0}, + {0x111181, 0x0}, + {0x1111d0, 0x0}, + {0x1111d1, 0x0}, + {0x11118c, 0x0}, + {0x11118d, 0x0}, + {0x1110c0, 0x0}, + {0x1110c1, 0x0}, + {0x1111c0, 0x0}, + {0x1111c1, 0x0}, + {0x1112c0, 0x0}, + {0x1112c1, 0x0}, + {0x1113c0, 0x0}, + {0x1113c1, 0x0}, + {0x1114c0, 0x0}, + {0x1114c1, 0x0}, + {0x1115c0, 0x0}, + {0x1115c1, 0x0}, + {0x1116c0, 0x0}, + {0x1116c1, 0x0}, + {0x1117c0, 0x0}, + {0x1117c1, 0x0}, + {0x1118c0, 0x0}, + {0x1118c1, 0x0}, + {0x1110ae, 0x0}, + {0x1110af, 0x0}, + {0x190201, 0x0}, + {0x190202, 0x0}, + {0x190203, 0x0}, + {0x190205, 0x0}, + {0x190206, 0x0}, + {0x190207, 0x0}, + {0x190208, 0x0}, + {0x120020, 0x0}, + {0x200080, 0x0}, + {0x201080, 0x0}, + {0x202080, 0x0}, + {0x210020, 0x0}, + {0x210080, 0x0}, + {0x210081, 0x0}, + {0x2100d0, 0x0}, + {0x2100d1, 0x0}, + {0x21008c, 0x0}, + {0x21008d, 0x0}, + {0x210180, 0x0}, + {0x210181, 0x0}, + {0x2101d0, 0x0}, + {0x2101d1, 0x0}, + {0x21018c, 0x0}, + {0x21018d, 0x0}, + {0x2100c0, 0x0}, + {0x2100c1, 0x0}, + {0x2101c0, 0x0}, + {0x2101c1, 0x0}, + {0x2102c0, 0x0}, + {0x2102c1, 0x0}, + {0x2103c0, 0x0}, + {0x2103c1, 0x0}, + {0x2104c0, 0x0}, + {0x2104c1, 0x0}, + {0x2105c0, 0x0}, + {0x2105c1, 0x0}, + {0x2106c0, 0x0}, + {0x2106c1, 0x0}, + {0x2107c0, 0x0}, + {0x2107c1, 0x0}, + {0x2108c0, 0x0}, + {0x2108c1, 0x0}, + {0x2100ae, 0x0}, + {0x2100af, 0x0}, + {0x211020, 0x0}, + {0x211080, 0x0}, + {0x211081, 0x0}, + {0x2110d0, 0x0}, + {0x2110d1, 0x0}, + {0x21108c, 0x0}, + {0x21108d, 0x0}, + {0x211180, 0x0}, + {0x211181, 0x0}, + {0x2111d0, 0x0}, + {0x2111d1, 0x0}, + {0x21118c, 0x0}, + {0x21118d, 0x0}, + {0x2110c0, 0x0}, + {0x2110c1, 0x0}, + {0x2111c0, 0x0}, + {0x2111c1, 0x0}, + {0x2112c0, 0x0}, + {0x2112c1, 0x0}, + {0x2113c0, 0x0}, + {0x2113c1, 0x0}, + {0x2114c0, 0x0}, + {0x2114c1, 0x0}, + {0x2115c0, 0x0}, + {0x2115c1, 0x0}, + {0x2116c0, 0x0}, + {0x2116c1, 0x0}, + {0x2117c0, 0x0}, + {0x2117c1, 0x0}, + {0x2118c0, 0x0}, + {0x2118c1, 0x0}, + {0x2110ae, 0x0}, + {0x2110af, 0x0}, + {0x290201, 0x0}, + {0x290202, 0x0}, + {0x290203, 0x0}, + {0x290205, 0x0}, + {0x290206, 0x0}, + {0x290207, 0x0}, + {0x290208, 0x0}, + {0x220020, 0x0}, {0x20077, 0x0}, {0x20072, 0x0}, {0x20073, 0x0}, @@ -888,7 +1232,6 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x11640, 0x0}, {0x11740, 0x0}, {0x11840, 0x0}, - };
/* P0 message block parameter for training firmware */ @@ -896,7 +1239,7 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = { {0xd0000, 0x0}, {0x54003, 0xe94}, {0x54004, 0x4}, - {0x54006, 0x15}, + {0x54006, 0x14}, {0x54008, 0x131f}, {0x54009, 0xc8}, {0x5400b, 0x4}, @@ -904,26 +1247,102 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = { {0x5400f, 0x100}, {0x54012, 0x110}, {0x54019, 0x36e4}, - {0x5401a, 0xf2}, - {0x5401b, 0x1146}, - {0x5401c, 0x1108}, + {0x5401a, 0x22}, + {0x5401b, 0x1e44}, + {0x5401c, 0x1208}, {0x5401e, 0x4}, {0x5401f, 0x36e4}, - {0x54020, 0xf2}, - {0x54021, 0x1146}, - {0x54022, 0x1108}, + {0x54020, 0x22}, + {0x54021, 0x1e44}, + {0x54022, 0x1208}, {0x54024, 0x4}, {0x54032, 0xe400}, - {0x54033, 0xf236}, - {0x54034, 0x4600}, - {0x54035, 0x811}, - {0x54036, 0x11}, + {0x54033, 0x2236}, + {0x54034, 0x4400}, + {0x54035, 0x81e}, + {0x54036, 0x12}, {0x54037, 0x400}, {0x54038, 0xe400}, - {0x54039, 0xf236}, - {0x5403a, 0x4600}, - {0x5403b, 0x811}, - {0x5403c, 0x11}, + {0x54039, 0x2236}, + {0x5403a, 0x4400}, + {0x5403b, 0x81e}, + {0x5403c, 0x12}, + {0x5403d, 0x400}, + {0xd0000, 0x1} +}; + +/* P1 message block parameter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x1}, + {0x54003, 0x74a}, + {0x54004, 0x4}, + {0x54006, 0x14}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x4}, + {0x5400d, 0x100}, + {0x5400f, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x1bb4}, + {0x5401a, 0x22}, + {0x5401b, 0x1e44}, + {0x5401c, 0x1208}, + {0x5401e, 0x4}, + {0x5401f, 0x1bb4}, + {0x54020, 0x22}, + {0x54021, 0x1e44}, + {0x54022, 0x1208}, + {0x54024, 0x4}, + {0x54032, 0xb400}, + {0x54033, 0x221b}, + {0x54034, 0x4400}, + {0x54035, 0x81e}, + {0x54036, 0x12}, + {0x54037, 0x400}, + {0x54038, 0xb400}, + {0x54039, 0x221b}, + {0x5403a, 0x4400}, + {0x5403b, 0x81e}, + {0x5403c, 0x12}, + {0x5403d, 0x400}, + {0xd0000, 0x1} +}; + +/* P2 message block parameter for training firmware */ +static struct dram_cfg_param ddr_fsp2_cfg[] = { + {0xd0000, 0x0}, + {0x54002, 0x102}, + {0x54003, 0x270}, + {0x54004, 0x4}, + {0x54006, 0x14}, + {0x54008, 0x121f}, + {0x54009, 0xc8}, + {0x5400b, 0x4}, + {0x5400d, 0x100}, + {0x5400f, 0x100}, + {0x54012, 0x110}, + {0x54019, 0x994}, + {0x5401a, 0x22}, + {0x5401b, 0x1e44}, + {0x5401c, 0x1200}, + {0x5401e, 0x4}, + {0x5401f, 0x994}, + {0x54020, 0x22}, + {0x54021, 0x1e44}, + {0x54022, 0x1200}, + {0x54024, 0x4}, + {0x54032, 0x9400}, + {0x54033, 0x2209}, + {0x54034, 0x4400}, + {0x54035, 0x1e}, + {0x54036, 0x12}, + {0x54037, 0x400}, + {0x54038, 0x9400}, + {0x54039, 0x2209}, + {0x5403a, 0x4400}, + {0x5403b, 0x1e}, + {0x5403c, 0x12}, {0x5403d, 0x400}, {0xd0000, 0x1} }; @@ -933,7 +1352,7 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { {0xd0000, 0x0}, {0x54003, 0xe94}, {0x54004, 0x4}, - {0x54006, 0x15}, + {0x54006, 0x14}, {0x54008, 0x61}, {0x54009, 0xc8}, {0x5400b, 0x4}, @@ -942,26 +1361,26 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { {0x54010, 0x2080}, {0x54012, 0x110}, {0x54019, 0x36e4}, - {0x5401a, 0xf2}, - {0x5401b, 0x1146}, - {0x5401c, 0x1108}, + {0x5401a, 0x22}, + {0x5401b, 0x1e44}, + {0x5401c, 0x1208}, {0x5401e, 0x4}, {0x5401f, 0x36e4}, - {0x54020, 0xf2}, - {0x54021, 0x1146}, - {0x54022, 0x1108}, + {0x54020, 0x22}, + {0x54021, 0x1e44}, + {0x54022, 0x1208}, {0x54024, 0x4}, {0x54032, 0xe400}, - {0x54033, 0xf236}, - {0x54034, 0x4600}, - {0x54035, 0x811}, - {0x54036, 0x11}, + {0x54033, 0x2236}, + {0x54034, 0x4400}, + {0x54035, 0x81e}, + {0x54036, 0x12}, {0x54037, 0x400}, {0x54038, 0xe400}, - {0x54039, 0xf236}, - {0x5403a, 0x4600}, - {0x5403b, 0x811}, - {0x5403c, 0x11}, + {0x54039, 0x2236}, + {0x5403a, 0x4400}, + {0x5403b, 0x81e}, + {0x5403c, 0x12}, {0x5403d, 0x400}, {0xd0000, 0x1} }; @@ -1451,10 +1870,18 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x400d7, 0x20b}, {0x2003a, 0x2}, {0x200be, 0x3}, - {0x2000b, 0x75}, + {0x2000b, 0x41a}, {0x2000c, 0xe9}, {0x2000d, 0x91c}, {0x2000e, 0x2c}, + {0x12000b, 0x20d}, + {0x12000c, 0x74}, + {0x12000d, 0x48e}, + {0x12000e, 0x2c}, + {0x22000b, 0xb0}, + {0x22000c, 0x27}, + {0x22000d, 0x186}, + {0x22000e, 0x10}, {0x9000c, 0x0}, {0x9000d, 0x173}, {0x9000e, 0x60}, @@ -1465,12 +1892,26 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x90013, 0x6152}, {0x20010, 0x5a}, {0x20011, 0x3}, + {0x120010, 0x5a}, + {0x120011, 0x3}, {0x40080, 0xe0}, {0x40081, 0x12}, {0x40082, 0xe0}, {0x40083, 0x12}, {0x40084, 0xe0}, {0x40085, 0x12}, + {0x140080, 0xe0}, + {0x140081, 0x12}, + {0x140082, 0xe0}, + {0x140083, 0x12}, + {0x140084, 0xe0}, + {0x140085, 0x12}, + {0x240080, 0xe0}, + {0x240081, 0x12}, + {0x240082, 0xe0}, + {0x240083, 0x12}, + {0x240084, 0xe0}, + {0x240085, 0x12}, {0x400fd, 0xf}, {0x400f1, 0xe}, {0x10011, 0x1}, @@ -1505,7 +1946,6 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x20088, 0x19}, {0xc0080, 0x0}, {0xd0000, 0x1}, - };
static struct dram_fsp_msg ddr_dram_fsp_msg[] = { @@ -1515,9 +1955,21 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { .fw_type = FW_1D_IMAGE, .fsp_cfg = ddr_fsp0_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg), - }, - + { + /* P1 1866mts 1D */ + .drate = 1866, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp1_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg), + }, + { + /* P2 625mts 1D */ + .drate = 625, + .fw_type = FW_1D_IMAGE, + .fsp_cfg = ddr_fsp2_cfg, + .fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg), + }, { /* P0 3733mts 2D */ .drate = 3733, @@ -1525,7 +1977,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { .fsp_cfg = ddr_fsp0_2d_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), }, - };
/* ddr timing config params */ @@ -1540,7 +1991,227 @@ struct dram_timing_info dram_timing = { .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, }, + .fsp_table = { 3733, 1866, 625, }, .fsp_cfg = ddr_dram_fsp_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_dram_fsp_cfg), }; + +void set_dram_timings_2gb_lpddr4x(void) +{ + /* Initialize DDRC registers */ + dram_timing.ddrc_cfg[1].val = 0x8000ff; + dram_timing.ddrc_cfg[3].val = 0x80000512; + + /* dram fsp cfg */ + dram_timing.fsp_cfg[0].ddrc_cfg[0].val = 0x24AB321B; + dram_timing.fsp_cfg[0].ddrc_cfg[2].val = 0x2F2EE233; + dram_timing.fsp_cfg[0].ddrc_cfg[9].val = 0x015B015B; + dram_timing.fsp_cfg[0].ddrc_cfg[13].val = 0x015B2213; + dram_timing.fsp_cfg[0].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[0].mr_cfg[5].val = 0x13; + + dram_timing.fsp_cfg[1].ddrc_cfg[0].val = 0x12552100; + dram_timing.fsp_cfg[1].ddrc_cfg[2].val = 0x1816B4AA; + dram_timing.fsp_cfg[1].ddrc_cfg[9].val = 0x00AA00AA; + dram_timing.fsp_cfg[1].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[1].mr_cfg[5].val = 0x13; + + dram_timing.fsp_cfg[2].ddrc_cfg[0].val = 0x00061000; + dram_timing.fsp_cfg[2].ddrc_cfg[2].val = 0x6E62FA48; + dram_timing.fsp_cfg[2].ddrc_cfg[9].val = 0x00340034; + dram_timing.fsp_cfg[2].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[2].mr_cfg[5].val = 0x13; + + /* P0 message block parameter for training firmware */ + dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x2044; + dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x1308; + dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x2044; + dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x1308; + dram_timing.fsp_msg[0].fsp_cfg[23].val = 0x820; + dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x13; + dram_timing.fsp_msg[0].fsp_cfg[29].val = 0x820; + dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x13; + + /* P1 message block parameter for training firmware */ + dram_timing.fsp_msg[1].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x1308; + dram_timing.fsp_msg[1].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x1308; + dram_timing.fsp_msg[1].fsp_cfg[24].val = 0x820; + dram_timing.fsp_msg[1].fsp_cfg[25].val = 0x13; + dram_timing.fsp_msg[1].fsp_cfg[30].val = 0x820; + dram_timing.fsp_msg[1].fsp_cfg[31].val = 0x13; + + /* P2 message block parameter for training firmware */ + dram_timing.fsp_msg[2].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x1300; + dram_timing.fsp_msg[2].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x1300; + dram_timing.fsp_msg[2].fsp_cfg[24].val = 0x20; + dram_timing.fsp_msg[2].fsp_cfg[25].val = 0x13; + dram_timing.fsp_msg[2].fsp_cfg[30].val = 0x20; + dram_timing.fsp_msg[2].fsp_cfg[31].val = 0x13; + + /* P0 2D message block parameter for training firmware */ + dram_timing.fsp_msg[3].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x1308; + dram_timing.fsp_msg[3].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x1308; + dram_timing.fsp_msg[3].fsp_cfg[24].val = 0x820; + dram_timing.fsp_msg[3].fsp_cfg[25].val = 0x13; + dram_timing.fsp_msg[3].fsp_cfg[30].val = 0x820; + dram_timing.fsp_msg[3].fsp_cfg[31].val = 0x13; +} + +/* Generated with DDR Tool v3.3.0_7.8-d1cdb7d3 */ +void set_dram_timings_1gb_lpddr4x_900mhz(void) +{ + /* Initialize DDRC registers */ + dram_timing.ddrc_cfg[6].val = 0x4080; + + /* dram fsp cfg */ + dram_timing.fsp_cfg[0].ddrc_cfg[0].val = 0x124F2100; + dram_timing.fsp_cfg[0].ddrc_cfg[1].val = 0xF877000E; + dram_timing.fsp_cfg[0].ddrc_cfg[2].val = 0x181AE4AA; + dram_timing.fsp_cfg[0].ddrc_cfg[3].val = 0x005101E6; + dram_timing.fsp_cfg[0].ddrc_cfg[4].val = 0x0E3C0000; + dram_timing.fsp_cfg[0].ddrc_cfg[5].val = 0x00009101; + dram_timing.fsp_cfg[0].ddrc_cfg[6].val = 0x30900000; + dram_timing.fsp_cfg[0].ddrc_cfg[7].val = 0x8A0A0508; + dram_timing.fsp_cfg[0].ddrc_cfg[8].val = 0x00000014; + dram_timing.fsp_cfg[0].ddrc_cfg[9].val = 0x007B007B; + dram_timing.fsp_cfg[0].ddrc_cfg[12].val = 0x1128110B; + dram_timing.fsp_cfg[0].ddrc_cfg[13].val = 0x007B140A; + dram_timing.fsp_cfg[0].ddrc_cfg[14].val = 0x0620071E; + dram_timing.fsp_cfg[0].mr_cfg[0].val = 0xB4; + dram_timing.fsp_cfg[0].mr_cfg[1].val = 0x1B; + dram_timing.fsp_cfg[0].mr_cfg[2].val = 0xE2; + dram_timing.fsp_cfg[0].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[0].mr_cfg[5].val = 0x15; + + dram_timing.fsp_cfg[1].ddrc_cfg[2].val = 0x181AE4AA; + dram_timing.fsp_cfg[1].mr_cfg[2].val = 0xE2; + dram_timing.fsp_cfg[1].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[1].mr_cfg[5].val = 0x15; + + dram_timing.fsp_cfg[2].ddrc_cfg[2].val = 0x6E660A48; + dram_timing.fsp_cfg[2].mr_cfg[2].val = 0xE2; + dram_timing.fsp_cfg[2].mr_cfg[4].val = 0x20; + dram_timing.fsp_cfg[2].mr_cfg[5].val = 0x15; + + /* PHY Initialize Configuration */ + dram_timing.ddrphy_cfg[31].val = 0xb; + dram_timing.ddrphy_cfg[86].val = 0x1d3; + dram_timing.ddrphy_cfg[90].val = 0x10c; + dram_timing.ddrphy_cfg[95].val = 0x10c; + dram_timing.ddrphy_cfg[100].val = 0x10c; + dram_timing.ddrphy_cfg[122].val = 0x1; + /** + * NOTE: + * In the output from DDR Tool v3.3.0_7.8-d1cdb7d3, array members 119 + * (reg=0x1004a, val=0x500) and 120 (reg=0x1104a, val=0x500) are not + * present in the ddr_ddrphy_cfg array. However they were present in array + * generated with previous DDR Tool v3.1.0_7.4. We simply set both values + * to default value of 0x400 (read with dwc_ddrphy_apb_rd()) here to avoid + * any negative side-effects. + */ + dram_timing.ddrphy_cfg[119].val = 0x400; + dram_timing.ddrphy_cfg[120].val = 0x400; + + /** + * NOTE: + * In the output from DDR Tool v3.3.0_7.8-d1cdb7d3, array members 101 + * (reg=0x1004a, val=0x0) and 120 (reg=0x1104a, val=0x0) are not present + * in the ddr_ddrphy_trained_csr array. However they were present in array + * generated with previous DDR Tool v3.1.0_7.4. We simply set both values + * to default 0x0 (like all other ddrphy_trained_csr values) here to avoid + * any negative side-effects. + */ + /* PHY trained csr */ + dram_timing.ddrphy_trained_csr[101].val = 0x0; + dram_timing.ddrphy_trained_csr[102].val = 0x0; + + /* P0 message block parameter for training firmware */ + dram_timing.fsp_msg[0].fsp_cfg[1].val = 0x74a; + dram_timing.fsp_msg[0].fsp_cfg[3].val = 0x15; + dram_timing.fsp_msg[0].fsp_cfg[10].val = 0x1bb4; + dram_timing.fsp_msg[0].fsp_cfg[11].val = 0xe2; + dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x2044; + dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x1508; + dram_timing.fsp_msg[0].fsp_cfg[15].val = 0x1bb4; + dram_timing.fsp_msg[0].fsp_cfg[16].val = 0xe2; + dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x2044; + dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x1508; + dram_timing.fsp_msg[0].fsp_cfg[20].val = 0xb400; + dram_timing.fsp_msg[0].fsp_cfg[21].val = 0xe21b; + dram_timing.fsp_msg[0].fsp_cfg[23].val = 0x820; + dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x15; + dram_timing.fsp_msg[0].fsp_cfg[26].val = 0xb400; + dram_timing.fsp_msg[0].fsp_cfg[27].val = 0xe21b; + dram_timing.fsp_msg[0].fsp_cfg[29].val = 0x820; + dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x15; + + /* P1 message block parameter for training firmware */ + dram_timing.fsp_msg[1].fsp_cfg[4].val = 0x15; + dram_timing.fsp_msg[1].fsp_cfg[12].val = 0xe2; + dram_timing.fsp_msg[1].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x1508; + dram_timing.fsp_msg[1].fsp_cfg[17].val = 0xe2; + dram_timing.fsp_msg[1].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x1508; + dram_timing.fsp_msg[1].fsp_cfg[22].val = 0xe21b; + dram_timing.fsp_msg[1].fsp_cfg[24].val = 0x820; + dram_timing.fsp_msg[1].fsp_cfg[25].val = 0x15; + dram_timing.fsp_msg[1].fsp_cfg[28].val = 0xe21b; + dram_timing.fsp_msg[1].fsp_cfg[30].val = 0x820; + dram_timing.fsp_msg[1].fsp_cfg[31].val = 0x15; + + /* P2 message block parameter for training firmware */ + dram_timing.fsp_msg[2].fsp_cfg[4].val = 0x15; + dram_timing.fsp_msg[2].fsp_cfg[12].val = 0xe2; + dram_timing.fsp_msg[2].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x1500; + dram_timing.fsp_msg[2].fsp_cfg[17].val = 0xe2; + dram_timing.fsp_msg[2].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x1500; + dram_timing.fsp_msg[2].fsp_cfg[22].val = 0xe209; + dram_timing.fsp_msg[2].fsp_cfg[24].val = 0x20; + dram_timing.fsp_msg[2].fsp_cfg[25].val = 0x15; + dram_timing.fsp_msg[2].fsp_cfg[28].val = 0xe209; + dram_timing.fsp_msg[2].fsp_cfg[30].val = 0x20; + dram_timing.fsp_msg[2].fsp_cfg[31].val = 0x15; + + /* P0 2D message block parameter for training firmware */ + dram_timing.fsp_msg[3].fsp_cfg[1].val = 0x74a; + dram_timing.fsp_msg[3].fsp_cfg[3].val = 0x15; + dram_timing.fsp_msg[3].fsp_cfg[11].val = 0x1bb4; + dram_timing.fsp_msg[3].fsp_cfg[12].val = 0xe2; + dram_timing.fsp_msg[3].fsp_cfg[13].val = 0x2044; + dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x1508; + dram_timing.fsp_msg[3].fsp_cfg[16].val = 0x1bb4; + dram_timing.fsp_msg[3].fsp_cfg[17].val = 0xe2; + dram_timing.fsp_msg[3].fsp_cfg[18].val = 0x2044; + dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x1508; + dram_timing.fsp_msg[3].fsp_cfg[21].val = 0xb400; + dram_timing.fsp_msg[3].fsp_cfg[22].val = 0xe21b; + dram_timing.fsp_msg[3].fsp_cfg[24].val = 0x820; + dram_timing.fsp_msg[3].fsp_cfg[25].val = 0x15; + dram_timing.fsp_msg[3].fsp_cfg[27].val = 0xb400; + dram_timing.fsp_msg[3].fsp_cfg[28].val = 0xe21b; + dram_timing.fsp_msg[3].fsp_cfg[30].val = 0x820; + dram_timing.fsp_msg[3].fsp_cfg[31].val = 0x15; + + /* DRAM PHY init engine image */ + dram_timing.ddrphy_pie[483].val = 0x20d; + dram_timing.ddrphy_pie[484].val = 0x74; + dram_timing.ddrphy_pie[485].val = 0x48e; + + /* P0 3733mts 1D */ + dram_timing.fsp_msg[0].drate = 1866; + + /* P0 1866mts 2D */ + dram_timing.fsp_msg[3].drate = 1866; + + /* ddr timing config params */ + dram_timing.fsp_table[0] = 1866; +}

Tested on phyBOARD-Nash-i.MX93 with phyCORE-i.MX93 2GiB SOM
Link: https://gist.github.com/pfiser/d5766c95f5639e6a9852c94412f39eb5
Tested-by: Primoz Fiser primoz.fiser@norik.com
On 19. 11. 24 17:29, Christoph Stoidner wrote:
The phyCORE-i.MX 93 is available with a 1GB ram chip or a 2GB ram chip. Add the ram timings for the 2GB chip, in form of a diff compared to the existing LPDDR4X 1GB timings. With that, the SPL can select the appropriate timings at startup. Update also the 1GB ram timings with new version of the DDR Tool.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de
Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de
No changes in v3
Changes in v2:
- remove multiple blank lines
- add update of 1GB ram timings to commit message
board/phytec/phycore_imx93/lpddr4_timing.c | 793 +++++++++++++++++++-- 1 file changed, 732 insertions(+), 61 deletions(-)
diff --git a/board/phytec/phycore_imx93/lpddr4_timing.c b/board/phytec/phycore_imx93/lpddr4_timing.c index 2111972a40..f1261f6a92 100644 --- a/board/phytec/phycore_imx93/lpddr4_timing.c +++ b/board/phytec/phycore_imx93/lpddr4_timing.c @@ -1,24 +1,24 @@ // SPDX-License-Identifier: GPL-2.0+ /*
- Copyright 2023 NXP
- Copyright (C) 2023 PHYTEC Messtechnik GmbH
- Copyright 2024 NXP
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Christoph Stoidner c.stoidner@phytec.de
- Code generated with DDR Tool v1.0.0.
*/
- Code generated with DDR Tool v3.1.0_7.4.
#include <linux/kernel.h> #include <asm/arch/ddr.h>
+/* Initialize DDRC registers */ static struct dram_cfg_param ddr_ddrc_cfg[] = {
- /** Initialize DDRC registers **/ {0x4e300110, 0x44100001}, {0x4e300000, 0x8000bf}, {0x4e300008, 0x0}, {0x4e300080, 0x80000412}, {0x4e300084, 0x0}, {0x4e300114, 0x1002},
- {0x4e300260, 0x4080},
- {0x4e300260, 0x80}, {0x4e300f04, 0x80}, {0x4e300800, 0x43b30002}, {0x4e300804, 0x1f1f1f1f},
@@ -31,18 +31,17 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = { {0x4e301254, 0x0}, {0x4e301258, 0x0}, {0x4e30125c, 0x0},
};
/* dram fsp cfg */ static struct dram_fsp_cfg ddr_dram_fsp_cfg[] = { { {
{0x4e300100, 0x24A0421B},
{0x4e300100, 0x24A0321B}, {0x4e300104, 0xF8EE001B},
{0x4e300108, 0x2F263233},
{0x4e30010C, 0x0005E18B},
{0x4e300124, 0x1C770000},
{0x4e300108, 0x2F2E3233},
{0x4e30010C, 0x0005C18B},
{0x4e300124, 0x1C790000}, {0x4e300160, 0x00009102}, {0x4e30016C, 0x35F00000}, {0x4e300170, 0x8B0B0608},
@@ -50,21 +49,73 @@ static struct dram_fsp_cfg ddr_dram_fsp_cfg[] = { {0x4e300254, 0x00FE00FE}, {0x4e300258, 0x00000008}, {0x4e30025C, 0x00000400},
{0x4e300300, 0x224F2215},
{0x4e300300, 0x224F2213}, {0x4e300304, 0x00FE2213},
{0x4e300308, 0x0A3C0E3C},
}, { {0x01, 0xE4}, {0x02, 0x36},{0x4e300308, 0x0A380E3D},
{0x03, 0xF2},
{0x0b, 0x46},
{0x0c, 0x11},
{0x0e, 0x11},
{0x03, 0x22},
{0x0b, 0x44},
{0x0c, 0x1E},
{0x0e, 0x12},
{0x16, 0x04},
},
0,
- },
- {
{
{0x4e300100, 0x124F2100},
{0x4e300104, 0xF877000E},
{0x4e300108, 0x1816E4AA},
{0x4e30010C, 0x005101E6},
{0x4e300124, 0x0E3C0000},
{0x4e300160, 0x00009101},
{0x4e30016C, 0x30900000},
{0x4e300170, 0x8A0A0508},
{0x4e300250, 0x00000014},
{0x4e300254, 0x007B007B},
{0x4e300258, 0x00000008},
{0x4e30025C, 0x00000400},
},
{
{0x01, 0xB4},
{0x02, 0x1B},
{0x03, 0x22},
{0x0b, 0x44},
{0x0c, 0x1E},
}, 0, },{0x0e, 0x12}, {0x16, 0x04},
- {
{
{0x4e300100, 0x00051000},
{0x4e300104, 0xF855000A},
{0x4e300108, 0x6E620A48},
{0x4e30010C, 0x0031010D},
{0x4e300124, 0x04C50000},
{0x4e300160, 0x00009100},
{0x4e30016C, 0x30000000},
{0x4e300170, 0x89090408},
{0x4e300250, 0x00000007},
{0x4e300254, 0x00240024},
{0x4e300258, 0x00000008},
{0x4e30025C, 0x00000400},
},
{
{0x01, 0x94},
{0x02, 0x9},
{0x03, 0x22},
{0x0b, 0x44},
{0x0c, 0x1E},
{0x0e, 0x12},
{0x16, 0x04},
},
1,
- },
};
@@ -90,25 +141,65 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x1015f, 0x5ff}, {0x1105f, 0x5ff}, {0x1115f, 0x5ff},
- {0x11005f, 0x5ff},
- {0x11015f, 0x5ff},
- {0x11105f, 0x5ff},
- {0x11115f, 0x5ff},
- {0x21005f, 0x5ff},
- {0x21015f, 0x5ff},
- {0x21105f, 0x5ff},
- {0x21115f, 0x5ff}, {0x55, 0x1ff}, {0x1055, 0x1ff}, {0x2055, 0x1ff}, {0x200c5, 0x19},
- {0x1200c5, 0xb},
- {0x2200c5, 0x7}, {0x2002e, 0x2},
- {0x12002e, 0x2},
- {0x22002e, 0x2}, {0x90204, 0x0},
- {0x190204, 0x0},
- {0x290204, 0x0}, {0x20024, 0x1e3}, {0x2003a, 0x2}, {0x2007d, 0x212}, {0x2007c, 0x61},
- {0x120024, 0x1e3},
- {0x2003a, 0x2},
- {0x12007d, 0x212},
- {0x12007c, 0x61},
- {0x220024, 0x1e3},
- {0x2003a, 0x2},
- {0x22007d, 0x212},
- {0x22007c, 0x61}, {0x20056, 0x3},
- {0x120056, 0x3},
- {0x220056, 0x3}, {0x1004d, 0x600}, {0x1014d, 0x600}, {0x1104d, 0x600}, {0x1114d, 0x600},
- {0x10049, 0xe00},
- {0x10149, 0xe00},
- {0x11049, 0xe00},
- {0x11149, 0xe00},
- {0x11004d, 0x600},
- {0x11014d, 0x600},
- {0x11104d, 0x600},
- {0x11114d, 0x600},
- {0x21004d, 0x600},
- {0x21014d, 0x600},
- {0x21104d, 0x600},
- {0x21114d, 0x600},
- {0x10049, 0x604},
- {0x10149, 0x604},
- {0x11049, 0x604},
- {0x11149, 0x604},
- {0x110049, 0x604},
- {0x110149, 0x604},
- {0x111049, 0x604},
- {0x111149, 0x604},
- {0x210049, 0x604},
- {0x210149, 0x604},
- {0x211049, 0x604},
- {0x211149, 0x604}, {0x43, 0x60}, {0x1043, 0x60}, {0x2043, 0x60},
@@ -117,14 +208,30 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x20050, 0x0}, {0x2009b, 0x2}, {0x20008, 0x3a5},
- {0x120008, 0x1d3},
- {0x220008, 0x9c}, {0x20088, 0x9},
- {0x200b2, 0x10c},
- {0x200b2, 0x104}, {0x10043, 0x5a1}, {0x10143, 0x5a1}, {0x11043, 0x5a1}, {0x11143, 0x5a1},
- {0x1200b2, 0x104},
- {0x110043, 0x5a1},
- {0x110143, 0x5a1},
- {0x111043, 0x5a1},
- {0x111143, 0x5a1},
- {0x2200b2, 0x104},
- {0x210043, 0x5a1},
- {0x210143, 0x5a1},
- {0x211043, 0x5a1},
- {0x211143, 0x5a1}, {0x200fa, 0x2},
- {0x1200fa, 0x2},
- {0x2200fa, 0x2}, {0x20019, 0x1},
- {0x120019, 0x1},
- {0x220019, 0x1}, {0x200f0, 0x600}, {0x200f1, 0x0}, {0x200f2, 0x4444},
@@ -133,42 +240,83 @@ static struct dram_cfg_param ddr_ddrphy_cfg[] = { {0x200f5, 0x0}, {0x200f6, 0x0}, {0x200f7, 0xf000},
- {0x1004a, 0x500},
- {0x1104a, 0x500}, {0x20025, 0x0},
- {0x2002d, 0x1},
- {0x2002d, 0x0},
- {0x12002d, 0x0},
- {0x22002d, 0x0}, {0x2002c, 0x0}, {0x20021, 0x0}, {0x200c7, 0x21}, {0x1200c7, 0x21}, {0x200ca, 0x24}, {0x1200ca, 0x24},
};
-/* ddr phy trained csr */ +/* PHY trained csr */ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x1005f, 0x0}, {0x1015f, 0x0}, {0x1105f, 0x0}, {0x1115f, 0x0},
- {0x11005f, 0x0},
- {0x11015f, 0x0},
- {0x11105f, 0x0},
- {0x11115f, 0x0},
- {0x21005f, 0x0},
- {0x21015f, 0x0},
- {0x21105f, 0x0},
- {0x21115f, 0x0}, {0x55, 0x0}, {0x1055, 0x0}, {0x2055, 0x0}, {0x200c5, 0x0},
- {0x1200c5, 0x0},
- {0x2200c5, 0x0}, {0x2002e, 0x0},
- {0x12002e, 0x0},
- {0x22002e, 0x0}, {0x90204, 0x0},
- {0x190204, 0x0},
- {0x290204, 0x0}, {0x20024, 0x0}, {0x2003a, 0x0}, {0x2007d, 0x0}, {0x2007c, 0x0},
- {0x120024, 0x0},
- {0x12007d, 0x0},
- {0x12007c, 0x0},
- {0x220024, 0x0},
- {0x22007d, 0x0},
- {0x22007c, 0x0}, {0x20056, 0x0},
- {0x120056, 0x0},
- {0x220056, 0x0}, {0x1004d, 0x0}, {0x1014d, 0x0}, {0x1104d, 0x0}, {0x1114d, 0x0},
- {0x11004d, 0x0},
- {0x11014d, 0x0},
- {0x11104d, 0x0},
- {0x11114d, 0x0},
- {0x21004d, 0x0},
- {0x21014d, 0x0},
- {0x21104d, 0x0},
- {0x21114d, 0x0}, {0x10049, 0x0}, {0x10149, 0x0}, {0x11049, 0x0}, {0x11149, 0x0},
- {0x110049, 0x0},
- {0x110149, 0x0},
- {0x111049, 0x0},
- {0x111149, 0x0},
- {0x210049, 0x0},
- {0x210149, 0x0},
- {0x211049, 0x0},
- {0x211149, 0x0}, {0x43, 0x0}, {0x1043, 0x0}, {0x2043, 0x0},
@@ -177,14 +325,30 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x20050, 0x0}, {0x2009b, 0x0}, {0x20008, 0x0},
- {0x120008, 0x0},
- {0x220008, 0x0}, {0x20088, 0x0}, {0x200b2, 0x0}, {0x10043, 0x0}, {0x10143, 0x0}, {0x11043, 0x0}, {0x11143, 0x0},
- {0x1200b2, 0x0},
- {0x110043, 0x0},
- {0x110143, 0x0},
- {0x111043, 0x0},
- {0x111143, 0x0},
- {0x2200b2, 0x0},
- {0x210043, 0x0},
- {0x210143, 0x0},
- {0x211043, 0x0},
- {0x211143, 0x0}, {0x200fa, 0x0},
- {0x1200fa, 0x0},
- {0x2200fa, 0x0}, {0x20019, 0x0},
- {0x120019, 0x0},
- {0x220019, 0x0}, {0x200f0, 0x0}, {0x200f1, 0x0}, {0x200f2, 0x0},
@@ -193,8 +357,12 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x200f5, 0x0}, {0x200f6, 0x0}, {0x200f7, 0x0},
- {0x1004a, 0x0},
- {0x1104a, 0x0}, {0x20025, 0x0}, {0x2002d, 0x0},
- {0x12002d, 0x0},
- {0x22002d, 0x0}, {0x2002c, 0x0}, {0xd0000, 0x0}, {0x90000, 0x0},
@@ -682,6 +850,14 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x2000c, 0x0}, {0x2000d, 0x0}, {0x2000e, 0x0},
- {0x12000b, 0x0},
- {0x12000c, 0x0},
- {0x12000d, 0x0},
- {0x12000e, 0x0},
- {0x22000b, 0x0},
- {0x22000c, 0x0},
- {0x22000d, 0x0},
- {0x22000e, 0x0}, {0x9000c, 0x0}, {0x9000d, 0x0}, {0x9000e, 0x0},
@@ -692,12 +868,26 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x90013, 0x0}, {0x20010, 0x0}, {0x20011, 0x0},
- {0x120010, 0x0},
- {0x120011, 0x0}, {0x40080, 0x0}, {0x40081, 0x0}, {0x40082, 0x0}, {0x40083, 0x0}, {0x40084, 0x0}, {0x40085, 0x0},
- {0x140080, 0x0},
- {0x140081, 0x0},
- {0x140082, 0x0},
- {0x140083, 0x0},
- {0x140084, 0x0},
- {0x140085, 0x0},
- {0x240080, 0x0},
- {0x240081, 0x0},
- {0x240082, 0x0},
- {0x240083, 0x0},
- {0x240084, 0x0},
- {0x240085, 0x0}, {0x400fd, 0x0}, {0x400f1, 0x0}, {0x10011, 0x0},
@@ -866,6 +1056,160 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x90207, 0x0}, {0x90208, 0x0}, {0x20020, 0x0},
- {0x100080, 0x0},
- {0x101080, 0x0},
- {0x102080, 0x0},
- {0x110020, 0x0},
- {0x110080, 0x0},
- {0x110081, 0x0},
- {0x1100d0, 0x0},
- {0x1100d1, 0x0},
- {0x11008c, 0x0},
- {0x11008d, 0x0},
- {0x110180, 0x0},
- {0x110181, 0x0},
- {0x1101d0, 0x0},
- {0x1101d1, 0x0},
- {0x11018c, 0x0},
- {0x11018d, 0x0},
- {0x1100c0, 0x0},
- {0x1100c1, 0x0},
- {0x1101c0, 0x0},
- {0x1101c1, 0x0},
- {0x1102c0, 0x0},
- {0x1102c1, 0x0},
- {0x1103c0, 0x0},
- {0x1103c1, 0x0},
- {0x1104c0, 0x0},
- {0x1104c1, 0x0},
- {0x1105c0, 0x0},
- {0x1105c1, 0x0},
- {0x1106c0, 0x0},
- {0x1106c1, 0x0},
- {0x1107c0, 0x0},
- {0x1107c1, 0x0},
- {0x1108c0, 0x0},
- {0x1108c1, 0x0},
- {0x1100ae, 0x0},
- {0x1100af, 0x0},
- {0x111020, 0x0},
- {0x111080, 0x0},
- {0x111081, 0x0},
- {0x1110d0, 0x0},
- {0x1110d1, 0x0},
- {0x11108c, 0x0},
- {0x11108d, 0x0},
- {0x111180, 0x0},
- {0x111181, 0x0},
- {0x1111d0, 0x0},
- {0x1111d1, 0x0},
- {0x11118c, 0x0},
- {0x11118d, 0x0},
- {0x1110c0, 0x0},
- {0x1110c1, 0x0},
- {0x1111c0, 0x0},
- {0x1111c1, 0x0},
- {0x1112c0, 0x0},
- {0x1112c1, 0x0},
- {0x1113c0, 0x0},
- {0x1113c1, 0x0},
- {0x1114c0, 0x0},
- {0x1114c1, 0x0},
- {0x1115c0, 0x0},
- {0x1115c1, 0x0},
- {0x1116c0, 0x0},
- {0x1116c1, 0x0},
- {0x1117c0, 0x0},
- {0x1117c1, 0x0},
- {0x1118c0, 0x0},
- {0x1118c1, 0x0},
- {0x1110ae, 0x0},
- {0x1110af, 0x0},
- {0x190201, 0x0},
- {0x190202, 0x0},
- {0x190203, 0x0},
- {0x190205, 0x0},
- {0x190206, 0x0},
- {0x190207, 0x0},
- {0x190208, 0x0},
- {0x120020, 0x0},
- {0x200080, 0x0},
- {0x201080, 0x0},
- {0x202080, 0x0},
- {0x210020, 0x0},
- {0x210080, 0x0},
- {0x210081, 0x0},
- {0x2100d0, 0x0},
- {0x2100d1, 0x0},
- {0x21008c, 0x0},
- {0x21008d, 0x0},
- {0x210180, 0x0},
- {0x210181, 0x0},
- {0x2101d0, 0x0},
- {0x2101d1, 0x0},
- {0x21018c, 0x0},
- {0x21018d, 0x0},
- {0x2100c0, 0x0},
- {0x2100c1, 0x0},
- {0x2101c0, 0x0},
- {0x2101c1, 0x0},
- {0x2102c0, 0x0},
- {0x2102c1, 0x0},
- {0x2103c0, 0x0},
- {0x2103c1, 0x0},
- {0x2104c0, 0x0},
- {0x2104c1, 0x0},
- {0x2105c0, 0x0},
- {0x2105c1, 0x0},
- {0x2106c0, 0x0},
- {0x2106c1, 0x0},
- {0x2107c0, 0x0},
- {0x2107c1, 0x0},
- {0x2108c0, 0x0},
- {0x2108c1, 0x0},
- {0x2100ae, 0x0},
- {0x2100af, 0x0},
- {0x211020, 0x0},
- {0x211080, 0x0},
- {0x211081, 0x0},
- {0x2110d0, 0x0},
- {0x2110d1, 0x0},
- {0x21108c, 0x0},
- {0x21108d, 0x0},
- {0x211180, 0x0},
- {0x211181, 0x0},
- {0x2111d0, 0x0},
- {0x2111d1, 0x0},
- {0x21118c, 0x0},
- {0x21118d, 0x0},
- {0x2110c0, 0x0},
- {0x2110c1, 0x0},
- {0x2111c0, 0x0},
- {0x2111c1, 0x0},
- {0x2112c0, 0x0},
- {0x2112c1, 0x0},
- {0x2113c0, 0x0},
- {0x2113c1, 0x0},
- {0x2114c0, 0x0},
- {0x2114c1, 0x0},
- {0x2115c0, 0x0},
- {0x2115c1, 0x0},
- {0x2116c0, 0x0},
- {0x2116c1, 0x0},
- {0x2117c0, 0x0},
- {0x2117c1, 0x0},
- {0x2118c0, 0x0},
- {0x2118c1, 0x0},
- {0x2110ae, 0x0},
- {0x2110af, 0x0},
- {0x290201, 0x0},
- {0x290202, 0x0},
- {0x290203, 0x0},
- {0x290205, 0x0},
- {0x290206, 0x0},
- {0x290207, 0x0},
- {0x290208, 0x0},
- {0x220020, 0x0}, {0x20077, 0x0}, {0x20072, 0x0}, {0x20073, 0x0},
@@ -888,7 +1232,6 @@ static struct dram_cfg_param ddr_ddrphy_trained_csr[] = { {0x11640, 0x0}, {0x11740, 0x0}, {0x11840, 0x0},
};
/* P0 message block parameter for training firmware */ @@ -896,7 +1239,7 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = { {0xd0000, 0x0}, {0x54003, 0xe94}, {0x54004, 0x4},
- {0x54006, 0x15},
- {0x54006, 0x14}, {0x54008, 0x131f}, {0x54009, 0xc8}, {0x5400b, 0x4},
@@ -904,26 +1247,102 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = { {0x5400f, 0x100}, {0x54012, 0x110}, {0x54019, 0x36e4},
- {0x5401a, 0xf2},
- {0x5401b, 0x1146},
- {0x5401c, 0x1108},
- {0x5401a, 0x22},
- {0x5401b, 0x1e44},
- {0x5401c, 0x1208}, {0x5401e, 0x4}, {0x5401f, 0x36e4},
- {0x54020, 0xf2},
- {0x54021, 0x1146},
- {0x54022, 0x1108},
- {0x54020, 0x22},
- {0x54021, 0x1e44},
- {0x54022, 0x1208}, {0x54024, 0x4}, {0x54032, 0xe400},
- {0x54033, 0xf236},
- {0x54034, 0x4600},
- {0x54035, 0x811},
- {0x54036, 0x11},
- {0x54033, 0x2236},
- {0x54034, 0x4400},
- {0x54035, 0x81e},
- {0x54036, 0x12}, {0x54037, 0x400}, {0x54038, 0xe400},
- {0x54039, 0xf236},
- {0x5403a, 0x4600},
- {0x5403b, 0x811},
- {0x5403c, 0x11},
- {0x54039, 0x2236},
- {0x5403a, 0x4400},
- {0x5403b, 0x81e},
- {0x5403c, 0x12},
- {0x5403d, 0x400},
- {0xd0000, 0x1}
+};
+/* P1 message block parameter for training firmware */ +static struct dram_cfg_param ddr_fsp1_cfg[] = {
- {0xd0000, 0x0},
- {0x54002, 0x1},
- {0x54003, 0x74a},
- {0x54004, 0x4},
- {0x54006, 0x14},
- {0x54008, 0x121f},
- {0x54009, 0xc8},
- {0x5400b, 0x4},
- {0x5400d, 0x100},
- {0x5400f, 0x100},
- {0x54012, 0x110},
- {0x54019, 0x1bb4},
- {0x5401a, 0x22},
- {0x5401b, 0x1e44},
- {0x5401c, 0x1208},
- {0x5401e, 0x4},
- {0x5401f, 0x1bb4},
- {0x54020, 0x22},
- {0x54021, 0x1e44},
- {0x54022, 0x1208},
- {0x54024, 0x4},
- {0x54032, 0xb400},
- {0x54033, 0x221b},
- {0x54034, 0x4400},
- {0x54035, 0x81e},
- {0x54036, 0x12},
- {0x54037, 0x400},
- {0x54038, 0xb400},
- {0x54039, 0x221b},
- {0x5403a, 0x4400},
- {0x5403b, 0x81e},
- {0x5403c, 0x12},
- {0x5403d, 0x400},
- {0xd0000, 0x1}
+};
+/* P2 message block parameter for training firmware */ +static struct dram_cfg_param ddr_fsp2_cfg[] = {
- {0xd0000, 0x0},
- {0x54002, 0x102},
- {0x54003, 0x270},
- {0x54004, 0x4},
- {0x54006, 0x14},
- {0x54008, 0x121f},
- {0x54009, 0xc8},
- {0x5400b, 0x4},
- {0x5400d, 0x100},
- {0x5400f, 0x100},
- {0x54012, 0x110},
- {0x54019, 0x994},
- {0x5401a, 0x22},
- {0x5401b, 0x1e44},
- {0x5401c, 0x1200},
- {0x5401e, 0x4},
- {0x5401f, 0x994},
- {0x54020, 0x22},
- {0x54021, 0x1e44},
- {0x54022, 0x1200},
- {0x54024, 0x4},
- {0x54032, 0x9400},
- {0x54033, 0x2209},
- {0x54034, 0x4400},
- {0x54035, 0x1e},
- {0x54036, 0x12},
- {0x54037, 0x400},
- {0x54038, 0x9400},
- {0x54039, 0x2209},
- {0x5403a, 0x4400},
- {0x5403b, 0x1e},
- {0x5403c, 0x12}, {0x5403d, 0x400}, {0xd0000, 0x1}
}; @@ -933,7 +1352,7 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { {0xd0000, 0x0}, {0x54003, 0xe94}, {0x54004, 0x4},
- {0x54006, 0x15},
- {0x54006, 0x14}, {0x54008, 0x61}, {0x54009, 0xc8}, {0x5400b, 0x4},
@@ -942,26 +1361,26 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = { {0x54010, 0x2080}, {0x54012, 0x110}, {0x54019, 0x36e4},
- {0x5401a, 0xf2},
- {0x5401b, 0x1146},
- {0x5401c, 0x1108},
- {0x5401a, 0x22},
- {0x5401b, 0x1e44},
- {0x5401c, 0x1208}, {0x5401e, 0x4}, {0x5401f, 0x36e4},
- {0x54020, 0xf2},
- {0x54021, 0x1146},
- {0x54022, 0x1108},
- {0x54020, 0x22},
- {0x54021, 0x1e44},
- {0x54022, 0x1208}, {0x54024, 0x4}, {0x54032, 0xe400},
- {0x54033, 0xf236},
- {0x54034, 0x4600},
- {0x54035, 0x811},
- {0x54036, 0x11},
- {0x54033, 0x2236},
- {0x54034, 0x4400},
- {0x54035, 0x81e},
- {0x54036, 0x12}, {0x54037, 0x400}, {0x54038, 0xe400},
- {0x54039, 0xf236},
- {0x5403a, 0x4600},
- {0x5403b, 0x811},
- {0x5403c, 0x11},
- {0x54039, 0x2236},
- {0x5403a, 0x4400},
- {0x5403b, 0x81e},
- {0x5403c, 0x12}, {0x5403d, 0x400}, {0xd0000, 0x1}
}; @@ -1451,10 +1870,18 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x400d7, 0x20b}, {0x2003a, 0x2}, {0x200be, 0x3},
- {0x2000b, 0x75},
- {0x2000b, 0x41a}, {0x2000c, 0xe9}, {0x2000d, 0x91c}, {0x2000e, 0x2c},
- {0x12000b, 0x20d},
- {0x12000c, 0x74},
- {0x12000d, 0x48e},
- {0x12000e, 0x2c},
- {0x22000b, 0xb0},
- {0x22000c, 0x27},
- {0x22000d, 0x186},
- {0x22000e, 0x10}, {0x9000c, 0x0}, {0x9000d, 0x173}, {0x9000e, 0x60},
@@ -1465,12 +1892,26 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x90013, 0x6152}, {0x20010, 0x5a}, {0x20011, 0x3},
- {0x120010, 0x5a},
- {0x120011, 0x3}, {0x40080, 0xe0}, {0x40081, 0x12}, {0x40082, 0xe0}, {0x40083, 0x12}, {0x40084, 0xe0}, {0x40085, 0x12},
- {0x140080, 0xe0},
- {0x140081, 0x12},
- {0x140082, 0xe0},
- {0x140083, 0x12},
- {0x140084, 0xe0},
- {0x140085, 0x12},
- {0x240080, 0xe0},
- {0x240081, 0x12},
- {0x240082, 0xe0},
- {0x240083, 0x12},
- {0x240084, 0xe0},
- {0x240085, 0x12}, {0x400fd, 0xf}, {0x400f1, 0xe}, {0x10011, 0x1},
@@ -1505,7 +1946,6 @@ static struct dram_cfg_param ddr_phy_pie[] = { {0x20088, 0x19}, {0xc0080, 0x0}, {0xd0000, 0x1},
};
static struct dram_fsp_msg ddr_dram_fsp_msg[] = { @@ -1515,9 +1955,21 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { .fw_type = FW_1D_IMAGE, .fsp_cfg = ddr_fsp0_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg),
- },
- {
/* P1 1866mts 1D */
.drate = 1866,
.fw_type = FW_1D_IMAGE,
.fsp_cfg = ddr_fsp1_cfg,
.fsp_cfg_num = ARRAY_SIZE(ddr_fsp1_cfg),
- },
- {
/* P2 625mts 1D */
.drate = 625,
.fw_type = FW_1D_IMAGE,
.fsp_cfg = ddr_fsp2_cfg,
.fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg),
- }, { /* P0 3733mts 2D */ .drate = 3733,
@@ -1525,7 +1977,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = { .fsp_cfg = ddr_fsp0_2d_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg), },
};
/* ddr timing config params */ @@ -1540,7 +1991,227 @@ struct dram_timing_info dram_timing = { .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, },
- .fsp_table = { 3733, 1866, 625, }, .fsp_cfg = ddr_dram_fsp_cfg, .fsp_cfg_num = ARRAY_SIZE(ddr_dram_fsp_cfg),
};
+void set_dram_timings_2gb_lpddr4x(void) +{
- /* Initialize DDRC registers */
- dram_timing.ddrc_cfg[1].val = 0x8000ff;
- dram_timing.ddrc_cfg[3].val = 0x80000512;
- /* dram fsp cfg */
- dram_timing.fsp_cfg[0].ddrc_cfg[0].val = 0x24AB321B;
- dram_timing.fsp_cfg[0].ddrc_cfg[2].val = 0x2F2EE233;
- dram_timing.fsp_cfg[0].ddrc_cfg[9].val = 0x015B015B;
- dram_timing.fsp_cfg[0].ddrc_cfg[13].val = 0x015B2213;
- dram_timing.fsp_cfg[0].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[0].mr_cfg[5].val = 0x13;
- dram_timing.fsp_cfg[1].ddrc_cfg[0].val = 0x12552100;
- dram_timing.fsp_cfg[1].ddrc_cfg[2].val = 0x1816B4AA;
- dram_timing.fsp_cfg[1].ddrc_cfg[9].val = 0x00AA00AA;
- dram_timing.fsp_cfg[1].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[1].mr_cfg[5].val = 0x13;
- dram_timing.fsp_cfg[2].ddrc_cfg[0].val = 0x00061000;
- dram_timing.fsp_cfg[2].ddrc_cfg[2].val = 0x6E62FA48;
- dram_timing.fsp_cfg[2].ddrc_cfg[9].val = 0x00340034;
- dram_timing.fsp_cfg[2].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[2].mr_cfg[5].val = 0x13;
- /* P0 message block parameter for training firmware */
- dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x2044;
- dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x1308;
- dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x2044;
- dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x1308;
- dram_timing.fsp_msg[0].fsp_cfg[23].val = 0x820;
- dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x13;
- dram_timing.fsp_msg[0].fsp_cfg[29].val = 0x820;
- dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x13;
- /* P1 message block parameter for training firmware */
- dram_timing.fsp_msg[1].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x1308;
- dram_timing.fsp_msg[1].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x1308;
- dram_timing.fsp_msg[1].fsp_cfg[24].val = 0x820;
- dram_timing.fsp_msg[1].fsp_cfg[25].val = 0x13;
- dram_timing.fsp_msg[1].fsp_cfg[30].val = 0x820;
- dram_timing.fsp_msg[1].fsp_cfg[31].val = 0x13;
- /* P2 message block parameter for training firmware */
- dram_timing.fsp_msg[2].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x1300;
- dram_timing.fsp_msg[2].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x1300;
- dram_timing.fsp_msg[2].fsp_cfg[24].val = 0x20;
- dram_timing.fsp_msg[2].fsp_cfg[25].val = 0x13;
- dram_timing.fsp_msg[2].fsp_cfg[30].val = 0x20;
- dram_timing.fsp_msg[2].fsp_cfg[31].val = 0x13;
- /* P0 2D message block parameter for training firmware */
- dram_timing.fsp_msg[3].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x1308;
- dram_timing.fsp_msg[3].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x1308;
- dram_timing.fsp_msg[3].fsp_cfg[24].val = 0x820;
- dram_timing.fsp_msg[3].fsp_cfg[25].val = 0x13;
- dram_timing.fsp_msg[3].fsp_cfg[30].val = 0x820;
- dram_timing.fsp_msg[3].fsp_cfg[31].val = 0x13;
+}
+/* Generated with DDR Tool v3.3.0_7.8-d1cdb7d3 */ +void set_dram_timings_1gb_lpddr4x_900mhz(void) +{
- /* Initialize DDRC registers */
- dram_timing.ddrc_cfg[6].val = 0x4080;
- /* dram fsp cfg */
- dram_timing.fsp_cfg[0].ddrc_cfg[0].val = 0x124F2100;
- dram_timing.fsp_cfg[0].ddrc_cfg[1].val = 0xF877000E;
- dram_timing.fsp_cfg[0].ddrc_cfg[2].val = 0x181AE4AA;
- dram_timing.fsp_cfg[0].ddrc_cfg[3].val = 0x005101E6;
- dram_timing.fsp_cfg[0].ddrc_cfg[4].val = 0x0E3C0000;
- dram_timing.fsp_cfg[0].ddrc_cfg[5].val = 0x00009101;
- dram_timing.fsp_cfg[0].ddrc_cfg[6].val = 0x30900000;
- dram_timing.fsp_cfg[0].ddrc_cfg[7].val = 0x8A0A0508;
- dram_timing.fsp_cfg[0].ddrc_cfg[8].val = 0x00000014;
- dram_timing.fsp_cfg[0].ddrc_cfg[9].val = 0x007B007B;
- dram_timing.fsp_cfg[0].ddrc_cfg[12].val = 0x1128110B;
- dram_timing.fsp_cfg[0].ddrc_cfg[13].val = 0x007B140A;
- dram_timing.fsp_cfg[0].ddrc_cfg[14].val = 0x0620071E;
- dram_timing.fsp_cfg[0].mr_cfg[0].val = 0xB4;
- dram_timing.fsp_cfg[0].mr_cfg[1].val = 0x1B;
- dram_timing.fsp_cfg[0].mr_cfg[2].val = 0xE2;
- dram_timing.fsp_cfg[0].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[0].mr_cfg[5].val = 0x15;
- dram_timing.fsp_cfg[1].ddrc_cfg[2].val = 0x181AE4AA;
- dram_timing.fsp_cfg[1].mr_cfg[2].val = 0xE2;
- dram_timing.fsp_cfg[1].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[1].mr_cfg[5].val = 0x15;
- dram_timing.fsp_cfg[2].ddrc_cfg[2].val = 0x6E660A48;
- dram_timing.fsp_cfg[2].mr_cfg[2].val = 0xE2;
- dram_timing.fsp_cfg[2].mr_cfg[4].val = 0x20;
- dram_timing.fsp_cfg[2].mr_cfg[5].val = 0x15;
- /* PHY Initialize Configuration */
- dram_timing.ddrphy_cfg[31].val = 0xb;
- dram_timing.ddrphy_cfg[86].val = 0x1d3;
- dram_timing.ddrphy_cfg[90].val = 0x10c;
- dram_timing.ddrphy_cfg[95].val = 0x10c;
- dram_timing.ddrphy_cfg[100].val = 0x10c;
- dram_timing.ddrphy_cfg[122].val = 0x1;
- /**
* NOTE:
* In the output from DDR Tool v3.3.0_7.8-d1cdb7d3, array members 119
* (reg=0x1004a, val=0x500) and 120 (reg=0x1104a, val=0x500) are not
* present in the ddr_ddrphy_cfg array. However they were present in array
* generated with previous DDR Tool v3.1.0_7.4. We simply set both values
* to default value of 0x400 (read with dwc_ddrphy_apb_rd()) here to avoid
* any negative side-effects.
*/
- dram_timing.ddrphy_cfg[119].val = 0x400;
- dram_timing.ddrphy_cfg[120].val = 0x400;
- /**
* NOTE:
* In the output from DDR Tool v3.3.0_7.8-d1cdb7d3, array members 101
* (reg=0x1004a, val=0x0) and 120 (reg=0x1104a, val=0x0) are not present
* in the ddr_ddrphy_trained_csr array. However they were present in array
* generated with previous DDR Tool v3.1.0_7.4. We simply set both values
* to default 0x0 (like all other ddrphy_trained_csr values) here to avoid
* any negative side-effects.
*/
- /* PHY trained csr */
- dram_timing.ddrphy_trained_csr[101].val = 0x0;
- dram_timing.ddrphy_trained_csr[102].val = 0x0;
- /* P0 message block parameter for training firmware */
- dram_timing.fsp_msg[0].fsp_cfg[1].val = 0x74a;
- dram_timing.fsp_msg[0].fsp_cfg[3].val = 0x15;
- dram_timing.fsp_msg[0].fsp_cfg[10].val = 0x1bb4;
- dram_timing.fsp_msg[0].fsp_cfg[11].val = 0xe2;
- dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x2044;
- dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x1508;
- dram_timing.fsp_msg[0].fsp_cfg[15].val = 0x1bb4;
- dram_timing.fsp_msg[0].fsp_cfg[16].val = 0xe2;
- dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x2044;
- dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x1508;
- dram_timing.fsp_msg[0].fsp_cfg[20].val = 0xb400;
- dram_timing.fsp_msg[0].fsp_cfg[21].val = 0xe21b;
- dram_timing.fsp_msg[0].fsp_cfg[23].val = 0x820;
- dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x15;
- dram_timing.fsp_msg[0].fsp_cfg[26].val = 0xb400;
- dram_timing.fsp_msg[0].fsp_cfg[27].val = 0xe21b;
- dram_timing.fsp_msg[0].fsp_cfg[29].val = 0x820;
- dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x15;
- /* P1 message block parameter for training firmware */
- dram_timing.fsp_msg[1].fsp_cfg[4].val = 0x15;
- dram_timing.fsp_msg[1].fsp_cfg[12].val = 0xe2;
- dram_timing.fsp_msg[1].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x1508;
- dram_timing.fsp_msg[1].fsp_cfg[17].val = 0xe2;
- dram_timing.fsp_msg[1].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x1508;
- dram_timing.fsp_msg[1].fsp_cfg[22].val = 0xe21b;
- dram_timing.fsp_msg[1].fsp_cfg[24].val = 0x820;
- dram_timing.fsp_msg[1].fsp_cfg[25].val = 0x15;
- dram_timing.fsp_msg[1].fsp_cfg[28].val = 0xe21b;
- dram_timing.fsp_msg[1].fsp_cfg[30].val = 0x820;
- dram_timing.fsp_msg[1].fsp_cfg[31].val = 0x15;
- /* P2 message block parameter for training firmware */
- dram_timing.fsp_msg[2].fsp_cfg[4].val = 0x15;
- dram_timing.fsp_msg[2].fsp_cfg[12].val = 0xe2;
- dram_timing.fsp_msg[2].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x1500;
- dram_timing.fsp_msg[2].fsp_cfg[17].val = 0xe2;
- dram_timing.fsp_msg[2].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x1500;
- dram_timing.fsp_msg[2].fsp_cfg[22].val = 0xe209;
- dram_timing.fsp_msg[2].fsp_cfg[24].val = 0x20;
- dram_timing.fsp_msg[2].fsp_cfg[25].val = 0x15;
- dram_timing.fsp_msg[2].fsp_cfg[28].val = 0xe209;
- dram_timing.fsp_msg[2].fsp_cfg[30].val = 0x20;
- dram_timing.fsp_msg[2].fsp_cfg[31].val = 0x15;
- /* P0 2D message block parameter for training firmware */
- dram_timing.fsp_msg[3].fsp_cfg[1].val = 0x74a;
- dram_timing.fsp_msg[3].fsp_cfg[3].val = 0x15;
- dram_timing.fsp_msg[3].fsp_cfg[11].val = 0x1bb4;
- dram_timing.fsp_msg[3].fsp_cfg[12].val = 0xe2;
- dram_timing.fsp_msg[3].fsp_cfg[13].val = 0x2044;
- dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x1508;
- dram_timing.fsp_msg[3].fsp_cfg[16].val = 0x1bb4;
- dram_timing.fsp_msg[3].fsp_cfg[17].val = 0xe2;
- dram_timing.fsp_msg[3].fsp_cfg[18].val = 0x2044;
- dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x1508;
- dram_timing.fsp_msg[3].fsp_cfg[21].val = 0xb400;
- dram_timing.fsp_msg[3].fsp_cfg[22].val = 0xe21b;
- dram_timing.fsp_msg[3].fsp_cfg[24].val = 0x820;
- dram_timing.fsp_msg[3].fsp_cfg[25].val = 0x15;
- dram_timing.fsp_msg[3].fsp_cfg[27].val = 0xb400;
- dram_timing.fsp_msg[3].fsp_cfg[28].val = 0xe21b;
- dram_timing.fsp_msg[3].fsp_cfg[30].val = 0x820;
- dram_timing.fsp_msg[3].fsp_cfg[31].val = 0x15;
- /* DRAM PHY init engine image */
- dram_timing.ddrphy_pie[483].val = 0x20d;
- dram_timing.ddrphy_pie[484].val = 0x74;
- dram_timing.ddrphy_pie[485].val = 0x48e;
- /* P0 3733mts 1D */
- dram_timing.fsp_msg[0].drate = 1866;
- /* P0 1866mts 2D */
- dram_timing.fsp_msg[3].drate = 1866;
- /* ddr timing config params */
- dram_timing.fsp_table[0] = 1866;
+}

The phyCORE-i.MX 93 is available in various variants. Relevant variant options for the spl/u-boot are: - with or without HS400 support for the eMMC - with 1GB ram chip, or 2GB ram chip
The phyCORE's eeprom contains all information about the existing variant options. Add evaluation of the eeprom data to the spl/u-boot to enable/disable HS400 and to select the appropriate ram configuration at startup.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de --- Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de --- Changes in v3: - remove unwanted dts node eepromid - correct typo in doc (PHYTEC_IMX93_VOLTAGE_3V3) - improve enum code-style (phytec_imx93_option_index)
Changes in v2: - encapsulate handling of feature flag VOLTAGE into own function - move definition of enum phytec_imx93_ddr_eeprom_code into header file
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 9 ++ arch/arm/mach-imx/imx9/Kconfig | 2 + arch/arm/mach-imx/imx9/soc.c | 2 +- board/phytec/common/Kconfig | 8 ++ board/phytec/common/Makefile | 1 + board/phytec/common/imx93_som_detection.c | 111 ++++++++++++++++++ board/phytec/common/imx93_som_detection.h | 51 ++++++++ board/phytec/phycore_imx93/Kconfig | 28 +++++ board/phytec/phycore_imx93/MAINTAINERS | 5 +- board/phytec/phycore_imx93/phycore-imx93.c | 51 ++++++++ board/phytec/phycore_imx93/spl.c | 48 ++++++++ 11 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 board/phytec/common/imx93_som_detection.c create mode 100644 board/phytec/common/imx93_som_detection.h
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi index 6897c91f4d..e001ee3288 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -305,4 +305,13 @@ }; }; }; + + eeprom@50 { + bootph-pre-ram; + bootph-some-ram; + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + vcc-supply = <&buck4>; + }; }; diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index 5c1054138f..2465e31d73 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -45,6 +45,8 @@ config TARGET_PHYCORE_IMX93 bool "phycore_imx93" select IMX93 select IMX9_LPDDR4X + select OF_BOARD_FIXUP + select OF_BOARD_SETUP
endchoice
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index 21e0e7dd1e..6837ac82b0 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -634,7 +634,7 @@ static int low_drive_freq_update(void *blob) return 0; }
-#ifdef CONFIG_OF_BOARD_FIXUP +#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_TARGET_PHYCORE_IMX93) #ifndef CONFIG_XPL_BUILD int board_fix_fdt(void *fdt) { diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig index f394ace786..bc5511707a 100644 --- a/board/phytec/common/Kconfig +++ b/board/phytec/common/Kconfig @@ -19,6 +19,14 @@ config PHYTEC_IMX8M_SOM_DETECTION Support of I2C EEPROM based SoM detection. Supported for PHYTEC i.MX8MM/i.MX8MP boards
+config PHYTEC_IMX93_SOM_DETECTION + bool "Support SoM detection for i.MX93 PHYTEC platforms" + depends on ARCH_IMX9 && PHYTEC_SOM_DETECTION + default y + help + Support of I2C EEPROM based SoM detection. Supported + for PHYTEC i.MX93 based boards + config PHYTEC_AM62_SOM_DETECTION bool "Support SoM detection for AM62x PHYTEC platforms" depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \ diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile index cd78f7686f..8126f7356e 100644 --- a/board/phytec/common/Makefile +++ b/board/phytec/common/Makefile @@ -10,3 +10,4 @@ endif obj-y += phytec_som_detection.o phytec_som_detection_blocks.o obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/ obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o +obj-$(CONFIG_ARCH_IMX9) += imx93_som_detection.o diff --git a/board/phytec/common/imx93_som_detection.c b/board/phytec/common/imx93_som_detection.c new file mode 100644 index 0000000000..eb9574d43b --- /dev/null +++ b/board/phytec/common/imx93_som_detection.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 PHYTEC Messtechnik GmbH + * Author: Primoz Fiser primoz.fiser@norik.com + */ + +#include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <i2c.h> +#include <u-boot/crc.h> + +#include "imx93_som_detection.h" + +extern struct phytec_eeprom_data eeprom_data; + +#if IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) + +/* Check if the SoM is actually one of the following products: + * - i.MX93 + * + * Returns 0 in case it's a known SoM. Otherwise, returns 1. + */ +u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{ + u8 som; + + if (!data) + data = &eeprom_data; + + /* Early API revisions are not supported */ + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return 1; + + som = data->payload.data.data_api2.som_no; + debug("%s: som id: %u\n", __func__, som); + + if (som == PHYTEC_IMX93_SOM && is_imx93()) + return 0; + + pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__); + return 1; +} + +/* + * Filter PHYTEC i.MX93 SoM options by option index + * + * Returns: + * - option value + * - PHYTEC_EEPROM_INVAL when the data is invalid + * + */ +u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx) +{ + char *opt; + u8 opt_id; + + if (!data) + data = &eeprom_data; + + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return PHYTEC_EEPROM_INVAL; + + opt = phytec_get_opt(data); + if (opt) + opt_id = PHYTEC_GET_OPTION(opt[idx]); + else + opt_id = PHYTEC_EEPROM_INVAL; + + debug("%s: opt[%d] id: %u\n", __func__, idx, opt_id); + return opt_id; +} + +/* + * Filter PHYTEC i.MX93 SoM voltage + * + * Returns: + * - PHYTEC_IMX93_VOLTAGE_1V8 or PHYTEC_IMX93_VOLTAGE_3V3 + * - PHYTEC_EEPROM_INVAL when the data is invalid + * + */ +enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage(struct phytec_eeprom_data *data) +{ + u8 option = phytec_imx93_get_opt(data, PHYTEC_IMX93_OPT_FEAT); + + if (option == PHYTEC_EEPROM_INVAL) + return PHYTEC_IMX93_VOLTAGE_INVALID; + return (option & 0x01) ? PHYTEC_IMX93_VOLTAGE_1V8 : PHYTEC_IMX93_VOLTAGE_3V3; +} + +#else + +inline u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{ + return 1; +} + +inline u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx) +{ + return PHYTEC_EEPROM_INVAL; +} + +inline enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage + (struct phytec_eeprom_data *data) +{ + return PHYTEC_EEPROM_INVAL; +} + +#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) */ diff --git a/board/phytec/common/imx93_som_detection.h b/board/phytec/common/imx93_som_detection.h new file mode 100644 index 0000000000..a0803b47cb --- /dev/null +++ b/board/phytec/common/imx93_som_detection.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 PHYTEC Messtechnik GmbH + * Author: Primoz Fiser primoz.fiser@norik.com + */ + +#ifndef _PHYTEC_IMX93_SOM_DETECTION_H +#define _PHYTEC_IMX93_SOM_DETECTION_H + +#include "phytec_som_detection.h" + +#define PHYTEC_IMX93_SOM 77 + +enum phytec_imx93_option_index { + PHYTEC_IMX93_OPT_DDR = 0, + PHYTEC_IMX93_OPT_EMMC = 1, + PHYTEC_IMX93_OPT_CPU = 2, + PHYTEC_IMX93_OPT_FREQ = 3, + PHYTEC_IMX93_OPT_NPU = 4, + PHYTEC_IMX93_OPT_DISP = 5, + PHYTEC_IMX93_OPT_ETH = 6, + PHYTEC_IMX93_OPT_FEAT = 7, + PHYTEC_IMX93_OPT_TEMP = 8, + PHYTEC_IMX93_OPT_BOOT = 9, + PHYTEC_IMX93_OPT_LED = 10, + PHYTEC_IMX93_OPT_EEPROM = 11, +}; + +enum phytec_imx93_voltage { + PHYTEC_IMX93_VOLTAGE_INVALID = PHYTEC_EEPROM_INVAL, + PHYTEC_IMX93_VOLTAGE_3V3 = 0, + PHYTEC_IMX93_VOLTAGE_1V8 = 1, +}; + +enum phytec_imx93_ddr_eeprom_code { + PHYTEC_IMX93_DDR_INVALID = PHYTEC_EEPROM_INVAL, + PHYTEC_IMX93_LPDDR4X_512MB = 0, + PHYTEC_IMX93_LPDDR4X_1GB = 1, + PHYTEC_IMX93_LPDDR4X_2GB = 2, + PHYTEC_IMX93_LPDDR4_512MB = 3, + PHYTEC_IMX93_LPDDR4_1GB = 4, + PHYTEC_IMX93_LPDDR4_2GB = 5, +}; + +u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data); +u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx); +enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage + (struct phytec_eeprom_data *data); + +#endif /* _PHYTEC_IMX93_SOM_DETECTION_H */ diff --git a/board/phytec/phycore_imx93/Kconfig b/board/phytec/phycore_imx93/Kconfig index a70104cb79..09f26e89e3 100644 --- a/board/phytec/phycore_imx93/Kconfig +++ b/board/phytec/phycore_imx93/Kconfig @@ -10,4 +10,32 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "phycore_imx93"
+config PHYCORE_IMX93_RAM_TYPE_FIX + bool "Set phyCORE-i.MX93 RAM type and size fix instead of detecting" + default false + help + RAM type and size is being automatically detected with the help + of the PHYTEC EEPROM introspection data. + Set RAM type to a fix value instead. + +choice + prompt "phyCORE-i.MX93 RAM type" + depends on PHYCORE_IMX93_RAM_TYPE_FIX + default PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB + +config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB + bool "LPDDR4X 1GB RAM" + help + Set RAM type fixed to LPDDR4X and RAM size fixed to 1GB + for phyCORE-i.MX93. + +config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB + bool "LPDDR4X 2GB RAM" + help + Set RAM type fixed to LPDDR4X and RAM size fixed to 2GB + for phyCORE-i.MX93. + +endchoice + +source "board/phytec/common/Kconfig" endif diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index 9e91a29dc3..cea817ffdc 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -1,10 +1,13 @@ phyCORE-i.MX93 -M: Mathieu Othacehe m.othacehe@gmail.com +M: Mathieu Othacehe m.othacehe@gmail.com +R: Christoph Stoidner c.stoidner@phytec.de W: https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/ S: Maintained F: arch/arm/dts/imx93-phyboard-segin.dts F: arch/arm/dts/imx93-phycore-som.dtsi F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ +F: board/phytec/common/imx93_som_detection.c +F: board/phytec/common/imx93_som_detection.h F: configs/imx93-phyboard-segin_defconfig F: include/configs/phycore_imx93.h diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore-imx93.c index 085c8e195a..a55795e060 100644 --- a/board/phytec/phycore_imx93/phycore-imx93.c +++ b/board/phytec/phycore_imx93/phycore-imx93.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com + * Copyright (C) 2024 PHYTEC Messtechnik GmbH */
#include <asm/arch-imx9/ccm_regs.h> @@ -12,11 +13,21 @@ #include <asm/global_data.h> #include <asm/mach-imx/boot_mode.h> #include <env.h> +#include <fdt_support.h> + +#include "../common/imx93_som_detection.h"
DECLARE_GLOBAL_DATA_PTR;
+#define EEPROM_ADDR 0x50 + int board_init(void) { + int ret = phytec_eeprom_data_setup(NULL, 2, EEPROM_ADDR); + + if (ret) + printf("%s: EEPROM data init failed\n", __func__); + return 0; }
@@ -40,3 +51,43 @@ int board_late_init(void)
return 0; } + +static void emmc_fixup(void *blob, struct phytec_eeprom_data *data) +{ + enum phytec_imx93_voltage voltage = phytec_imx93_get_voltage(data); + int offset; + + if (voltage == PHYTEC_IMX93_VOLTAGE_INVALID) + goto err; + + if (voltage == PHYTEC_IMX93_VOLTAGE_1V8) { + offset = fdt_node_offset_by_compat_reg(blob, "fsl,imx93-usdhc", + 0x42850000); + if (offset) + fdt_delprop(blob, offset, "no-1-8-v"); + else + goto err; + } + + return; +err: + printf("Could not detect eMMC VDD-IO. Fall back to default.\n"); +} + +int board_fix_fdt(void *blob) +{ + struct phytec_eeprom_data data; + + phytec_eeprom_data_setup(&data, 2, EEPROM_ADDR); + + emmc_fixup(blob, &data); + + return 0; +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + emmc_fixup(blob, NULL); + + return 0; +} diff --git a/board/phytec/phycore_imx93/spl.c b/board/phytec/phycore_imx93/spl.c index 17a8736c73..a4d2aaac32 100644 --- a/board/phytec/phycore_imx93/spl.c +++ b/board/phytec/phycore_imx93/spl.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com + * Copyright (C) 2024 PHYTEC Messtechnik GmbH */
#include <asm/arch/clock.h> @@ -20,6 +21,8 @@ #include <power/pca9450.h> #include <spl.h>
+#include "../common/imx93_som_detection.h" + DECLARE_GLOBAL_DATA_PTR;
/* @@ -27,6 +30,13 @@ DECLARE_GLOBAL_DATA_PTR; * when pca9451a support is added. */ #define PCA9450_REG_PWRCTRL_TOFF_DEB BIT(5) +#define EEPROM_ADDR 0x50 + +/* + * Prototypes of automatically generated ram config file + */ +void set_dram_timings_2gb_lpddr4x(void); +void set_dram_timings_1gb_lpddr4x_900mhz(void);
int spl_board_boot_device(enum boot_device boot_dev_spl) { @@ -46,6 +56,44 @@ void spl_board_init(void)
void spl_dram_init(void) { + int ret; + enum phytec_imx93_ddr_eeprom_code ddr_opt = PHYTEC_IMX93_DDR_INVALID; + + /* NOTE: In SPL lpi2c3 is mapped to bus 0 */ + ret = phytec_eeprom_data_setup(NULL, 0, EEPROM_ADDR); + if (ret && !IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) + goto out; + + ret = phytec_imx93_detect(NULL); + if (!ret) + phytec_print_som_info(NULL); + + if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) { + if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB)) + ddr_opt = PHYTEC_IMX93_LPDDR4X_1GB; + else if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB)) + ddr_opt = PHYTEC_IMX93_LPDDR4X_2GB; + } else { + ddr_opt = phytec_imx93_get_opt(NULL, PHYTEC_IMX93_OPT_DDR); + } + + switch (ddr_opt) { + case PHYTEC_IMX93_LPDDR4X_1GB: + if (is_voltage_mode(VOLT_LOW_DRIVE)) + set_dram_timings_1gb_lpddr4x_900mhz(); + break; + case PHYTEC_IMX93_LPDDR4X_2GB: + set_dram_timings_2gb_lpddr4x(); + break; + default: + goto out; + } + ddr_init(&dram_timing); + return; +out: + puts("Could not detect correct RAM type and size. Fall back to default.\n"); + if (is_voltage_mode(VOLT_LOW_DRIVE)) + set_dram_timings_1gb_lpddr4x_900mhz(); ddr_init(&dram_timing); }

On Tue, 2024-11-19 at 17:29 +0100, Christoph Stoidner wrote:
The phyCORE-i.MX 93 is available in various variants. Relevant variant options for the spl/u-boot are:
- with or without HS400 support for the eMMC
- with 1GB ram chip, or 2GB ram chip
The phyCORE's eeprom contains all information about the existing variant options. Add evaluation of the eeprom data to the spl/u-boot to enable/disable HS400 and to select the appropriate ram configuration at startup.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de
Reviewed-by: Yannic Moog y.moog@phytec.de
Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de
Changes in v3:
- remove unwanted dts node eepromid
- correct typo in doc (PHYTEC_IMX93_VOLTAGE_3V3)
- improve enum code-style (phytec_imx93_option_index)
Changes in v2:
- encapsulate handling of feature flag VOLTAGE into own function
- move definition of enum phytec_imx93_ddr_eeprom_code into header file
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 9 ++ arch/arm/mach-imx/imx9/Kconfig | 2 + arch/arm/mach-imx/imx9/soc.c | 2 +- board/phytec/common/Kconfig | 8 ++ board/phytec/common/Makefile | 1 + board/phytec/common/imx93_som_detection.c | 111 ++++++++++++++++++ board/phytec/common/imx93_som_detection.h | 51 ++++++++ board/phytec/phycore_imx93/Kconfig | 28 +++++ board/phytec/phycore_imx93/MAINTAINERS | 5 +- board/phytec/phycore_imx93/phycore-imx93.c | 51 ++++++++ board/phytec/phycore_imx93/spl.c | 48 ++++++++ 11 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 board/phytec/common/imx93_som_detection.c create mode 100644 board/phytec/common/imx93_som_detection.h
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u- boot.dtsi index 6897c91f4d..e001ee3288 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -305,4 +305,13 @@ }; }; };
- eeprom@50 {
bootph-pre-ram;
bootph-some-ram;
compatible = "atmel,24c32";
reg = <0x50>;
pagesize = <32>;
vcc-supply = <&buck4>;
- };
}; diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index 5c1054138f..2465e31d73 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -45,6 +45,8 @@ config TARGET_PHYCORE_IMX93 bool "phycore_imx93" select IMX93 select IMX9_LPDDR4X
- select OF_BOARD_FIXUP
- select OF_BOARD_SETUP
endchoice diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index 21e0e7dd1e..6837ac82b0 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -634,7 +634,7 @@ static int low_drive_freq_update(void *blob) return 0; } -#ifdef CONFIG_OF_BOARD_FIXUP +#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_TARGET_PHYCORE_IMX93) #ifndef CONFIG_XPL_BUILD int board_fix_fdt(void *fdt) { diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig index f394ace786..bc5511707a 100644 --- a/board/phytec/common/Kconfig +++ b/board/phytec/common/Kconfig @@ -19,6 +19,14 @@ config PHYTEC_IMX8M_SOM_DETECTION Support of I2C EEPROM based SoM detection. Supported for PHYTEC i.MX8MM/i.MX8MP boards +config PHYTEC_IMX93_SOM_DETECTION
- bool "Support SoM detection for i.MX93 PHYTEC platforms"
- depends on ARCH_IMX9 && PHYTEC_SOM_DETECTION
- default y
- help
- Support of I2C EEPROM based SoM detection. Supported
- for PHYTEC i.MX93 based boards
config PHYTEC_AM62_SOM_DETECTION bool "Support SoM detection for AM62x PHYTEC platforms" depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \ diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile index cd78f7686f..8126f7356e 100644 --- a/board/phytec/common/Makefile +++ b/board/phytec/common/Makefile @@ -10,3 +10,4 @@ endif obj-y += phytec_som_detection.o phytec_som_detection_blocks.o obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/ obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o +obj-$(CONFIG_ARCH_IMX9) += imx93_som_detection.o diff --git a/board/phytec/common/imx93_som_detection.c b/board/phytec/common/imx93_som_detection.c new file mode 100644 index 0000000000..eb9574d43b --- /dev/null +++ b/board/phytec/common/imx93_som_detection.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <i2c.h> +#include <u-boot/crc.h>
+#include "imx93_som_detection.h"
+extern struct phytec_eeprom_data eeprom_data;
+#if IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION)
+/* Check if the SoM is actually one of the following products:
- i.MX93
- Returns 0 in case it's a known SoM. Otherwise, returns 1.
- */
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{
- u8 som;
- if (!data)
data = &eeprom_data;
- /* Early API revisions are not supported */
- if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
return 1;
- som = data->payload.data.data_api2.som_no;
- debug("%s: som id: %u\n", __func__, som);
- if (som == PHYTEC_IMX93_SOM && is_imx93())
return 0;
- pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__);
- return 1;
+}
+/*
- Filter PHYTEC i.MX93 SoM options by option index
- Returns:
- * - option value
- * - PHYTEC_EEPROM_INVAL when the data is invalid
- */
+u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx)
+{
- char *opt;
- u8 opt_id;
- if (!data)
data = &eeprom_data;
- if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
return PHYTEC_EEPROM_INVAL;
- opt = phytec_get_opt(data);
- if (opt)
opt_id = PHYTEC_GET_OPTION(opt[idx]);
- else
opt_id = PHYTEC_EEPROM_INVAL;
- debug("%s: opt[%d] id: %u\n", __func__, idx, opt_id);
- return opt_id;
+}
+/*
- Filter PHYTEC i.MX93 SoM voltage
- Returns:
- * - PHYTEC_IMX93_VOLTAGE_1V8 or PHYTEC_IMX93_VOLTAGE_3V3
- * - PHYTEC_EEPROM_INVAL when the data is invalid
- */
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage(struct phytec_eeprom_data *data) +{
- u8 option = phytec_imx93_get_opt(data, PHYTEC_IMX93_OPT_FEAT);
- if (option == PHYTEC_EEPROM_INVAL)
return PHYTEC_IMX93_VOLTAGE_INVALID;
- return (option & 0x01) ? PHYTEC_IMX93_VOLTAGE_1V8 : PHYTEC_IMX93_VOLTAGE_3V3;
+}
+#else
+inline u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{
- return 1;
+}
+inline u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx)
+{
- return PHYTEC_EEPROM_INVAL;
+}
+inline enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
- (struct phytec_eeprom_data *data)
+{
- return PHYTEC_EEPROM_INVAL;
+}
+#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) */ diff --git a/board/phytec/common/imx93_som_detection.h b/board/phytec/common/imx93_som_detection.h new file mode 100644 index 0000000000..a0803b47cb --- /dev/null +++ b/board/phytec/common/imx93_som_detection.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#ifndef _PHYTEC_IMX93_SOM_DETECTION_H +#define _PHYTEC_IMX93_SOM_DETECTION_H
+#include "phytec_som_detection.h"
+#define PHYTEC_IMX93_SOM 77
+enum phytec_imx93_option_index {
- PHYTEC_IMX93_OPT_DDR = 0,
- PHYTEC_IMX93_OPT_EMMC = 1,
- PHYTEC_IMX93_OPT_CPU = 2,
- PHYTEC_IMX93_OPT_FREQ = 3,
- PHYTEC_IMX93_OPT_NPU = 4,
- PHYTEC_IMX93_OPT_DISP = 5,
- PHYTEC_IMX93_OPT_ETH = 6,
- PHYTEC_IMX93_OPT_FEAT = 7,
- PHYTEC_IMX93_OPT_TEMP = 8,
- PHYTEC_IMX93_OPT_BOOT = 9,
- PHYTEC_IMX93_OPT_LED = 10,
- PHYTEC_IMX93_OPT_EEPROM = 11,
+};
+enum phytec_imx93_voltage {
- PHYTEC_IMX93_VOLTAGE_INVALID = PHYTEC_EEPROM_INVAL,
- PHYTEC_IMX93_VOLTAGE_3V3 = 0,
- PHYTEC_IMX93_VOLTAGE_1V8 = 1,
+};
+enum phytec_imx93_ddr_eeprom_code {
- PHYTEC_IMX93_DDR_INVALID = PHYTEC_EEPROM_INVAL,
- PHYTEC_IMX93_LPDDR4X_512MB = 0,
- PHYTEC_IMX93_LPDDR4X_1GB = 1,
- PHYTEC_IMX93_LPDDR4X_2GB = 2,
- PHYTEC_IMX93_LPDDR4_512MB = 3,
- PHYTEC_IMX93_LPDDR4_1GB = 4,
- PHYTEC_IMX93_LPDDR4_2GB = 5,
+};
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data); +u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx);
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
- (struct phytec_eeprom_data *data);
+#endif /* _PHYTEC_IMX93_SOM_DETECTION_H */ diff --git a/board/phytec/phycore_imx93/Kconfig b/board/phytec/phycore_imx93/Kconfig index a70104cb79..09f26e89e3 100644 --- a/board/phytec/phycore_imx93/Kconfig +++ b/board/phytec/phycore_imx93/Kconfig @@ -10,4 +10,32 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "phycore_imx93" +config PHYCORE_IMX93_RAM_TYPE_FIX
- bool "Set phyCORE-i.MX93 RAM type and size fix instead of detecting"
- default false
- help
- RAM type and size is being automatically detected with the help
- of the PHYTEC EEPROM introspection data.
- Set RAM type to a fix value instead.
+choice
- prompt "phyCORE-i.MX93 RAM type"
- depends on PHYCORE_IMX93_RAM_TYPE_FIX
- default PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
- bool "LPDDR4X 1GB RAM"
- help
- Set RAM type fixed to LPDDR4X and RAM size fixed to 1GB
- for phyCORE-i.MX93.
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB
- bool "LPDDR4X 2GB RAM"
- help
- Set RAM type fixed to LPDDR4X and RAM size fixed to 2GB
- for phyCORE-i.MX93.
+endchoice
+source "board/phytec/common/Kconfig" endif diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index 9e91a29dc3..cea817ffdc 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -1,10 +1,13 @@ phyCORE-i.MX93 -M: Mathieu Othacehe m.othacehe@gmail.com +M: Mathieu Othacehe m.othacehe@gmail.com +R: Christoph Stoidner c.stoidner@phytec.de W: https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/ S: Maintained F: arch/arm/dts/imx93-phyboard-segin.dts F: arch/arm/dts/imx93-phycore-som.dtsi F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ +F: board/phytec/common/imx93_som_detection.c +F: board/phytec/common/imx93_som_detection.h F: configs/imx93-phyboard-segin_defconfig F: include/configs/phycore_imx93.h diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore- imx93.c index 085c8e195a..a55795e060 100644 --- a/board/phytec/phycore_imx93/phycore-imx93.c +++ b/board/phytec/phycore_imx93/phycore-imx93.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
*/ #include <asm/arch-imx9/ccm_regs.h> @@ -12,11 +13,21 @@ #include <asm/global_data.h> #include <asm/mach-imx/boot_mode.h> #include <env.h> +#include <fdt_support.h>
+#include "../common/imx93_som_detection.h" DECLARE_GLOBAL_DATA_PTR; +#define EEPROM_ADDR 0x50
int board_init(void) {
- int ret = phytec_eeprom_data_setup(NULL, 2, EEPROM_ADDR);
- if (ret)
printf("%s: EEPROM data init failed\n", __func__);
return 0; } @@ -40,3 +51,43 @@ int board_late_init(void) return 0; }
+static void emmc_fixup(void *blob, struct phytec_eeprom_data *data) +{
- enum phytec_imx93_voltage voltage = phytec_imx93_get_voltage(data);
- int offset;
- if (voltage == PHYTEC_IMX93_VOLTAGE_INVALID)
goto err;
- if (voltage == PHYTEC_IMX93_VOLTAGE_1V8) {
offset = fdt_node_offset_by_compat_reg(blob, "fsl,imx93-usdhc",
0x42850000);
if (offset)
fdt_delprop(blob, offset, "no-1-8-v");
else
goto err;
- }
- return;
+err:
- printf("Could not detect eMMC VDD-IO. Fall back to default.\n");
+}
+int board_fix_fdt(void *blob) +{
- struct phytec_eeprom_data data;
- phytec_eeprom_data_setup(&data, 2, EEPROM_ADDR);
- emmc_fixup(blob, &data);
- return 0;
+}
+int ft_board_setup(void *blob, struct bd_info *bd) +{
- emmc_fixup(blob, NULL);
- return 0;
+} diff --git a/board/phytec/phycore_imx93/spl.c b/board/phytec/phycore_imx93/spl.c index 17a8736c73..a4d2aaac32 100644 --- a/board/phytec/phycore_imx93/spl.c +++ b/board/phytec/phycore_imx93/spl.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
*/ #include <asm/arch/clock.h> @@ -20,6 +21,8 @@ #include <power/pca9450.h> #include <spl.h> +#include "../common/imx93_som_detection.h"
DECLARE_GLOBAL_DATA_PTR; /* @@ -27,6 +30,13 @@ DECLARE_GLOBAL_DATA_PTR; * when pca9451a support is added. */ #define PCA9450_REG_PWRCTRL_TOFF_DEB BIT(5) +#define EEPROM_ADDR 0x50
+/*
- Prototypes of automatically generated ram config file
- */
+void set_dram_timings_2gb_lpddr4x(void); +void set_dram_timings_1gb_lpddr4x_900mhz(void); int spl_board_boot_device(enum boot_device boot_dev_spl) { @@ -46,6 +56,44 @@ void spl_board_init(void) void spl_dram_init(void) {
- int ret;
- enum phytec_imx93_ddr_eeprom_code ddr_opt = PHYTEC_IMX93_DDR_INVALID;
- /* NOTE: In SPL lpi2c3 is mapped to bus 0 */
- ret = phytec_eeprom_data_setup(NULL, 0, EEPROM_ADDR);
- if (ret && !IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX))
goto out;
- ret = phytec_imx93_detect(NULL);
- if (!ret)
phytec_print_som_info(NULL);
- if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) {
if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB))
ddr_opt = PHYTEC_IMX93_LPDDR4X_1GB;
else if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB))
ddr_opt = PHYTEC_IMX93_LPDDR4X_2GB;
- } else {
ddr_opt = phytec_imx93_get_opt(NULL, PHYTEC_IMX93_OPT_DDR);
- }
- switch (ddr_opt) {
- case PHYTEC_IMX93_LPDDR4X_1GB:
if (is_voltage_mode(VOLT_LOW_DRIVE))
set_dram_timings_1gb_lpddr4x_900mhz();
break;
- case PHYTEC_IMX93_LPDDR4X_2GB:
set_dram_timings_2gb_lpddr4x();
break;
- default:
goto out;
- }
- ddr_init(&dram_timing);
- return;
+out:
- puts("Could not detect correct RAM type and size. Fall back to default.\n");
- if (is_voltage_mode(VOLT_LOW_DRIVE))
set_dram_timings_1gb_lpddr4x_900mhz();
ddr_init(&dram_timing); }

Hi Christoph,
I get the following runtime error for eMMC:
U-Boot SPL 2025.01-rc2-00132-gef3b6c6bc869 (Nov 20 2024 - 09:45:19 +0100) SoM: PCL-077-23231211I000.1 PCB rev: 1 M33 prepare ok WDT: Started wdog@42490000 with servicing every 1000ms (40s timeout) Normal Boot Trying to boot from BOOTROM Boot Stage: Primary boot image offset 0x8000, pagesize 0x200, ivt offset 0x0 Load image from 0x49800 by ROM_API NOTICE: BL31: v2.8(release):lf-6.1.36-2.1.0-0-g1a3beeab6484 NOTICE: BL31: Built : 11:39:38, Aug 7 2023
U-Boot 2025.01-rc2-00132-gef3b6c6bc869 (Nov 20 2024 - 09:45:19 +0100)
CPU: i.MX93 rev1.1 Model: PHYTEC phyCORE-i.MX93 DRAM: 2 GiB Core: 190 devices, 25 uclasses, devicetree: separate WDT: Started wdog@42490000 with servicing every 1000ms (40s timeout) MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from MMC... Reading from redundant MMC(1)... OK In: serial@44380000 Out: serial@44380000 Err: serial@44380000 Net: eth0: ethernet@42890000 Hit any key to stop autoboot: 0 u-boot=> mmc info esdhc_change_pinstate 12 error esdhc_set_timing error -38 Select HS400ES failed -38 unable to select a mode: -5 u-boot=>
This means, HS400 is properly selected but I guess you forgot to add ushdc1 pinctrl settings for 100 and 200MHz modes (HS400).
BR, Primoz
On 19. 11. 24 17:29, Christoph Stoidner wrote:
The phyCORE-i.MX 93 is available in various variants. Relevant variant options for the spl/u-boot are:
- with or without HS400 support for the eMMC
- with 1GB ram chip, or 2GB ram chip
The phyCORE's eeprom contains all information about the existing variant options. Add evaluation of the eeprom data to the spl/u-boot to enable/disable HS400 and to select the appropriate ram configuration at startup.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de
Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de
Changes in v3:
- remove unwanted dts node eepromid
- correct typo in doc (PHYTEC_IMX93_VOLTAGE_3V3)
- improve enum code-style (phytec_imx93_option_index)
Changes in v2:
- encapsulate handling of feature flag VOLTAGE into own function
- move definition of enum phytec_imx93_ddr_eeprom_code into header file
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 9 ++ arch/arm/mach-imx/imx9/Kconfig | 2 + arch/arm/mach-imx/imx9/soc.c | 2 +- board/phytec/common/Kconfig | 8 ++ board/phytec/common/Makefile | 1 + board/phytec/common/imx93_som_detection.c | 111 ++++++++++++++++++ board/phytec/common/imx93_som_detection.h | 51 ++++++++ board/phytec/phycore_imx93/Kconfig | 28 +++++ board/phytec/phycore_imx93/MAINTAINERS | 5 +- board/phytec/phycore_imx93/phycore-imx93.c | 51 ++++++++ board/phytec/phycore_imx93/spl.c | 48 ++++++++ 11 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 board/phytec/common/imx93_som_detection.c create mode 100644 board/phytec/common/imx93_som_detection.h
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi index 6897c91f4d..e001ee3288 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -305,4 +305,13 @@ }; }; };
- eeprom@50 {
bootph-pre-ram;
bootph-some-ram;
compatible = "atmel,24c32";
reg = <0x50>;
pagesize = <32>;
vcc-supply = <&buck4>;
- };
}; diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index 5c1054138f..2465e31d73 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -45,6 +45,8 @@ config TARGET_PHYCORE_IMX93 bool "phycore_imx93" select IMX93 select IMX9_LPDDR4X
- select OF_BOARD_FIXUP
- select OF_BOARD_SETUP
endchoice
diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach-imx/imx9/soc.c index 21e0e7dd1e..6837ac82b0 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -634,7 +634,7 @@ static int low_drive_freq_update(void *blob) return 0; }
-#ifdef CONFIG_OF_BOARD_FIXUP +#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_TARGET_PHYCORE_IMX93) #ifndef CONFIG_XPL_BUILD int board_fix_fdt(void *fdt) { diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig index f394ace786..bc5511707a 100644 --- a/board/phytec/common/Kconfig +++ b/board/phytec/common/Kconfig @@ -19,6 +19,14 @@ config PHYTEC_IMX8M_SOM_DETECTION Support of I2C EEPROM based SoM detection. Supported for PHYTEC i.MX8MM/i.MX8MP boards
+config PHYTEC_IMX93_SOM_DETECTION
- bool "Support SoM detection for i.MX93 PHYTEC platforms"
- depends on ARCH_IMX9 && PHYTEC_SOM_DETECTION
- default y
- help
Support of I2C EEPROM based SoM detection. Supported
for PHYTEC i.MX93 based boards
config PHYTEC_AM62_SOM_DETECTION bool "Support SoM detection for AM62x PHYTEC platforms" depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \ diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile index cd78f7686f..8126f7356e 100644 --- a/board/phytec/common/Makefile +++ b/board/phytec/common/Makefile @@ -10,3 +10,4 @@ endif obj-y += phytec_som_detection.o phytec_som_detection_blocks.o obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/ obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o +obj-$(CONFIG_ARCH_IMX9) += imx93_som_detection.o diff --git a/board/phytec/common/imx93_som_detection.c b/board/phytec/common/imx93_som_detection.c new file mode 100644 index 0000000000..eb9574d43b --- /dev/null +++ b/board/phytec/common/imx93_som_detection.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <i2c.h> +#include <u-boot/crc.h>
+#include "imx93_som_detection.h"
+extern struct phytec_eeprom_data eeprom_data;
+#if IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION)
+/* Check if the SoM is actually one of the following products:
- i.MX93
- Returns 0 in case it's a known SoM. Otherwise, returns 1.
- */
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{
- u8 som;
- if (!data)
data = &eeprom_data;
- /* Early API revisions are not supported */
- if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
return 1;
- som = data->payload.data.data_api2.som_no;
- debug("%s: som id: %u\n", __func__, som);
- if (som == PHYTEC_IMX93_SOM && is_imx93())
return 0;
- pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__);
- return 1;
+}
+/*
- Filter PHYTEC i.MX93 SoM options by option index
- Returns:
- option value
- PHYTEC_EEPROM_INVAL when the data is invalid
- */
+u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx)
+{
- char *opt;
- u8 opt_id;
- if (!data)
data = &eeprom_data;
- if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2)
return PHYTEC_EEPROM_INVAL;
- opt = phytec_get_opt(data);
- if (opt)
opt_id = PHYTEC_GET_OPTION(opt[idx]);
- else
opt_id = PHYTEC_EEPROM_INVAL;
- debug("%s: opt[%d] id: %u\n", __func__, idx, opt_id);
- return opt_id;
+}
+/*
- Filter PHYTEC i.MX93 SoM voltage
- Returns:
- PHYTEC_IMX93_VOLTAGE_1V8 or PHYTEC_IMX93_VOLTAGE_3V3
- PHYTEC_EEPROM_INVAL when the data is invalid
- */
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage(struct phytec_eeprom_data *data) +{
- u8 option = phytec_imx93_get_opt(data, PHYTEC_IMX93_OPT_FEAT);
- if (option == PHYTEC_EEPROM_INVAL)
return PHYTEC_IMX93_VOLTAGE_INVALID;
- return (option & 0x01) ? PHYTEC_IMX93_VOLTAGE_1V8 : PHYTEC_IMX93_VOLTAGE_3V3;
+}
+#else
+inline u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{
- return 1;
+}
+inline u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx)
+{
- return PHYTEC_EEPROM_INVAL;
+}
+inline enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
- (struct phytec_eeprom_data *data)
+{
- return PHYTEC_EEPROM_INVAL;
+}
+#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) */ diff --git a/board/phytec/common/imx93_som_detection.h b/board/phytec/common/imx93_som_detection.h new file mode 100644 index 0000000000..a0803b47cb --- /dev/null +++ b/board/phytec/common/imx93_som_detection.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#ifndef _PHYTEC_IMX93_SOM_DETECTION_H +#define _PHYTEC_IMX93_SOM_DETECTION_H
+#include "phytec_som_detection.h"
+#define PHYTEC_IMX93_SOM 77
+enum phytec_imx93_option_index {
- PHYTEC_IMX93_OPT_DDR = 0,
- PHYTEC_IMX93_OPT_EMMC = 1,
- PHYTEC_IMX93_OPT_CPU = 2,
- PHYTEC_IMX93_OPT_FREQ = 3,
- PHYTEC_IMX93_OPT_NPU = 4,
- PHYTEC_IMX93_OPT_DISP = 5,
- PHYTEC_IMX93_OPT_ETH = 6,
- PHYTEC_IMX93_OPT_FEAT = 7,
- PHYTEC_IMX93_OPT_TEMP = 8,
- PHYTEC_IMX93_OPT_BOOT = 9,
- PHYTEC_IMX93_OPT_LED = 10,
- PHYTEC_IMX93_OPT_EEPROM = 11,
+};
+enum phytec_imx93_voltage {
- PHYTEC_IMX93_VOLTAGE_INVALID = PHYTEC_EEPROM_INVAL,
- PHYTEC_IMX93_VOLTAGE_3V3 = 0,
- PHYTEC_IMX93_VOLTAGE_1V8 = 1,
+};
+enum phytec_imx93_ddr_eeprom_code {
- PHYTEC_IMX93_DDR_INVALID = PHYTEC_EEPROM_INVAL,
- PHYTEC_IMX93_LPDDR4X_512MB = 0,
- PHYTEC_IMX93_LPDDR4X_1GB = 1,
- PHYTEC_IMX93_LPDDR4X_2GB = 2,
- PHYTEC_IMX93_LPDDR4_512MB = 3,
- PHYTEC_IMX93_LPDDR4_1GB = 4,
- PHYTEC_IMX93_LPDDR4_2GB = 5,
+};
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data); +u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data,
enum phytec_imx93_option_index idx);
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage
- (struct phytec_eeprom_data *data);
+#endif /* _PHYTEC_IMX93_SOM_DETECTION_H */ diff --git a/board/phytec/phycore_imx93/Kconfig b/board/phytec/phycore_imx93/Kconfig index a70104cb79..09f26e89e3 100644 --- a/board/phytec/phycore_imx93/Kconfig +++ b/board/phytec/phycore_imx93/Kconfig @@ -10,4 +10,32 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "phycore_imx93"
+config PHYCORE_IMX93_RAM_TYPE_FIX
- bool "Set phyCORE-i.MX93 RAM type and size fix instead of detecting"
- default false
- help
RAM type and size is being automatically detected with the help
of the PHYTEC EEPROM introspection data.
Set RAM type to a fix value instead.
+choice
- prompt "phyCORE-i.MX93 RAM type"
- depends on PHYCORE_IMX93_RAM_TYPE_FIX
- default PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
- bool "LPDDR4X 1GB RAM"
- help
Set RAM type fixed to LPDDR4X and RAM size fixed to 1GB
for phyCORE-i.MX93.
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB
- bool "LPDDR4X 2GB RAM"
- help
Set RAM type fixed to LPDDR4X and RAM size fixed to 2GB
for phyCORE-i.MX93.
+endchoice
+source "board/phytec/common/Kconfig" endif diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index 9e91a29dc3..cea817ffdc 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -1,10 +1,13 @@ phyCORE-i.MX93 -M: Mathieu Othacehe m.othacehe@gmail.com +M: Mathieu Othacehe m.othacehe@gmail.com +R: Christoph Stoidner c.stoidner@phytec.de W: https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/ S: Maintained F: arch/arm/dts/imx93-phyboard-segin.dts F: arch/arm/dts/imx93-phycore-som.dtsi F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ +F: board/phytec/common/imx93_som_detection.c +F: board/phytec/common/imx93_som_detection.h F: configs/imx93-phyboard-segin_defconfig F: include/configs/phycore_imx93.h diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore-imx93.c index 085c8e195a..a55795e060 100644 --- a/board/phytec/phycore_imx93/phycore-imx93.c +++ b/board/phytec/phycore_imx93/phycore-imx93.c @@ -3,6 +3,7 @@
- Copyright (C) 2023 PHYTEC Messtechnik GmbH
- Author: Christoph Stoidner c.stoidner@phytec.de
- Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
*/
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
#include <asm/arch-imx9/ccm_regs.h> @@ -12,11 +13,21 @@ #include <asm/global_data.h> #include <asm/mach-imx/boot_mode.h> #include <env.h> +#include <fdt_support.h>
+#include "../common/imx93_som_detection.h"
DECLARE_GLOBAL_DATA_PTR;
+#define EEPROM_ADDR 0x50
int board_init(void) {
- int ret = phytec_eeprom_data_setup(NULL, 2, EEPROM_ADDR);
- if (ret)
printf("%s: EEPROM data init failed\n", __func__);
- return 0;
}
@@ -40,3 +51,43 @@ int board_late_init(void)
return 0; }
+static void emmc_fixup(void *blob, struct phytec_eeprom_data *data) +{
- enum phytec_imx93_voltage voltage = phytec_imx93_get_voltage(data);
- int offset;
- if (voltage == PHYTEC_IMX93_VOLTAGE_INVALID)
goto err;
- if (voltage == PHYTEC_IMX93_VOLTAGE_1V8) {
offset = fdt_node_offset_by_compat_reg(blob, "fsl,imx93-usdhc",
0x42850000);
if (offset)
fdt_delprop(blob, offset, "no-1-8-v");
else
goto err;
- }
- return;
+err:
- printf("Could not detect eMMC VDD-IO. Fall back to default.\n");
+}
+int board_fix_fdt(void *blob) +{
- struct phytec_eeprom_data data;
- phytec_eeprom_data_setup(&data, 2, EEPROM_ADDR);
- emmc_fixup(blob, &data);
- return 0;
+}
+int ft_board_setup(void *blob, struct bd_info *bd) +{
- emmc_fixup(blob, NULL);
- return 0;
+} diff --git a/board/phytec/phycore_imx93/spl.c b/board/phytec/phycore_imx93/spl.c index 17a8736c73..a4d2aaac32 100644 --- a/board/phytec/phycore_imx93/spl.c +++ b/board/phytec/phycore_imx93/spl.c @@ -3,6 +3,7 @@
- Copyright (C) 2023 PHYTEC Messtechnik GmbH
- Author: Christoph Stoidner c.stoidner@phytec.de
- Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
*/
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
#include <asm/arch/clock.h> @@ -20,6 +21,8 @@ #include <power/pca9450.h> #include <spl.h>
+#include "../common/imx93_som_detection.h"
DECLARE_GLOBAL_DATA_PTR;
/* @@ -27,6 +30,13 @@ DECLARE_GLOBAL_DATA_PTR;
- when pca9451a support is added.
*/ #define PCA9450_REG_PWRCTRL_TOFF_DEB BIT(5) +#define EEPROM_ADDR 0x50
+/*
- Prototypes of automatically generated ram config file
- */
+void set_dram_timings_2gb_lpddr4x(void); +void set_dram_timings_1gb_lpddr4x_900mhz(void);
int spl_board_boot_device(enum boot_device boot_dev_spl) { @@ -46,6 +56,44 @@ void spl_board_init(void)
void spl_dram_init(void) {
- int ret;
- enum phytec_imx93_ddr_eeprom_code ddr_opt = PHYTEC_IMX93_DDR_INVALID;
- /* NOTE: In SPL lpi2c3 is mapped to bus 0 */
- ret = phytec_eeprom_data_setup(NULL, 0, EEPROM_ADDR);
- if (ret && !IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX))
goto out;
- ret = phytec_imx93_detect(NULL);
- if (!ret)
phytec_print_som_info(NULL);
- if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) {
if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB))
ddr_opt = PHYTEC_IMX93_LPDDR4X_1GB;
else if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB))
ddr_opt = PHYTEC_IMX93_LPDDR4X_2GB;
- } else {
ddr_opt = phytec_imx93_get_opt(NULL, PHYTEC_IMX93_OPT_DDR);
- }
- switch (ddr_opt) {
- case PHYTEC_IMX93_LPDDR4X_1GB:
if (is_voltage_mode(VOLT_LOW_DRIVE))
set_dram_timings_1gb_lpddr4x_900mhz();
break;
- case PHYTEC_IMX93_LPDDR4X_2GB:
set_dram_timings_2gb_lpddr4x();
break;
- default:
goto out;
- }
- ddr_init(&dram_timing);
- return;
+out:
- puts("Could not detect correct RAM type and size. Fall back to default.\n");
- if (is_voltage_mode(VOLT_LOW_DRIVE))
ddr_init(&dram_timing);set_dram_timings_1gb_lpddr4x_900mhz();
}

Hi Primoz,
On Mi, 2024-11-20 at 10:12 +0100, Primoz Fiser wrote:
Hi Christoph,
I get the following runtime error for eMMC:
U-Boot SPL 2025.01-rc2-00132-gef3b6c6bc869 (Nov 20 2024 - 09:45:19 +0100) SoM: PCL-077-23231211I000.1 PCB rev: 1 M33 prepare ok WDT: Started wdog@42490000 with servicing every 1000ms (40s timeout) Normal Boot Trying to boot from BOOTROM Boot Stage: Primary boot image offset 0x8000, pagesize 0x200, ivt offset 0x0 Load image from 0x49800 by ROM_API NOTICE: BL31: v2.8(release):lf-6.1.36-2.1.0-0-g1a3beeab6484 NOTICE: BL31: Built : 11:39:38, Aug 7 2023
U-Boot 2025.01-rc2-00132-gef3b6c6bc869 (Nov 20 2024 - 09:45:19 +0100)
CPU: i.MX93 rev1.1 Model: PHYTEC phyCORE-i.MX93 DRAM: 2 GiB Core: 190 devices, 25 uclasses, devicetree: separate WDT: Started wdog@42490000 with servicing every 1000ms (40s timeout) MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from MMC... Reading from redundant MMC(1)... OK In: serial@44380000 Out: serial@44380000 Err: serial@44380000 Net: eth0: ethernet@42890000 Hit any key to stop autoboot: 0 u-boot=> mmc info esdhc_change_pinstate 12 error esdhc_set_timing error -38 Select HS400ES failed -38 unable to select a mode: -5 u-boot=>
This means, HS400 is properly selected but I guess you forgot to add ushdc1 pinctrl settings for 100 and 200MHz modes (HS400).
True, pinctrl_usdhc1_100mhz_and pinctrl_usdhc1_200mhz are missing. Thanks for pointing. I will fix it right away.
Regards, Christoph
BR, Primoz
On 19. 11. 24 17:29, Christoph Stoidner wrote:
The phyCORE-i.MX 93 is available in various variants. Relevant variant options for the spl/u-boot are:
- with or without HS400 support for the eMMC
- with 1GB ram chip, or 2GB ram chip
The phyCORE's eeprom contains all information about the existing variant options. Add evaluation of the eeprom data to the spl/u-boot to enable/disable HS400 and to select the appropriate ram configuration at startup.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de
Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de
Changes in v3:
- remove unwanted dts node eepromid
- correct typo in doc (PHYTEC_IMX93_VOLTAGE_3V3)
- improve enum code-style (phytec_imx93_option_index)
Changes in v2:
- encapsulate handling of feature flag VOLTAGE into own function
- move definition of enum phytec_imx93_ddr_eeprom_code into header
file
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 9 ++ arch/arm/mach-imx/imx9/Kconfig | 2 + arch/arm/mach-imx/imx9/soc.c | 2 +- board/phytec/common/Kconfig | 8 ++ board/phytec/common/Makefile | 1 + board/phytec/common/imx93_som_detection.c | 111 ++++++++++++++++++ board/phytec/common/imx93_som_detection.h | 51 ++++++++ board/phytec/phycore_imx93/Kconfig | 28 +++++ board/phytec/phycore_imx93/MAINTAINERS | 5 +- board/phytec/phycore_imx93/phycore-imx93.c | 51 ++++++++ board/phytec/phycore_imx93/spl.c | 48 ++++++++ 11 files changed, 314 insertions(+), 2 deletions(-) create mode 100644 board/phytec/common/imx93_som_detection.c create mode 100644 board/phytec/common/imx93_som_detection.h
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi index 6897c91f4d..e001ee3288 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -305,4 +305,13 @@ }; }; };
+ eeprom@50 { + bootph-pre-ram; + bootph-some-ram; + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + vcc-supply = <&buck4>; + }; }; diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach- imx/imx9/Kconfig index 5c1054138f..2465e31d73 100644 --- a/arch/arm/mach-imx/imx9/Kconfig +++ b/arch/arm/mach-imx/imx9/Kconfig @@ -45,6 +45,8 @@ config TARGET_PHYCORE_IMX93 bool "phycore_imx93" select IMX93 select IMX9_LPDDR4X + select OF_BOARD_FIXUP + select OF_BOARD_SETUP endchoice diff --git a/arch/arm/mach-imx/imx9/soc.c b/arch/arm/mach- imx/imx9/soc.c index 21e0e7dd1e..6837ac82b0 100644 --- a/arch/arm/mach-imx/imx9/soc.c +++ b/arch/arm/mach-imx/imx9/soc.c @@ -634,7 +634,7 @@ static int low_drive_freq_update(void *blob) return 0; } -#ifdef CONFIG_OF_BOARD_FIXUP +#if defined(CONFIG_OF_BOARD_FIXUP) && !defined(CONFIG_TARGET_PHYCORE_IMX93) #ifndef CONFIG_XPL_BUILD int board_fix_fdt(void *fdt) { diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig index f394ace786..bc5511707a 100644 --- a/board/phytec/common/Kconfig +++ b/board/phytec/common/Kconfig @@ -19,6 +19,14 @@ config PHYTEC_IMX8M_SOM_DETECTION Support of I2C EEPROM based SoM detection. Supported for PHYTEC i.MX8MM/i.MX8MP boards +config PHYTEC_IMX93_SOM_DETECTION + bool "Support SoM detection for i.MX93 PHYTEC platforms" + depends on ARCH_IMX9 && PHYTEC_SOM_DETECTION + default y + help + Support of I2C EEPROM based SoM detection. Supported + for PHYTEC i.MX93 based boards
config PHYTEC_AM62_SOM_DETECTION bool "Support SoM detection for AM62x PHYTEC platforms" depends on (TARGET_PHYCORE_AM62X_A53 || TARGET_PHYCORE_AM62X_R5) && \ diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile index cd78f7686f..8126f7356e 100644 --- a/board/phytec/common/Makefile +++ b/board/phytec/common/Makefile @@ -10,3 +10,4 @@ endif obj-y += phytec_som_detection.o phytec_som_detection_blocks.o obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/ obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o +obj-$(CONFIG_ARCH_IMX9) += imx93_som_detection.o diff --git a/board/phytec/common/imx93_som_detection.c b/board/phytec/common/imx93_som_detection.c new file mode 100644 index 0000000000..eb9574d43b --- /dev/null +++ b/board/phytec/common/imx93_som_detection.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#include <asm/arch/sys_proto.h> +#include <dm/device.h> +#include <dm/uclass.h> +#include <i2c.h> +#include <u-boot/crc.h>
+#include "imx93_som_detection.h"
+extern struct phytec_eeprom_data eeprom_data;
+#if IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION)
+/* Check if the SoM is actually one of the following products:
- i.MX93
- Returns 0 in case it's a known SoM. Otherwise, returns 1.
- */
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{ + u8 som;
+ if (!data) + data = &eeprom_data;
+ /* Early API revisions are not supported */ + if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return 1;
+ som = data->payload.data.data_api2.som_no; + debug("%s: som id: %u\n", __func__, som);
+ if (som == PHYTEC_IMX93_SOM && is_imx93()) + return 0;
+ pr_err("%s: SoM ID does not match. Wrong EEPROM data?\n", __func__); + return 1; +}
+/*
- Filter PHYTEC i.MX93 SoM options by option index
- Returns:
- * - option value
- * - PHYTEC_EEPROM_INVAL when the data is invalid
- */
+u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx) +{ + char *opt; + u8 opt_id;
+ if (!data) + data = &eeprom_data;
+ if (!data->valid || data->payload.api_rev < PHYTEC_API_REV2) + return PHYTEC_EEPROM_INVAL;
+ opt = phytec_get_opt(data); + if (opt) + opt_id = PHYTEC_GET_OPTION(opt[idx]); + else + opt_id = PHYTEC_EEPROM_INVAL;
+ debug("%s: opt[%d] id: %u\n", __func__, idx, opt_id); + return opt_id; +}
+/*
- Filter PHYTEC i.MX93 SoM voltage
- Returns:
- * - PHYTEC_IMX93_VOLTAGE_1V8 or PHYTEC_IMX93_VOLTAGE_3V3
- * - PHYTEC_EEPROM_INVAL when the data is invalid
- */
+enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage(struct phytec_eeprom_data *data) +{ + u8 option = phytec_imx93_get_opt(data, PHYTEC_IMX93_OPT_FEAT);
+ if (option == PHYTEC_EEPROM_INVAL) + return PHYTEC_IMX93_VOLTAGE_INVALID; + return (option & 0x01) ? PHYTEC_IMX93_VOLTAGE_1V8 : PHYTEC_IMX93_VOLTAGE_3V3; +}
+#else
+inline u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data) +{ + return 1; +}
+inline u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx) +{ + return PHYTEC_EEPROM_INVAL; +}
+inline enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage + (struct phytec_eeprom_data *data) +{ + return PHYTEC_EEPROM_INVAL; +}
+#endif /* IS_ENABLED(CONFIG_PHYTEC_IMX93_SOM_DETECTION) */ diff --git a/board/phytec/common/imx93_som_detection.h b/board/phytec/common/imx93_som_detection.h new file mode 100644 index 0000000000..a0803b47cb --- /dev/null +++ b/board/phytec/common/imx93_som_detection.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/*
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
- Author: Primoz Fiser primoz.fiser@norik.com
- */
+#ifndef _PHYTEC_IMX93_SOM_DETECTION_H +#define _PHYTEC_IMX93_SOM_DETECTION_H
+#include "phytec_som_detection.h"
+#define PHYTEC_IMX93_SOM 77
+enum phytec_imx93_option_index { + PHYTEC_IMX93_OPT_DDR = 0, + PHYTEC_IMX93_OPT_EMMC = 1, + PHYTEC_IMX93_OPT_CPU = 2, + PHYTEC_IMX93_OPT_FREQ = 3, + PHYTEC_IMX93_OPT_NPU = 4, + PHYTEC_IMX93_OPT_DISP = 5, + PHYTEC_IMX93_OPT_ETH = 6, + PHYTEC_IMX93_OPT_FEAT = 7, + PHYTEC_IMX93_OPT_TEMP = 8, + PHYTEC_IMX93_OPT_BOOT = 9, + PHYTEC_IMX93_OPT_LED = 10, + PHYTEC_IMX93_OPT_EEPROM = 11, +};
+enum phytec_imx93_voltage { + PHYTEC_IMX93_VOLTAGE_INVALID = PHYTEC_EEPROM_INVAL, + PHYTEC_IMX93_VOLTAGE_3V3 = 0, + PHYTEC_IMX93_VOLTAGE_1V8 = 1, +};
+enum phytec_imx93_ddr_eeprom_code { + PHYTEC_IMX93_DDR_INVALID = PHYTEC_EEPROM_INVAL, + PHYTEC_IMX93_LPDDR4X_512MB = 0, + PHYTEC_IMX93_LPDDR4X_1GB = 1, + PHYTEC_IMX93_LPDDR4X_2GB = 2, + PHYTEC_IMX93_LPDDR4_512MB = 3, + PHYTEC_IMX93_LPDDR4_1GB = 4, + PHYTEC_IMX93_LPDDR4_2GB = 5, +};
+u8 __maybe_unused phytec_imx93_detect(struct phytec_eeprom_data *data); +u8 __maybe_unused phytec_imx93_get_opt(struct phytec_eeprom_data *data, + enum phytec_imx93_option_index idx); +enum phytec_imx93_voltage __maybe_unused phytec_imx93_get_voltage + (struct phytec_eeprom_data *data);
+#endif /* _PHYTEC_IMX93_SOM_DETECTION_H */ diff --git a/board/phytec/phycore_imx93/Kconfig b/board/phytec/phycore_imx93/Kconfig index a70104cb79..09f26e89e3 100644 --- a/board/phytec/phycore_imx93/Kconfig +++ b/board/phytec/phycore_imx93/Kconfig @@ -10,4 +10,32 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "phycore_imx93" +config PHYCORE_IMX93_RAM_TYPE_FIX + bool "Set phyCORE-i.MX93 RAM type and size fix instead of detecting" + default false + help + RAM type and size is being automatically detected with the help + of the PHYTEC EEPROM introspection data. + Set RAM type to a fix value instead.
+choice + prompt "phyCORE-i.MX93 RAM type" + depends on PHYCORE_IMX93_RAM_TYPE_FIX + default PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB + bool "LPDDR4X 1GB RAM" + help + Set RAM type fixed to LPDDR4X and RAM size fixed to 1GB + for phyCORE-i.MX93.
+config PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB + bool "LPDDR4X 2GB RAM" + help + Set RAM type fixed to LPDDR4X and RAM size fixed to 2GB + for phyCORE-i.MX93.
+endchoice
+source "board/phytec/common/Kconfig" endif diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index 9e91a29dc3..cea817ffdc 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -1,10 +1,13 @@ phyCORE-i.MX93 -M: Mathieu Othacehe m.othacehe@gmail.com +M: Mathieu Othacehe m.othacehe@gmail.com +R: Christoph Stoidner c.stoidner@phytec.de W: https://www.phytec.eu/en/produkte/system-on- modules/phycore-imx-91-93/ S: Maintained F: arch/arm/dts/imx93-phyboard-segin.dts F: arch/arm/dts/imx93-phycore-som.dtsi F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ +F: board/phytec/common/imx93_som_detection.c +F: board/phytec/common/imx93_som_detection.h F: configs/imx93-phyboard-segin_defconfig F: include/configs/phycore_imx93.h diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore-imx93.c index 085c8e195a..a55795e060 100644 --- a/board/phytec/phycore_imx93/phycore-imx93.c +++ b/board/phytec/phycore_imx93/phycore-imx93.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
*/ #include <asm/arch-imx9/ccm_regs.h> @@ -12,11 +13,21 @@ #include <asm/global_data.h> #include <asm/mach-imx/boot_mode.h> #include <env.h> +#include <fdt_support.h>
+#include "../common/imx93_som_detection.h" DECLARE_GLOBAL_DATA_PTR; +#define EEPROM_ADDR 0x50
int board_init(void) { + int ret = phytec_eeprom_data_setup(NULL, 2, EEPROM_ADDR);
+ if (ret) + printf("%s: EEPROM data init failed\n", __func__);
return 0; } @@ -40,3 +51,43 @@ int board_late_init(void) return 0; }
+static void emmc_fixup(void *blob, struct phytec_eeprom_data *data) +{ + enum phytec_imx93_voltage voltage = phytec_imx93_get_voltage(data); + int offset;
+ if (voltage == PHYTEC_IMX93_VOLTAGE_INVALID) + goto err;
+ if (voltage == PHYTEC_IMX93_VOLTAGE_1V8) { + offset = fdt_node_offset_by_compat_reg(blob, "fsl,imx93-usdhc", + 0x42850000); + if (offset) + fdt_delprop(blob, offset, "no-1-8-v"); + else + goto err; + }
+ return; +err: + printf("Could not detect eMMC VDD-IO. Fall back to default.\n"); +}
+int board_fix_fdt(void *blob) +{ + struct phytec_eeprom_data data;
+ phytec_eeprom_data_setup(&data, 2, EEPROM_ADDR);
+ emmc_fixup(blob, &data);
+ return 0; +}
+int ft_board_setup(void *blob, struct bd_info *bd) +{ + emmc_fixup(blob, NULL);
+ return 0; +} diff --git a/board/phytec/phycore_imx93/spl.c b/board/phytec/phycore_imx93/spl.c index 17a8736c73..a4d2aaac32 100644 --- a/board/phytec/phycore_imx93/spl.c +++ b/board/phytec/phycore_imx93/spl.c @@ -3,6 +3,7 @@ * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Author: Christoph Stoidner c.stoidner@phytec.de * Copyright (C) 2024 Mathieu Othacehe m.othacehe@gmail.com
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
*/ #include <asm/arch/clock.h> @@ -20,6 +21,8 @@ #include <power/pca9450.h> #include <spl.h> +#include "../common/imx93_som_detection.h"
DECLARE_GLOBAL_DATA_PTR; /* @@ -27,6 +30,13 @@ DECLARE_GLOBAL_DATA_PTR; * when pca9451a support is added. */ #define PCA9450_REG_PWRCTRL_TOFF_DEB BIT(5) +#define EEPROM_ADDR 0x50
+/*
- Prototypes of automatically generated ram config file
- */
+void set_dram_timings_2gb_lpddr4x(void); +void set_dram_timings_1gb_lpddr4x_900mhz(void); int spl_board_boot_device(enum boot_device boot_dev_spl) { @@ -46,6 +56,44 @@ void spl_board_init(void) void spl_dram_init(void) { + int ret; + enum phytec_imx93_ddr_eeprom_code ddr_opt = PHYTEC_IMX93_DDR_INVALID;
+ /* NOTE: In SPL lpi2c3 is mapped to bus 0 */ + ret = phytec_eeprom_data_setup(NULL, 0, EEPROM_ADDR); + if (ret && !IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) + goto out;
+ ret = phytec_imx93_detect(NULL); + if (!ret) + phytec_print_som_info(NULL);
+ if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_FIX)) { + if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_1GB)) + ddr_opt = PHYTEC_IMX93_LPDDR4X_1GB; + else if (IS_ENABLED(CONFIG_PHYCORE_IMX93_RAM_TYPE_LPDDR4X_2GB)) + ddr_opt = PHYTEC_IMX93_LPDDR4X_2GB; + } else { + ddr_opt = phytec_imx93_get_opt(NULL, PHYTEC_IMX93_OPT_DDR); + }
+ switch (ddr_opt) { + case PHYTEC_IMX93_LPDDR4X_1GB: + if (is_voltage_mode(VOLT_LOW_DRIVE)) + set_dram_timings_1gb_lpddr4x_900mhz(); + break; + case PHYTEC_IMX93_LPDDR4X_2GB: + set_dram_timings_2gb_lpddr4x(); + break; + default: + goto out; + } + ddr_init(&dram_timing); + return; +out: + puts("Could not detect correct RAM type and size. Fall back to default.\n"); + if (is_voltage_mode(VOLT_LOW_DRIVE)) + set_dram_timings_1gb_lpddr4x_900mhz(); ddr_init(&dram_timing); }

The phyCORE-i.MX 93 is available in various variants (e.g. different ram sizes, eMMC HS400 yes/no). Enable hardware introspection for the imx93-phyboard-segin_defconfig, so that during startup the SOM module variant can be detected, and the hardware can be configured accordingly. The resulting SPL and u-boot binary shall able to boot each phyCORE-i.MX 93 module variant on each carrier board. Finally rename imx93-phyboard-segin_defconfig to imx93-phycore_defconfig, to highlight its SOM scope.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de --- Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de --- Changes in v3: - add comment about SoM-scope to imx93-phyboard-segin-u-boot.dtsi - rebase to the latest master - adapt doc according to new defconfig
Changes in v2: - just rename imx93-phyboard-segin_defconfig and add needed CONFIGs, instead of creating an entirely new second defconfig - remove wrong comment from imx93-phyboard-segin-u-boot.dtsi - improve commit message
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 11 +++++++++-- board/phytec/phycore_imx93/MAINTAINERS | 2 +- ...yboard-segin_defconfig => imx93-phycore_defconfig} | 2 ++ .../{imx93-phyboard-segin.rst => imx93-phycore.rst} | 8 ++++---- doc/board/phytec/index.rst | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) rename configs/{imx93-phyboard-segin_defconfig => imx93-phycore_defconfig} (98%) rename doc/board/phytec/{imx93-phyboard-segin.rst => imx93-phycore.rst} (91%)
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi index e001ee3288..635e298507 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -2,15 +2,22 @@ /* * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Christoph Stoidner c.stoidner@phytec.de + * Copyright (C) 2024 PHYTEC Messtechnik GmbH * * Product homepage: - * phyBOARD-Segin carrier board is reused for the i.MX93 design. - * https://www.phytec.eu/en/produkte/single-board-computer/phyboard-segin-imx6u... + https://www.phytec.de/produkte/system-on-modules/phycore-imx-91-93/ */
#include "imx93-u-boot.dtsi"
/ { + /* + * The phyCORE-i.MX93 u-boot uses the imx93-phyboard-segin.dts as + * reference, but does only make use of its SoM (phyCORE) contained + * periphery. + */ + model = "PHYTEC phyCORE-i.MX93"; + wdt-reboot { compatible = "wdt-reboot"; wdt = <&wdog3>; diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index cea817ffdc..718f89a084 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -9,5 +9,5 @@ F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ F: board/phytec/common/imx93_som_detection.c F: board/phytec/common/imx93_som_detection.h -F: configs/imx93-phyboard-segin_defconfig +F: configs/imx93-phycore_defconfig F: include/configs/phycore_imx93.h diff --git a/configs/imx93-phyboard-segin_defconfig b/configs/imx93-phycore_defconfig similarity index 98% rename from configs/imx93-phyboard-segin_defconfig rename to configs/imx93-phycore_defconfig index 309262c430..cf9800118a 100644 --- a/configs/imx93-phyboard-segin_defconfig +++ b/configs/imx93-phycore_defconfig @@ -6,6 +6,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x20000 CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=2 +CONFIG_PHYTEC_SOM_DETECTION=y CONFIG_ENV_SOURCE_FILE="phycore_imx93" CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x700000 @@ -31,6 +32,7 @@ CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x88000000 CONFIG_SYS_MEMTEST_START=0x80000000 CONFIG_SYS_MEMTEST_END=0x90000000 CONFIG_REMAKE_ELF=y +# CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_DISTRO_DEFAULTS=y CONFIG_OF_SYSTEM_SETUP=y CONFIG_BOOTCOMMAND="mmc dev ${mmcdev}; if mmc rescan; then if run loadimage; then run mmcboot; else run netboot; fi; fi;" diff --git a/doc/board/phytec/imx93-phyboard-segin.rst b/doc/board/phytec/imx93-phycore.rst similarity index 91% rename from doc/board/phytec/imx93-phyboard-segin.rst rename to doc/board/phytec/imx93-phycore.rst index ce17fbec78..bd110a3ebe 100644 --- a/doc/board/phytec/imx93-phyboard-segin.rst +++ b/doc/board/phytec/imx93-phycore.rst @@ -1,9 +1,9 @@ .. SPDX-License-Identifier: GPL-2.0+
-phyBOARD-Segin-i.MX93 -===================== +phyCORE-i.MX 93 +===============
-U-Boot for the phyBOARD-Segin-i.MX93. +U-Boot for the phyCORE-i.MX 93.
Quick Start ----------- @@ -51,7 +51,7 @@ Build U-Boot
.. code-block:: bash
- $ make imx93-phyboard-segin_defconfig + $ make imx93-phycore_defconfig $ make
Burn the flash.bin to MicroSD card offset 32KB: diff --git a/doc/board/phytec/index.rst b/doc/board/phytec/index.rst index 99848a9e95..fa30697464 100644 --- a/doc/board/phytec/index.rst +++ b/doc/board/phytec/index.rst @@ -7,7 +7,7 @@ PHYTEC :maxdepth: 2
imx8mm-phygate-tauri-l - imx93-phyboard-segin + imx93-phycore phycore-am62x phycore-am64x phycore-imx8mm

On Tue, 2024-11-19 at 17:29 +0100, Christoph Stoidner wrote:
The phyCORE-i.MX 93 is available in various variants (e.g. different ram sizes, eMMC HS400 yes/no). Enable hardware introspection for the imx93-phyboard-segin_defconfig, so that during startup the SOM module variant can be detected, and the hardware can be configured accordingly. The resulting SPL and u-boot binary shall able to boot each phyCORE-i.MX 93 module variant on each carrier board. Finally rename imx93-phyboard-segin_defconfig to imx93-phycore_defconfig, to highlight its SOM scope.
Signed-off-by: Christoph Stoidner c.stoidner@phytec.de Reviewed-by: Wadim Egorov w.egorov@phytec.de
Reviewed-by: Yannic Moog y.moog@phytec.de
Cc: Mathieu Othacehe m.othacehe@gmail.com Cc: Christoph Stoidner c.stoidner@phytec.de Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: "NXP i.MX U-Boot Team" uboot-imx@nxp.com Cc: Tom Rini trini@konsulko.com Cc: Yannic Moog y.moog@phytec.de Cc: Primoz Fiser primoz.fiser@norik.com Cc: Andrej Picej andrej.picej@norik.com Cc: Wadim Egorov w.egorov@phytec.de
Changes in v3:
- add comment about SoM-scope to imx93-phyboard-segin-u-boot.dtsi
- rebase to the latest master
- adapt doc according to new defconfig
Changes in v2:
- just rename imx93-phyboard-segin_defconfig and add needed CONFIGs,
instead of creating an entirely new second defconfig
- remove wrong comment from imx93-phyboard-segin-u-boot.dtsi
- improve commit message
arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi | 11 +++++++++-- board/phytec/phycore_imx93/MAINTAINERS | 2 +- ...yboard-segin_defconfig => imx93-phycore_defconfig} | 2 ++ .../{imx93-phyboard-segin.rst => imx93-phycore.rst} | 8 ++++---- doc/board/phytec/index.rst | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) rename configs/{imx93-phyboard-segin_defconfig => imx93-phycore_defconfig} (98%) rename doc/board/phytec/{imx93-phyboard-segin.rst => imx93-phycore.rst} (91%)
diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u- boot.dtsi index e001ee3288..635e298507 100644 --- a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi +++ b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi @@ -2,15 +2,22 @@ /* * Copyright (C) 2023 PHYTEC Messtechnik GmbH * Christoph Stoidner c.stoidner@phytec.de
- Copyright (C) 2024 PHYTEC Messtechnik GmbH
* * Product homepage:
- phyBOARD-Segin carrier board is reused for the i.MX93 design.
+ https://www.phytec.de/produkte/system-on-modules/phycore-imx-91-93/ */ #include "imx93-u-boot.dtsi" / {
- /*
* The phyCORE-i.MX93 u-boot uses the imx93-phyboard-segin.dts as
* reference, but does only make use of its SoM (phyCORE) contained
* periphery.
*/
- model = "PHYTEC phyCORE-i.MX93";
wdt-reboot { compatible = "wdt-reboot"; wdt = <&wdog3>; diff --git a/board/phytec/phycore_imx93/MAINTAINERS b/board/phytec/phycore_imx93/MAINTAINERS index cea817ffdc..718f89a084 100644 --- a/board/phytec/phycore_imx93/MAINTAINERS +++ b/board/phytec/phycore_imx93/MAINTAINERS @@ -9,5 +9,5 @@ F: arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi F: board/phytec/phycore_imx93/ F: board/phytec/common/imx93_som_detection.c F: board/phytec/common/imx93_som_detection.h -F: configs/imx93-phyboard-segin_defconfig +F: configs/imx93-phycore_defconfig F: include/configs/phycore_imx93.h diff --git a/configs/imx93-phyboard-segin_defconfig b/configs/imx93-phycore_defconfig similarity index 98% rename from configs/imx93-phyboard-segin_defconfig rename to configs/imx93-phycore_defconfig index 309262c430..cf9800118a 100644 --- a/configs/imx93-phyboard-segin_defconfig +++ b/configs/imx93-phycore_defconfig @@ -6,6 +6,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x20000 CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=2 +CONFIG_PHYTEC_SOM_DETECTION=y CONFIG_ENV_SOURCE_FILE="phycore_imx93" CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x700000 @@ -31,6 +32,7 @@ CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x88000000 CONFIG_SYS_MEMTEST_START=0x80000000 CONFIG_SYS_MEMTEST_END=0x90000000 CONFIG_REMAKE_ELF=y +# CONFIG_ANDROID_BOOT_IMAGE is not set CONFIG_DISTRO_DEFAULTS=y CONFIG_OF_SYSTEM_SETUP=y CONFIG_BOOTCOMMAND="mmc dev ${mmcdev}; if mmc rescan; then if run loadimage; then run mmcboot; else run netboot; fi; fi;" diff --git a/doc/board/phytec/imx93-phyboard-segin.rst b/doc/board/phytec/imx93-phycore.rst similarity index 91% rename from doc/board/phytec/imx93-phyboard-segin.rst rename to doc/board/phytec/imx93-phycore.rst index ce17fbec78..bd110a3ebe 100644 --- a/doc/board/phytec/imx93-phyboard-segin.rst +++ b/doc/board/phytec/imx93-phycore.rst @@ -1,9 +1,9 @@ .. SPDX-License-Identifier: GPL-2.0+
-phyBOARD-Segin-i.MX93
+phyCORE-i.MX 93 +=============== -U-Boot for the phyBOARD-Segin-i.MX93. +U-Boot for the phyCORE-i.MX 93. Quick Start ----------- @@ -51,7 +51,7 @@ Build U-Boot .. code-block:: bash - $ make imx93-phyboard-segin_defconfig + $ make imx93-phycore_defconfig $ make Burn the flash.bin to MicroSD card offset 32KB: diff --git a/doc/board/phytec/index.rst b/doc/board/phytec/index.rst index 99848a9e95..fa30697464 100644 --- a/doc/board/phytec/index.rst +++ b/doc/board/phytec/index.rst @@ -7,7 +7,7 @@ PHYTEC :maxdepth: 2 imx8mm-phygate-tauri-l - imx93-phyboard-segin + imx93-phycore phycore-am62x phycore-am64x phycore-imx8mm
participants (4)
-
Christoph Stoidner
-
Christoph Stoidner
-
Primoz Fiser
-
Yannic Moog