From ef7b440a8b8dec65d60a66d633b5af4e40b19eab Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Sun, 13 Apr 2025 13:01:18 +0200 Subject: [PATCH 01/14] MAINTAINERS: Update email of Stefano Babic Replace my old e-mail with the current one to get still involved in the project. Signed-off-by: Stefano Babic --- .mailmap | 2 +- MAINTAINERS | 2 +- doc/git-mailrc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.mailmap b/.mailmap index 4afc3b7e0d5..5c481144ddc 100644 --- a/.mailmap +++ b/.mailmap @@ -125,7 +125,7 @@ Siva Durga Prasad Paladugu Srinivas Neeli Stefan Roese -Stefano Babic +Stefano Babic Stefano Stabellini Sumit Garg Tom Rini diff --git a/MAINTAINERS b/MAINTAINERS index ebbb0b6e8d0..d62dd35a385 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -297,7 +297,7 @@ F: test/cmd/armffa.c F: test/dm/ffa.c ARM FREESCALE IMX -M: Stefano Babic +M: Stefano Babic M: Fabio Estevam R: NXP i.MX U-Boot Team S: Maintained diff --git a/doc/git-mailrc b/doc/git-mailrc index 1177e42df2f..6214daeaecf 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -42,7 +42,7 @@ alias mbrugger Matthias Brugger alias monstr Michal Simek alias prom Minkyu Kang alias ptomsich Philipp Tomsich -alias sbabic Stefano Babic +alias sbabic Stefano Babic alias simongoldschmidt Simon Goldschmidt alias sjg Simon Glass alias smcnutt Scott McNutt From 566af0b21fde1d8919bf573d9d3cf69637b6fd85 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Sun, 13 Apr 2025 13:01:38 +0200 Subject: [PATCH 02/14] imx: mx51evk: drop Stefano Babic from MAINTAINERS I haven't anymore the MX51EVK board. Signed-off-by: Stefano Babic CC: Fabio Estevam --- board/freescale/mx51evk/MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/board/freescale/mx51evk/MAINTAINERS b/board/freescale/mx51evk/MAINTAINERS index 1ca55f7d14e..025a5f8b582 100644 --- a/board/freescale/mx51evk/MAINTAINERS +++ b/board/freescale/mx51evk/MAINTAINERS @@ -1,6 +1,5 @@ MX51EVK BOARD M: Fabio Estevam -M: Stefano Babic S: Maintained F: board/freescale/mx51evk/ F: include/configs/mx51evk.h From 1d22ea1d88bac4bd8e48340739267758d6f83f29 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Wed, 16 Apr 2025 16:55:24 -0500 Subject: [PATCH 03/14] clk: imx: Finish converting clock-osc-24 back to osc_24 The UART clocks were added around the same time some other clock updates were happening, so converting clock-osc-24 back to osc_24 was missed on the UART clocks for imx8mm and imx8mn, so update them here. Fixes: b4734c9c333b ("clk: imx: Convert clock-osc-* back to osc_*") Signed-off-by: Adam Ford Reported-by: Christoph Niedermaier Reviewed-by: Fabio Estevam --- drivers/clk/imx/clk-imx8mm.c | 8 ++++---- drivers/clk/imx/clk-imx8mn.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index b81db516a69..7eb05180e15 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -81,19 +81,19 @@ static const char * const imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; -static const char * const imx8mm_uart1_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; -static const char * const imx8mm_uart2_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; -static const char * const imx8mm_uart3_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; -static const char * const imx8mm_uart4_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index be5b7933a8d..2dfa860bf37 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -97,19 +97,19 @@ static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys "sys_pll3_out", "audio_pll1_out", "video_pll_out", "audio_pll2_out", "sys_pll1_133m", }; -static const char * const imx8mn_uart1_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; -static const char * const imx8mn_uart2_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mn_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; -static const char * const imx8mn_uart3_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mn_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; -static const char * const imx8mn_uart4_sels[] = {"clock-osc-24m", "sys_pll1_80m", "sys_pll2_200m", +static const char * const imx8mn_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; From 81b1a42be08d36b510cdfd9b7f3f742bc780a4b6 Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Thu, 24 Apr 2025 10:28:59 +0200 Subject: [PATCH 04/14] toradex: tdx-cfg-block: fix verdin imx95 sku 0089 pid4 The memory size of the 0089 SKU is 8 GB instead of 16 GB. Fix PID4 0089 Verdin iMX95 definition, in the configuration block. Fixes: ce53f46f33b4 ("toradex: tdx-cfg-block: add verdin imx95 sku 0089 pid4") Signed-off-by: Emanuele Ghidoli Reviewed-by: Francesco Dolcini --- board/toradex/common/tdx-cfg-block.c | 2 +- board/toradex/common/tdx-cfg-block.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 41e3852b8fa..6c1cea77c8c 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -157,7 +157,7 @@ const struct toradex_som toradex_modules[] = { { VERDIN_IMX8MMDL_2G_IT, "Verdin iMX8M Mini DualLite 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, { VERDIN_IMX8MMQ_2G_IT_NO_CAN, "Verdin iMX8M Mini Quad 2GB IT", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, { AQUILA_AM69O_32G_WIFI_BT_IT, "Aquila AM69 Octa 32GB WB IT", TARGET_IS_ENABLED(AQUILA_AM69_A72) }, - { VERDIN_IMX95H_16G_WIFI_BT_IT, "Verdin iMX95 Hexa 16GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, + { VERDIN_IMX95H_8G_WIFI_BT_IT, "Verdin iMX95 Hexa 8GB WB IT", TARGET_IS_ENABLED(VERDIN_IMX95) }, { VERDIN_IMX8MMQ_4G_WIFI_BT_ET, "Verdin iMX8M Mini Quad 4GB WB ET", TARGET_IS_ENABLED(VERDIN_IMX8MM) }, { APALIS_IMX8QM_WIFI_BT_IT_1300MHZ, "Apalis iMX8QM 4GB WB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, { APALIS_IMX8QM_IT_1300MHZ, "Apalis iMX8QM 4GB IT", TARGET_IS_ENABLED(APALIS_IMX8) }, diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 4a29c0bca84..f4dd853306b 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -115,7 +115,7 @@ enum { VERDIN_IMX8MMDL_2G_IT, VERDIN_IMX8MMQ_2G_IT_NO_CAN, AQUILA_AM69O_32G_WIFI_BT_IT, - VERDIN_IMX95H_16G_WIFI_BT_IT, + VERDIN_IMX95H_8G_WIFI_BT_IT, VERDIN_IMX8MMQ_4G_WIFI_BT_ET, /* 90 */ APALIS_IMX8QM_WIFI_BT_IT_1300MHZ, APALIS_IMX8QM_IT_1300MHZ, From ddd6d6f8dbd940edf3b62e1b37bc86734aec236c Mon Sep 17 00:00:00 2001 From: Pawel Kochanowski Date: Thu, 24 Apr 2025 09:45:39 +0200 Subject: [PATCH 05/14] spi: fsl_qspi: Move AHB read buffer config after LUT When using CONFIG_FSL_QSPI_AHB_FULL_MAP the fsl_qspi_default_setup() sets the BFGENCR register to use the LUT(SEQID_LUT_AHB) before the Look Up Table is populated. This result in a situation that after 'sf probe' command any memory read from qspi using AHB will result in undefined behaviour (hang) untill first 'sf read' op is executed. Move the BFGENCR write to fsl_qspi_prepare_lut() to ensure that the setup is consistent. AHB reads will use the default LUT(index 0) setup by previous boot stage untill the first read op. Signed-off-by: Pawel Kochanowski --- drivers/spi/fsl_qspi.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index c7f554826c3..65ab3e306d7 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -472,7 +472,13 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q, op->addr.nbytes) { for (i = 0; i < ARRAY_SIZE(lutval); i++) qspi_writel(q, lutval[i], base + QUADSPI_AHB_LUT_REG(i)); + + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB), + q->iobase + QUADSPI_BFGENCR); } + } else { + qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), + q->iobase + QUADSPI_BFGENCR); } /* lock LUT */ @@ -737,13 +743,6 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) qspi_writel(q, 0, base + QUADSPI_BUF1IND); qspi_writel(q, 0, base + QUADSPI_BUF2IND); - if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) - qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB), - q->iobase + QUADSPI_BFGENCR); - else - qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT), - q->iobase + QUADSPI_BFGENCR); - qspi_writel(q, QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT); qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK | QUADSPI_BUF3CR_ADATSZ(q->devtype_data->ahb_buf_size / 8), From 9086b64ca07166b1e72b29ad04e3fe2a483c5454 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 25 Apr 2025 08:49:32 +0200 Subject: [PATCH 06/14] power-domain: Add support for refcounting (again) It is very surprising that such an uclass, specifically designed to handle resources that may be shared by different devices, is not keeping the count of the number of times a power domain has been enabled/disabled to avoid shutting it down unexpectedly or disabling it several times. Doing this causes troubles on eg. i.MX8MP because disabling power domains can be done in recursive loops were the same power domain disabled up to 4 times in a row. PGCs seem to have tight FSM internal timings to respect and it is easy to produce a race condition that puts the power domains in an unstable state, leading to ADB400 errors and later crashes in Linux. Some drivers implement their own mechanism for that, but it is probably best to add this feature in the uclass and share the common code across drivers. In order to avoid breaking existing drivers, refcounting is only enabled if the number of subdomains a device node supports is explicitly set in the probe function. ->xlate() callbacks will return the power domain ID which is then being used as the array index to reach the correct refcounter. As we do not want to break existing users while stile getting interesting error codes, the implementation is split between: - a low-level helper reporting error codes if the requested transition could not be operated, - a higher-level helper ignoring the "non error" codes, like EALREADY and EBUSY. CI tests using power domains are slightly updated to make sure the count of on/off calls is even and the results match what we *now* expect. They are also extended to test the low-level functions. Signed-off-by: Miquel Raynal --- arch/sandbox/include/asm/power-domain.h | 2 + drivers/firmware/scmi/sandbox-scmi_devices.c | 1 + drivers/power/domain/power-domain-uclass.c | 90 +++++++++++++++++-- .../power/domain/sandbox-power-domain-test.c | 15 ++++ drivers/power/domain/sandbox-power-domain.c | 4 + include/power-domain.h | 69 ++++++++++++-- test/dm/power-domain.c | 11 ++- 7 files changed, 177 insertions(+), 15 deletions(-) diff --git a/arch/sandbox/include/asm/power-domain.h b/arch/sandbox/include/asm/power-domain.h index 4d5e861dbce..3b0717f8fa0 100644 --- a/arch/sandbox/include/asm/power-domain.h +++ b/arch/sandbox/include/asm/power-domain.h @@ -13,6 +13,8 @@ int sandbox_power_domain_query(struct udevice *dev, unsigned long id); int sandbox_power_domain_test_get(struct udevice *dev); int sandbox_power_domain_test_on(struct udevice *dev); int sandbox_power_domain_test_off(struct udevice *dev); +int sandbox_power_domain_test_on_ll(struct udevice *dev); +int sandbox_power_domain_test_off_ll(struct udevice *dev); int sandbox_power_domain_test_free(struct udevice *dev); #endif diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c index 96c2922b067..9f253b0fd40 100644 --- a/drivers/firmware/scmi/sandbox-scmi_devices.c +++ b/drivers/firmware/scmi/sandbox-scmi_devices.c @@ -163,4 +163,5 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = { .priv_auto = sizeof(struct sandbox_scmi_device_priv), .remove = sandbox_scmi_devices_remove, .probe = sandbox_scmi_devices_probe, + .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index 938bd8cbc9f..d9fa8ad4bd2 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -12,6 +12,10 @@ #include #include +struct power_domain_priv { + int *on_count; +}; + static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev) { return (struct power_domain_ops *)dev->driver->ops; @@ -107,22 +111,67 @@ int power_domain_free(struct power_domain *power_domain) return ops->rfree ? ops->rfree(power_domain) : 0; } -int power_domain_on(struct power_domain *power_domain) +int power_domain_on_lowlevel(struct power_domain *power_domain) { + struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev); + struct power_domain_plat *plat = dev_get_uclass_plat(power_domain->dev); struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); + int *on_count = plat->subdomains ? &priv->on_count[power_domain->id] : NULL; + int ret; - debug("%s(power_domain=%p)\n", __func__, power_domain); + /* Refcounting is not enabled on all drivers by default */ + if (on_count) { + debug("Enable power domain %s.%ld: %d -> %d (%s)\n", + power_domain->dev->name, power_domain->id, *on_count, *on_count + 1, + (((*on_count + 1) > 1) ? "EALREADY" : "todo")); - return ops->on ? ops->on(power_domain) : 0; + (*on_count)++; + if (*on_count > 1) + return -EALREADY; + } + + ret = ops->on ? ops->on(power_domain) : 0; + if (ret) { + if (on_count) + (*on_count)--; + return ret; + } + + return 0; } -int power_domain_off(struct power_domain *power_domain) +int power_domain_off_lowlevel(struct power_domain *power_domain) { + struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev); + struct power_domain_plat *plat = dev_get_uclass_plat(power_domain->dev); struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); + int *on_count = plat->subdomains ? &priv->on_count[power_domain->id] : NULL; + int ret; - debug("%s(power_domain=%p)\n", __func__, power_domain); + /* Refcounting is not enabled on all drivers by default */ + if (on_count) { + debug("Disable power domain %s.%ld: %d -> %d (%s%s)\n", + power_domain->dev->name, power_domain->id, *on_count, *on_count - 1, + (((*on_count) <= 0) ? "EALREADY" : ""), + (((*on_count - 1) > 0) ? "BUSY" : "todo")); - return ops->off ? ops->off(power_domain) : 0; + if (*on_count <= 0) + return -EALREADY; + + (*on_count)--; + if (*on_count > 0) + return -EBUSY; + } + + ret = ops->off ? ops->off(power_domain) : 0; + if (ret) { + if (on_count) + (*on_count)++; + + return ret; + } + + return 0; } #if CONFIG_IS_ENABLED(OF_REAL) @@ -177,7 +226,36 @@ int dev_power_domain_off(struct udevice *dev) } #endif /* OF_REAL */ +static int power_domain_post_probe(struct udevice *dev) +{ + struct power_domain_priv *priv = dev_get_uclass_priv(dev); + struct power_domain_plat *plat = dev_get_uclass_plat(dev); + + if (plat->subdomains) { + priv->on_count = calloc(sizeof(int), plat->subdomains); + if (!priv->on_count) + return -ENOMEM; + } + + return 0; +} + +static int power_domain_pre_remove(struct udevice *dev) +{ + struct power_domain_priv *priv = dev_get_uclass_priv(dev); + struct power_domain_plat *plat = dev_get_uclass_plat(dev); + + if (plat->subdomains) + free(priv->on_count); + + return 0; +} + UCLASS_DRIVER(power_domain) = { .id = UCLASS_POWER_DOMAIN, .name = "power_domain", + .post_probe = power_domain_post_probe, + .pre_remove = power_domain_pre_remove, + .per_device_auto = sizeof(struct power_domain_priv), + .per_device_plat_auto = sizeof(struct power_domain_plat), }; diff --git a/drivers/power/domain/sandbox-power-domain-test.c b/drivers/power/domain/sandbox-power-domain-test.c index 08c15ef342b..df063001f51 100644 --- a/drivers/power/domain/sandbox-power-domain-test.c +++ b/drivers/power/domain/sandbox-power-domain-test.c @@ -34,6 +34,20 @@ int sandbox_power_domain_test_off(struct udevice *dev) return power_domain_off(&sbrt->pd); } +int sandbox_power_domain_test_on_ll(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_on_lowlevel(&sbrt->pd); +} + +int sandbox_power_domain_test_off_ll(struct udevice *dev) +{ + struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); + + return power_domain_off_lowlevel(&sbrt->pd); +} + int sandbox_power_domain_test_free(struct udevice *dev) { struct sandbox_power_domain_test *sbrt = dev_get_priv(dev); @@ -51,4 +65,5 @@ U_BOOT_DRIVER(sandbox_power_domain_test) = { .id = UCLASS_MISC, .of_match = sandbox_power_domain_test_ids, .priv_auto = sizeof(struct sandbox_power_domain_test), + .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; diff --git a/drivers/power/domain/sandbox-power-domain.c b/drivers/power/domain/sandbox-power-domain.c index 9dd490b14a3..a8031657638 100644 --- a/drivers/power/domain/sandbox-power-domain.c +++ b/drivers/power/domain/sandbox-power-domain.c @@ -64,8 +64,12 @@ static int sandbox_power_domain_bind(struct udevice *dev) static int sandbox_power_domain_probe(struct udevice *dev) { + struct power_domain_plat *plat = dev_get_uclass_plat(dev); + debug("%s(dev=%p)\n", __func__, dev); + plat->subdomains = 1; + return 0; } diff --git a/include/power-domain.h b/include/power-domain.h index 18525073e5e..7fd2c5e365b 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -65,6 +65,15 @@ struct power_domain { void *priv; }; +/** + * struct power_domain_plat - Per device accessible structure + * @subdomains: Number of subdomains covered by this device, required + * for refcounting + */ +struct power_domain_plat { + int subdomains; +}; + /** * power_domain_get - Get/request the power domain for a device. * @@ -147,37 +156,81 @@ static inline int power_domain_free(struct power_domain *power_domain) #endif /** - * power_domain_on - Enable power to a power domain. + * power_domain_on_lowlevel - Enable power to a power domain (with refcounting) * * @power_domain: A power domain struct that was previously successfully * requested by power_domain_get(). - * Return: 0 if OK, or a negative error code. + * Return: 0 if the transition has been performed correctly, + * -EALREADY if the domain is already on, + * a negative error code otherwise. */ #if CONFIG_IS_ENABLED(POWER_DOMAIN) -int power_domain_on(struct power_domain *power_domain); +int power_domain_on_lowlevel(struct power_domain *power_domain); #else -static inline int power_domain_on(struct power_domain *power_domain) +static inline int power_domain_on_lowlevel(struct power_domain *power_domain) { return -ENOSYS; } #endif /** - * power_domain_off - Disable power to a power domain. + * power_domain_on - Enable power to a power domain (ignores the actual state + * of the power domain) * * @power_domain: A power domain struct that was previously successfully * requested by power_domain_get(). - * Return: 0 if OK, or a negative error code. + * Return: a negative error code upon error during the transition, 0 otherwise. + */ +static inline int power_domain_on(struct power_domain *power_domain) +{ + int ret; + + ret = power_domain_on_lowlevel(power_domain); + if (ret == -EALREADY) + ret = 0; + + return ret; +} + +/** + * power_domain_off_lowlevel - Disable power to a power domain (with refcounting) + * + * @power_domain: A power domain struct that was previously successfully + * requested by power_domain_get(). + * Return: 0 if the transition has been performed correctly, + * -EALREADY if the domain is already off, + * -EBUSY if another device is keeping the domain on (but the refcounter + * is decremented), + * a negative error code otherwise. */ #if CONFIG_IS_ENABLED(POWER_DOMAIN) -int power_domain_off(struct power_domain *power_domain); +int power_domain_off_lowlevel(struct power_domain *power_domain); #else -static inline int power_domain_off(struct power_domain *power_domain) +static inline int power_domain_off_lowlevel(struct power_domain *power_domain) { return -ENOSYS; } #endif +/** + * power_domain_off - Disable power to a power domain (ignores the actual state + * of the power domain) + * + * @power_domain: A power domain struct that was previously successfully + * requested by power_domain_get(). + * Return: a negative error code upon error during the transition, 0 otherwise. + */ +static inline int power_domain_off(struct power_domain *power_domain) +{ + int ret; + + ret = power_domain_off_lowlevel(power_domain); + if (ret == -EALREADY || ret == -EBUSY) + ret = 0; + + return ret; +} + /** * dev_power_domain_on - Enable power domains for a device . * diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c index 896cf5b2ae9..1002d831764 100644 --- a/test/dm/power-domain.c +++ b/test/dm/power-domain.c @@ -27,17 +27,26 @@ static int dm_test_power_domain(struct unit_test_state *uts) ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test", &dev_test)); - ut_asserteq(1, sandbox_power_domain_query(dev_power_domain, + ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, TEST_POWER_DOMAIN)); ut_assertok(sandbox_power_domain_test_get(dev_test)); ut_assertok(sandbox_power_domain_test_on(dev_test)); ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0)); + ut_asserteq(1, sandbox_power_domain_query(dev_power_domain, + TEST_POWER_DOMAIN)); + ut_asserteq(-EALREADY, sandbox_power_domain_test_on_ll(dev_test)); + ut_asserteq(1, sandbox_power_domain_query(dev_power_domain, + TEST_POWER_DOMAIN)); + ut_asserteq(-EBUSY, sandbox_power_domain_test_off_ll(dev_test)); ut_asserteq(1, sandbox_power_domain_query(dev_power_domain, TEST_POWER_DOMAIN)); ut_assertok(sandbox_power_domain_test_off(dev_test)); ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, 0)); + ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, + TEST_POWER_DOMAIN)); + ut_asserteq(-EALREADY, sandbox_power_domain_test_off_ll(dev_test)); ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, TEST_POWER_DOMAIN)); From a785ef24487b51f911fe11bc91f30877eb1ced83 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 25 Apr 2025 08:49:33 +0200 Subject: [PATCH 07/14] imx: power-domain: Enable refcounting on imx8mp Prevent enabling/disabling multiple times the same power domain to avoid breakages due to the same power domains being referenced several times by different device nodes. Signed-off-by: Miquel Raynal --- drivers/power/domain/imx8m-power-domain.c | 4 ++++ drivers/power/domain/imx8mp-hsiomix.c | 4 ++++ drivers/power/domain/imx8mp-mediamix.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index e54ba5d9a54..b44aae78e6d 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -506,8 +506,12 @@ static int imx8m_power_domain_bind(struct udevice *dev) static int imx8m_power_domain_probe(struct udevice *dev) { struct imx8m_power_domain_plat *pdata = dev_get_plat(dev); + struct power_domain_plat *plat = dev_get_uclass_plat(dev); int ret; + /* Every subdomain has its own device node */ + plat->subdomains = 1; + /* Nothing to do for non-"power-domain" driver instances. */ if (!strstr(dev->name, "power-domain")) return 0; diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c index 455ad53ef52..1ca43880ef5 100644 --- a/drivers/power/domain/imx8mp-hsiomix.c +++ b/drivers/power/domain/imx8mp-hsiomix.c @@ -201,8 +201,12 @@ int imx8mp_hsiomix_bind(struct udevice *dev) static int imx8mp_hsiomix_probe(struct udevice *dev) { struct imx8mp_hsiomix_priv *priv = dev_get_priv(dev); + struct power_domain_plat *plat = dev_get_uclass_plat(dev); int ret; + /* Definitions are in imx8mp-power.h */ + plat->subdomains = 5; + priv->base = dev_read_addr_ptr(dev); ret = clk_get_by_name(dev, "usb", &priv->clk_usb); diff --git a/drivers/power/domain/imx8mp-mediamix.c b/drivers/power/domain/imx8mp-mediamix.c index 78c32ca3d3a..504c22f7d36 100644 --- a/drivers/power/domain/imx8mp-mediamix.c +++ b/drivers/power/domain/imx8mp-mediamix.c @@ -143,9 +143,13 @@ static int imx8mp_mediamix_bind(struct udevice *dev) static int imx8mp_mediamix_probe(struct udevice *dev) { + struct power_domain_plat *plat = dev_get_uclass_plat(dev); struct imx8mp_mediamix_priv *priv = dev_get_priv(dev); int ret; + /* Definitions are in imx8mp-power.h */ + plat->subdomains = 9; + priv->base = dev_read_addr_ptr(dev); ret = clk_get_by_name(dev, "apb", &priv->clk_apb); From a08c252c80538292f2b67760044e3cd1792be43e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 25 Apr 2025 14:39:01 -0300 Subject: [PATCH 08/14] arm64: dts: imx8mm: Make osc_32k available in SPL Since commit b4734c9c333b ("clk: imx: Convert clock-osc-* back to osc_*") SPL takes a long time to load U-Boot proper on an imx8mm-evk board. The reason for the long delay is because the osc_32k clock is not available in the SPL phase. Fix this problem by passing the 'bootph-all' and 'bootph-pre-ram' properties to make the osc_32k clock available in SPL. This also aligns with imx8mn and imx8mp-u-boot.dtsi files. Fixes: b4734c9c333b ("clk: imx: Convert clock-osc-* back to osc_*") Suggested-by: Marek Vasut Signed-off-by: Fabio Estevam Reviewed-by: Adam Ford --- arch/arm/dts/imx8mm-u-boot.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/dts/imx8mm-u-boot.dtsi b/arch/arm/dts/imx8mm-u-boot.dtsi index abb3aa5b635..59453dc36d3 100644 --- a/arch/arm/dts/imx8mm-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-u-boot.dtsi @@ -240,6 +240,11 @@ bootph-pre-ram; }; +&osc_32k { + bootph-all; + bootph-pre-ram; +}; + #ifdef CONFIG_FSL_CAAM &sec_jr0 { bootph-pre-ram; From eeb2db1edcc02b4b137c4c78d43669375a5e2de1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 27 Apr 2025 17:39:34 +0200 Subject: [PATCH 09/14] clk: imx: Pass CCM udevice into clk_register_composite() Pass the clock controller udevice into clk_register_composite(), so it can be passed further to any registered composite clocks and used for look up of parent clock referenced in DT "clocks" and "clock-names" properties by phandle and name pair. Use the clock controller udevice in imx8m_clk_mux_set_parent() to perform accurate look up of parent clock referenced in the CCM driver by name. If the clock name that is being looked up matches one of the names listed in the clock controller DT node "clock-names" array property, then the offset of the name is looked up in the "clocks" DT property and the phandle at that offset is resolved to the parent clock udevice. The test to determine whether a particular driver instance registered with clock uclass matches the parent clock is done by comparing the OF nodes of the clock registered with clock uclass and parent clock resolved from the phandle. Example: drivers/clk/imx/clk-imx8mm.c: static const char * const imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", ... _____________| arch/arm/dts/imx8mm.dtsi: | clk: clock-controller@30380000 { v clock-names = "osc_32k", "osc_24m", ... | v clocks = <&osc_32k>, <&osc_24m>, ... }; _______________________| ... | / { v osc_24m: clock-osc-24m { compatible = "fixed-clock"; ... }; Signed-off-by: Marek Vasut Reported-by: Francesco Dolcini Tested-by: Fabio Estevam Tested-by: Adam Ford # imx8mp-beacon --- drivers/clk/clk-composite.c | 2 ++ drivers/clk/imx/clk-composite-8m.c | 30 +++++++++++++++++++++++++++++- include/linux/clk-provider.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 9e3b5191767..207224b1320 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -155,6 +155,8 @@ struct clk *clk_register_composite(struct udevice *dev, const char *name, goto err; } + composite->dev = dev; + if (composite->mux) composite->mux->dev = clk->dev; if (composite->rate) diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 14c5b92939c..e1a3c0af308 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -116,14 +116,42 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = { .set_rate = imx8m_clk_composite_divider_set_rate, }; +static int imx8m_clk_mux_fetch_parent_index(struct udevice *cdev, struct clk *clk, struct clk *parent) +{ + struct clk_mux *mux = to_clk_mux(clk); + struct clk cclk; + int ret; + int i; + + if (!parent) + return -EINVAL; + + for (i = 0; i < mux->num_parents; i++) { + ret = clk_get_by_name(cdev, mux->parent_names[i], &cclk); + if (!ret && ofnode_equal(dev_ofnode(parent->dev), dev_ofnode(cclk.dev))) + return i; + + if (!strcmp(parent->dev->name, mux->parent_names[i])) + return i; + if (!strcmp(parent->dev->name, + clk_resolve_parent_clk(clk->dev, + mux->parent_names[i]))) + return i; + } + + return -EINVAL; +} + + static int imx8m_clk_mux_set_parent(struct clk *clk, struct clk *parent) { struct clk_mux *mux = to_clk_mux(clk); + struct clk_composite *composite = (struct clk_composite *)clk->data; int index; u32 val; u32 reg; - index = clk_mux_fetch_parent_index(clk, parent); + index = imx8m_clk_mux_fetch_parent_index(composite->dev, clk, parent); if (index < 0) { log_err("Could not fetch index\n"); return index; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 5ea2171492e..267757939e0 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -219,6 +219,8 @@ struct clk_composite { const struct clk_ops *mux_ops; const struct clk_ops *rate_ops; const struct clk_ops *gate_ops; + + struct udevice *dev; }; #define to_clk_composite(_clk) container_of(_clk, struct clk_composite, clk) From 445626b8a6300de0ca12dbb39b0674dd7681825a Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 28 Apr 2025 07:28:53 +0200 Subject: [PATCH 10/14] imx8qxp: capricorn defconfig: collect common Kconfig options Siemens have some defconfigs for different hardware versions, all based on mainline cxg3 board. For easier updating the downstream defconfigs, move common settings into new file. configs/imx8qxp_capricorn.config Signed-off-by: Heiko Schocher Signed-off-by: Walter Schweizer --- board/siemens/capricorn/MAINTAINERS | 1 + configs/capricorn_cxg3_defconfig | 132 +-------------------------- configs/imx8qxp_capricorn.config | 135 ++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 128 deletions(-) create mode 100644 configs/imx8qxp_capricorn.config diff --git a/board/siemens/capricorn/MAINTAINERS b/board/siemens/capricorn/MAINTAINERS index 5f467aa9b6e..3b4bd64dd00 100644 --- a/board/siemens/capricorn/MAINTAINERS +++ b/board/siemens/capricorn/MAINTAINERS @@ -9,4 +9,5 @@ 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: configs/imx8qxp_capricorn.config F: include/configs/capricorn-common.h diff --git a/configs/capricorn_cxg3_defconfig b/configs/capricorn_cxg3_defconfig index 3cc46067f7d..530b1f47695 100644 --- a/configs/capricorn_cxg3_defconfig +++ b/configs/capricorn_cxg3_defconfig @@ -1,117 +1,13 @@ -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=0x200000 -CONFIG_DM_GPIO=y +#include + CONFIG_DEFAULT_DEVICE_TREE="imx8-capricorn-cxg3" -CONFIG_TARGET_CAPRICORN=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=0x202000 CONFIG_IDENT_STRING=" ##v01.06" -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 \"\" 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_HAVE_INIT_STACK=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=0x4000 -CONFIG_SPL_SYS_MMCSD_RAW_MODE=y -CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040 -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_WDT=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_BOOTCOUNT_ALTBOOTCMD="run bootcmd" -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 @@ -119,23 +15,3 @@ 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 -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_WATCHDOG is not set -CONFIG_WDT=y -CONFIG_WDT_SIEMENS_PMIC=y -CONFIG_SPL_TINY_MEMSET=y diff --git a/configs/imx8qxp_capricorn.config b/configs/imx8qxp_capricorn.config new file mode 100644 index 00000000000..f59f2129d56 --- /dev/null +++ b/configs/imx8qxp_capricorn.config @@ -0,0 +1,135 @@ +CONFIG_ARM=y +CONFIG_ARCH_IMX8=y +CONFIG_TEXT_BASE=0x80020000 +CONFIG_SYS_MALLOC_LEN=0x2800000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +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=0x200000 +CONFIG_ENV_OFFSET_REDUND=0x202000 +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_MMC_ENV_PART=2 + +CONFIG_DM_GPIO=y + +CONFIG_TARGET_CAPRICORN=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=0x4000000 +CONFIG_SYS_LOAD_ADDR=0x80280000 +CONFIG_SPL=y + +CONFIG_REMAKE_ELF=y +# CONFIG_EFI_LOADER is not set +# CONFIG_ANDROID_BOOT_IMAGE 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 \"\" 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_HAVE_INIT_STACK=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=0x4000 +CONFIG_SPL_SYS_MMCSD_RAW_MODE=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1040 +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_BIND is not set +CONFIG_CMD_WDT=y +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_SPL_DM=y +CONFIG_BOOTCOUNT_LIMIT=y +CONFIG_BOOTCOUNT_ENV=y +CONFIG_BOOTCOUNT_ALTBOOTCMD="run bootcmd" +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_MII=y +CONFIG_PHY=y +CONFIG_NOP_PHY=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_WATCHDOG is not set +CONFIG_WDT=y +CONFIG_WDT_SIEMENS_PMIC=y +CONFIG_SPL_TINY_MEMSET=y From eda18cc2c3db0448bc7a710e7f82b59638271264 Mon Sep 17 00:00:00 2001 From: Walter Schweizer Date: Mon, 28 Apr 2025 07:28:54 +0200 Subject: [PATCH 11/14] siemens: capricorn: enable text based default environment enable text based default U-Boot Environment by enabling CONFIG_ENV_SOURCE_FILE and adding default environment file: board/siemens/capricorn/capricorn_cxg3.env Signed-off-by: Heiko Schocher Signed-off-by: Walter Schweizer --- board/siemens/capricorn/capricorn_default.env | 49 +++++++++++++++++ configs/capricorn_cxg3_defconfig | 1 + include/configs/capricorn-common.h | 52 +------------------ 3 files changed, 51 insertions(+), 51 deletions(-) create mode 100644 board/siemens/capricorn/capricorn_default.env diff --git a/board/siemens/capricorn/capricorn_default.env b/board/siemens/capricorn/capricorn_default.env new file mode 100644 index 00000000000..4c26e9d43eb --- /dev/null +++ b/board/siemens/capricorn/capricorn_default.env @@ -0,0 +1,49 @@ +altbootcmd=run bootcmd +baudrate=115200 +bootcmd=run flash_self;reset; +bootdelay=3 +bootdir=targetdir/rootfs/boot +bootlimit=3 +check_upgrade=if test ${upgrade_available} -eq 1; then echo upgrade_available is set; if test ${bootcount} -gt ${bootlimit}; then setenv upgrade_available 0;echo toggle partition;run toggle_partition;fi;fi; +cntr_addr=0x88000000 +cntr_file=os_cntr_signed.bin +console=ttyLP2 +dtb_name_default=default +ethprime=eth1 +fdt_addr=0x83000000 +fdt_high=0xffffffffffffffff +flash_self=run mmc_boot +flash_self_test=setenv testargs test loglevel=3 systemd.unit=test.target; run mmc_boot +hostname=capricorn +initrd_addr=0x83100000 +initrd_high=0xffffffffffffffff +ip_method=none +kernel_name=Image +loadaddr=0x80400000 +mmc_boot=run set_bootargs;run check_upgrade; run set_partition;run set_bootargs_mmc;run mmc_load_bootfiles +mmc_boot_fit=ext4load mmc 0:${mmc_part_nr} 0x88000000 boot/fitImage;if test -n ${A};then setenv bootargs ${bootargs} rootfs_sig=${sig_a};fi;if test -n ${B};then setenv bootargs ${bootargs} rootfs_sig=${sig_b};fi;bootm 0x88000000#conf-${dtb_name}.dtb;bootm +mmc_boot_image=ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name}.dtb;if test $? -eq 1;then ext4load mmc 0:${mmc_part_nr} ${fdt_addr} boot/${dtb_name_default}.dtb;fi; ext4load mmc 0:${mmc_part_nr} ${loadaddr} boot/${kernel_name}; booti ${loadaddr} - ${fdt_addr} +mmc_load_bootfiles=echo -n Loading from eMMC ...; if test -e mmc 0:${mmc_part_nr} boot/fitImage; then echo fit; setenv fdt_high; setenv initrd_high; run mmc_boot_fit; else echo image; run mmc_boot_image; fi +net_nfs=wdt dev scu-wdt; wdt stop; echo Booting from network ...; run set_bootargs_net; tftpboot ${loadaddr} ${bootdir}/${kernel_name}; printenv bootargs; if test ${kernel_name} = fitImage; then setenv fdt_high; setenv initrd_high; bootm ${loadaddr}#conf-${dtb_name}.dtb; else tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name}.dtb; if test $? -eq 1; then echo Loading default.dtb!; tftpboot ${fdt_addr} ${serverip}:${bootdir}/${dtb_name_default}.dtb; fi; booti ${loadaddr} - ${fdt_addr}; fi +net_unfs=setenv nfsopts vers=3,udp,rsize=4096,wsize=4096,nolock,port=3049,mountport=3048 rw; run net_nfs +netdev=lan0 +nfsopts=vers=3,udp,rsize=4096,wsize=4096,nolock rw +partitionset_active=A +rootfs_name=/dev/mmcblk0 +rootpath=/home/projects/targetdir/rootfs +script_file=u-boot-commands.img +set_bootargs_mmc=setenv bootargs ${bootargs} root=${mmc_active_vol} ro rootdelay=1 rootwait rootfstype=ext4 ip=${ip_method} +set_bootargs_net=run set_bootargs; if test ${kernel_name} = fitImage; then setenv loadaddr 0x88000000; fi; setenv bootargs ${bootargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off +set_bootargs=setenv bootargs console=${console},${baudrate} target_env=${target_env} ${testargs} ${optargs} +set_partition=setenv ${partitionset_active} true;if test -n ${A}; then setenv mmc_part_nr 1;fi;if test -n ${B}; then setenv mmc_part_nr 2;fi;setenv mmc_active_vol ${rootfs_name}p${mmc_part_nr} +tftp_run_script=tftpboot ${kernel_loadaddr} ${serverip}:${script_file};if test $? -eq 0;then source ${kernel_loadaddr};fi +toggle_partition=setenv ${partitionset_active} true; if test -n ${A}; then setenv partitionset_active B; mmc partconf 0 1 2 0; env delete A; fi; if test -n ${B}; then setenv partitionset_active A; mmc partconf 0 1 1 0; env delete B; fi;saveenv; reset +upgrade_available=0 +emmc_dev=0 +sd_dev=1 +mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused +kboot=booti +bootcmd_mfg=run mfgtool_args; if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else booti ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot usb auto; fi; +fastboot_bytes=124c00 +fastboot_dev=mmc +mmcautodetect=yes diff --git a/configs/capricorn_cxg3_defconfig b/configs/capricorn_cxg3_defconfig index 530b1f47695..5f09ceee8bc 100644 --- a/configs/capricorn_cxg3_defconfig +++ b/configs/capricorn_cxg3_defconfig @@ -3,6 +3,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx8-capricorn-cxg3" CONFIG_IDENT_STRING=" ##v01.06" +CONFIG_ENV_SOURCE_FILE="capricorn_default" CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_USE_ETHPRIME=y CONFIG_ETHPRIME="eth1" diff --git a/include/configs/capricorn-common.h b/include/configs/capricorn-common.h index 4d95f3fd79b..7120a44d186 100644 --- a/include/configs/capricorn-common.h +++ b/include/configs/capricorn-common.h @@ -10,8 +10,6 @@ #include #include -#include "siemens-env-common.h" - /* SPL config */ #ifdef CONFIG_XPL_BUILD #define CFG_MALLOC_F_ADDR 0x00120000 @@ -36,57 +34,9 @@ #define AHAB_ENV "sec_boot=no\0" #endif -#define MFG_ENV_SETTINGS_DEFAULT \ - "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ - "rdinit=/linuxrc " \ - "clk_ignore_unused "\ - "\0" \ - "kboot=booti\0"\ - "bootcmd_mfg=run mfgtool_args;" \ - "if iminfo ${initrd_addr}; then " \ - "if test ${tee} = yes; then " \ - "bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; " \ - "else " \ - "booti ${loadaddr} ${initrd_addr} ${fdt_addr}; " \ - "fi; " \ - "else " \ - "echo \"Run fastboot ...\"; fastboot 0; " \ - "fi;\0" - -/* Boot M4 */ -#define M4_BOOT_ENV \ - "m4_0_image=m4_0.bin\0" \ - "loadm4image_0=fatload mmc ${mmcdev}:${mmcpart} " \ - "${loadaddr} ${m4_0_image}\0" \ - "m4boot_0=run loadm4image_0; dcache flush; bootaux ${loadaddr} 0\0" \ - -#define CFG_MFG_ENV_SETTINGS \ - MFG_ENV_SETTINGS_DEFAULT \ - "initrd_addr=0x83100000\0" \ - "initrd_high=0xffffffffffffffff\0" \ - "emmc_dev=0\0" - /* Initial environment variables */ #define CFG_EXTRA_ENV_SETTINGS \ - CFG_MFG_ENV_SETTINGS \ - M4_BOOT_ENV \ - AHAB_ENV \ - ENV_COMMON \ - "script=boot.scr\0" \ - "image=Image\0" \ - "panel=NULL\0" \ - "console=ttyLP2\0" \ - "fdt_addr=0x83000000\0" \ - "fdt_high=0xffffffffffffffff\0" \ - "cntr_addr=0x88000000\0" \ - "cntr_file=os_cntr_signed.bin\0" \ - "initrd_addr=0x83800000\0" \ - "initrd_high=0xffffffffffffffff\0" \ - "netdev=eth0\0" \ - "nfsopts=vers=3,udp,rsize=4096,wsize=4096,nolock rw\0" \ - "hostname=capricorn\0" \ - ENV_EMMC \ - ENV_NET + AHAB_ENV /* Default location for tftp and bootm */ From 6695706325fd855a71c594e342ecf5663addcd98 Mon Sep 17 00:00:00 2001 From: Walter Schweizer Date: Mon, 28 Apr 2025 07:28:55 +0200 Subject: [PATCH 12/14] siemens: capricorn: defconfig updates add ahab command as secure boot is used on this boards, and enable watchdog, so U-Boot triggers it. Signed-off-by: Walter Schweizer for respelling commit subject and message: Signed-off-by: Heiko Schocher --- configs/imx8qxp_capricorn.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/imx8qxp_capricorn.config b/configs/imx8qxp_capricorn.config index f59f2129d56..032cab63af8 100644 --- a/configs/imx8qxp_capricorn.config +++ b/configs/imx8qxp_capricorn.config @@ -16,6 +16,7 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_MMC_ENV_PART=2 CONFIG_DM_GPIO=y +CONFIG_AHAB_BOOT=y CONFIG_TARGET_CAPRICORN=y CONFIG_SPL_MMC=y @@ -129,7 +130,7 @@ CONFIG_DM_SERIAL=y CONFIG_FSL_LPUART=y CONFIG_DM_THERMAL=y CONFIG_IMX_SCU_THERMAL=y -# CONFIG_WATCHDOG is not set +CONFIG_WATCHDOG=y CONFIG_WDT=y CONFIG_WDT_SIEMENS_PMIC=y CONFIG_SPL_TINY_MEMSET=y From 683531bd19f228fdf5b8fbdde3416c2382922c5b Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 28 Apr 2025 07:28:56 +0200 Subject: [PATCH 13/14] arm: imx8qxp: capricorn: move env offset settings move the ENV_OFFSET settings from common config settings file configs/imx8qxp_capricorn.config to defconfig file for the cxg3 board, as other imx8qxp based boards from siemens has the environment on other offsets. Signed-off-by: Heiko Schocher --- configs/capricorn_cxg3_defconfig | 2 ++ configs/imx8qxp_capricorn.config | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/capricorn_cxg3_defconfig b/configs/capricorn_cxg3_defconfig index 5f09ceee8bc..5689544c1d0 100644 --- a/configs/capricorn_cxg3_defconfig +++ b/configs/capricorn_cxg3_defconfig @@ -5,6 +5,8 @@ CONFIG_IDENT_STRING=" ##v01.06" CONFIG_ENV_SOURCE_FILE="capricorn_default" CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_ENV_OFFSET=0x200000 +CONFIG_ENV_OFFSET_REDUND=0x202000 CONFIG_USE_ETHPRIME=y CONFIG_ETHPRIME="eth1" CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/imx8qxp_capricorn.config b/configs/imx8qxp_capricorn.config index 032cab63af8..463e584530f 100644 --- a/configs/imx8qxp_capricorn.config +++ b/configs/imx8qxp_capricorn.config @@ -10,8 +10,6 @@ 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=0x200000 -CONFIG_ENV_OFFSET_REDUND=0x202000 CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_MMC_ENV_PART=2 From ef41a9f01d20e9209942db4a679ab89b80bb876c Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 28 Apr 2025 07:28:57 +0200 Subject: [PATCH 14/14] siemens: imx8qxp: remove unused config file include/configs/giedi.h is not longer used after siemens imx8qxp cleanup series, so remove it. Signed-off-by: Heiko Schocher --- include/configs/giedi.h | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 include/configs/giedi.h diff --git a/include/configs/giedi.h b/include/configs/giedi.h deleted file mode 100644 index 19a795bcf86..00000000000 --- a/include/configs/giedi.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2019 Siemens AG - * - */ - -#ifndef __GIEDI_H -#define __GIEDI_H - -#include "capricorn-common.h" - -/* DDR3 board total DDR is 1 GB */ -#undef PHYS_SDRAM_1_SIZE -#define PHYS_SDRAM_1_SIZE 0x40000000 /* 1 GB */ - -#endif /* __GIEDI_H */