diff options
55 files changed, 2140 insertions, 446 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 042282f3723..d81a9f95977 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -935,8 +935,7 @@ dtb-$(CONFIG_ARCH_IMX8) += \ fsl-imx8qxp-ai_ml.dtb \ fsl-imx8qxp-colibri.dtb \ fsl-imx8qxp-mek.dtb \ - imx8-deneb.dtb \ - imx8-giedi.dtb + imx8-capricorn-cxg3.dtb \ dtb-$(CONFIG_ARCH_IMX8ULP) += \ imx8ulp-evk.dtb diff --git a/arch/arm/dts/imx8-capricorn-cxg3.dts b/arch/arm/dts/imx8-capricorn-cxg3.dts new file mode 100644 index 00000000000..2f8597579f3 --- /dev/null +++ b/arch/arm/dts/imx8-capricorn-cxg3.dts @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Siemens AG + */ + +#include "imx8-capricorn.dtsi" + +/ { + model = "Siemens CXG3"; + + leds_default: leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + run { + label = "run"; + gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + flt { + label = "flt"; + gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + svc { + label = "svc"; + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + com1_tx { + label = "com1-tx"; + gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + com1_rx { + label = "com1-rx"; + gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + com2_tx { + label = "com2-tx"; + gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + com2_rx { + label = "com2-rx"; + gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + cloud { + label = "cloud"; + gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + wlan { + label = "wlan"; + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + apps { + label = "apps"; + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + dbg2 { + label = "dbg2"; + gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + dbg3 { + label = "dbg3"; + gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + dbg4 { + label = "dbg4"; + gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>; + }; +}; + +&iomuxc { + pinctrl-0 = <&pinctrl_gpio_keys>; + + muxcgrp: imx8qxp-som { + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + SC_P_ESAI0_FST_LSIO_GPIO0_IO01 0x06000021 + SC_P_ESAI0_TX0_LSIO_GPIO0_IO04 0x06000021 + SC_P_SAI0_TXC_LSIO_GPIO0_IO26 0x06000021 + SC_P_SAI1_RXD_LSIO_GPIO0_IO29 0x06000021 + SC_P_FLEXCAN1_RX_LSIO_GPIO1_IO17 0x06000021 + SC_P_FLEXCAN1_TX_LSIO_GPIO1_IO18 0x06000021 + SC_P_QSPI0B_SCLK_LSIO_GPIO3_IO17 0x06000021 + SC_P_QSPI0B_DATA0_LSIO_GPIO3_IO18 0x06000021 + SC_P_QSPI0B_DATA1_LSIO_GPIO3_IO19 0x06000021 + SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 0x06000021 + SC_P_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00 0x06000021 + SC_P_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01 0x06000021 + SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x06000021 + >; + }; + }; + + pinctrl_gpio_keys: gpiokeysgrp { + fsl,pins = < + SC_P_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO31 0x06000021 + >; + }; +}; diff --git a/arch/arm/dts/imx8qxp-capricorn-u-boot.dtsi b/arch/arm/dts/imx8-capricorn-u-boot.dtsi index cba56188f86..ad5309bd969 100644 --- a/arch/arm/dts/imx8qxp-capricorn-u-boot.dtsi +++ b/arch/arm/dts/imx8-capricorn-u-boot.dtsi @@ -6,130 +6,133 @@ #include "imx8qxp-u-boot.dtsi" &{/imx8qx-pm} { + bootph-all; +}; - bootph-pre-ram; +&A35_0 { + bootph-all; }; &mu { - bootph-pre-ram; + bootph-all; }; &clk { - bootph-pre-ram; + bootph-all; }; &iomuxc { - bootph-pre-ram; + bootph-all; }; &pd_lsio { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio0 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio1 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio2 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio3 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio4 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio5 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio6 { - bootph-pre-ram; + bootph-all; }; &pd_lsio_gpio7 { - bootph-pre-ram; + bootph-all; }; &pd_dma { - bootph-pre-ram; + bootph-all; }; &pd_dma_lpuart0 { - bootph-pre-ram; + bootph-all; }; &pd_dma_lpuart2 { - bootph-pre-ram; + bootph-all; }; &pd_conn { - bootph-pre-ram; + bootph-all; }; &pd_conn_sdch0 { - bootph-pre-ram; + bootph-all; }; &pd_conn_sdch1 { - bootph-pre-ram; + bootph-all; }; &pd_conn_sdch2 { - bootph-pre-ram; + bootph-all; }; &gpio0 { - bootph-pre-ram; + bootph-all; }; &gpio1 { - bootph-pre-ram; + bootph-all; }; &gpio2 { - bootph-pre-ram; + bootph-all; }; &gpio3 { - bootph-pre-ram; + bootph-all; }; &gpio4 { - bootph-pre-ram; + bootph-all; }; &gpio5 { - bootph-pre-ram; + bootph-all; }; &gpio6 { - bootph-pre-ram; + bootph-all; }; &gpio7 { - bootph-pre-ram; + bootph-all; }; &lpuart0 { - bootph-pre-ram; + bootph-all; }; &lpuart2 { - bootph-pre-ram; + bootph-all; }; &usdhc1 { - bootph-pre-ram; + bootph-all; }; &usdhc2 { - bootph-pre-ram; + bootph-all; }; diff --git a/arch/arm/dts/imx8qxp-capricorn.dtsi b/arch/arm/dts/imx8-capricorn.dtsi index db5653ea1ff..3734a9d21f1 100644 --- a/arch/arm/dts/imx8qxp-capricorn.dtsi +++ b/arch/arm/dts/imx8-capricorn.dtsi @@ -9,124 +9,25 @@ /dts-v1/; #include "fsl-imx8qxp.dtsi" -#include "imx8qxp-capricorn-u-boot.dtsi" +#include "imx8-capricorn-u-boot.dtsi" / { - model = "Siemens Giedi"; - compatible = "siemens,capricorn", "fsl,imx8qxp"; - chosen { bootargs = "console=ttyLP2,115200 earlycon=lpuart32,0x5a080000,115200"; stdout-path = &lpuart2; }; - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpio_leds>; - - run { - label = "run"; - gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - flt { - label = "flt"; - gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - svc { - label = "svc"; - gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - com1_tx { - label = "com1-tx"; - gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - com1_rx { - label = "com1-rx"; - gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - com2_tx { - label = "com2-tx"; - gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - com2_rx { - label = "com2-rx"; - gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - cloud { - label = "cloud"; - gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - wlan { - label = "wlan"; - gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - dbg1 { - label = "dbg1"; - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - dbg2 { - label = "dbg2"; - gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - dbg3 { - label = "dbg3"; - gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - dbg4 { - label = "dbg4"; - gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; + /* create device for u-boot wdt command */ + scu-wdt { + compatible = "siemens,scu-wdt"; }; + }; &iomuxc { pinctrl-names = "default"; muxcgrp: imx8qxp-som { - pinctrl_gpio_leds: gpioledsgrp { - fsl,pins = < - SC_P_ESAI0_FST_LSIO_GPIO0_IO01 0x06000021 - SC_P_ESAI0_TX0_LSIO_GPIO0_IO04 0x06000021 - SC_P_SAI0_TXC_LSIO_GPIO0_IO26 0x06000021 - SC_P_SAI1_RXD_LSIO_GPIO0_IO29 0x06000021 - SC_P_FLEXCAN1_RX_LSIO_GPIO1_IO17 0x06000021 - SC_P_FLEXCAN1_TX_LSIO_GPIO1_IO18 0x06000021 - SC_P_QSPI0B_SCLK_LSIO_GPIO3_IO17 0x06000021 - SC_P_QSPI0B_DATA0_LSIO_GPIO3_IO18 0x06000021 - SC_P_QSPI0B_DATA1_LSIO_GPIO3_IO19 0x06000021 - SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 0x06000021 - SC_P_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00 0x06000021 - SC_P_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01 0x06000021 - SC_P_ENET0_REFCLK_125M_25M_LSIO_GPIO5_IO09 0x06000021 - >; - }; - pinctrl_lpi2c0: lpi2c0grp { fsl,pins = < SC_P_MIPI_CSI0_GPIO0_00_ADMA_I2C0_SCL 0x0C000020 diff --git a/arch/arm/dts/imx8-deneb.dts b/arch/arm/dts/imx8-deneb.dts deleted file mode 100644 index 04c764aa941..00000000000 --- a/arch/arm/dts/imx8-deneb.dts +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2019 Siemens AG - */ - -#include "imx8qxp-capricorn.dtsi" - -/ { - model = "Siemens Deneb"; -}; diff --git a/arch/arm/dts/imx8-giedi.dts b/arch/arm/dts/imx8-giedi.dts deleted file mode 100644 index 0dbfef2ee97..00000000000 --- a/arch/arm/dts/imx8-giedi.dts +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2019 Siemens AG - */ - -#include "imx8qxp-capricorn.dtsi" - -/ { - model = "Siemens Giedi"; -}; diff --git a/arch/arm/dts/imx8mm-phyboard-polis-rdk-u-boot.dtsi b/arch/arm/dts/imx8mm-phyboard-polis-rdk-u-boot.dtsi index 516e52e1f5d..512dbc9ee86 100644 --- a/arch/arm/dts/imx8mm-phyboard-polis-rdk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-phyboard-polis-rdk-u-boot.dtsi @@ -14,6 +14,10 @@ }; }; +&pinctrl_i2c1 { + bootph-pre-ram; +}; + &pinctrl_uart3 { bootph-pre-ram; }; @@ -54,6 +58,10 @@ bootph-pre-ram; }; +&i2c1 { + bootph-pre-ram; +}; + &uart3 { bootph-pre-ram; }; diff --git a/arch/arm/dts/imx8qxp-u-boot.dtsi b/arch/arm/dts/imx8qxp-u-boot.dtsi index 62791c34c77..8058caae9ba 100644 --- a/arch/arm/dts/imx8qxp-u-boot.dtsi +++ b/arch/arm/dts/imx8qxp-u-boot.dtsi @@ -120,6 +120,7 @@ }; }; +#ifdef CONFIG_XPL_BUILD imx-boot { filename = "flash.bin"; pad-byte = <0x00>; @@ -130,4 +131,5 @@ type = "blob-ext"; }; }; +#endif }; diff --git a/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi b/arch/arm/dts/imx93-phyboard-segin-u-boot.dtsi index 6897c91f4d9..0c3ca2961c9 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-imx6ul/ + 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>; @@ -139,6 +146,13 @@ &usdhc1 { bootph-pre-ram; bootph-some-ram; + /* + * Remove pinctrl assignments once they are added to imx93-phycore-som.dtsi + */ + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; }; &usdhc2 { @@ -215,6 +229,48 @@ MX93_PAD_ENET2_RD3__GPIO4_IO27 0x31e >; }; + + /* + * Remove pinctrl_usdhc1_100mhz and pinctrl_usdhc1_200mhz once they + * are added to imx93-phycore-som.dtsi + */ + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + bootph-pre-ram; + bootph-some-ram; + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x17be + MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000139e + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000139e + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013be + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000139e + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000139e + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000139e + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000139e + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000139e + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x179e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + bootph-pre-ram; + bootph-some-ram; + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x17be + MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000139e + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000139e + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013be + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013be + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013be + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013be + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013be + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013be + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013be + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x179e + >; + }; }; &lpi2c3 { @@ -305,4 +361,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/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 59d11b3179e..9a43beda6fa 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -54,15 +54,8 @@ config TARGET_COLIBRI_IMX8X select BOARD_LATE_INIT select IMX8QXP -config TARGET_DENEB - bool "Support i.MX8QXP Capricorn Deneb board" - select BINMAN - select BOARD_LATE_INIT - select FACTORYSET - select IMX8QXP - -config TARGET_GIEDI - bool "Support i.MX8QXP Capricorn Giedi board" +config TARGET_CAPRICORN + bool "Support i.MX8QXP Capricorn board" select BINMAN select BOARD_LATE_INIT select FACTORYSET diff --git a/arch/arm/mach-imx/imx9/Kconfig b/arch/arm/mach-imx/imx9/Kconfig index 5c1054138fc..2465e31d738 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 21e0e7dd1e8..6837ac82b05 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/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c index b85fd806cba..1adee9a461f 100644 --- a/board/boundary/nitrogen6x/nitrogen6x.c +++ b/board/boundary/nitrogen6x/nitrogen6x.c @@ -281,7 +281,7 @@ int board_eth_init(struct bd_info *bis) setup_iomux_enet(); #ifdef CONFIG_FEC_MXC - bus = fec_get_miibus(base, -1); + bus = fec_get_miibus(NULL, base, -1); if (!bus) return -EINVAL; /* scan phy 4,5,6,7 */ diff --git a/board/phytec/common/Kconfig b/board/phytec/common/Kconfig index f394ace786a..bc5511707ac 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 cd78f7686fe..8126f7356e1 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 00000000000..eb9574d43b5 --- /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 00000000000..a0803b47cbe --- /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_imx8mm/Kconfig b/board/phytec/phycore_imx8mm/Kconfig index 25e4bf2f836..06449128ba8 100644 --- a/board/phytec/phycore_imx8mm/Kconfig +++ b/board/phytec/phycore_imx8mm/Kconfig @@ -12,4 +12,5 @@ config SYS_CONFIG_NAME config IMX_CONFIG default "board/phytec/phycore_imx8mm/imximage-8mm-sd.cfg" +source "board/phytec/common/Kconfig" endif diff --git a/board/phytec/phycore_imx8mm/spl.c b/board/phytec/phycore_imx8mm/spl.c index 8d858590a39..faff064779c 100644 --- a/board/phytec/phycore_imx8mm/spl.c +++ b/board/phytec/phycore_imx8mm/spl.c @@ -17,8 +17,13 @@ #include <log.h> #include <spl.h> +#include "../common/imx8m_som_detection.h" + DECLARE_GLOBAL_DATA_PTR; +#define EEPROM_ADDR 0x51 +#define EEPROM_ADDR_FALLBACK 0x59 + int spl_board_boot_device(enum boot_device boot_dev_spl) { switch (boot_dev_spl) { @@ -39,6 +44,18 @@ int spl_board_boot_device(enum boot_device boot_dev_spl) static void spl_dram_init(void) { + int ret; + + ret = phytec_eeprom_data_setup_fallback(NULL, 0, EEPROM_ADDR, + EEPROM_ADDR_FALLBACK); + if (ret) + goto out; + + ret = phytec_imx8m_detect(NULL); + if (!ret) + phytec_print_som_info(NULL); + +out: ddr_init(&dram_timing); } diff --git a/board/phytec/phycore_imx93/Kconfig b/board/phytec/phycore_imx93/Kconfig index a70104cb798..09f26e89e33 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 9e91a29dc31..718f89a084a 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: configs/imx93-phyboard-segin_defconfig +F: board/phytec/common/imx93_som_detection.c +F: board/phytec/common/imx93_som_detection.h +F: configs/imx93-phycore_defconfig F: include/configs/phycore_imx93.h diff --git a/board/phytec/phycore_imx93/lpddr4_timing.c b/board/phytec/phycore_imx93/lpddr4_timing.c index 2111972a40e..f1261f6a92a 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; +} diff --git a/board/phytec/phycore_imx93/phycore-imx93.c b/board/phytec/phycore_imx93/phycore-imx93.c index 085c8e195a6..a55795e0603 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 17a8736c73f..a4d2aaac320 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); } diff --git a/board/siemens/capricorn/Kconfig b/board/siemens/capricorn/Kconfig index c5a28ff0220..fe230971e97 100644 --- a/board/siemens/capricorn/Kconfig +++ b/board/siemens/capricorn/Kconfig @@ -1,4 +1,5 @@ -if TARGET_GIEDI +if TARGET_CAPRICORN + config SYS_BOARD default "capricorn" @@ -7,24 +8,18 @@ config SYS_VENDOR default "siemens" config SYS_CONFIG_NAME - default "giedi" + default "capricorn-common" config IMX_CONFIG default "board/siemens/capricorn/imximage.cfg" -endif -if TARGET_DENEB - -config SYS_BOARD - default "capricorn" - -config SYS_VENDOR - default "siemens" +endif -config SYS_CONFIG_NAME - default "deneb" -config IMX_CONFIG - default "board/siemens/capricorn/imximage.cfg" +config SPL_CMT + bool "Enable Siemens SPL RAM test" + depends on SPL + help + Enable SIemens SPL RAM test. -endif +source "board/siemens/common/Kconfig" diff --git a/board/siemens/capricorn/MAINTAINERS b/board/siemens/capricorn/MAINTAINERS index b4c52032cc9..5f467aa9b6e 100644 --- a/board/siemens/capricorn/MAINTAINERS +++ b/board/siemens/capricorn/MAINTAINERS @@ -1,10 +1,12 @@ CAPRICORN BOARD +M: Alexander Sverdlin <alexander.sverdlin@siemens.com> M: Anatolij Gustschin <agust@denx.de> +M: Heiko Schocher <hs@denx.de> +M: Walter Schweizer <walter.schweizer@siemens.com> S: Maintained +F: arch/arm/dts/imx8-capricorn-cxg3.dts +F: arch/arm/dts/imx8-capricorn-u-boot.dtsi +F: arch/arm/dts/imx8-capricorn.dtsi F: board/siemens/capricorn/ +F: configs/capricorn_cxg3_defconfig F: include/configs/capricorn-common.h -F: include/configs/deneb.h -F: include/configs/giedi.h -F: include/configs/siemens-env-common.h -F: configs/deneb_defconfig -F: configs/giedi_defconfig diff --git a/board/siemens/capricorn/Makefile b/board/siemens/capricorn/Makefile index e8a24c448b9..a03d54ef3b3 100644 --- a/board/siemens/capricorn/Makefile +++ b/board/siemens/capricorn/Makefile @@ -8,6 +8,8 @@ obj-y += ../common/eeprom.o ifdef CONFIG_XPL_BUILD obj-y += spl.o +obj-$(CONFIG_SPL_CMT) += spl_memory_test.o else obj-y += ../common/factoryset.o +obj-$(CONFIG_DDR_SI_TEST) += ../common/ddr_si_test.o endif diff --git a/board/siemens/capricorn/board.c b/board/siemens/capricorn/board.c index ad474d9baa0..390a7b0d841 100644 --- a/board/siemens/capricorn/board.c +++ b/board/siemens/capricorn/board.c @@ -26,6 +26,7 @@ #include <asm/arch-imx8/clock.h> #endif #include <linux/delay.h> +#include "../common/board.h" #include "../common/eeprom.h" #include "../common/factoryset.h" @@ -63,8 +64,7 @@ int board_early_init_f(void) sc_pm_clock_rate_t rate = SC_80MHZ; int ret; - ret = sc_pm_setup_uart(SC_R_UART_0, rate); - ret |= sc_pm_setup_uart(SC_R_UART_2, rate); + ret = sc_pm_setup_uart(SC_R_UART_2, rate); if (ret) return ret; @@ -73,6 +73,40 @@ int board_early_init_f(void) return 0; } +#ifndef CONFIG_XPL_BUILD +void board_mem_get_layout(u64 *phys_sdram_1_start, + u64 *phys_sdram_1_size, + u64 *phys_sdram_2_start, + u64 *phys_sdram_2_size) +{ + sc_faddr_t addr_start, addr_end; + sc_faddr_t sdram_1_size, sdram_2_size; + sc_err_t sc_err; + + sc_err = sc_rm_get_memreg_info(-1, 6, &addr_start, &addr_end); + if (sc_err == SC_ERR_NONE) { + if (addr_end < 0x100000000) { + /* only lower RAM available */ + sdram_1_size = (addr_end + 1) - PHYS_SDRAM_1; + sdram_2_size = 0; + } else { + /* lower RAM (2 GB) und upper RAM available */ + sdram_1_size = SZ_2G; + sdram_2_size = (addr_end + 1) - PHYS_SDRAM_2; + } + } else { + /* Get default in case it would fail */ + sdram_1_size = PHYS_SDRAM_1_SIZE; + sdram_2_size = PHYS_SDRAM_2_SIZE; + } + + *phys_sdram_1_start = PHYS_SDRAM_1; + *phys_sdram_1_size = sdram_1_size; + *phys_sdram_2_start = PHYS_SDRAM_2; + *phys_sdram_2_size = sdram_2_size; +} +#endif /* ! CONFIG_XPL_BUILD */ + #define ENET_PHY_RESET IMX_GPIO_NR(0, 3) #define ENET_TEST_1 IMX_GPIO_NR(0, 8) #define ENET_TEST_2 IMX_GPIO_NR(0, 9) @@ -271,11 +305,7 @@ int checkboard(void) { puts("Board: Capricorn\n"); - /* - * Running build_info() doesn't work with current SCFW blob. - * Uncomment below call when new blob is available. - */ - /*build_info();*/ + build_info(); print_bootinfo(); return 0; @@ -283,6 +313,32 @@ int checkboard(void) int board_init(void) { + struct chip_data eeprom_data = {}; + char module_name[16]; + int ret; + + ret = siemens_ee_setup(); + if (ret) { + printf("'siemens_ee_setup' failed, ret: %d\n", ret); + goto skip; + } + + /* Get module name from EEPROM */ + siemens_ee_read_data(SIEMENS_EE_ADDR_DDR3, module_name, + sizeof(module_name)); + printf("CPU module: %s\n", module_name); + + ret = siemens_ee_read_data(SIEMENS_EE_ADDR_CHIP, + (uchar *)&eeprom_data, + sizeof(eeprom_data)); + if (ret) { + printf("'siemens_ee_read_data' failed, ret: %d\n", ret); + goto skip; + } + + printf("HW Version: %s\n", eeprom_data.shwver); +skip: + setup_fec(); return 0; } diff --git a/board/siemens/capricorn/imximage.cfg b/board/siemens/capricorn/imximage.cfg index 4350e2967cc..7fd3fb8b72e 100644 --- a/board/siemens/capricorn/imximage.cfg +++ b/board/siemens/capricorn/imximage.cfg @@ -9,13 +9,24 @@ /* Boot from SD, sector size 0x400 */ BOOT_FROM sd + +/* skip DCD data, as firmware initializes the RAM */ +DCD_SKIP true + /* SoC type IMX8QX */ SOC_TYPE IMX8QX -/* Append seco container image */ -APPEND ahab-container.img +/* + * Append seco container image, + * use same name as in arch/arm/dts/imx8qxp-u-boot.dtsi + */ +APPEND mx8qxc0-ahab-container.img /* Create the 2nd container */ CONTAINER -/* Add scfw image with exec attribute */ -IMAGE SCU capricorn-scfw-tcm.bin -/* Add ATF image with exec attribute */ +/* + * Add scfw image with exec attribute + * use same name as in arch/arm/dts/imx8qxp-u-boot.dtsi + */ +IMAGE SCU mx8qx-mek-scfw-tcm.bin + +/* Add SPL image with exec attribute */ IMAGE A35 spl/u-boot-spl.bin 0x00100000 diff --git a/board/siemens/capricorn/spl.c b/board/siemens/capricorn/spl.c index 696b5ebd340..5865cde80b4 100644 --- a/board/siemens/capricorn/spl.c +++ b/board/siemens/capricorn/spl.c @@ -15,12 +15,31 @@ #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <firmware/imx/sci/sci.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> +#include <asm/gpio.h> +#include <asm/arch/sys_proto.h> +#include "spl_memory_test.h" + DECLARE_GLOBAL_DATA_PTR; +#define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define USDHC2_SD_PWR IMX_GPIO_NR(4, 19) +static iomux_cfg_t usdhc2_sd_pwr[] = { + SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(GPIO_PAD_CTRL), +}; + void spl_board_init(void) { struct udevice *dev; + uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(imx8_scu), &dev); + uclass_find_first_device(UCLASS_MISC, &dev); for (; dev; uclass_find_next_device(&dev)) { @@ -34,8 +53,32 @@ void spl_board_init(void) timer_init(); + imx8_iomux_setup_multiple_pads(usdhc2_sd_pwr, ARRAY_SIZE(usdhc2_sd_pwr)); + gpio_direction_output(USDHC2_SD_PWR, 0); + preloader_console_init(); + + puts("Normal Boot\n"); + +#if IS_ENABLED(CONFIG_SPL_CMT) + spl_siemens_memory_full_test(); +#endif +} + +void spl_board_prepare_for_boot(void) +{ + imx8_power_off_pd_devices(NULL, 0); +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; } +#endif void board_init_f(ulong dummy) { diff --git a/board/siemens/capricorn/spl_memory_test.c b/board/siemens/capricorn/spl_memory_test.c new file mode 100644 index 00000000000..84c97e7853c --- /dev/null +++ b/board/siemens/capricorn/spl_memory_test.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright Siemens AG 2020 + * + * SPL Full Memory Test + * - memory test through the full DDR area + * - refresh over temperature torture (write all, read all) + * + * Remark: + * This test has ran properly with the definition of the RAM sizes in board + * headers. Since these headers are removed it's necessary to set the correct + * values to PHYS_SDRAM_1_SIZE & PHYS_SDRAM_2_SIZE before to recompile. + * + * An alternative is to refactor the code to get the size info from system + * controller + */ + +#include <init.h> +#include <log.h> + +/* ----- Defines ----- */ +#define CHECK_LOWER_UPPER + +#define LEVEL2_PRINT 0x0FFFFFFF + +/* use 0x7FFF0000 for shorter loop test */ +#define BASE_OFFSET 0x00000000 + +/* ----- Types ----- */ +struct ct_t { + unsigned long *start; + unsigned long *end; +}; + +/* ----- Variables ----- */ +static struct ct_t ct; +static unsigned long error_counter; + +static void print_parameters(void) +{ + printf("\nstart addr: %p\n", ct.start); + printf("end addr : %p\n", ct.end); +} + +static void run_test(void) +{ + /* moved full test in one void */ + unsigned long *address; /* 512 */ + unsigned long ebyte1; + unsigned long ebyte2; + unsigned int i; + unsigned long rpattern; + + for (i = 0; i <= 255; i++) { + memset(&ebyte1, i, sizeof(ebyte1)); + ebyte2 = ~ebyte1; + printf("LWord: %016lx #LWord: %016lx\n", ebyte1, ebyte2); + + /* write all bytes -> duration ~ 150 s */ + for (address = ct.start; address <= ct.end; address++) { +#ifdef LEVEL2_PRINT + if (((unsigned long)address & LEVEL2_PRINT) == 0) + printf("write to %p - %p\n", address, + (void *)((unsigned long)address + + LEVEL2_PRINT)); +#endif + *address = ebyte1; + address++; + *address = ebyte2; + } + + /* check all bytes */ + for (address = ct.start; address <= ct.end; address++) { +#ifdef LEVEL2_PRINT + if (((unsigned long)address & LEVEL2_PRINT) == 0) + printf("check from %p - %p\n", address, + (void *)((unsigned long)address + + LEVEL2_PRINT)); +#endif + + rpattern = *address; + if (rpattern != ebyte1) { + error_counter++; + printf("Error! Read: %016lX Wrote: %016lX Address: %p\n", + rpattern, ebyte1, address); + } + + address++; + rpattern = *address; + if (rpattern != ebyte2) { + error_counter++; + printf("Error! Read: %016lX Wrote: %016lX Address: %p\n", + rpattern, ebyte2, address); + } + } + } +} + +#ifdef CHECK_LOWER_UPPER +void test_lower_upper(void) +{ + /* + * write different values at the same address of both memory areas + * and check them + */ +#define TEST_ADDRESS 0x12345670UL +#define LOWER_ADDRESS (PHYS_SDRAM_1 + TEST_ADDRESS) +#define UPPER_ADDRESS (PHYS_SDRAM_2 + TEST_ADDRESS) +#define LOWER_VALUE 0x0011223344556677 +#define UPPER_VALUE 0x89ab89abffeeddcc + + *(unsigned long *)LOWER_ADDRESS = LOWER_VALUE; + *(unsigned long *)UPPER_ADDRESS = UPPER_VALUE; + + puts("\nlower-upper memory area test\n"); + printf("write %016lx to lower address %010lx\n", LOWER_VALUE, + LOWER_ADDRESS); + printf("write %016lx to upper address %010lx\n", UPPER_VALUE, + UPPER_ADDRESS); + printf("read %016lx from lower address %010lx\n", + *(unsigned long *)LOWER_ADDRESS, LOWER_ADDRESS); + printf("read %016lx from upper address %010lx\n", + *(unsigned long *)UPPER_ADDRESS, UPPER_ADDRESS); +} +#endif + +void spl_siemens_memory_full_test(void) +{ + unsigned long loopc = 0; + + puts("\nSPL: memory cell test\n"); + +#ifdef CHECK_LOWER_UPPER + if (PHYS_SDRAM_2_SIZE != 0) + test_lower_upper(); +#endif + + while (true) { + /* imx8x has 2 memory areas up to 2 GB */ + + /* 1st memory area @ 0x80000000 */ + ct.start = (unsigned long *)(PHYS_SDRAM_1 + BASE_OFFSET); + ct.end = (unsigned long *)(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE - 1); + print_parameters(); + run_test(); + + /* 2nd memory area @ 0x880000000 */ + if (PHYS_SDRAM_2_SIZE != 0) { + ct.start = (unsigned long *)(PHYS_SDRAM_2 + BASE_OFFSET); + ct.end = (unsigned long *)(PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE - 1); + print_parameters(); + run_test(); + } + + loopc++; + printf("loop: %ld, errors: %ld\n\n", loopc, error_counter); + }; +} diff --git a/board/siemens/capricorn/spl_memory_test.h b/board/siemens/capricorn/spl_memory_test.h new file mode 100644 index 00000000000..28df284b6d5 --- /dev/null +++ b/board/siemens/capricorn/spl_memory_test.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright Siemens AG 2020 + * + */ + +void spl_siemens_memory_full_test(void); diff --git a/board/siemens/common/Kconfig b/board/siemens/common/Kconfig index 131439fcfea..4ae12b1c973 100644 --- a/board/siemens/common/Kconfig +++ b/board/siemens/common/Kconfig @@ -1,2 +1,6 @@ config FACTORYSET bool + +config DDR_SI_TEST + bool "DDR signal integrity test implementations" + default y diff --git a/board/siemens/common/board.h b/board/siemens/common/board.h new file mode 100644 index 00000000000..db34bc78711 --- /dev/null +++ b/board/siemens/common/board.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Common board functions for siemens based boards + * (C) Copyright 2022 Siemens Schweiz AG + */ + +#ifndef __COMMON_BOARD_H +#define __COMMON_BOARD_H + +/* + * Chip data + * Offset in EEPROM: 0x120 - 0x14F + * + * ----------------------------------------------------------------------------------- + * | Address range | Content | + * ----------------------------------------------------------------------------------- + * | 0x120 - 0x123 | Magic Number - 0x43484950 (4 byte) | + * ----------------------------------------------------------------------------------- + * | 0x124 - 0x133 | Device Nomenclature (15 + 1 byte) | + * ----------------------------------------------------------------------------------- + * | 0x134 - 0x13A | HW Version of the form "v00.00" (6 + 1 byte) | + * | | - First 2 digits: Layout revision (starting from 1) | + * | | - Last 2 digits: Assembly variant revision (starting from 1) | + * ----------------------------------------------------------------------------------- + * | 0x13B - 0x13F | Flash Size in Gibit (4 + 1 byte) | + * ----------------------------------------------------------------------------------- + * | 0x140 - 0x144 | Ram Size in Gibit (4 + 1 byte) | + * ----------------------------------------------------------------------------------- + * | 0x145 - 0x14F | Sequence number, equals DMC-code (10 + 1 byte) [OBSOLETE] | + * ----------------------------------------------------------------------------------- + */ + +#define MAGIC_CHIP 0x50494843 +#define EEPROM_CHIP_OFFSET 0x120 + +struct chip_data { + unsigned int magic; + char sdevname[16]; + char shwver[7]; + char flash_size[5]; + char ram_size[5]; +}; + +#endif /* __COMMON_BOARD_H */ diff --git a/board/siemens/common/ddr_si_test.c b/board/siemens/common/ddr_si_test.c new file mode 100644 index 00000000000..c1f523eb3f4 --- /dev/null +++ b/board/siemens/common/ddr_si_test.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright Siemens AG 2023 + * + * DDR signal integrity test + * Check signals on DDR lines + * - signals must be as fast as possible and generate long burst + * - signals must be unidirectional (to DDR or from DDR only) + * + * Set pattern: define 2^n 32-bit patterns (up to 4) + * Addresses: must be multiple of 16 to avoid checks in loops + * Test functions + * - write: write pattern to memory area for iteration times + * - read: write pattern once to memory area, read for iteration times + */ + +#include <command.h> +#include <exports.h> +#include <time.h> +#if CONFIG_IS_ENABLED(AM33XX) +#include <asm/arch-am33xx/hardware_am33xx.h> +#include <asm/arch-am33xx/cpu.h> +#include <asm/io.h> +#endif + +/* enable some print for debugging */ +#ifdef PR_DEBUG + #define PDEBUG(fmt, args...) printf(fmt, ## args) +#else + #define PDEBUG(fmt, args...) +#endif + +/* define 4 32-bit patterns */ +#define MAX_PTN_SIZE (128) +#define PTN_ARRAY_SIZE (MAX_PTN_SIZE / (8 * sizeof(u32))) + +/* define test direction */ +#define DIR_READ 0 +#define DIR_WRITE 1 + +static union { + u64 l[2]; + u32 s[4]; + } test_pattern; +static int num_ptn32; + +#if CONFIG_IS_ENABLED(AM33XX) +static inline void wdt_disable(void) +{ + struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + + writel(0xAAAA, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; + writel(0x5555, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; +} + +static inline void wdt_enable(void) +{ + struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; + + writel(0xBBBB, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; + writel(0x4444, &wdtimer->wdtwspr); + while (readl(&wdtimer->wdtwwps) != 0x0) + ; +} +#else /* ! */ +static inline void wdt_disable(void) {} + +static inline void wdt_enable(void) {} +#endif /* CONFIG_IS_ENABLED(AM33XX) */ + +static int do_ddr_set_ptn(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int i, n; + + if (argc < 1) + return CMD_RET_USAGE; + + /* number of patterns: 2 exponent */ + n = argc - 1; + if (n > PTN_ARRAY_SIZE || (n & (n - 1))) + return CMD_RET_USAGE; + num_ptn32 = n; + + /* get patterns */ + for (i = 0; i < n; i++) + test_pattern.s[i] = simple_strtoul(argv[i + 1], NULL, 0); + + printf("Test pattern set\n"); + + return CMD_RET_SUCCESS; +} + +static int do_ddr_show_ptn(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (!num_ptn32) { + printf("No pattern available\n"); + } else { + u32 *buf = test_pattern.s; + int len = num_ptn32; + int i; + + printf("Pattern: "); + for (i = 0 ; i < len; i++) + printf("0x%08X ", *buf++); + + printf("\n"); + } + + return CMD_RET_SUCCESS; +} + +static void ddr_read32(u64 start_addr, u64 n_word, unsigned long iter) +{ + while (iter--) { + register volatile u32 *addr = (u32 *)start_addr; + register u64 count = n_word; + + while (count) { + (void)*addr++; + PDEBUG("Read 0x%08X from 0x%p\n", val, addr - 1); + count--; + } + } +} + +static void ddr_read64(u64 start_addr, u64 n_word, unsigned long iter) +{ + while (iter--) { + register volatile u64 *addr = (u64 *)start_addr; + register u64 count = n_word; + + if (num_ptn32 == 4) + count *= 2; + + /* + * 64 & 128 bit pattern. Increase the nummber of read + * commands in the loop to generate longer burst signal + */ + while (count) { + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + (void)*addr++; + PDEBUG("Read 0x%016llX from 0x%p\n", val, addr - 1); + /* + * underflow cannot happen since n_word = end - + * start, end & start addresses are checked to be + * multiple of 16 + */ + count -= 8; + } + } +} + +static void ddr_write32(u64 start_addr, u64 n_word, unsigned long iter) +{ + while (iter--) { + register u32 *addr = (u32 *)start_addr; + register u32 ptn = *test_pattern.s; + register u64 count = n_word; + + while (count) { + PDEBUG("Write 0x%08X to 0x%p\n", ptn, addr); + *addr++ = ptn; + count--; + } + } +} + +static void ddr_write64(u64 start_addr, u64 n_word, unsigned long iter) +{ + while (iter--) { + register u64 *addr = (u64 *)start_addr; + register u64 ptnA = test_pattern.l[0]; + register u64 ptnB = test_pattern.l[1]; + register u64 count = n_word; + + if (num_ptn32 == 2) + ptnB = ptnA; + else + count *= 2; + + /* + * 64 & 128 bit pattern. Increase the nummber of write + * commands in the loop to generate longer burst signal + */ + while (count) { + PDEBUG("Write 0x%016llX to 0x%p\n", ptnA, addr); + *addr++ = ptnA; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnB, addr); + *addr++ = ptnB; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnA, addr); + *addr++ = ptnA; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnB, addr); + *addr++ = ptnB; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnA, addr); + *addr++ = ptnA; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnB, addr); + *addr++ = ptnB; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnA, addr); + *addr++ = ptnA; + PDEBUG("Write 0x%016llX to 0x%p\n", ptnB, addr); + *addr++ = ptnB; + /* + * underflow cannot happen since n_word = end - + * start, end & start addresses are checked to be + * multiple of 16 + */ + count -= 8; + } + } +} + +static int do_ddr_si_test(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + u64 start_addr, end_addr, n_word; + u64 ts_start, ts_end; + unsigned long iteration, wr_iter; + int direction, i; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + /* get arguments */ + direction = strcmp(argv[0], "read") ? DIR_WRITE : DIR_READ; + start_addr = simple_strtoul(argv[1], NULL, 0); + end_addr = simple_strtoul(argv[2], NULL, 0); + iteration = simple_strtoul(argv[3], NULL, 10); + + n_word = (end_addr - start_addr) / (num_ptn32 * 4); + printf("\nDDR signal integrity %s test: start\n", argv[0]); + /* checks */ + if (start_addr & 0xF) { + printf("ERROR: start_address should be 16 bytes aligned\n\n"); + return CMD_RET_USAGE; + } + + if (end_addr & 0xF) { + printf("ERROR: end_address should be 16 bytes aligned\n\n"); + return CMD_RET_USAGE; + } + + if (start_addr >= end_addr) { + printf("ERROR: end_address is not bigger than start_address\n\n"); + return CMD_RET_USAGE; + } + + if (!iteration) { + printf("ERROR: no iteration specified\n\n"); + return CMD_RET_USAGE; + } + + if (!num_ptn32) { + printf("ERROR: no test pattern specified\n\n"); + return CMD_RET_USAGE; + } + + /* print parameters */ + printf("start_address = 0x%016llX\n", start_addr); + printf("end_address = 0x%016llX\n", end_addr); + printf("iterations = %lu\n", iteration); + + /* print pattern */ + printf("test pattern 0x"); + for (i = 0; i < num_ptn32; i++) + printf("%08X", test_pattern.s[i]); + + printf("\n"); + + wdt_disable(); + + /* writing */ + printf("Writing..\n"); + ts_start = get_timer_us(0); + + if (direction == DIR_READ) + wr_iter = 1; + else + wr_iter = iteration; + + if (num_ptn32 == 1) + ddr_write32(start_addr, n_word, wr_iter); + else + ddr_write64(start_addr, n_word, wr_iter); + + ts_end = get_timer_us(0); + + /* reading */ + if (direction == DIR_READ) { + printf("Reading..\n"); + /* we need read time, just overwrite */ + ts_start = get_timer_us(0); + + if (num_ptn32 == 1) + ddr_read32(start_addr, n_word, iteration); + else + ddr_read64(start_addr, n_word, iteration); + + ts_end = get_timer_us(0); + } + + wdt_enable(); + + /* print stats */ + printf("DONE."); + printf(" Bytes=%llu ", n_word * num_ptn32 * 4 * iteration); + printf(" Time=%llu us ", ts_end - ts_start); + printf("\nDDR signal integrity %s test: end\n", argv[0]); + + return CMD_RET_SUCCESS; +} + +static char ddr_si_help_text[] = + "- DDR signal integrity test\n\n" + "ddr_si setptn <pattern> [<pattern>] : set [1,2,4] 32-bit patterns\n" + "ddr_si showptn : show patterns\n" + "ddr_si read <start> <end> <iterations> : run test for reading\n" + "ddr_si write <start> <end> <iterations> : run test for writing\n" + "\nWith\n" + "\t<pattern>: 32-bit pattern in hex format\n" + "\t<start>: test start address in hex format\n" + "\t<end>: test end address in hex format\n" + "\t<iterations>: number of iterations\n"; + +U_BOOT_CMD_WITH_SUBCMDS(ddr_si, "DDR si test", ddr_si_help_text, + U_BOOT_SUBCMD_MKENT(setptn, 5, 0, do_ddr_set_ptn), + U_BOOT_SUBCMD_MKENT(showptn, 1, 0, do_ddr_show_ptn), + U_BOOT_SUBCMD_MKENT(read, 4, 0, do_ddr_si_test), + U_BOOT_SUBCMD_MKENT(write, 4, 0, do_ddr_si_test)); diff --git a/board/siemens/draco/board.h b/board/siemens/draco/board.h index 935f340a8f2..77f35a6ab7b 100644 --- a/board/siemens/draco/board.h +++ b/board/siemens/draco/board.h @@ -11,6 +11,8 @@ #ifndef _BOARD_DRACO_H_ #define _BOARD_DRACO_H_ +#include "../common/board.h" + #define PARGS(x) #x , /* Parameter Name */ \ settings.ddr3.x, /* EEPROM Value */ \ ddr3_default.x, /* Default Value */ \ @@ -18,8 +20,6 @@ #define PRINTARGS(y) printf("%-20s, %8x, %8x, %4d\n", PARGS(y)) -#define MAGIC_CHIP 0x50494843 - /* Automatic generated definition */ /* Wed, 16 Apr 2014 16:50:41 +0200 */ /* From file: draco/ddr3-data-universal-default@303MHz-i0-ES3.txt */ @@ -43,12 +43,6 @@ struct ddr3_data { char manu_marking[32]; /* "default \0" */ }; -struct chip_data { - unsigned int magic; - char sdevname[16]; - char shwver[7]; -}; - struct draco_baseboard_id { struct ddr3_data ddr3; struct chip_data chip; diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index e9269ef5353..b543bf8c1fb 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -385,7 +385,7 @@ static int find_ethernet_phy(void) int phy_addr = -ENOENT; #ifdef CONFIG_FEC_MXC - bus = fec_get_miibus(ENET_BASE_ADDR, -1); + bus = fec_get_miibus(NULL, ENET_BASE_ADDR, -1); if (!bus) return -ENOENT; diff --git a/configs/deneb_defconfig b/configs/capricorn_cxg3_defconfig index 98841bb8771..276445528a9 100644 --- a/configs/deneb_defconfig +++ b/configs/capricorn_cxg3_defconfig @@ -10,10 +10,11 @@ CONFIG_NR_DRAM_BANKS=3 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000 CONFIG_ENV_SIZE=0x2000 -CONFIG_ENV_OFFSET=0x0 +CONFIG_ENV_OFFSET=0x200000 CONFIG_DM_GPIO=y -CONFIG_DEFAULT_DEVICE_TREE="imx8-deneb" -CONFIG_TARGET_DENEB=y +CONFIG_DEFAULT_DEVICE_TREE="imx8-capricorn-cxg3" +CONFIG_SPL_TEXT_BASE=0x100000 +CONFIG_TARGET_CAPRICORN=y CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y @@ -25,7 +26,7 @@ CONFIG_SPL_BSS_MAX_SIZE=0x1000 CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_SYS_LOAD_ADDR=0x80280000 CONFIG_SPL=y -CONFIG_ENV_OFFSET_REDUND=0x2000 +CONFIG_ENV_OFFSET_REDUND=0x202000 CONFIG_IDENT_STRING=" ##v01.06" CONFIG_REMAKE_ELF=y # CONFIG_EFI_LOADER is not set @@ -55,9 +56,10 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SYS_MALLOC=y CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x120000 -CONFIG_SPL_SYS_MALLOC_SIZE=0x3000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x4000 CONFIG_SPL_SYS_MMCSD_RAW_MODE=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x800 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040 CONFIG_SPL_POWER_DOMAIN=y CONFIG_SPL_WATCHDOG=y CONFIG_HUSH_PARSER=y @@ -112,10 +114,13 @@ CONFIG_PHYLIB=y CONFIG_MV88E61XX_SWITCH=y CONFIG_MV88E61XX_CPU_PORT=5 CONFIG_MV88E61XX_PHY_PORTS=0x7 +CONFIG_DM_ETH_PHY=y CONFIG_FEC_MXC_SHARE_MDIO=y CONFIG_FEC_MXC_MDIO_BASE=0x5B050000 CONFIG_FEC_MXC=y CONFIG_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8=y @@ -129,5 +134,7 @@ CONFIG_DM_SERIAL=y CONFIG_FSL_LPUART=y CONFIG_DM_THERMAL=y CONFIG_IMX_SCU_THERMAL=y -# CONFIG_SPL_WDT is not set +# CONFIG_WATCHDOG is not set +CONFIG_WDT=y +CONFIG_WDT_SIEMENS_PMIC=y CONFIG_SPL_TINY_MEMSET=y diff --git a/configs/giedi_defconfig b/configs/giedi_defconfig deleted file mode 100644 index af9c7a4aed6..00000000000 --- a/configs/giedi_defconfig +++ /dev/null @@ -1,133 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_IMX8=y -CONFIG_TEXT_BASE=0x80020000 -CONFIG_SYS_MALLOC_LEN=0x2800000 -CONFIG_SYS_MALLOC_F_LEN=0x4000 -CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=3 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000 -CONFIG_ENV_SIZE=0x2000 -CONFIG_ENV_OFFSET=0x0 -CONFIG_DM_GPIO=y -CONFIG_DEFAULT_DEVICE_TREE="imx8-giedi" -CONFIG_TARGET_GIEDI=y -CONFIG_SPL_MMC=y -CONFIG_SPL_SERIAL=y -CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK=0x13e000 -CONFIG_SPL_TEXT_BASE=0x100000 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x128000 -CONFIG_SPL_BSS_MAX_SIZE=0x1000 -CONFIG_SYS_BOOTM_LEN=0x800000 -CONFIG_SYS_LOAD_ADDR=0x80280000 -CONFIG_SPL=y -CONFIG_ENV_OFFSET_REDUND=0x2000 -CONFIG_IDENT_STRING=" ##v01.07" -CONFIG_REMAKE_ELF=y -# CONFIG_EFI_LOADER is not set -CONFIG_FIT=y -CONFIG_FIT_EXTERNAL_OFFSET=0x3000 -CONFIG_BOOTDELAY=3 -CONFIG_AUTOBOOT_KEYED=y -CONFIG_AUTOBOOT_PROMPT="Autobooting in %d seconds, press \"<Esc><Esc>\" to stop\n" -CONFIG_AUTOBOOT_STOP_STR="\x1b\x1b" -CONFIG_AUTOBOOT_KEYED_CTRLC=y -CONFIG_OF_BOARD_SETUP=y -CONFIG_OF_SYSTEM_SETUP=y -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="if usrbutton; then run flash_self_test; reset; fi;run flash_self;reset;" -CONFIG_SYS_CBSIZE=2048 -CONFIG_SYS_PBSIZE=2073 -CONFIG_LOG=y -CONFIG_BOARD_EARLY_INIT_F=y -CONFIG_SPL_MAX_SIZE=0x1f000 -CONFIG_SPL_BOARD_INIT=y -# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_LEGACY_IMAGE_FORMAT is not set -CONFIG_SPL_LOAD_IMX_CONTAINER=y -CONFIG_IMX_CONTAINER_CFG="board/siemens/capricorn/uboot-container.cfg" -CONFIG_SPL_SYS_MALLOC_SIMPLE=y -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set -CONFIG_SPL_SYS_MALLOC=y -CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y -CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x120000 -CONFIG_SPL_SYS_MALLOC_SIZE=0x3000 -CONFIG_SPL_SYS_MMCSD_RAW_MODE=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x800 -CONFIG_SPL_POWER_DOMAIN=y -CONFIG_SPL_WATCHDOG=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_PROMPT="U-Boot# " -CONFIG_CMD_CPU=y -# CONFIG_BOOTM_NETBSD is not set -# CONFIG_CMD_EXPORTENV is not set -# CONFIG_CMD_IMPORTENV is not set -# CONFIG_CMD_CRC32 is not set -CONFIG_CMD_CLK=y -CONFIG_CMD_DM=y -CONFIG_CMD_FUSE=y -CONFIG_CMD_GPIO=y -CONFIG_CMD_I2C=y -CONFIG_CMD_MMC=y -CONFIG_CMD_READ=y -CONFIG_CMD_DHCP=y -CONFIG_CMD_MII=y -CONFIG_CMD_PING=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_EXT2=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_MMC=y -CONFIG_SYS_REDUNDAND_ENVIRONMENT=y -CONFIG_SYS_MMC_ENV_PART=2 -CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y -CONFIG_USE_ETHPRIME=y -CONFIG_ETHPRIME="eth1" -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_SPL_DM=y -CONFIG_BOOTCOUNT_LIMIT=y -CONFIG_BOOTCOUNT_ENV=y -CONFIG_SPL_CLK=y -CONFIG_CLK_IMX8=y -CONFIG_CPU=y -CONFIG_MXC_GPIO=y -CONFIG_DM_I2C=y -CONFIG_SYS_I2C_IMX_LPI2C=y -CONFIG_LED=y -CONFIG_LED_GPIO=y -CONFIG_MISC=y -CONFIG_SUPPORT_EMMC_BOOT=y -CONFIG_MMC_IO_VOLTAGE=y -CONFIG_MMC_UHS_SUPPORT=y -CONFIG_MMC_HS400_SUPPORT=y -CONFIG_FSL_USDHC=y -CONFIG_PHYLIB=y -CONFIG_MV88E61XX_SWITCH=y -CONFIG_MV88E61XX_CPU_PORT=5 -CONFIG_MV88E61XX_PHY_PORTS=0x7 -CONFIG_FEC_MXC_SHARE_MDIO=y -CONFIG_FEC_MXC_MDIO_BASE=0x5B050000 -CONFIG_FEC_MXC=y -CONFIG_MII=y -CONFIG_PINCTRL=y -CONFIG_SPL_PINCTRL=y -CONFIG_PINCTRL_IMX8=y -CONFIG_POWER_DOMAIN=y -CONFIG_IMX8_POWER_DOMAIN=y -CONFIG_DM_REGULATOR=y -CONFIG_DM_REGULATOR_FIXED=y -CONFIG_DM_REGULATOR_GPIO=y -CONFIG_SPL_DM_REGULATOR_GPIO=y -CONFIG_DM_SERIAL=y -CONFIG_FSL_LPUART=y -CONFIG_DM_THERMAL=y -CONFIG_IMX_SCU_THERMAL=y -# CONFIG_SPL_WDT is not set -CONFIG_SPL_TINY_MEMSET=y diff --git a/configs/imx93-phyboard-segin_defconfig b/configs/imx93-phycore_defconfig index 309262c4303..cf9800118ac 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/configs/phycore-imx8mm_defconfig b/configs/phycore-imx8mm_defconfig index 5e59efe5649..c24580430f2 100644 --- a/configs/phycore-imx8mm_defconfig +++ b/configs/phycore-imx8mm_defconfig @@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x3C0000 CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mm-phyboard-polis-rdk" CONFIG_TARGET_PHYCORE_IMX8MM=y +CONFIG_PHYTEC_SOM_DETECTION=y CONFIG_DM_RESET=y CONFIG_SYS_MONITOR_LEN=524288 CONFIG_SPL_MMC=y diff --git a/doc/board/phytec/imx93-phyboard-segin.rst b/doc/board/phytec/imx93-phycore.rst index ce17fbec78d..bd110a3ebee 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 99848a9e958..fa306974645 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 diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 591d71b096a..a40c8badf9a 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -951,6 +951,26 @@ int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window) return ret; } +int sc_timer_control_siemens_pmic_wdog(sc_ipc_t ipc, u8 cmd) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SVC(&msg) = (u8)SC_RPC_SVC_TIMER; + RPC_FUNC(&msg) = (u8)TIMER_FUNC_CTRL_SIEMENS_PMIC_WDOG; + RPC_U8(&msg, 0U) = (u8)cmd; + RPC_SIZE(&msg) = 2U; + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s: res:%d\n", __func__, RPC_R8(&msg)); + + return ret; +} + int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd, sc_faddr_t addr) { diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index d6d5cb52fdd..eca681b16d1 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -160,7 +160,7 @@ static int fec_get_clk_rate(void *udev, int idx) } } -static void fec_mii_setspeed(struct ethernet_regs *eth) +static void fec_mii_setspeed(struct udevice *dev, struct ethernet_regs *eth) { /* * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock @@ -182,7 +182,7 @@ static void fec_mii_setspeed(struct ethernet_regs *eth) u32 hold; int ret; - ret = fec_get_clk_rate(NULL, 0); + ret = fec_get_clk_rate(dev, 0); if (ret < 0) { printf("Can't find FEC0 clk rate: %d\n", ret); return; @@ -581,7 +581,7 @@ static int fecmxc_init(struct udevice *dev) fec_reg_setup(fec); if (fec->xcv_type != SEVENWIRE) - fec_mii_setspeed(fec->bus->priv); + fec_mii_setspeed(dev, fec->bus->priv); /* Set Opcode/Pause Duration Register */ writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ @@ -996,7 +996,7 @@ static void fec_free_descs(struct fec_priv *fec) free(fec->tbd_base); } -struct mii_dev *fec_get_miibus(ulong base_addr, int dev_id) +struct mii_dev *fec_get_miibus(struct udevice *dev, ulong base_addr, int dev_id) { struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; struct mii_dev *bus; @@ -1018,7 +1018,7 @@ struct mii_dev *fec_get_miibus(ulong base_addr, int dev_id) free(bus); return NULL; } - fec_mii_setspeed(eth); + fec_mii_setspeed(dev, eth); return bus; } @@ -1354,10 +1354,10 @@ static int fecmxc_probe(struct udevice *dev) if (!bus) { dm_mii_bus = false; #ifdef CONFIG_FEC_MXC_MDIO_BASE - bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, + bus = fec_get_miibus(dev, (ulong)CONFIG_FEC_MXC_MDIO_BASE, dev_seq(dev)); #else - bus = fec_get_miibus((ulong)priv->eth, dev_seq(dev)); + bus = fec_get_miibus(dev, (ulong)priv->eth, dev_seq(dev)); #endif } if (!bus) { diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0e45f0a0922..b39b2546e5c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -351,6 +351,13 @@ config WDT_SBSA In the single stage mode, when the timeout is reached, your system will be reset by WS1. The first signal (WS0) is ignored. +config WDT_SIEMENS_PMIC + bool "Enable PMIC Watchdog Timer support for Siemens platforms" + depends on ARCH_IMX8 && WDT + help + Select this to enable the PMIC watchdog driver controlled via + IMX8 SCU API found on Siemens platforms. + config WDT_SL28CPLD bool "sl28cpld watchdog timer support" depends on WDT && SL28CPLD diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 0b107c008f7..9b6b1a8e8ad 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o +obj-$(CONFIG_WDT_SIEMENS_PMIC) += siemens_pmic_wdt.o obj-$(CONFIG_WDT_SL28CPLD) += sl28cpld-wdt.o obj-$(CONFIG_WDT_SP805) += sp805_wdt.o obj-$(CONFIG_WDT_STARFIVE) += starfive_wdt.o diff --git a/drivers/watchdog/siemens_pmic_wdt.c b/drivers/watchdog/siemens_pmic_wdt.c new file mode 100644 index 00000000000..87e817bb5b2 --- /dev/null +++ b/drivers/watchdog/siemens_pmic_wdt.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Driver for a PMIC watchdog timer controlled via Siemens SCU firmware + * extensions. Only useful on some Siemens i.MX8-based platforms as + * special NXP SCFW is needed which provides the needed SCU API. + * + * Copyright (C) 2024 Siemens AG + */ + +#include <dm.h> +#include <wdt.h> +#include <firmware/imx/sci/sci.h> + +/* watchdog commands */ +#define CMD_START_WDT 0x55 +#define CMD_STOP_WDT 0x45 +#define CMD_PING_WDT 0x35 + +static int scu_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + /* start external watchdog via Timer API */ + return sc_timer_control_siemens_pmic_wdog(-1, CMD_START_WDT); +} + +static int scu_wdt_stop(struct udevice *dev) +{ + /* stop external watchdog via Timer API */ + return sc_timer_control_siemens_pmic_wdog(-1, CMD_STOP_WDT); +} + +static int scu_wdt_reset(struct udevice *dev) +{ + return sc_timer_control_siemens_pmic_wdog(-1, CMD_PING_WDT); +} + +static int scu_wdt_probe(struct udevice *dev) +{ + debug("%s(dev=%p)\n", __func__, dev); + return 0; +} + +static const struct wdt_ops scu_wdt_ops = { + .reset = scu_wdt_reset, + .start = scu_wdt_start, + .stop = scu_wdt_stop, +}; + +static const struct udevice_id scu_wdt_ids[] = { + { .compatible = "siemens,scu-wdt" }, + { } +}; + +U_BOOT_DRIVER(scu_wdt) = { + .name = "scu_wdt", + .id = UCLASS_WDT, + .of_match = scu_wdt_ids, + .probe = scu_wdt_probe, + .ops = &scu_wdt_ops, +}; diff --git a/include/configs/capricorn-common.h b/include/configs/capricorn-common.h index 1f61b2b6af6..4d95f3fd79b 100644 --- a/include/configs/capricorn-common.h +++ b/include/configs/capricorn-common.h @@ -95,7 +95,9 @@ #define CFG_SYS_SDRAM_BASE 0x80000000 #define PHYS_SDRAM_1 0x80000000 #define PHYS_SDRAM_2 0x880000000 -/* DDR3 board total DDR is 1 GB */ +/* Set default values to the smallest DDR we have in capricorn modules + * Use it in case the system controller would return an error + */ #define PHYS_SDRAM_1_SIZE 0x40000000 /* 1 GB */ #define PHYS_SDRAM_2_SIZE 0x00000000 /* 0 GB */ diff --git a/include/configs/deneb.h b/include/configs/deneb.h deleted file mode 100644 index f155bb8bf50..00000000000 --- a/include/configs/deneb.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2019 Siemens AG - * - */ - -#ifndef __DENEB_H -#define __DENEB_H - -#include "capricorn-common.h" - -/* DDR3 board total DDR is 2 GB */ -#undef PHYS_SDRAM_1_SIZE -#define PHYS_SDRAM_1_SIZE 0x80000000 /* 2 GB */ - -#endif /* __DENEB_H */ diff --git a/include/firmware/imx/sci/rpc.h b/include/firmware/imx/sci/rpc.h index 28adec2a8e1..04acc7ff95b 100644 --- a/include/firmware/imx/sci/rpc.h +++ b/include/firmware/imx/sci/rpc.h @@ -231,4 +231,7 @@ struct sc_rpc_msg_s { #define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U /* Index for sc_timer_set_sysctr_periodic_alarm() RPC call */ #define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U /* Index for sc_timer_cancel_sysctr_alarm() RPC call */ +/* Siemens specific API extension */ +#define TIMER_FUNC_CTRL_SIEMENS_PMIC_WDOG 20U /*!< Index for sc_timer_ctrl_pmic_wdog() RPC call */ + #endif /* SC_RPC_H */ diff --git a/include/firmware/imx/sci/sci.h b/include/firmware/imx/sci/sci.h index 7d8499f070a..588f3671103 100644 --- a/include/firmware/imx/sci/sci.h +++ b/include/firmware/imx/sci/sci.h @@ -123,6 +123,7 @@ int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid); /* Timer API */ int sc_timer_set_wdog_window(sc_ipc_t ipc, sc_timer_wdog_time_t window); +int sc_timer_control_siemens_pmic_wdog(sc_ipc_t ipc, u8 cmd); /* SECO API */ int sc_seco_authenticate(sc_ipc_t ipc, sc_seco_auth_cmd_t cmd, diff --git a/include/netdev.h b/include/netdev.h index 2a06d9a261b..949245ecdec 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -117,7 +117,7 @@ static inline int pci_eth_init(struct bd_info *bis) return num; } -struct mii_dev *fec_get_miibus(ulong base_addr, int dev_id); +struct mii_dev *fec_get_miibus(struct udevice *dev, ulong base_addr, int dev_id); #ifdef CONFIG_PHYLIB struct phy_device; diff --git a/tools/imx8image.c b/tools/imx8image.c index 7a060811c7e..15510d3e712 100644 --- a/tools/imx8image.c +++ b/tools/imx8image.c @@ -734,7 +734,7 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align) fclose(fd); if (header.tag != IVT_HEADER_TAG_B0) { - fprintf(stderr, "header tag mismatched \n"); + fprintf(stderr, "header tag mismatched file %s\n", img_sp->filename); exit(EXIT_FAILURE); } else { file_off += diff --git a/tools/imx_cntr_image.sh b/tools/imx_cntr_image.sh index 972b95ccbee..07acd385631 100755 --- a/tools/imx_cntr_image.sh +++ b/tools/imx_cntr_image.sh @@ -14,6 +14,10 @@ for f in $blobs; do continue fi + if [ $f = "spl/u-boot-spl.bin" ]; then + continue + fi + if [ -f $f ]; then continue fi |