Merge tag 'u-boot-imx-next-20241126' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx into next

CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/23563

- Make Siemens i.MX8 Capricorn board to boot U-Boot mainline again.
- Add support for phycore-imx93 2GB LPDDR4X variant.
- Add phycore-imx8mm EEPROM detection initialisation.
This commit is contained in:
Tom Rini
2024-11-26 10:49:44 -06:00
55 changed files with 2142 additions and 448 deletions
+1 -2
View File
@@ -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
+129
View File
@@ -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
>;
};
};
@@ -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;
};
@@ -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
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019 Siemens AG
*/
#include "imx8qxp-capricorn.dtsi"
/ {
model = "Siemens Deneb";
};
-10
View File
@@ -1,10 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019 Siemens AG
*/
#include "imx8qxp-capricorn.dtsi"
/ {
model = "Siemens Giedi";
};
@@ -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;
};
+2
View File
@@ -120,6 +120,7 @@
};
};
#ifdef CONFIG_XPL_BUILD
imx-boot {
filename = "flash.bin";
pad-byte = <0x00>;
@@ -130,4 +131,5 @@
type = "blob-ext";
};
};
#endif
};
+67 -2
View File
@@ -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>;
};
};
+2 -9
View File
@@ -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
+2
View File
@@ -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
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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 */
+8
View File
@@ -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) && \
+1
View File
@@ -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
+111
View File
@@ -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) */
+51
View File
@@ -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 */
+1
View File
@@ -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
+17
View File
@@ -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);
}
+28
View File
@@ -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
+5 -2
View File
@@ -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
File diff suppressed because it is too large Load Diff
@@ -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;
}
+48
View File
@@ -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);
}
+12 -17
View File
@@ -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"
config IMX_CONFIG
default "board/siemens/capricorn/imximage.cfg"
endif
if TARGET_DENEB
config SYS_BOARD
default "capricorn"
config SYS_VENDOR
default "siemens"
config SYS_CONFIG_NAME
default "deneb"
default "capricorn-common"
config IMX_CONFIG
default "board/siemens/capricorn/imximage.cfg"
endif
config SPL_CMT
bool "Enable Siemens SPL RAM test"
depends on SPL
help
Enable SIemens SPL RAM test.
source "board/siemens/common/Kconfig"
+7 -5
View File
@@ -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
+2
View File
@@ -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
+63 -7
View File
@@ -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;
}
+16 -5
View File
@@ -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
+43
View File
@@ -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,9 +53,33 @@ 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)
{
/* Clear global data */
+158
View File
@@ -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);
};
}
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright Siemens AG 2020
*
*/
void spl_siemens_memory_full_test(void);
+4
View File
@@ -1,2 +1,6 @@
config FACTORYSET
bool
config DDR_SI_TEST
bool "DDR signal integrity test implementations"
default y
+44
View File
@@ -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 */
+348
View File
@@ -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));
+2 -8
View File
@@ -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;
+1 -1
View File
@@ -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;
@@ -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
-133
View File
@@ -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
@@ -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;"
+1
View File
@@ -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
@@ -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:
+1 -1
View File
@@ -7,7 +7,7 @@ PHYTEC
:maxdepth: 2
imx8mm-phygate-tauri-l
imx93-phyboard-segin
imx93-phycore
phycore-am62x
phycore-am64x
phycore-imx8mm
+20
View File
@@ -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)
{
+7 -7
View File
@@ -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) {
+7
View File
@@ -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
+1
View File
@@ -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
+59
View File
@@ -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,
};
+3 -1
View File
@@ -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 */
-16
View File
@@ -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 */
+3
View File
@@ -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 */
+1
View File
@@ -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,
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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 +=
+4
View File
@@ -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