diff --git a/arch/arm/core/cortex_a_r/Kconfig b/arch/arm/core/cortex_a_r/Kconfig index ddf388c195b6c..a6176bbe5c094 100644 --- a/arch/arm/core/cortex_a_r/Kconfig +++ b/arch/arm/core/cortex_a_r/Kconfig @@ -13,6 +13,15 @@ # CPU_AARCH32_CORTEX_A / if CPU_AARCH32_CORTEX_R blocks so they are not # exposed if one selects a different ARM Cortex Family (Cortex-M). +config CPU_CORTEX_A7 + bool + select CPU_AARCH32_CORTEX_A + select ARMV7_A + select CPU_HAS_ICACHE + select CPU_HAS_DCACHE + help + This option signifies the use of a Cortex-A7 CPU. + config CPU_CORTEX_A9 bool select CPU_AARCH32_CORTEX_A diff --git a/arch/arm/core/cortex_a_r/fault.c b/arch/arm/core/cortex_a_r/fault.c index daf1d2345ca06..eac07cbf9b25b 100644 --- a/arch/arm/core/cortex_a_r/fault.c +++ b/arch/arm/core/cortex_a_r/fault.c @@ -100,6 +100,59 @@ static uint32_t dump_fault(uint32_t status, uint32_t addr) reason = K_ERR_ARM_UNSUPPORTED_EXCLUSIVE_ACCESS_FAULT; LOG_ERR("Unsupported Exclusive Access Fault @ 0x%08x", addr); break; +#elif defined(CONFIG_ARMV7_A) + case FSR_FS_PERMISSION_FAULT_2ND_LEVEL: + reason = K_ERR_ARM_PERMISSION_FAULT_2ND_LEVEL; + LOG_ERR("2nd Level Permission Fault @ 0x%08x", addr); + break; + case FSR_FS_ACCESS_FLAG_FAULT_1ST_LEVEL: + reason = K_ERR_ARM_ACCESS_FLAG_FAULT_1ST_LEVEL; + LOG_ERR("1st Level Access Flag Fault @ 0x%08x", addr); + break; + case FSR_FS_ACCESS_FLAG_FAULT_2ND_LEVEL: + reason = K_ERR_ARM_ACCESS_FLAG_FAULT_2ND_LEVEL; + LOG_ERR("2nd Level Access Flag Fault @ 0x%08x", addr); + break; + case FSR_FS_CACHE_MAINTENANCE_INSTRUCTION_FAULT: + reason = K_ERR_ARM_CACHE_MAINTENANCE_INSTRUCTION_FAULT; + LOG_ERR("Cache Maintenance Instruction Fault @ 0x%08x", addr); + break; + case FSR_FS_TRANSLATION_FAULT: + reason = K_ERR_ARM_TRANSLATION_FAULT; + LOG_ERR("1st Level Translation Fault @ 0x%08x", addr); + break; + case FSR_FS_TRANSLATION_FAULT_2ND_LEVEL: + reason = K_ERR_ARM_TRANSLATION_FAULT_2ND_LEVEL; + LOG_ERR("2nd Level Translation Fault @ 0x%08x", addr); + break; + case FSR_FS_DOMAIN_FAULT_1ST_LEVEL: + reason = K_ERR_ARM_DOMAIN_FAULT_1ST_LEVEL; + LOG_ERR("1st Level Domain Fault @ 0x%08x", addr); + break; + case FSR_FS_DOMAIN_FAULT_2ND_LEVEL: + reason = K_ERR_ARM_DOMAIN_FAULT_2ND_LEVEL; + LOG_ERR("2nd Level Domain Fault @ 0x%08x", addr); + break; + case FSR_FS_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_1ST_LEVEL: + reason = K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_1ST_LEVEL; + LOG_ERR("1st Level Synchronous External Abort Translation Table @ 0x%08x", addr); + break; + case FSR_FS_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_2ND_LEVEL: + reason = K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_2ND_LEVEL; + LOG_ERR("2nd Level Synchronous External Abort Translation Table @ 0x%08x", addr); + break; + case FSR_FS_TLB_CONFLICT_FAULT: + reason = K_ERR_ARM_TLB_CONFLICT_FAULT; + LOG_ERR("Table Conflict Fault @ 0x%08x", addr); + break; + case FSR_FS_SYNC_PARITY_ERROR_TRANSLATION_TABLE_1ST_LEVEL: + reason = K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_1ST_LEVEL; + LOG_ERR("1st Level Synchronous Parity Error Translation Table @ 0x%08x", addr); + break; + case FSR_FS_SYNC_PARITY_ERROR_TRANSLATION_TABLE_2ND_LEVEL: + reason = K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_2ND_LEVEL; + LOG_ERR("2nd Level Synchronous Parity Error Translation Table @ 0x%08x", addr); + break; #else case FSR_FS_BACKGROUND_FAULT: reason = K_ERR_ARM_BACKGROUND_FAULT; diff --git a/boards/st/stm32mp135f_dk/Kconfig.stm32mp135f_dk b/boards/st/stm32mp135f_dk/Kconfig.stm32mp135f_dk new file mode 100644 index 0000000000000..c648af34bc372 --- /dev/null +++ b/boards/st/stm32mp135f_dk/Kconfig.stm32mp135f_dk @@ -0,0 +1,5 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_STM32MP135F_DK + select SOC_STM32MP135FXX diff --git a/boards/st/stm32mp135f_dk/board.cmake b/boards/st/stm32mp135f_dk/board.cmake new file mode 100644 index 0000000000000..af21b18031704 --- /dev/null +++ b/boards/st/stm32mp135f_dk/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) + +board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd.cfg") diff --git a/boards/st/stm32mp135f_dk/board.yml b/boards/st/stm32mp135f_dk/board.yml new file mode 100644 index 0000000000000..2e3886965ba73 --- /dev/null +++ b/boards/st/stm32mp135f_dk/board.yml @@ -0,0 +1,6 @@ +board: + name: stm32mp135f_dk + full_name: STM32MP135F-DK Discovery + vendor: st + socs: + - name: stm32mp135fxx diff --git a/boards/st/stm32mp135f_dk/doc/img/stm32mp135f_dk.webp b/boards/st/stm32mp135f_dk/doc/img/stm32mp135f_dk.webp new file mode 100644 index 0000000000000..d4e5a32a261ac Binary files /dev/null and b/boards/st/stm32mp135f_dk/doc/img/stm32mp135f_dk.webp differ diff --git a/boards/st/stm32mp135f_dk/doc/index.rst b/boards/st/stm32mp135f_dk/doc/index.rst new file mode 100644 index 0000000000000..9000f28bbfbe6 --- /dev/null +++ b/boards/st/stm32mp135f_dk/doc/index.rst @@ -0,0 +1,203 @@ +.. zephyr:board:: stm32mp135f_dk + +Overview +******** +The STM32MP135 Discovery kit (STM32MP135F-DK) leverages the capabilities of the +1 GHz STM32MP135 microprocessors to allow users to develop applications easily with Zephyr RTOS. + +It includes an ST-LINK embedded debug tool, LEDs, push-buttons, two 10/100 Mbit/s Ethernet (RMII) connectors, one USB Type-C |reg| connector, four USB Host Type-A connectors, and one microSD™ connector. + +To expand the functionality of the STM32MP135 Discovery kit, one GPIO expansion connector is also available for third-party shields. + +Additionally, the STM32MP135 Discovery kit features an LCD display with a touch panel, Wi‑Fi |reg| and Bluetooth |reg| Low Energy capability, and a 2-megapixel CMOS camera module. + +It also provides secure boot and cryptography features. + +Zephyr OS is ported to run on the Cortex |reg|-A7 core. + +- STM32MP135FAF7: Arm |reg| Cortex |reg|-A7 32-bit processor at 1 GHz, in a TFBGA320 package +- ST PMIC STPMIC1 +- 4-Gbit DDR3L, 16 bits, 533 MHz +- 4.3" 480x272 pixels LCD display module with capacitive touch panel and RGB interface +- UXGA 2-megapixel CMOS camera module (included) with MIPI CSI-2 |reg| / SMIA CCP2 deserializer +- Wi-Fi |reg| 802.11b/g/n +- Bluetooth |reg| Low Energy 4.1 +- Dual 10/100 Mbit/s Ethernet (RMII) compliant with IEEE-802.3u, one with Wake on LAN (WoL) support +- USB Host 4-port hub +- USB Type-C |reg| DRP based on an STM32G0 device +- 4 user LEDs +- 4 push-buttons (2× user, tamper, and reset) +- 1 wake-up button +- Board connectors: + + - Dual-lane MIPI CSI-2 |reg| camera module expansion + - 2x Ethernet RJ45 + - 4x USB Type-A + - USB Micro-B + - USB Type-C |reg| + - microSD™ card holder + - GPIO expansion + - 5 V / 3 A USB Type-C |reg| power supply input (charger not provided) + - VBAT for power backup + +- On-board current measurement +- On-board STLINK-V3E debugger/programmer with USB re-enumeration capability: + + - mass storage + - Virtual COM port + - debug port + +More information about the board can be found at the +`STM32P135 Discovery website`_. + +Hardware +******** + +More information about the STM32MP135F_DK board hardware can be found here: + +- `STM32MP135F_DK Hardware Description`_ + +More information about STM32P135F microprocessor can be found here: + +- `STM32MP135F on www.st.com`_ +- `STM32MP135F reference manual`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Connections and IOs +=================== + +STM32MP135F-DK Discovery Board schematic is available here: +`STM32MP135F Discovery board schematics`_. + + +Default Zephyr Peripheral Mapping: +---------------------------------- + +- USART_4 TX/RX : PD6/PD8 (UART console) + +- USER_BUTTON : PA13 +- LED_3 : PA14 +- LED_4 : PA13 + +System Clock +------------ + +The Cortex |reg|-A7 core is configured to run at a clock speed of up to 1GHz. + +Memory mapping +-------------- + ++------------+-----------------------+----------------+ +| Region | Address | Size | ++============+=======================+================+ +| SYSRAM | 0x2FFE0000-0x2FFFFFFF | 128KB | ++------------+-----------------------+----------------+ +| SRAM 1 | 0x30000000-0x30003FFF | 16KB | ++------------+-----------------------+----------------+ +| SRAM 2 | 0x30004000-0x30005FFF | 8KB | ++------------+-----------------------+----------------+ +| SRAM 3 | 0x30006000-0x30007FFF | 8KB | ++------------+-----------------------+----------------+ +| DDR | 0xC0000000-0xDFFFFFFF | 512 MB | ++------------+-----------------------+----------------+ + +Programming and Debugging +************************* + +Prerequisite +============ + +The STM32MP135 has a DDR controller that need to be initialized before loading the Zephyr example. + +One method to perform this is to flash the Zephyr executable, along with the DDR initialization script, on an SD card inserted in the board. To do so, you first need to :ref:`install STM32CubeProgrammer ` and download the `STM32CubeMP13 package`_. + +Signature and flashing +====================== + +After building the Zephyr project, you need to sign your binary file using the Stm32ImageAddHeader.py with the following command: + +.. code-block:: console + + python3 ${Path_to_STM32CubeMP13}/Utilities/ImageHeader/Python3/Stm32ImageAddHeader.py ${Path_to_build_dir}/zephyr/zephyr.bin ${STM32CubeMP13}/Projects/STM32MP135C-DK/External_Loader/Prebuild_Binaries/SD_Ext_Loader/zephyr_Signed.bin -bt 10 -la C0000000 -ep C0000000 + +Here -bt specifies the boot type, -la specifies the load address and -ep the entry point for your executable (same as the load address in this case). + +Then, copy :zephyr_file:`boards/st/stm32mp135f_dk/support/Zephyr.tsv` to ``${Path_to_STM32CubeMP13}/Projects/STM32MP135C-DK/External_Loader/Prebuild_Binaries/SD_Ext_Loader/``. + +Finally using the Cube Programmer select the Zephyr.tsv and flash the SD card with the following command: + +.. code-block:: console + + ${Path_to_STM32cube_Programmer}/bin/STM32_Programmer.sh -c port=${ConnectedPort} p=even br=115200 -d ${Path_to_STM32CubeMP13}/Projects/STM32MP135C-DK/External_Loader/Prebuild_Binaries/SD_Ext_Loader/Zephyr.tsv + +.. note:: + You can refer to this example to flash an example to the SD card: + `How to install STM32Cube software package on microSD card`_ + +Debugging +========= + +You can debug an application using OpenOCD and GDB. + +- Build the sample: + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: stm32mp135f_dk + :goals: build + +- Flash the SD card using: + `How to install STM32Cube software package on microSD card`_ + +- Run the application from the SD card + +- Attach to the target: + + .. code-block:: console + + west attach + +.. note:: + The ``run`` command of GDB isn't supported at the moment for this board. + +References +********** + +.. target-notes:: + +.. _STM32P135 Discovery website: + https://www.st.com/en/evaluation-tools/stm32mp135f-dk.html + +.. _STM32MP135F Discovery board User Manual: + https://www.st.com/resource/en/user_manual/dm00862450.pdf + +.. _STM32MP135F Discovery board schematics: + https://www.st.com/resource/en/schematic_pack/mb1635-mp135f-e02-schematic.pdf + +.. _STM32MP135F on www.st.com: + https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-arm-cortex-mpus/stm32mp1-series/stm32mp135/stm32mp135f.html + +.. _STM32MP135F reference manual: + https://www.st.com/resource/en/reference_manual/DM00670465-.pdf + +.. _STM32MP135 STM32Cube software package: + https://www.st.com/en/embedded-software/stm32cubemp13.html#get-software + +.. _How to install STM32Cube software package on microSD card: + https://wiki.st.com/stm32mpu/wiki/How_to_load_and_start_STM32CubeMP13_applications_via_microSD_card + +.. _STM32MP135F boot architecture: + https://wiki.st.com/stm32mpu/wiki/STM32CubeMP13_package_-_boot_architecture + +.. _STM32MP135F baremetal distribution: + https://wiki.st.com/stm32mpu/wiki/Category:Bare_metal_-_RTOS_embedded_software + +.. _STM32CubeMP13 package: + https://github.com/STMicroelectronics/STM32CubeMP13 + +.. _STM32MP135F_DK Hardware Description: + https://wiki.stmicroelectronics.cn/stm32mpu/wiki/STM32MP135x-DK_-_hardware_description diff --git a/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts b/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts new file mode 100644 index 0000000000000..5d2f343835568 --- /dev/null +++ b/boards/st/stm32mp135f_dk/stm32mp135f_dk.dts @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include + +/ { + model = "STMicroelectronics STM32MP135-DK board"; + compatible = "st,stm32mp135f-dk"; + + chosen { + zephyr,flash = &ddr_code; + zephyr,sram = &ddr_data; + zephyr,console = &uart4; + zephyr,shell-uart = &uart4; + }; + + gpio_keys { + compatible = "gpio-keys"; + + user_button: button { + label = "User 1"; + gpios = <&gpioa 13 GPIO_ACTIVE_LOW>; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + blue_led_1: led_1 { + gpios = <&gpioa 14 GPIO_ACTIVE_HIGH>; + label = "LD3"; + }; + + red_led_2: led_2 { + gpios = <&gpioa 13 GPIO_ACTIVE_HIGH>; + label = "LD4"; + }; + }; + + aliases { + led0 = &blue_led_1; + led1 = &red_led_2; + sw0 = &user_button; + }; +}; + +&clk_hsi { + clock-frequency = ; + status = "okay"; +}; + +&clk_hse { + clock-frequency = ; + status = "okay"; +}; + +&cpusw { + clocks = <&clk_hsi>; + clock-frequency = ; + status = "okay"; +}; + +&pll1 { + clocks = <&clk_hse>; + div-m = <2>; + mul-n = <83>; + div-p = <1>; + frac-v = <2730>; + status = "okay"; +}; + +&rcc { + clock-frequency = ; + clocks = <&pll>; + ahb-prescaler = <1>; + apb1-prescaler = <1>; + apb2-prescaler = <1>; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_tx_pd6 &uart4_rx_pd8>; + current-speed = <115200>; + status = "okay"; +}; diff --git a/boards/st/stm32mp135f_dk/stm32mp135f_dk_defconfig b/boards/st/stm32mp135f_dk/stm32mp135f_dk_defconfig new file mode 100644 index 0000000000000..5a7682e99ddba --- /dev/null +++ b/boards/st/stm32mp135f_dk/stm32mp135f_dk_defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2025, STMicroelectronics + +# SPDX-License-Identifier: Apache-2.0 + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +# Console (remote proc console by default) +CONFIG_CONSOLE=y + +# UART console (overrides remote proc console) +CONFIG_UART_CONSOLE=y diff --git a/boards/st/stm32mp135f_dk/support/Zephyr.tsv b/boards/st/stm32mp135f_dk/support/Zephyr.tsv new file mode 100644 index 0000000000000..9f59a34e9274e --- /dev/null +++ b/boards/st/stm32mp135f_dk/support/Zephyr.tsv @@ -0,0 +1,5 @@ +#Opt Id Name Type IP Offset Binary +P 0x1 fsbl-openbl Binary none 0x0 External_Mem_Loader_A7.stm32 +P 0x3 fsbl-extfl Binary none 0x0 SD_Ext_Loader.bin +P 0x4 fsbl-app Binary mmc0 0x0000080 FSBLA_Sdmmc1_A7_Signed.bin +P 0x5 fsbl-app Binary mmc0 0x0000500 zephyr_Signed.bin diff --git a/boards/st/stm32mp135f_dk/support/openocd.cfg b/boards/st/stm32mp135f_dk/support/openocd.cfg new file mode 100644 index 0000000000000..95aff7bb7ba7b --- /dev/null +++ b/boards/st/stm32mp135f_dk/support/openocd.cfg @@ -0,0 +1,4 @@ +source [find board/stm32mp13x_dk.cfg] + +# Don't reset the SoC to keep DDR configuration +reset_config none diff --git a/boards/st/stm32mp135f_dk/twister.yaml b/boards/st/stm32mp135f_dk/twister.yaml new file mode 100644 index 0000000000000..6e2d37a648298 --- /dev/null +++ b/boards/st/stm32mp135f_dk/twister.yaml @@ -0,0 +1,14 @@ +identifier: stm32mp135f_dk +name: ST STM32MP135F-DK Discovery +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - gpio + - uart + - shell +ram: 256 +flash: 256 +vendor: st diff --git a/cmake/compiler/iar/iccarm-cpu.cmake b/cmake/compiler/iar/iccarm-cpu.cmake index 70eee9240b654..f191bb7e314a8 100644 --- a/cmake/compiler/iar/iccarm-cpu.cmake +++ b/cmake/compiler/iar/iccarm-cpu.cmake @@ -67,6 +67,8 @@ if("${ARCH}" STREQUAL "arm") set(ICCARM_CPU ${ICCARM_CPU}+fp.sp) endif() endif() + elseif(CONFIG_CPU_CORTEX_A7) + set(ICCARM_CPU Cortex-A7) elseif(CONFIG_CPU_CORTEX_A9) set(ICCARM_CPU Cortex-A9) else() diff --git a/cmake/gcc-m-cpu.cmake b/cmake/gcc-m-cpu.cmake index 6f00283b6b8e4..75b13fa423844 100644 --- a/cmake/gcc-m-cpu.cmake +++ b/cmake/gcc-m-cpu.cmake @@ -84,6 +84,8 @@ if("${ARCH}" STREQUAL "arm") set(GCC_M_CPU ${GCC_M_CPU}+nofp.dp) endif() endif() + elseif(CONFIG_CPU_CORTEX_A7) + set(GCC_M_CPU cortex-a7) elseif(CONFIG_CPU_CORTEX_A9) set(GCC_M_CPU cortex-a9) else() diff --git a/cmake/gcc-m-fpu.cmake b/cmake/gcc-m-fpu.cmake index d1ce9655b46d0..aafe5b75c8616 100644 --- a/cmake/gcc-m-fpu.cmake +++ b/cmake/gcc-m-fpu.cmake @@ -45,6 +45,10 @@ if("${ARCH}" STREQUAL "arm") set(FPU_FOR_cortex-m85+nodsp auto) set(GCC_M_FPU ${FPU_FOR_${GCC_M_CPU}}) + elseif(CONFIG_CPU_AARCH32_CORTEX_A) + if(CONFIG_CPU_CORTEX_A7) + set(GCC_M_FPU vfpv4-d16) + endif() endif() endif() diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 1b8332cdc6f35..4016d73b5b9c2 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -55,6 +55,8 @@ if(CONFIG_CLOCK_CONTROL_STM32_CUBE) zephyr_library_sources_ifdef(CONFIG_CLOCK_STM32_MCO clock_stm32_mco.c) if(CONFIG_SOC_SERIES_STM32MP1X) zephyr_library_sources(clock_stm32_ll_mp1.c) +elseif(CONFIG_SOC_SERIES_STM32MP13X) + zephyr_library_sources(clock_stm32_ll_mp13.c) elseif(CONFIG_SOC_SERIES_STM32H7X) zephyr_library_sources(clock_stm32_ll_h7.c) elseif(CONFIG_SOC_SERIES_STM32H7RSX) diff --git a/drivers/clock_control/Kconfig.stm32 b/drivers/clock_control/Kconfig.stm32 index d99fa3b62eb29..9dacd04dbeac9 100644 --- a/drivers/clock_control/Kconfig.stm32 +++ b/drivers/clock_control/Kconfig.stm32 @@ -9,7 +9,7 @@ menuconfig CLOCK_CONTROL_STM32_CUBE depends on SOC_FAMILY_STM32 default y select USE_STM32_LL_UTILS - select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32H7X || \ + select USE_STM32_LL_RCC if (SOC_SERIES_STM32MP1X || SOC_SERIES_STM32MP13X || SOC_SERIES_STM32H7X || \ SOC_SERIES_STM32H7RSX || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || \ SOC_SERIES_STM32N6X) select RUNTIME_NMI if ($(dt_nodelabel_enabled,clk_hse) && \ diff --git a/drivers/clock_control/clock_stm32_ll_mp13.c b/drivers/clock_control/clock_stm32_ll_mp13.c new file mode 100644 index 0000000000000..6c8da819e5116 --- /dev/null +++ b/drivers/clock_control/clock_stm32_ll_mp13.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; + volatile int temp; + + ARG_UNUSED(dev); + + if (!IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX)) { + /* Attempt to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + + sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, pclken->enr); + /* Ensure that the write operation is completed */ + temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus); + UNUSED(temp); + + return 0; +} + +static int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; + volatile int temp; + + ARG_UNUSED(dev); + + if (!IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX)) { + /* Attempt to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + + sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus, pclken->enr); + /* Ensure that the write operation is completed */ + temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus); + UNUSED(temp); + + return 0; +} + +static int stm32_clock_control_get_subsys_rate(const struct device *dev, + clock_control_subsys_t sub_system, uint32_t *rate) +{ + struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system; + + ARG_UNUSED(dev); + + switch (pclken->bus) { + case STM32_CLOCK_BUS_APB1: + switch (pclken->enr) { + case LL_APB1_GRP1_PERIPH_UART4: + *rate = LL_RCC_GetUARTClockFreq(LL_RCC_UART4_CLKSOURCE); + break; + default: + return -ENOTSUP; + } + break; + default: + return -ENOTSUP; + } + return 0; +} + +static const struct clock_control_driver_api stm32_clock_control_api = { + .on = stm32_clock_control_on, + .off = stm32_clock_control_off, + .get_rate = stm32_clock_control_get_subsys_rate, +}; + +static void set_up_fixed_clock_sources(void) +{ + if (IS_ENABLED(STM32_HSE_ENABLED)) { + /* Enable HSE */ + LL_RCC_HSE_Enable(); + while (LL_RCC_HSE_IsReady() != 1) { + /* Wait for HSE ready */ + } + } + + if (IS_ENABLED(STM32_HSI_ENABLED)) { + /* Enable HSI if not enabled */ + if (LL_RCC_HSI_IsReady() != 1) { + /* Enable HSI */ + LL_RCC_HSI_Enable(); + while (LL_RCC_HSI_IsReady() != 1) { + /* Wait for HSI ready */ + } + } + } +} + +static int stm32_clock_control_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + set_up_fixed_clock_sources(); + +#if STM32_SYSCLK_SRC_HSE + + LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_HSE); + while (LL_RCC_GetMPUClkSource() != LL_RCC_MPU_CLKSOURCE_HSE) { + } + +#elif STM32_SYSCLK_SRC_HSI + + LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_HSI); + while (LL_RCC_GetMPUClkSource() != LL_RCC_MPU_CLKSOURCE_HSI) { + } + +#elif STM32_SYSCLK_SRC_PLL + + BUILD_ASSERT(IS_ENABLED(STM32_HSE_ENABLED), + "STM32MP13 PLL requires HSE to be enabled!"); + + /* The default system clock source is HSI, but the bootloader may have switched it. */ + /* Switch back to HSE for clock setup as PLL1 configuration must not be modified */ + /* while active.*/ + + LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_HSE); + while ((READ_BIT(RCC->MPCKSELR, RCC_MPCKSELR_MPUSRCRDY) != RCC_MPCKSELR_MPUSRCRDY)) { + } + + CLEAR_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVPEN); + while (READ_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVPEN) == RCC_PLL1CR_DIVPEN) { + }; + + CLEAR_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVQEN); + while (READ_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVQEN) == RCC_PLL1CR_DIVQEN) { + }; + + CLEAR_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVREN); + while (READ_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVREN) == RCC_PLL1CR_DIVREN) { + }; + + uint32_t pll1_n = DT_PROP(DT_NODELABEL(pll1), mul_n); + uint32_t pll1_m = DT_PROP(DT_NODELABEL(pll1), div_m); + uint32_t pll1_p = DT_PROP(DT_NODELABEL(pll1), div_p); + uint32_t pll1_v = DT_PROP(DT_NODELABEL(pll1), frac_v); + + LL_RCC_PLL1_SetN(pll1_n); + while (LL_RCC_PLL1_GetN() != pll1_n) { + } + LL_RCC_PLL1_SetM(pll1_m); + while (LL_RCC_PLL1_GetM() != pll1_m) { + } + LL_RCC_PLL1_SetP(pll1_p); + while (LL_RCC_PLL1_GetP() != pll1_p) { + } + LL_RCC_PLL1_SetFRACV(pll1_v); + while (LL_RCC_PLL1_GetFRACV() != pll1_v) { + } + + LL_RCC_PLL1_Enable(); + while (LL_RCC_PLL1_IsReady() != 1) { + } + + SET_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVPEN); + while (READ_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVPEN) != RCC_PLL1CR_DIVPEN) { + }; + + LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_PLL1); + while (LL_RCC_GetMPUClkSource() != LL_RCC_MPU_CLKSOURCE_PLL1) { + } + +#endif + + return 0; +} + +/** + * @brief RCC device, note that priority is intentionally set to 1 so + * that the device init runs just after SOC init + */ +DEVICE_DT_DEFINE(DT_NODELABEL(rcc), + stm32_clock_control_init, + NULL, + NULL, NULL, + PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, + &stm32_clock_control_api); diff --git a/dts/arm/st/mp13/stm32mp13.dtsi b/dts/arm/st/mp13/stm32mp13.dtsi new file mode 100644 index 0000000000000..d781890d1b5f6 --- /dev/null +++ b/dts/arm/st/mp13/stm32mp13.dtsi @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include + +#include +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + }; + }; + + soc { + interrupt-parent = <&gic>; + + sysram: memory@2ffe0000 { + compatible = "mmio-sram"; + reg = <0x2FFE0000 DT_SIZE_K(128)>; + }; + + uart4: serial@40010000 { + compatible = "st,stm32-uart"; + reg = <0x40010000 0x400>; + clocks = <&rcc STM32_CLOCK(APB1, 16)>; + resets = <&rctl STM32_RESET(APB1, 16)>; + interrupts = ; + status = "disabled"; + }; + + rcc: rcc@50000000 { + compatible = "st,stm32-rcc"; + reg = <0x50000000 0x1000>; + #clock-cells = <2>; + + rctl: reset-controller { + compatible = "st,stm32-rcc-rctl"; + #reset-cells = <1>; + set-bit-to-deassert; + }; + }; + + pinctrl: pin-controller@50002000 { + compatible = "st,stm32-pinctrl"; + reg = <0x50002000 0x9000>; + #address-cells = <1>; + #size-cells = <1>; + + gpioa: gpio@50002000 { + compatible = "st,stm32-gpio"; + reg = <0x50002000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 0)>; + }; + + gpiob: gpio@50003000 { + compatible = "st,stm32-gpio"; + reg = <0x50003000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 1)>; + }; + + gpioc: gpio@50004000 { + compatible = "st,stm32-gpio"; + reg = <0x50004000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 2)>; + }; + + gpiod: gpio@50005000 { + compatible = "st,stm32-gpio"; + reg = <0x50005000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 3)>; + }; + + gpioe: gpio@50006000 { + compatible = "st,stm32-gpio"; + reg = <0x50006000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 4)>; + }; + + gpiof: gpio@50007000 { + compatible = "st,stm32-gpio"; + reg = <0x50007000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 5)>; + }; + + gpiog: gpio@50008000 { + compatible = "st,stm32-gpio"; + reg = <0x50008000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 6)>; + }; + + gpioh: gpio@50009000 { + compatible = "st,stm32-gpio"; + reg = <0x50009000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 7)>; + }; + + gpioi: gpio@5000a000 { + compatible = "st,stm32-gpio"; + reg = <0x5000a000 0x400>; + gpio-controller; + #gpio-cells = <2>; + clocks = <&rcc STM32_CLOCK(AHB4, 8)>; + }; + }; + + exti: interrupt-controller@5000d000 { + compatible = "st,stm32g0-exti","st,stm32-exti"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + reg = <0x5000D000 0x400>; + num-lines = <16>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "line0", "line1", "line2", "line3", + "line4", "line5", "line6", "line7", + "line8", "line9", "line10", "line11", + "line12", "line13", "line14", "line15"; + line-ranges = <0 1>, <1 1>, <2 1>, <3 1>, + <4 1>, <5 1>, <6 1>, <7 1>, + <8 1>, <9 1>, <10 1>, <11 1>, + <12 1>, <13 1>, <14 1>, <15 1>; + }; + }; + + gic: gic@A0021000 { + compatible = "arm,gic-v2", "arm,gic"; + reg = <0xA0021000 0x1000>, + <0xA0022000 0x2000>; + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + ddr_code: memory@C0000000 { + compatible = "mmio-sram"; + reg = <0xC0000000 0x10000000>; + }; + + ddr_data: memory@D0000000 { + compatible = "mmio-sram"; + reg = <0xD0000000 0x10000000>; + }; + + clocks { + + clk_hse: clk-hse { + #clock-cells = <0>; + compatible = "fixed-clock"; + status = "disabled"; + }; + + clk_hsi: clk-hsi { + #clock-cells = <0>; + compatible = "fixed-clock"; + status = "disabled"; + }; + + cpusw: cpusw { + #clock-cells = <0>; + compatible = "st,stm32mp13-cpu-clock-mux"; + status = "disabled"; + }; + + pll1: pll: pll { + #clock-cells = <0>; + compatible = "st,stm32mp13-pll-clock"; + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; +}; diff --git a/dts/arm/st/mp13/stm32mp135.dtsi b/dts/arm/st/mp13/stm32mp135.dtsi new file mode 100644 index 0000000000000..4b754a69d583b --- /dev/null +++ b/dts/arm/st/mp13/stm32mp135.dtsi @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/ { + soc { + compatible = "st,stm32mp135", "st,stm32mp13", "simple-bus"; + }; +}; diff --git a/dts/bindings/clock/st,stm32mp13-cpu-clock-mux.yaml b/dts/bindings/clock/st,stm32mp13-cpu-clock-mux.yaml new file mode 100644 index 0000000000000..529d9ef82599a --- /dev/null +++ b/dts/bindings/clock/st,stm32mp13-cpu-clock-mux.yaml @@ -0,0 +1,31 @@ +# Copyright (c) 2025, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32MP13 CPU Clock + Describes the STM32MP13 CPU armv7 timer multiplexer. + For the STM32MP13 the CPU armv7 timer input can either be the HSI or the HSE. + For instance: + cpusw: cpusw { + #clock-cells = <0>; + clocks = <&clk_hsi>; + clock-frequency = ; + compatible = "st,stm32mp13-cpu-clock-mux", "st,stm32-clock-mux"; + status = "okay"; + }; + +compatible: "st,stm32mp13-cpu-clock-mux" + +include: + - name: base.yaml + property-allowlist: + - status + - compatible + - clocks + +properties: + clock-frequency: + required: true + type: int + description: | + default frequency in Hz for the timer diff --git a/dts/bindings/clock/st,stm32mp13-pll-clock.yaml b/dts/bindings/clock/st,stm32mp13-pll-clock.yaml new file mode 100644 index 0000000000000..5128ea05f0d8e --- /dev/null +++ b/dts/bindings/clock/st,stm32mp13-pll-clock.yaml @@ -0,0 +1,68 @@ +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + PLL node binding for STM32MP13 devices + + It can be used to describe 4 different PLLs: PLL1, PLL2, PLL3 and PLL4. + + These PLLs can take one of hse_ck, hsi_ck or csi_ck as input clock. + PLLM factor is used to set the input clock in this acceptable range. + + Each PLL has one output clock whose frequency can be computed with the + following formula: + + f(PLL_P) = f(VCO clock) / (DIVP × DIVR × DIVQ) + + with f(VCO clock) = f(PLL clock input) × 2 × (((DIVN + 1) + (FRACV / 8192)) / DIVM1) + + Note: To reduce the power consumption, it is recommended to configure the VCOx + clock output to the lowest frequency. + + The PLL1 output frequency must not exceed 2000 MHz. + The PLL2 output frequency must not exceed 1600 MHz. + The PLL3 output frequency must not exceed 800 MHz. + The PLL4 output frequency must not exceed 800 MHz. + + Note: The CPU clock should not exceed 1Ghz so avoid configuring the PLL1 to more + than 1000 MHz or program the mpuss_ck mux to use the MPUDIV + (refer to the stm32mp13 reference manual for details) + +compatible: "st,stm32mp13-pll-clock" + +include: [clock-controller.yaml, base.yaml] + +properties: + + "#clock-cells": + const: 0 + + clocks: + required: true + + div-m: + type: int + required: true + description: | + Prescaler for PLLx + input clock + Valid range: 1 - 64 + + mul-n: + type: int + required: true + description: | + PLLx multiplication factor for VCO + Valid range: 31 - 125 + + div-p: + type: int + description: | + PLLx DIVP division factor + Valid range: 1 - 128 + + frac-v: + type: int + description: | + PLLx FRACV fractional latch + Valid range: 1 - 8192 diff --git a/include/zephyr/arch/arm/arch.h b/include/zephyr/arch/arm/arch.h index 9bbcc2375f1cd..1a33196b15e4f 100644 --- a/include/zephyr/arch/arm/arch.h +++ b/include/zephyr/arch/arm/arch.h @@ -40,9 +40,9 @@ #elif defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) #include #include -#if defined(CONFIG_AARCH32_ARMV8_R) +#if defined(CONFIG_AARCH32_ARMV8_R) || defined(CONFIG_CPU_CORTEX_A7) #include -#include +#include #else #include #endif @@ -99,13 +99,25 @@ enum k_fatal_error_reason_arch { K_ERR_ARM_ALIGNMENT_FAULT, K_ERR_ARM_BACKGROUND_FAULT, K_ERR_ARM_PERMISSION_FAULT, + K_ERR_ARM_PERMISSION_FAULT_2ND_LEVEL, K_ERR_ARM_SYNC_EXTERNAL_ABORT, K_ERR_ARM_ASYNC_EXTERNAL_ABORT, K_ERR_ARM_SYNC_PARITY_ERROR, K_ERR_ARM_ASYNC_PARITY_ERROR, K_ERR_ARM_DEBUG_EVENT, K_ERR_ARM_TRANSLATION_FAULT, - K_ERR_ARM_UNSUPPORTED_EXCLUSIVE_ACCESS_FAULT + K_ERR_ARM_TRANSLATION_FAULT_2ND_LEVEL, + K_ERR_ARM_UNSUPPORTED_EXCLUSIVE_ACCESS_FAULT, + K_ERR_ARM_ACCESS_FLAG_FAULT_1ST_LEVEL, + K_ERR_ARM_ACCESS_FLAG_FAULT_2ND_LEVEL, + K_ERR_ARM_CACHE_MAINTENANCE_INSTRUCTION_FAULT, + K_ERR_ARM_DOMAIN_FAULT_1ST_LEVEL, + K_ERR_ARM_DOMAIN_FAULT_2ND_LEVEL, + K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_1ST_LEVEL, + K_ERR_ARM_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_2ND_LEVEL, + K_ERR_ARM_TLB_CONFLICT_FAULT, + K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_1ST_LEVEL, + K_ERR_ARM_SYNC_PARITY_ERROR_TRANSLATION_TABLE_2ND_LEVEL, }; #endif /* _ASMLANGUAGE */ diff --git a/include/zephyr/arch/arm/cortex_a_r/armv8_timer.h b/include/zephyr/arch/arm/cortex_a_r/armv7_v8_timer.h similarity index 86% rename from include/zephyr/arch/arm/cortex_a_r/armv8_timer.h rename to include/zephyr/arch/arm/cortex_a_r/armv7_v8_timer.h index 3950397f71a62..911bed910f0db 100644 --- a/include/zephyr/arch/arm/cortex_a_r/armv8_timer.h +++ b/include/zephyr/arch/arm/cortex_a_r/armv7_v8_timer.h @@ -5,8 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV8_TIMER_H_ -#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV8_TIMER_H_ +#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV7_V8_TIMER_H_ +#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV7_V8_TIMER_H_ #ifndef _ASMLANGUAGE @@ -71,4 +71,4 @@ static ALWAYS_INLINE uint64_t arm_arch_timer_count(void) #endif /* _ASMLANGUAGE */ -#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV8_TIMER_H_ */ +#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_A_R_ARMV7_V8_TIMER_H_ */ diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index fddf67e4da5ea..49c74d1922bf1 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -53,6 +53,8 @@ #include #elif defined(CONFIG_SOC_SERIES_STM32H7RSX) #include +#elif defined(CONFIG_SOC_SERIES_STM32MP13X) +#include #elif defined(CONFIG_SOC_SERIES_STM32N6X) #include #elif defined(CONFIG_SOC_SERIES_STM32U0X) diff --git a/include/zephyr/dt-bindings/clock/stm32mp13_clock.h b/include/zephyr/dt-bindings/clock/stm32mp13_clock.h new file mode 100644 index 0000000000000..daf2d8ca2cd57 --- /dev/null +++ b/include/zephyr/dt-bindings/clock/stm32mp13_clock.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32MP13_CLOCK_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32MP13_CLOCK_H_ + +#include "stm32_common_clocks.h" + +/** Bus clocks */ +#define STM32_CLOCK_BUS_APB1 0x700 +#define STM32_CLOCK_BUS_APB2 0x708 +#define STM32_CLOCK_BUS_APB3 0x710 +#define STM32_CLOCK_BUS_APB4 0x728 +#define STM32_CLOCK_BUS_APB5 0x740 +#define STM32_CLOCK_BUS_APB6 0x748 +#define STM32_CLOCK_BUS_AHB2 0x750 +#define STM32_CLOCK_BUS_AHB4 0x768 +#define STM32_CLOCK_BUS_AHB5 0x778 +#define STM32_CLOCK_BUS_AHB6 0x780 + +#define STM32_PERIPH_BUS_MIN STM32_CLOCK_BUS_APB1 +#define STM32_PERIPH_BUS_MAX STM32_CLOCK_BUS_AHB6 + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_STM32MP13_CLOCK_H_ */ diff --git a/include/zephyr/dt-bindings/reset/stm32mp13_reset.h b/include/zephyr/dt-bindings/reset/stm32mp13_reset.h new file mode 100644 index 0000000000000..f393fdb269015 --- /dev/null +++ b/include/zephyr/dt-bindings/reset/stm32mp13_reset.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32MP13_RESET_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32MP13_RESET_H_ + +/** + * Pack RCC register offset and bit in one 32-bit value. + * + * bits[4..0] stores the reset controller bit in 32bit RCC register + * bits[16..5] stores the reset controller set register offset from RCC base + * bits[28..17] stores the reset controller clear register offset from RCC base + * + * @param bus STM32 bus name + * @param bit Reset bit + */ +#define STM32_RESET(bus, bit) \ + (((STM32_RESET_BUS_##bus##_CLR) << 17U) | ((STM32_RESET_BUS_##bus##_SET) << 5U) | (bit)) + +/* RCC bus reset register offset */ +#define STM32_RESET_BUS_AHB2_SET 0x6D0 +#define STM32_RESET_BUS_AHB2_CLR 0x6D4 +#define STM32_RESET_BUS_AHB4_SET 0x6E0 +#define STM32_RESET_BUS_AHB4_CLR 0x6E4 +#define STM32_RESET_BUS_AHB5_SET 0x6E8 +#define STM32_RESET_BUS_AHB5_CLR 0x6EC +#define STM32_RESET_BUS_AHB6_SET 0x6F0 +#define STM32_RESET_BUS_AHB6_CLR 0x6F4 +#define STM32_RESET_BUS_APB1_SET 0x6A0 +#define STM32_RESET_BUS_APB1_CLR 0x6A4 +#define STM32_RESET_BUS_APB2_SET 0x6A8 +#define STM32_RESET_BUS_APB2_CLR 0x6AC +#define STM32_RESET_BUS_APB3_SET 0x6B0 +#define STM32_RESET_BUS_APB3_CLR 0x6B4 +#define STM32_RESET_BUS_APB4_SET 0x6B8 +#define STM32_RESET_BUS_APB4_CLR 0x6BC +#define STM32_RESET_BUS_APB5_SET 0x6C0 +#define STM32_RESET_BUS_APB5_CLR 0x6C4 +#define STM32_RESET_BUS_APB6_SET 0x6C8 +#define STM32_RESET_BUS_APB6_CLR 0x6CC + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RESET_STM32MP13_RESET_H_ */ diff --git a/modules/cmsis/cmsis_core_a_r_ext.h b/modules/cmsis/cmsis_core_a_r_ext.h index 0752b1474fa2b..e1ddce4c0664c 100644 --- a/modules/cmsis/cmsis_core_a_r_ext.h +++ b/modules/cmsis/cmsis_core_a_r_ext.h @@ -29,6 +29,33 @@ #define FSR_FS_ALIGNMENT_FAULT (33) #define FSR_FS_DEBUG_EVENT (34) #define FSR_FS_UNSUPPORTED_EXCLUSIVE_ACCESS_FAULT (53) +#elif defined(CONFIG_ARMV7_A) + +/** + * N.B.: these FSR encodings are only valid when the + * Short-descriptor translation table format is used + */ + +#define FSR_FS_ALIGNMENT_FAULT (1) +#define FSR_FS_DEBUG_EVENT (2) +#define FSR_FS_ACCESS_FLAG_FAULT_1ST_LEVEL (3) +#define FSR_FS_CACHE_MAINTENANCE_INSTRUCTION_FAULT (4) +#define FSR_FS_TRANSLATION_FAULT (5) +#define FSR_FS_ACCESS_FLAG_FAULT_2ND_LEVEL (6) +#define FSR_FS_TRANSLATION_FAULT_2ND_LEVEL (7) +#define FSR_FS_SYNC_EXTERNAL_ABORT (8) +#define FSR_FS_DOMAIN_FAULT_1ST_LEVEL (9) +#define FSR_FS_DOMAIN_FAULT_2ND_LEVEL (11) +#define FSR_FS_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_1ST_LEVEL (12) +#define FSR_FS_PERMISSION_FAULT (13) +#define FSR_FS_SYNC_EXTERNAL_ABORT_TRANSLATION_TABLE_2ND_LEVEL (14) +#define FSR_FS_PERMISSION_FAULT_2ND_LEVEL (15) +#define FSR_FS_TLB_CONFLICT_FAULT (16) +#define FSR_FS_ASYNC_EXTERNAL_ABORT (22) +#define FSR_FS_ASYNC_PARITY_ERROR (24) +#define FSR_FS_SYNC_PARITY_ERROR (25) +#define FSR_FS_SYNC_PARITY_ERROR_TRANSLATION_TABLE_1ST_LEVEL (28) +#define FSR_FS_SYNC_PARITY_ERROR_TRANSLATION_TABLE_2ND_LEVEL (30) #else #define FSR_FS_BACKGROUND_FAULT (0) #define FSR_FS_ALIGNMENT_FAULT (1) diff --git a/soc/st/stm32/common/soc_config.c b/soc/st/stm32/common/soc_config.c index 9275ce72babba..07eb74a697c65 100644 --- a/soc/st/stm32/common/soc_config.c +++ b/soc/st/stm32/common/soc_config.c @@ -76,6 +76,8 @@ static int st_stm32_common_config(void) LL_DBGMCU_EnableDebugInStopMode(); #elif defined(CONFIG_SOC_SERIES_STM32WB0X) LL_PWR_EnableDEEPSTOP2(); +#elif defined(CONFIG_SOC_SERIES_STM32MP13X) + LL_DBGMCU_EnableDebugInLowPowerMode(); #else /* all other parts */ LL_DBGMCU_EnableDBGStopMode(); #endif @@ -90,6 +92,8 @@ static int st_stm32_common_config(void) LL_DBGMCU_DisableDebugInStopMode(); #elif defined(CONFIG_SOC_SERIES_STM32WB0X) LL_PWR_DisableDEEPSTOP2(); +#elif defined(CONFIG_SOC_SERIES_STM32MP13X) + LL_DBGMCU_DisableDebugInLowPowerMode(); #else /* all other parts */ LL_DBGMCU_DisableDBGStopMode(); #endif diff --git a/soc/st/stm32/soc.yml b/soc/st/stm32/soc.yml index 21b92d9eea44b..a12213170958c 100644 --- a/soc/st/stm32/soc.yml +++ b/soc/st/stm32/soc.yml @@ -187,6 +187,9 @@ family: - name: stm32mp1x socs: - name: stm32mp157cxx + - name: stm32mp13x + socs: + - name: stm32mp135fxx - name: stm32n6x socs: - name: stm32n657xx diff --git a/soc/st/stm32/stm32mp13x/CMakeLists.txt b/soc/st/stm32/stm32mp13x/CMakeLists.txt new file mode 100644 index 0000000000000..792d64f8df5ca --- /dev/null +++ b/soc/st/stm32/stm32mp13x/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2025 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(${ZEPHYR_BASE}/drivers) +zephyr_sources( + soc.c + ) + +zephyr_include_directories(.) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/st/stm32/stm32mp13x/Kconfig b/soc/st/stm32/stm32mp13x/Kconfig new file mode 100644 index 0000000000000..7be5ca01a0c1e --- /dev/null +++ b/soc/st/stm32/stm32mp13x/Kconfig @@ -0,0 +1,14 @@ +# STMicroelectronics STM32MP13 MPU series + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_STM32MP13X + select ARM + select CPU_CORTEX_A7 + select HAS_STM32CUBE + select CPU_HAS_FPU + select SOC_EARLY_INIT_HOOK + select ARM_ARCH_TIMER + select SYS_CLOCK_EXISTS + select XIP diff --git a/soc/st/stm32/stm32mp13x/Kconfig.defconfig b/soc/st/stm32/stm32mp13x/Kconfig.defconfig new file mode 100644 index 0000000000000..2a3929e30a7ba --- /dev/null +++ b/soc/st/stm32/stm32mp13x/Kconfig.defconfig @@ -0,0 +1,20 @@ +# STMicroelectronics STM32MP13 MPU series + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_STM32MP13X + +rsource "Kconfig.defconfig.stm32mp13_a7" + +config CACHE_MANAGEMENT + default y + +DT_STM32_CPU_CLOCK_PATH := $(dt_nodelabel_path,cpusw) +DT_STM32_CPU_CLOCK_FREQ := $(dt_node_int_prop_int,$(DT_STM32_CPU_CLOCK_PATH),clock-frequency) + +# For STM32MP13, override the default value defined in STM32 Kconfig +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(DT_STM32_CPU_CLOCK_FREQ) if $(dt_nodelabel_enabled,cpusw) + +endif # SOC_SERIES_STM32MP13X diff --git a/soc/st/stm32/stm32mp13x/Kconfig.defconfig.stm32mp13_a7 b/soc/st/stm32/stm32mp13x/Kconfig.defconfig.stm32mp13_a7 new file mode 100644 index 0000000000000..f65e137dab620 --- /dev/null +++ b/soc/st/stm32/stm32mp13x/Kconfig.defconfig.stm32mp13_a7 @@ -0,0 +1,11 @@ +# STMicroelectronics STM32MP13_A7 MPU + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if SOC_STM32MP135FXX + +config NUM_IRQS + default 181 + +endif # SOC_STM32MP135FXX diff --git a/soc/st/stm32/stm32mp13x/Kconfig.soc b/soc/st/stm32/stm32mp13x/Kconfig.soc new file mode 100644 index 0000000000000..9507ce31a9be8 --- /dev/null +++ b/soc/st/stm32/stm32mp13x/Kconfig.soc @@ -0,0 +1,18 @@ +# STMicroelectronics STM32MP13 MPU series + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_STM32MP13X + bool + select SOC_FAMILY_STM32 + +config SOC_SERIES + default "stm32mp13x" if SOC_SERIES_STM32MP13X + +config SOC_STM32MP135FXX + bool + select SOC_SERIES_STM32MP13X + +config SOC + default "stm32mp135fxx" if SOC_STM32MP135FXX diff --git a/soc/st/stm32/stm32mp13x/soc.c b/soc/st/stm32/stm32mp13x/soc.c new file mode 100644 index 0000000000000..7d07902637319 --- /dev/null +++ b/soc/st/stm32/stm32mp13x/soc.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for STM32MP13 processor + */ + +#include +#include +#include +#include + +#include +#include + +#define VECTOR_ADDRESS ((uintptr_t)_vector_start) + +void relocate_vector_table(void) +{ + write_sctlr(read_sctlr() & ~HIVECS); + write_vbar(VECTOR_ADDRESS & VBAR_MASK); + barrier_isync_fence_full(); +} + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + */ + +void soc_early_init_hook(void) +{ + /* Update CMSIS SystemCoreClock variable (HCLK) */ + SystemCoreClock = 1000000000U; + + /* Clear TE bit to take exceptions in Thumb mode to fix the DDR init */ + write_sctlr(read_sctlr() & ~SCTLR_TE_Msk); + barrier_isync_fence_full(); +} + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("APB1", 0x40000000, 0x19400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("APB2", 0x44000000, 0x14000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("AHB2", 0x48000000, 0x1040000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("APB6", 0x4C000000, 0xC400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("AHB4", 0x50000000, 0xD400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("APB3", 0x50020000, 0xA400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("DEBUG APB", 0x50080000, 0x5D000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("AHB5", 0x54000000, 0x8000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("AXIMC", 0x57000000, 0x100000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("AHB6", 0x58000000, 0x10000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("APB4", 0x5A000000, 0x7400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("APB5", 0x5C000000, 0xA400, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("GIC", 0xA0021000, 0x7000, MPERM_R | MPERM_W | MT_DEVICE), + + MMU_REGION_FLAT_ENTRY("vectors", 0xC0000000, 0x1000, MPERM_R | MPERM_X | MT_NORMAL), + + MMU_REGION_FLAT_ENTRY("DAPBUS", 0xE0080000, 0x5D000, MPERM_R | MPERM_W | MT_DEVICE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; diff --git a/soc/st/stm32/stm32mp13x/soc.h b/soc/st/stm32/stm32mp13x/soc.h new file mode 100644 index 0000000000000..49847550700e1 --- /dev/null +++ b/soc/st/stm32/stm32mp13x/soc.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _STM32MP13SOC_H_ +#define _STM32MP13SOC_H_ + +#ifndef _ASMLANGUAGE + +#include + +#endif /* !_ASMLANGUAGE */ + +#endif /* _STM32MP13SOC_H_ */ diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h b/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h index 71dfda7c19311..21f9f272a6337 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/include/os_mgmt_processor.h @@ -103,6 +103,8 @@ extern "C" { #else #define PROCESSOR_NAME "cortex-r52" #endif +#elif defined(CONFIG_CPU_CORTEX_A7) +#define PROCESSOR_NAME "cortex-a7" #elif defined(CONFIG_CPU_CORTEX_A9) #define PROCESSOR_NAME "cortex-a9" #endif diff --git a/west.yml b/west.yml index 4f7196d7f48df..ab8abfeaceb08 100644 --- a/west.yml +++ b/west.yml @@ -238,7 +238,7 @@ manifest: groups: - hal - name: hal_stm32 - revision: 4ec1fd2e65b4f55eb516b16df73a2dd9f0cf6e1f + revision: def7e1a025877a35d070439e70668f5ec319c32e path: modules/hal/stm32 groups: - hal