diff --git a/boards/st/stm32h573i_dk/board.cmake b/boards/st/stm32h573i_dk/board.cmake index 1ce1627e7eb74..a98d8bd66650b 100644 --- a/boards/st/stm32h573i_dk/board.cmake +++ b/boards/st/stm32h573i_dk/board.cmake @@ -1,11 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 # keep first -if(CONFIG_STM32_MEMMAP) -board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") -board_runner_args(stm32cubeprogrammer "--extload=MX25LM51245G_STM32H573I-DK-RevB-SFIx.stldr") -else() board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw") +if(CONFIG_STM32_MEMMAP OR (CONFIG_XIP AND CONFIG_BOOTLOADER_MCUBOOT)) + board_runner_args(stm32cubeprogrammer "--extload=MX25LM51245G_STM32H573I-DK-RevB-SFIx.stldr") endif() board_runner_args(pyocd "--target=stm32h573iikx") diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk.dts b/boards/st/stm32h573i_dk/stm32h573i_dk.dts index f839c1eb1967e..c431357be226a 100644 --- a/boards/st/stm32h573i_dk/stm32h573i_dk.dts +++ b/boards/st/stm32h573i_dk/stm32h573i_dk.dts @@ -307,21 +307,6 @@ reg = <0x00000000 DT_SIZE_K(64)>; }; - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x00010000 DT_SIZE_K(416)>; - }; - - slot1_partition: partition@78000 { - label = "image-1"; - reg = <0x00078000 DT_SIZE_K(416)>; - }; - - scratch_partition: partition@e0000 { - label = "image-scratch"; - reg = <0x000e0000 DT_SIZE_K(64)>; - }; - /* Set 64KB of storage at the end of Bank1 */ storage_partition: partition@f0000 { label = "storage"; @@ -406,9 +391,19 @@ #address-cells = <1>; #size-cells = <1>; - partition@0 { - label = "nor"; - reg = <0x00000000 DT_SIZE_M(64)>; + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x00000000 DT_SIZE_M(16)>; + }; + + slot1_partition: partition@1000000 { + label = "image-1"; + reg = <0x01000000 DT_SIZE_M(16)>; + }; + + scratch_partition: partition@2000000 { + label = "image-scratch"; + reg = <0x02000000 DT_SIZE_M(24)>; }; }; }; diff --git a/boards/st/stm32h573i_dk/stm32h573i_dk.yaml b/boards/st/stm32h573i_dk/stm32h573i_dk.yaml index a743fbca02f6d..c52fa0c3f6d06 100644 --- a/boards/st/stm32h573i_dk/stm32h573i_dk.yaml +++ b/boards/st/stm32h573i_dk/stm32h573i_dk.yaml @@ -24,7 +24,6 @@ supported: - spi - octospi - can - - usb_device - i2c - rtc - usbd diff --git a/drivers/clock_control/clock_stm32_ll_h5.c b/drivers/clock_control/clock_stm32_ll_h5.c index 7ea568149703e..feb1e9812e94f 100644 --- a/drivers/clock_control/clock_stm32_ll_h5.c +++ b/drivers/clock_control/clock_stm32_ll_h5.c @@ -349,10 +349,36 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, return 0; } +static enum clock_control_status stm32_clock_control_get_status(const struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; + + ARG_UNUSED(dev); + + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == true) { + /* Gated clocks */ + if ((sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus) & pclken->enr) + == pclken->enr) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } + } else { + /* Domain clock sources */ + if (enabled_clock(pclken->bus) == 0) { + return CLOCK_CONTROL_STATUS_ON; + } else { + return CLOCK_CONTROL_STATUS_OFF; + } + } +} + static DEVICE_API(clock_control, stm32_clock_control_api) = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .get_status = stm32_clock_control_get_status, .configure = stm32_clock_control_configure, }; @@ -435,7 +461,19 @@ static int set_up_plls(void) #endif #if defined(STM32_PLL_ENABLED) + +#if defined(CONFIG_STM32_APP_IN_EXT_FLASH) /* + * Don't disable PLL1 during application initialization + * that runs on the external octospi flash (in memmap mode) + * when (Q/O)SPI uses PLL1 as its clock source. + */ + if (LL_RCC_GetOCTOSPIClockSource(LL_RCC_OCTOSPI_CLKSOURCE) == LL_RCC_OSPI_CLKSOURCE_PLL1Q) { + goto setup_pll2; + } +#endif /* CONFIG_STM32_APP_IN_EXT_FLASH */ + /* + * Case of chain-loaded applications: * Switch to HSI and disable the PLL before configuration. * (Switching to HSI makes sure we have a SYSCLK source in * case we're currently running from the PLL we're about to @@ -501,12 +539,30 @@ static int set_up_plls(void) LL_RCC_PLL1_Enable(); while (LL_RCC_PLL1_IsReady() != 1U) { } + + goto setup_pll2; #else /* Init PLL source to None */ LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_NONE); + + goto setup_pll2; #endif /* STM32_PLL_ENABLED */ +setup_pll2: #if defined(STM32_PLL2_ENABLED) + +#if defined(CONFIG_STM32_APP_IN_EXT_FLASH) + /* + * Don't disable PLL2 during application initialization + * that runs on the external octospi flash (in memmap mode) + * when (Q/O)SPI uses PLL2 as its clock source. + */ + if (LL_RCC_GetOCTOSPIClockSource(LL_RCC_OCTOSPI_CLKSOURCE) == LL_RCC_OSPI_CLKSOURCE_PLL2R) { + goto setup_pll3; + } +#endif /* CONFIG_STM32_APP_IN_EXT_FLASH */ + LL_RCC_PLL2_Disable(); + /* Configure PLL2 source */ if (IS_ENABLED(STM32_PLL2_SRC_HSE)) { LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_HSE); @@ -554,11 +610,16 @@ static int set_up_plls(void) LL_RCC_PLL2_Enable(); while (LL_RCC_PLL2_IsReady() != 1U) { } + + goto setup_pll3; #else /* Init PLL2 source to None */ LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_NONE); + + goto setup_pll3; #endif /* STM32_PLL2_ENABLED */ +setup_pll3: #if defined(RCC_CR_PLL3ON) #if defined(STM32_PLL3_ENABLED) /* Configure PLL3 source */ diff --git a/drivers/flash/flash_stm32_xspi.c b/drivers/flash/flash_stm32_xspi.c index 78068413600e6..6ff3262598502 100644 --- a/drivers/flash/flash_stm32_xspi.c +++ b/drivers/flash/flash_stm32_xspi.c @@ -966,16 +966,6 @@ static int stm32_xspi_set_memorymap(const struct device *dev) return 0; } -/* Function to return true if the octoflash is in MemoryMapped else false */ -static bool stm32_xspi_is_memorymap(const struct device *dev) -{ - struct flash_stm32_xspi_data *dev_data = dev->data; - - return ((READ_BIT(dev_data->hxspi.Instance->CR, - XSPI_CR_FMODE) == XSPI_CR_FMODE) ? - true : false); -} - static int stm32_xspi_abort(const struct device *dev) { struct flash_stm32_xspi_data *dev_data = dev->data; @@ -989,6 +979,17 @@ static int stm32_xspi_abort(const struct device *dev) } #endif /* CONFIG_STM32_MEMMAP */ + +#if defined(CONFIG_STM32_MEMMAP) || defined(CONFIG_STM32_APP_IN_EXT_FLASH) +/* Function to return true if the octoflash is in MemoryMapped else false */ +static bool stm32_xspi_is_memorymap(const struct device *dev) +{ + struct flash_stm32_xspi_data *dev_data = dev->data; + + return READ_BIT(dev_data->hxspi.Instance->CR, XSPI_CR_FMODE) == XSPI_CR_FMODE; +} +#endif + /* * Function to erase the flash : chip or sector with possible OCTO/SPI and STR/DTR * to erase the complete chip (using dedicated command) : @@ -2047,7 +2048,7 @@ static int flash_stm32_xspi_init(const struct device *dev) return -ENODEV; } -#ifdef CONFIG_STM32_MEMMAP +#ifdef CONFIG_STM32_APP_IN_EXT_FLASH /* If MemoryMapped then configure skip init * Check clock status first as reading CR register without bus clock doesn't work on N6 * If clock is off, then MemoryMapped is off too and we do init @@ -2056,13 +2057,13 @@ static int flash_stm32_xspi_init(const struct device *dev) (clock_control_subsys_t) &dev_cfg->pclken) == CLOCK_CONTROL_STATUS_ON) { if (stm32_xspi_is_memorymap(dev)) { - LOG_ERR("NOR init'd in MemMapped mode"); + LOG_DBG("NOR init'd in MemMapped mode"); /* Force HAL instance in correct state */ dev_data->hxspi.State = HAL_XSPI_STATE_BUSY_MEM_MAPPED; return 0; } } -#endif /* CONFIG_STM32_MEMMAP */ +#endif /* CONFIG_STM32_APP_IN_EXT_FLASH */ /* The SPI/DTR is not a valid config of data_mode/data_rate according to the DTS */ if ((dev_cfg->data_mode != XSPI_OCTO_MODE) diff --git a/samples/subsys/mgmt/hawkbit/boards/stm32h573i_dk.overlay b/samples/subsys/mgmt/hawkbit/boards/stm32h573i_dk.overlay new file mode 100644 index 0000000000000..2e4030e522419 --- /dev/null +++ b/samples/subsys/mgmt/hawkbit/boards/stm32h573i_dk.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Define the device, controller and partition to be the external memory + * for running the application in external NOR from MCUboot + */ +/ { + chosen { + zephyr,flash = &mx25lm51245; + zephyr,flash-controller = &mx25lm51245; + }; +}; diff --git a/samples/subsys/mgmt/hawkbit/sample.yaml b/samples/subsys/mgmt/hawkbit/sample.yaml index 14b066625318e..c37258106b10a 100644 --- a/samples/subsys/mgmt/hawkbit/sample.yaml +++ b/samples/subsys/mgmt/hawkbit/sample.yaml @@ -17,8 +17,6 @@ tests: sample.net.hawkbit.default: {} sample.net.hawkbit.sysbuild: sysbuild: true - extra_args: - - platform:stm32h573i_dk/stm32h573xx:mcuboot_CONFIG_BOOT_MAX_IMG_SECTORS=128 sample.net.hawkbit.manual: extra_configs: - CONFIG_HAWKBIT_MANUAL=y diff --git a/samples/sysbuild/with_mcuboot/boards/stm32h573i_dk.overlay b/samples/sysbuild/with_mcuboot/boards/stm32h573i_dk.overlay new file mode 100644 index 0000000000000..2e4030e522419 --- /dev/null +++ b/samples/sysbuild/with_mcuboot/boards/stm32h573i_dk.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Define the device, controller and partition to be the external memory + * for running the application in external NOR from MCUboot + */ +/ { + chosen { + zephyr,flash = &mx25lm51245; + zephyr,flash-controller = &mx25lm51245; + }; +}; diff --git a/samples/sysbuild/with_mcuboot/sample.yaml b/samples/sysbuild/with_mcuboot/sample.yaml index a2e53a4fbecb0..bdd79980ed298 100644 --- a/samples/sysbuild/with_mcuboot/sample.yaml +++ b/samples/sysbuild/with_mcuboot/sample.yaml @@ -17,6 +17,7 @@ tests: - nucleo_h7s3l8 - nucleo_u385rg_q - stm32h7s78_dk + - stm32h573i_dk integration_platforms: - nrf52840dk/nrf52840 - esp32_devkitc/esp32/procpu diff --git a/soc/st/stm32/Kconfig b/soc/st/stm32/Kconfig index b4d1e1148ae3c..06215237cac32 100644 --- a/soc/st/stm32/Kconfig +++ b/soc/st/stm32/Kconfig @@ -104,4 +104,12 @@ config STM32_BACKUP_PROTECTION Enabled for SoCs for which access protection to backup domain resources needs to be explicitly handled. +config STM32_APP_IN_EXT_FLASH + bool + help + Allows the SoC clock driver to correctly initialize the + Q/O/XSPI controller clocks when the application is residing + in external Flash and is chainloaded with MCUboot. + Whether the app is eXecuted in Place (XiP) depends on the MCUboot mode used. + endif # SOC_FAMILY_STM32 diff --git a/soc/st/stm32/Kconfig.defconfig b/soc/st/stm32/Kconfig.defconfig index aafb321151a46..22b8d06040412 100644 --- a/soc/st/stm32/Kconfig.defconfig +++ b/soc/st/stm32/Kconfig.defconfig @@ -85,6 +85,9 @@ config FLASH_BASE_ADDRESS if $(DT_FLASH_PARENT_IS_XSPI) default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) +config STM32_APP_IN_EXT_FLASH + default $(DT_FLASH_PARENT_IS_XSPI) + # The XSPI PSRAM driver creates a SMH region with attribute SMH_REG_ATTR_EXTERNAL (2) # If applicable set the LTDC / VIDEO_BUFFER SMH attribute to SMH_REG_ATTR_EXTERNAL (2) # in order to be able to allocate from the XSPI PSRAM