From 10d1e8d0e43c938c68729ef434878115973e113e Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Wed, 23 Oct 2024 14:02:32 +0100 Subject: [PATCH 01/43] mod/noc_s3: Fix FWK_LOG_ERR format specifier type In an FWK_LOG_ERR, the format specifies type 'int' but the argument has type 'unsigned long' which causes the clang compilation to fail. Use the correct format specifier to fix this problem. Signed-off-by: Ziad Elhanafy --- module/noc_s3/src/noc_s3_discovery.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/noc_s3/src/noc_s3_discovery.c b/module/noc_s3/src/noc_s3_discovery.c index f07bf311e..ee0d9810a 100644 --- a/module/noc_s3/src/noc_s3_discovery.c +++ b/module/noc_s3/src/noc_s3_discovery.c @@ -344,8 +344,9 @@ int noc_s3_get_subfeature_offset( } FWK_LOG_ERR( - MOD_NAME "Subfeature(%d) not supported by the Node[Type: %" PRId32 - "][ID: %" PRId32 "]", + MOD_NAME + "Subfeature(%d) not supported by the Node[Type: %lu" + "][ID: %lu]", subfeature_type, GET_NODE_TYPE(component_hdr->node_type), GET_NODE_ID(component_hdr->node_type)); -- GitLab From 253ecc28f2ac6f804ed8fe5e4667388f80ef4ef1 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Tue, 23 Apr 2024 17:49:53 +0100 Subject: [PATCH 02/43] automotive-rd/rd1ae: Introduce Arm RD1AE platform Introduce new platform RD1AE, this include: 1- Minimal memory layout 2- MPU module configurations. 3- cmake files. Signed-off-by: Luca Fancellu Signed-off-by: Ziad Elhanafy --- product/automotive-rd/rd1ae/product.mk | 10 +++ .../rd1ae/scp_ramfw/CMakeLists.txt | 37 ++++++++++ .../rd1ae/scp_ramfw/Firmware.cmake | 30 +++++++++ .../rd1ae/scp_ramfw/Toolchain-ArmClang.cmake | 17 +++++ .../rd1ae/scp_ramfw/Toolchain-Clang.cmake | 17 +++++ .../rd1ae/scp_ramfw/Toolchain-GNU.cmake | 18 +++++ .../rd1ae/scp_ramfw/config_armv7m_mpu.c | 67 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/fmw_cmsis.h | 44 ++++++++++++ .../rd1ae/scp_ramfw/include/fmw_memory.h | 30 +++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 22 ++++++ 10 files changed, 292 insertions(+) create mode 100644 product/automotive-rd/rd1ae/product.mk create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake create mode 100755 product/automotive-rd/rd1ae/scp_ramfw/Toolchain-ArmClang.cmake create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/Toolchain-Clang.cmake create mode 100755 product/automotive-rd/rd1ae/scp_ramfw/Toolchain-GNU.cmake create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/fmw_memory.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h diff --git a/product/automotive-rd/rd1ae/product.mk b/product/automotive-rd/rd1ae/product.mk new file mode 100644 index 000000000..fb857f288 --- /dev/null +++ b/product/automotive-rd/rd1ae/product.mk @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# + +BS_PRODUCT_NAME := rd1ae +BS_FIRMWARE_LIST := scp_ramfw diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt new file mode 100644 index 000000000..c8566d76f --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# cmake-lint: disable=E1122 + +# +# Create the firmware target. +# +add_executable(rd1ae-bl2) + +target_include_directories( + rd1ae-bl2 + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources( + rd1ae-bl2 + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c") + +# +# Some of our firmware includes require CMSIS. +# + +target_link_libraries(rd1ae-bl2 PUBLIC cmsis::core-m) + +# +# We explicitly add the CMSIS include directories to our interface include +# directories. Each module target adds these include directories to their own, +# allowing them to include any firmware includes we expose. +# + +target_include_directories( + rd1ae-bl2 + PUBLIC $) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake new file mode 100644 index 000000000..453e9bee0 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -0,0 +1,30 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# +# Configure the build system. +# + +set(SCP_FIRMWARE "rd1ae-bl2") + +set(SCP_FIRMWARE_TARGET "rd1ae-bl2") + +set(SCP_TOOLCHAIN_INIT "GNU") + +set(SCP_GENERATE_FLAT_BINARY_INIT TRUE) + +# Disable Interprocedural optimization +set(SCP_ENABLE_IPO_INIT FALSE) + +set(SCP_ARCHITECTURE "arm-m") + +set(SCP_ENABLE_NEWLIB_NANO FALSE) + +# The order of the modules in the following list is the order in which the +# modules are initialized, bound, started during the pre-runtime phase. +# Any change in the order will cause firmware initialization errors. +list(APPEND SCP_MODULES "armv7m-mpu") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-ArmClang.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-ArmClang.cmake new file mode 100755 index 000000000..2ab30d850 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-ArmClang.cmake @@ -0,0 +1,17 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include_guard() + +set(CMAKE_SYSTEM_PROCESSOR "cortex-m7") + +set(CMAKE_ASM_COMPILER_TARGET "arm-arm-none-eabi") +set(CMAKE_C_COMPILER_TARGET "arm-arm-none-eabi") +set(CMAKE_CXX_COMPILER_TARGET "arm-arm-none-eabi") + +set(CMAKE_TOP_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../..") +include("${CMAKE_TOP_DIR}/cmake/Toolchain/ArmClang-Baremetal.cmake") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-Clang.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-Clang.cmake new file mode 100644 index 000000000..0d52f0281 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-Clang.cmake @@ -0,0 +1,17 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include_guard() + +set(CMAKE_SYSTEM_PROCESSOR "cortex-m7") + +set(CMAKE_ASM_COMPILER_TARGET "arm-arm-none-eabi") +set(CMAKE_C_COMPILER_TARGET "arm-arm-none-eabi") +set(CMAKE_CXX_COMPILER_TARGET "arm-arm-none-eabi") + +set(CMAKE_TOP_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../..") +include("${CMAKE_TOP_DIR}/cmake/Toolchain/Clang-Baremetal.cmake") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-GNU.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-GNU.cmake new file mode 100755 index 000000000..62d475fac --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/Toolchain-GNU.cmake @@ -0,0 +1,18 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include_guard() + +set(CMAKE_SYSTEM_PROCESSOR "cortex-m7") +set(CMAKE_TOOLCHAIN_PREFIX "arm-none-eabi-") + +set(CMAKE_ASM_COMPILER_TARGET "arm-none-eabi") +set(CMAKE_C_COMPILER_TARGET "arm-none-eabi") +set(CMAKE_CXX_COMPILER_TARGET "arm-none-eabi") + +set(CMAKE_TOP_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../..") +include("${CMAKE_TOP_DIR}/cmake/Toolchain/GNU-Baremetal.cmake") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c b/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c new file mode 100644 index 000000000..995d5fe10 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'armv7m_mpu'. + */ + +#include "scp_mmap.h" + +#include + +#include +#include + +#define SCP_MPU_REGION_COUNT 3 + +static const ARM_MPU_Region_t regions[SCP_MPU_REGION_COUNT] = { + { + /* 0x0000_0000 - 0xFFFF_FFFF */ + .RBAR = ARM_MPU_RBAR(0x0UL, 0x00000000UL), + .RASR = ARM_MPU_RASR( + 1, + ARM_MPU_AP_PRIV, + 0, + 1, + 0, + 1, + 0, + ARM_MPU_REGION_SIZE_4GB), + }, + { + /* 0x0000_0000 - 0x0003_FFFF */ + .RBAR = ARM_MPU_RBAR(0x1UL, SCP_ITC_RAM_BASE), + .RASR = ARM_MPU_RASR( + 0, + ARM_MPU_AP_PRO, + 0, + 0, + 1, + 0, + 0, + ARM_MPU_REGION_SIZE_256KB), + }, + { + /* 0x2000_0000 - 0x2003_FFFF */ + .RBAR = ARM_MPU_RBAR(0x2UL, SCP_DTC_RAM_BASE), + .RASR = ARM_MPU_RASR( + 1, + ARM_MPU_AP_PRIV, + 0, + 0, + 1, + 1, + 0, + ARM_MPU_REGION_SIZE_256KB), + }, +}; + +const struct fwk_module_config config_armv7m_mpu = { + .data = &((struct mod_armv7m_mpu_config){ + .region_count = FWK_ARRAY_SIZE(regions), + .regions = regions, + }), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h new file mode 100644 index 000000000..3d6b3dfa5 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h @@ -0,0 +1,44 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_CMSIS_H +#define FMW_CMSIS_H + +#include + +#define __CHECK_DEVICE_DEFINES +#define __CM7_REV 0x0000U +#define __FPU_PRESENT 0U +#define __MPU_PRESENT 1U +#define __ICACHE_PRESENT 0U +#define __DCACHE_PRESENT 0U +#define __DTCM_PRESENT 0U +#define __NVIC_PRIO_BITS 3U +#define __Vendor_SysTickConfig 0U +#define __VTOR_PRESENT 1U + +/* System Clock Frequency (Core Clock) */ +extern uint32_t SystemCoreClock; + +typedef enum IRQn { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + + IRQn_MAX = INT16_MAX, +} IRQn_Type; + +#include + +#endif /* FMW_CMSIS_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_memory.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_memory.h new file mode 100644 index 000000000..b8c39e3a9 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_memory.h @@ -0,0 +1,30 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP RAM firmware memory layout for the linker script. + */ + +#ifndef FMW_MEMORY_H +#define FMW_MEMORY_H + +#include "scp_mmap.h" + +#define FMW_MEM_MODE ARCH_MEM_MODE_DUAL_REGION_RELOCATION + +/* + * RAM instruction memory + */ +#define FMW_MEM0_SIZE SCP_ITC_RAM_SIZE +#define FMW_MEM0_BASE SCP_ITC_RAM_BASE + +/* + * RAM data memory + */ +#define FMW_MEM1_SIZE SCP_DTC_RAM_SIZE +#define FMW_MEM1_BASE SCP_DTC_RAM_BASE + +#endif /* FMW_MEMORY_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h new file mode 100644 index 000000000..25c237890 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -0,0 +1,22 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Base address definitions for the SCP's sub-system. + */ + +#ifndef SCP_MMAP_H +#define SCP_MMAP_H + +/* Base address and size of SCP's ITCM */ +#define SCP_ITC_RAM_BASE (0x00000000) +#define SCP_ITC_RAM_SIZE (256 * 1024) + +/* Base address and size of SCP's DTCM */ +#define SCP_DTC_RAM_BASE (0x20000000) +#define SCP_DTC_RAM_SIZE (256 * 1024) + +#endif /* SCP_MMAP_H */ -- GitLab From 6fc2a69d1f32e9e5dd4d224e93375a1816b645ff Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 3 Jun 2024 12:08:31 +0100 Subject: [PATCH 03/43] automotive-rd/rd1ae: Add PL011 module configurations Add PL011 module configurations, PL011 controller is used as a console port for debug and log messages. Add config data of this controller in scp ramfw, including base address and input clock frequency for the PL011 module to use. Signed-off-by: Luca Fancellu Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/CMakeLists.txt | 3 +- .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_pl011.c | 36 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/fmw_io.h | 17 +++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 3 ++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/fmw_io.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index c8566d76f..c8f6224ea 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -18,7 +18,8 @@ target_include_directories( target_sources( rd1ae-bl2 - PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c") + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c") # # Some of our firmware includes require CMSIS. diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 453e9bee0..dd17092e1 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -28,3 +28,4 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) # modules are initialized, bound, started during the pre-runtime phase. # Any change in the order will cause firmware initialization errors. list(APPEND SCP_MODULES "armv7m-mpu") +list(APPEND SCP_MODULES "pl011") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c new file mode 100644 index 000000000..9c3749615 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c @@ -0,0 +1,36 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'pl011'. + */ + +#include "scp_mmap.h" + +#include + +#include +#include +#include + +#define MOD_PL011_ELEMENT_COUNT 2 + +static const struct fwk_element pl011_table[MOD_PL011_ELEMENT_COUNT] = { + { + .name = "scp_uart", + .data = + &(struct mod_pl011_element_cfg){ + .reg_base = SCP_UART_BASE, + .baud_rate_bps = 115200, + .clock_rate_hz = 24 * FWK_MHZ, + }, + }, + { 0 }, +}; + +const struct fwk_module_config config_pl011 = { + .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(pl011_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_io.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_io.h new file mode 100644 index 000000000..ec7f58908 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_io.h @@ -0,0 +1,17 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_IO_H +#define FMW_IO_H + +#include +#include + +#define FMW_IO_STDIN_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_PL011, 0) +#define FMW_IO_STDOUT_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_PL011, 0) + +#endif /* FMW_IO_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 25c237890..4f56955e1 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -19,4 +19,7 @@ #define SCP_DTC_RAM_BASE (0x20000000) #define SCP_DTC_RAM_SIZE (256 * 1024) +/* SCP sub-system peripherals */ +#define SCP_UART_BASE (0x44002000UL) + #endif /* SCP_MMAP_H */ -- GitLab From 3d78dc7417b2683b60c645599d6693fbc7cbe3ab Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Thu, 6 Jun 2024 16:17:47 +0100 Subject: [PATCH 04/43] automotive-rd/rd1ae: Add System PLL module configurations PLLs are connected to the SCP's expansion3 memory region. Add the configuration data for the module 'system_pll' that will manage and setup these PLLs to the required frequency. The configuration data includes the SYSTOP PLL and the interconnect PLL. Additionally add SCP power control block register declaration SCP's power control block includes registers for various system configuration and status. Add the register space declaration for this block. Signed-off-by: Ziad Elhanafy igned-off-by: Divin Raj Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 3 +- .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_system_pll.c | 59 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_clock.h | 23 ++++++++ .../rd1ae/scp_ramfw/include/scp_exp_mmap.h | 27 +++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 3 + 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_system_pll.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_exp_mmap.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index c8f6224ea..e11967018 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -19,7 +19,8 @@ target_include_directories( target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" - "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c") + "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c") # # Some of our firmware includes require CMSIS. diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index dd17092e1..58b1d474e 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -29,3 +29,4 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) # Any change in the order will cause firmware initialization errors. list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") +list(APPEND SCP_MODULES "system-pll") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_system_pll.c b/product/automotive-rd/rd1ae/scp_ramfw/config_system_pll.c new file mode 100644 index 000000000..7619badd5 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_system_pll.c @@ -0,0 +1,59 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'system_pll'. + */ + +#include "scp_clock.h" +#include "scp_exp_mmap.h" + +#include + +#include +#include +#include +#include + +#define MOD_SYSTEM_PLL_ELEMENT_COUNT (CFGD_MOD_SYSTEM_PLL_EIDX_COUNT + 1) + +static const struct fwk_element sys_pll_table[MOD_SYSTEM_PLL_ELEMENT_COUNT] = { + [CFGD_MOD_SYSTEM_PLL_EIDX_SYS] = { + .name = "SYS_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_SYSPLL, + .status_reg = (void *)SCP_PLL_STATUS0, + .lock_flag_mask = PLL_STATUS_0_SYSPLL_LOCK, + .initial_rate = 2000 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CFGD_MOD_SYSTEM_PLL_EIDX_INTERCONNECT] = { + .name = "INT_PLL", + .data = &((struct mod_system_pll_dev_config) { + .control_reg = (void *)SCP_PLL_INTERCONNECT, + .status_reg = (void *)SCP_PLL_STATUS0, + .lock_flag_mask = PLL_STATUS_0_INTPLL_LOCK, + .initial_rate = 2000 * FWK_MHZ, + .min_rate = MOD_SYSTEM_PLL_MIN_RATE, + .max_rate = MOD_SYSTEM_PLL_MAX_RATE, + .min_step = MOD_SYSTEM_PLL_MIN_INTERVAL, + }), + }, + [CFGD_MOD_SYSTEM_PLL_EIDX_COUNT] = { 0 }, /* Termination description. */ +}; + +static const struct fwk_element *system_pll_get_element_table( + fwk_id_t module_id) +{ + return sys_pll_table; +} + +const struct fwk_module_config config_system_pll = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(system_pll_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h new file mode 100644 index 000000000..46442cf74 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h @@ -0,0 +1,23 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP clock definitions. + */ + +#ifndef SCP_CLOCK_H +#define SCP_CLOCK_H + +/* + * PLL clock indices. + */ +enum clock_pll_idx { + CFGD_MOD_SYSTEM_PLL_EIDX_SYS, + CFGD_MOD_SYSTEM_PLL_EIDX_INTERCONNECT, + CFGD_MOD_SYSTEM_PLL_EIDX_COUNT +}; + +#endif /* SCP_CLOCK_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_exp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_exp_mmap.h new file mode 100644 index 000000000..540a73bb7 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_exp_mmap.h @@ -0,0 +1,27 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Base address definitions for the SCP's expansion memory regions. + */ + +#ifndef SCP_EXP_MMAP_H +#define SCP_EXP_MMAP_H + +#include "scp_mmap.h" + +/* PLLs are connected in SCP's expansion3 memory region */ +#define SCP_PLL_BASE (SCP_SOC_EXPANSION3_BASE + 0x03000000UL) + +#define SCP_PLL_SYSPLL (SCP_PLL_BASE + 0x00000000UL) +#define SCP_PLL_INTERCONNECT (SCP_PLL_BASE + 0x00000020UL) +#define SCP_PLL_STATUS0 (SCP_PLL_BASE + 0x00000180UL) + +/* PLL lock status flag mask */ +#define PLL_STATUS_0_SYSPLL_LOCK (0x00000002UL) +#define PLL_STATUS_0_INTPLL_LOCK (0x00000008UL) + +#endif /* SCP_EXP_MMAP_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 4f56955e1..d2137a174 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -22,4 +22,7 @@ /* SCP sub-system peripherals */ #define SCP_UART_BASE (0x44002000UL) +/* Base address of SCP expansion memory regions */ +#define SCP_SOC_EXPANSION3_BASE (0x40000000UL) /* 64MB size */ + #endif /* SCP_MMAP_H */ -- GitLab From c8708dc4341c9a6b68cd3217a1b37c42b8e3d542 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 26 Apr 2024 20:11:47 +0100 Subject: [PATCH 05/43] automotive-rd/rd1ae: Add PIK clock module configurations The configuration data for PIK clock devices includes register address of its control and dividers, the rate table and the initial rate. The clock controller devices for all the CPUs, interconnect, systop, GIC, SCP, UART and other clocks are included in the configuration data. Additionally add System PIK register space declaration and core manager register block declaration System Power Integration Kit (PIK) control register block includes registers for clock control of clocks in SYSTOP power domain. Add the register space declaration for System PIK. Core Manager block includes registers for configuration and clock control for application cores and the associated clusters. Add the register space declaration and the base address macro for the core manager block. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_pik_clock.c | 227 ++++++++++++++++++ .../rd1ae/scp_ramfw/include/core_manager.h | 77 ++++++ .../rd1ae/scp_ramfw/include/scp_clock.h | 33 +++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 32 +++ .../rd1ae/scp_ramfw/include/scp_pwrctrl.h | 139 +++++++++++ .../rd1ae/scp_ramfw/include/system_pik.h | 81 +++++++ 8 files changed, 591 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_pik_clock.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/core_manager.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_pwrctrl.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/system_pik.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index e11967018..98d3fa31b 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -19,6 +19,7 @@ target_include_directories( target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 58b1d474e..daf211d42 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -30,3 +30,4 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "system-pll") +list(APPEND SCP_MODULES "pik-clock") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_pik_clock.c b/product/automotive-rd/rd1ae/scp_ramfw/config_pik_clock.c new file mode 100644 index 000000000..5293a696f --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_pik_clock.c @@ -0,0 +1,227 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'pik_clock'. + */ + +#include "core_manager.h" +#include "scp_clock.h" +#include "scp_pwrctrl.h" +#include "system_pik.h" + +#include + +#include +#include +#include +#include + +/* Rate table count */ +#define CPU_CLK_RATE_COUNT 1 +#define INT_CLK_RATE_COUNT 1 +#define SCP_CLK_RATE_COUNT 1 +#define GIC_CLK_RATE_COUNT 1 +#define SCP_PIK_CLK_RATE_COUNT 1 +#define SYSPER_CLK_RATE_COUNT 1 +#define UART_CLK_RATE_COUNT 1 + +/* Module 'pik_clock' element count */ +#define MOD_PIK_CLOCK_ELEMENT_COUNT (CFGD_MOD_PIK_CLOCK_EIDX_COUNT + 1) + +#define CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(n) \ + [CFGD_MOD_PIK_CLOCK_EIDX_CPU##n] = { \ + .name = "PIK CLK CPU" #n, \ + .data = &((struct mod_pik_clock_dev_config){ \ + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, \ + .is_group_member = false, \ + .control_reg = \ + &SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(n)->CORECLK_CTRL, \ + .divext_reg = \ + &SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(n)->CORECLK_DIV1, \ + .rate_table = rate_table_cpu_clk, \ + .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_clk), \ + .initial_rate = 0, \ + }), \ + } + +/* CPU clock rate table */ +static const struct mod_pik_clock_rate + rate_table_cpu_clk[CPU_CLK_RATE_COUNT] = { + { + .rate = 0, + .source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, + }, + }; + +/* Cache Coherent Interconnect clock rate table */ +static const struct mod_pik_clock_rate + rate_table_int_clk[INT_CLK_RATE_COUNT] = { + { + .rate = 2000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_INTCLK_SOURCE_INTPLL, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, + .divider = 1, + }, + }; + +/* SCP CORE clock rate table */ +static const struct mod_pik_clock_rate + rate_table_scp_clk[SCP_CLK_RATE_COUNT] = { + { + .rate = 800 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (800 * FWK_MHZ), + }, + }; + +/* GIC clock rate table */ +static const struct mod_pik_clock_rate + rate_table_gic_clk[GIC_CLK_RATE_COUNT] = { + { + .rate = 1000 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (1000 * FWK_MHZ), + }, + }; + +/* SCP PIK clock rate table */ +static const struct mod_pik_clock_rate + rate_table_scp_pik_clk[SCP_PIK_CLK_RATE_COUNT] = { + { + .rate = 400 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (400 * FWK_MHZ), + }, + }; + +/* System Peripheral clock rate table */ +static const struct mod_pik_clock_rate + rate_table_sysper_clk[SYSPER_CLK_RATE_COUNT] = { + { + .rate = 500 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (500 * FWK_MHZ), + }, + }; + +/* UART clock rate table */ +static const struct mod_pik_clock_rate + rate_table_uart_clk[UART_CLK_RATE_COUNT] = { + { + .rate = 250 * FWK_MHZ, + .source = MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK, + .divider_reg = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, + .divider = CLOCK_RATE_SYSPLLCLK / (250 * FWK_MHZ), + }, + }; + +static const struct fwk_element pik_clock_table[MOD_PIK_CLOCK_ELEMENT_COUNT] = { + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(0), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(1), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(2), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(3), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(4), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(5), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(6), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(7), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(8), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(9), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(10), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(11), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(12), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(13), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(14), + CFGD_MOD_PIK_CLOCK_ELEMENT_CPU(15), + [CFGD_MOD_PIK_CLOCK_EIDX_CMN] = { + .name = "PIK CLK CMN", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SYSTEM_PIK_PTR->INTCLK_CTRL, + .divext_reg = &SYSTEM_PIK_PTR->INTCLK_DIV1, + .rate_table = rate_table_int_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_int_clk), + .initial_rate = 2000 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_SCP] = { + .name = "PIK CLK SCP", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SCP_PWRCTRL_PTR->CORECLK_CTRL, + .divsys_reg = &SCP_PWRCTRL_PTR->CORECLK_DIV1, + .rate_table = rate_table_scp_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_scp_clk), + .initial_rate = 800 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_GIC] = { + .name = "PIK CLK GIC", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SYSTEM_PIK_PTR->GICCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->GICCLK_DIV1, + .rate_table = rate_table_gic_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_gic_clk), + .initial_rate = 1000 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_SCP_PIK] = { + .name = "PIK CLK SCP PIK", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SYSTEM_PIK_PTR->SCPPIKCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->SCPPIKCLK_DIV1, + .rate_table = rate_table_scp_pik_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_scp_pik_clk), + .initial_rate = 400 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_SYSPERCLK] = { + .name = "PIK CLK SYSPER", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SYSTEM_PIK_PTR->SYSPERCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->SYSPERCLK_DIV1, + .rate_table = rate_table_sysper_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_sysper_clk), + .initial_rate = 500 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_UARTCLK] = { + .name = "PIK CLK UART", + .data = &((struct mod_pik_clock_dev_config) { + .type = MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, + .is_group_member = false, + .control_reg = &SYSTEM_PIK_PTR->APUARTCLK_CTRL, + .divsys_reg = &SYSTEM_PIK_PTR->APUARTCLK_DIV1, + .rate_table = rate_table_uart_clk, + .rate_count = FWK_ARRAY_SIZE(rate_table_uart_clk), + .initial_rate = 250 * FWK_MHZ, + }), + }, + [CFGD_MOD_PIK_CLOCK_EIDX_COUNT] = { 0 }, +}; + +static const struct fwk_element *pik_clock_get_element_table(fwk_id_t module_id) +{ + return pik_clock_table; +} + +const struct fwk_module_config config_pik_clock = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(pik_clock_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/core_manager.h b/product/automotive-rd/rd1ae/scp_ramfw/include/core_manager.h new file mode 100644 index 000000000..bccfb3c34 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/core_manager.h @@ -0,0 +1,77 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Core Manager and clock control registers + */ + +#ifndef CORE_MANAGER_H +#define CORE_MANAGER_H + +#include "scp_mmap.h" + +#include + +#include + +// clang-format off +struct core_manager_reg { + uint8_t RESERVED0[0x10 - 0x00]; + FWK_RW uint32_t PE_STATIC_CONFIG; + uint8_t RESERVED1[0x18 - 0x14]; + FWK_RW uint32_t PE_RVBARADDR_LW; + FWK_RW uint32_t PE_RVBARADDR_UP; + uint8_t RESERVED2[0x030-0x020]; + FWK_R uint32_t PE_STATUS; + uint8_t RESERVED3[0x800-0x034]; + FWK_RW uint32_t CLUS_MGRCLK_CTRL; + FWK_RW uint32_t CLUS_MGRCLK_DIV1; + uint8_t RESERVED4[0x820 - 0x808]; + FWK_RW uint32_t CLUS_EXP1CLK_CTRL; + FWK_RW uint32_t CLUS_EXP1CLK_DIV; + uint8_t RESERVED5[0x830 - 0x828]; + FWK_RW uint32_t CLUS_EXP2CLK_CTRL; + FWK_RW uint32_t CLUS_EXP2CLK_DIV; + uint8_t RESERVED6[0x840 - 0x838]; + FWK_RW uint32_t CLUS_GICCLK_CTRL; + FWK_RW uint32_t CLUS_GICCLK_DIV1; + uint8_t RESERVED7[0x850 -0x848]; + FWK_RW uint32_t CLUS_PERIPHCLK_CTRL; + FWK_RW uint32_t CLUS_PERIPHCLK_DIV1; + uint8_t RESERVED8[0x860 - 0x858]; + FWK_RW uint32_t CORECLK_CTRL; + FWK_RW uint32_t CORECLK_DIV1; + FWK_RW uint32_t CORECLK_MOD1; + uint8_t RESERVED9[0xA00 - 0x086C]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLR; + uint8_t RESERVED10[0x0FB4 - 0x0A0C]; + FWK_R uint32_t CAP3; + FWK_R uint32_t CAP2; + FWK_R uint32_t CAP1; + FWK_R uint32_t PWR_CTRL_CONFIG; + uint8_t RESERVED11[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; +// clang-format on + +/* Pointer to SCP Cluster utility core manager register block */ +#define SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(IDX) \ + ((struct core_manager_reg *)SCP_CLUSTER_UTILITY_CORE_MANAGER_BASE(IDX)) + +#endif /* CORE_MANAGER_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h index 46442cf74..c062a7a2e 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h @@ -11,6 +11,10 @@ #ifndef SCP_CLOCK_H #define SCP_CLOCK_H +#include + +#define CLOCK_RATE_SYSPLLCLK (2000UL * FWK_MHZ) + /* * PLL clock indices. */ @@ -20,4 +24,33 @@ enum clock_pll_idx { CFGD_MOD_SYSTEM_PLL_EIDX_COUNT }; +/* + * PIK clock indexes. + */ +enum clock_pik_idx { + CFGD_MOD_PIK_CLOCK_EIDX_CPU0, + CFGD_MOD_PIK_CLOCK_EIDX_CPU1, + CFGD_MOD_PIK_CLOCK_EIDX_CPU2, + CFGD_MOD_PIK_CLOCK_EIDX_CPU3, + CFGD_MOD_PIK_CLOCK_EIDX_CPU4, + CFGD_MOD_PIK_CLOCK_EIDX_CPU5, + CFGD_MOD_PIK_CLOCK_EIDX_CPU6, + CFGD_MOD_PIK_CLOCK_EIDX_CPU7, + CFGD_MOD_PIK_CLOCK_EIDX_CPU8, + CFGD_MOD_PIK_CLOCK_EIDX_CPU9, + CFGD_MOD_PIK_CLOCK_EIDX_CPU10, + CFGD_MOD_PIK_CLOCK_EIDX_CPU11, + CFGD_MOD_PIK_CLOCK_EIDX_CPU12, + CFGD_MOD_PIK_CLOCK_EIDX_CPU13, + CFGD_MOD_PIK_CLOCK_EIDX_CPU14, + CFGD_MOD_PIK_CLOCK_EIDX_CPU15, + CFGD_MOD_PIK_CLOCK_EIDX_CMN, + CFGD_MOD_PIK_CLOCK_EIDX_SCP, + CFGD_MOD_PIK_CLOCK_EIDX_GIC, + CFGD_MOD_PIK_CLOCK_EIDX_SCP_PIK, + CFGD_MOD_PIK_CLOCK_EIDX_SYSPERCLK, + CFGD_MOD_PIK_CLOCK_EIDX_UARTCLK, + CFGD_MOD_PIK_CLOCK_EIDX_COUNT +}; + #endif /* SCP_CLOCK_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index d2137a174..3e38392e4 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -20,9 +20,41 @@ #define SCP_DTC_RAM_SIZE (256 * 1024) /* SCP sub-system peripherals */ +#define SCP_POWER_CONTROL_BASE (0x50000000UL) +#define SCP_SYSTEM_PIK_BASE (0x50040000UL) #define SCP_UART_BASE (0x44002000UL) /* Base address of SCP expansion memory regions */ #define SCP_SOC_EXPANSION3_BASE (0x40000000UL) /* 64MB size */ +/* SCP addresses mapped via ATU into address translation windows */ +#define SCP_ADDRESS_TRANSLATION_WINDOW0_BASE (0x60000000UL) + +/* + * Offsets within SCP's Address Translation Window0 + * __________________________ + * | | + * | CLUSTER UTIL 256M | + * |__________________________| 0x60000000 + */ + +#define SCP_ATW0_CLUSTER_UTILITY_BASE SCP_ADDRESS_TRANSLATION_WINDOW0_BASE + +/* + * Size of SCP's view of per-cluster utility memory region. + */ +#define SCP_CLUSTER_UTILITY_SIZE (0x200000UL) + +/* + * Offsets of various blocks within cluster utility that is + * mapped into SCP's address translation window 0. These offsets are applicable + * to each cluster in the system. + */ +#define SCP_CLUSTER_UTILITY_CORE_MANAGER_OFFSET (0x80000UL) + +/* Core Manager base address for a cluster 'n' */ +#define SCP_CLUSTER_UTILITY_CORE_MANAGER_BASE(n) \ + (SCP_ATW0_CLUSTER_UTILITY_BASE + (n * SCP_CLUSTER_UTILITY_SIZE) + \ + SCP_CLUSTER_UTILITY_CORE_MANAGER_OFFSET) + #endif /* SCP_MMAP_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_pwrctrl.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_pwrctrl.h new file mode 100644 index 000000000..a58998909 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_pwrctrl.h @@ -0,0 +1,139 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP Power Control registers + */ + +#ifndef SCP_PWRCTRL_H +#define SCP_PWRCTRL_H + +#include "scp_mmap.h" + +#include + +#include + +/*! + * \brief SCP Power Control register definitions + */ + +// clang-format off +struct scp_power_control_reg { + uint8_t RESERVED0[0x10 - 0x0]; + FWK_RW uint32_t RESET_SYNDROME; + uint8_t RESERVED1[0x18 - 0x14]; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP0; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP1; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP2; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP3; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP4; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP5; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP6; + FWK_RW uint32_t LCP2SCP_INT_SOURCE_GROUP7; + uint8_t RESERVED2[0x200 - 0x38]; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP0; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP1; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP2; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP3; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP4; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP5; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP6; + FWK_R uint32_t SCP2LCP_MHU_PBX_INT_SOURCE_GROUP7; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP0; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP1; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP2; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP3; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP4; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP5; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP6; + FWK_R uint32_t LCP2SCP_MHU_MBX_INT_SOURCE_GROUP7; + uint8_t RESERVED3[0x810 - 0x248]; + FWK_RW uint32_t CORECLK_CTRL; + FWK_RW uint32_t CORECLK_DIV1; + uint8_t RESERVED4[0x820 - 0x818]; + FWK_RW uint32_t ACLK_CTRL; + FWK_RW uint32_t ACLK_DIV1; + uint8_t RESERVED5[0x830 - 0x828]; + FWK_RW uint32_t GTSYNCCLK_CTRL; + FWK_RW uint32_t GTSYNCCLK_DIV1; + uint8_t RESERVED6[0x840 - 0x838]; + FWK_RW uint32_t LCPCLK_CTRL; + FWK_RW uint32_t LCPCLK_DIV1; + uint8_t RESERVED7[0xA00 - 0x848]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLEAR; + uint8_t RESERVED8[0xA50 - 0xA0C]; + FWK_R uint32_t CONS_MMUTCU_INT_STATUS; + FWK_W uint32_t CONS_MMUTCU_INT_CLR; + FWK_R uint32_t CONS_MMUTCU1_INT_STATUS; + FWK_W uint32_t CONS_MMUTCU1_INT_CLR; + uint8_t RESERVED9[0xA68 - 0xA60]; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS0; + FWK_W uint32_t CONS_MMUTBU_INT_CLR0; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS1; + FWK_W uint32_t CONS_MMUTBU_INT_CLR1; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS2; + FWK_W uint32_t CONS_MMUTBU_INT_CLR2; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS3; + FWK_W uint32_t CONS_MMUTBU_INT_CLR3; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS4; + FWK_W uint32_t CONS_MMUTBU_INT_CLR4; + FWK_R uint32_t CONS_MMUTBU_INT_STATUS5; + FWK_W uint32_t CONS_MMUTBU_INT_CLR5; + uint8_t RESERVED10[0xB20 - 0xA98]; + FWK_R uint32_t CPU_PPU_INT_STATUS[8]; + FWK_R uint32_t CLUS_PPU_INT_STATUS[8]; + FWK_R uint32_t PROC_PEX_INT_STATUS[8]; + FWK_RW uint32_t CPU_PLL_LOCK_STATUS[8]; + uint8_t RESERVED11[0xBC0 - 0xBA0]; + FWK_RW uint32_t CPU_PLL_UNLOCK_STATUS[7]; + uint8_t RESERVED12[0xC10 - 0xBE0]; + FWK_W uint32_t SMCF_MGI_TRIGGER; + uint8_t RESERVED13[0xC20 - 0xC14]; + FWK_R uint32_t SRAMECC_ERRFR; + FWK_R uint32_t SRAMECC_ERRFR_H; + FWK_RW uint32_t SRAMECC_ERRCTRL; + FWK_RW uint32_t SRAMECC_ERRCTRL_H; + FWK_RW uint32_t SRAMECC_ERRSTATUS; + FWK_RW uint32_t SRAMECC_ERRSTATUS_H; + FWK_RW uint32_t SRAMECC_ERRADDR; + FWK_RW uint32_t SRAMECC_ERRADDR_H; + uint8_t RESERVED14[0xC48 - 0xC40]; + FWK_RW uint32_t SRAMECC_ERRMISC1; + FWK_RW uint32_t SRAMECC_ERRMISC1_H; + uint8_t RESERVED15[0xC60 - 0xC50]; + FWK_R uint32_t SYSNCI_PMU_CONS_INT_STATUS; + FWK_R uint32_t SYSNCI_CONS_INT_STATUS; + FWK_R uint32_t INTNCI_PMU_CONS_INT_STATUS; + FWK_R uint32_t INTNCI_CONS_INT_STATUS; + FWK_R uint32_t PERIPHNCI_PMU_CONS_INT_STATUS; + FWK_R uint32_t PERIPHNCI_CONS_INT_STATUS; + uint8_t RESERVED16[0xFC0 - 0xC78]; + FWK_R uint32_t PWR_CTRL_CONFIG; + uint8_t RESERVED17[0xFD0 - 0xFC4]; + FWK_R uint32_t PERIPHERAL_ID4; + FWK_R uint32_t PERIPHERAL_ID5; + FWK_R uint32_t PERIPHERAL_ID6; + FWK_R uint32_t PERIPHERAL_ID7; + FWK_R uint32_t PERIPHERAL_ID0; + FWK_R uint32_t PERIPHERAL_ID1; + FWK_R uint32_t PERIPHERAL_ID2; + FWK_R uint32_t PERIPHERAL_ID3; + FWK_R uint32_t COMPONENT_ID0; + FWK_R uint32_t COMPONENT_ID1; + FWK_R uint32_t COMPONENT_ID2; + FWK_R uint32_t COMPONENT_ID3; +}; +// clang-format on + +/* Pointer to SCP Power Control register block */ +#define SCP_PWRCTRL_PTR ((struct scp_power_control_reg *)SCP_POWER_CONTROL_BASE) + +#endif /* SCP_PWRCTRL_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/system_pik.h b/product/automotive-rd/rd1ae/scp_ramfw/include/system_pik.h new file mode 100644 index 000000000..d65243af8 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/system_pik.h @@ -0,0 +1,81 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP System PIK registers + */ + +#ifndef SYSTEM_PIK_H +#define SYSTEM_PIK_H + +#include "scp_mmap.h" + +#include + +#include + +/*! + * \brief System PIK register definitions + */ + +// clang-format off +struct system_pik_reg { + uint8_t RESERVED0[0x820 - 0x0]; + FWK_RW uint32_t INTCLK_CTRL; + FWK_RW uint32_t INTCLK_DIV1; + uint8_t RESERVED1[0x850 - 0x828]; + FWK_RW uint32_t GICCLK_CTRL; + FWK_RW uint32_t GICCLK_DIV1; + uint8_t RESERVED2[0x860 - 0x858]; + FWK_RW uint32_t SCPPIKCLK_CTRL; + FWK_RW uint32_t SCPPIKCLK_DIV1; + uint8_t RESERVED3[0x870 - 0x868]; + FWK_RW uint32_t SYSPERCLK_CTRL; + FWK_RW uint32_t SYSPERCLK_DIV1; + uint8_t RESERVED4[0x8A0 - 0x878]; + FWK_RW uint32_t APUARTCLK_CTRL; + FWK_RW uint32_t APUARTCLK_DIV1; + uint8_t RESERVED5[0x8B0 - 0x8A8]; + FWK_RW uint32_t IONCICLK_CTRL; + FWK_RW uint32_t IONCICLK_DIV1; + uint8_t RESERVED6[0x900 - 0x8B8]; + FWK_RW uint32_t TCUCLK_CTRL; + FWK_RW uint32_t TCUCLK_DIV1; + uint8_t RESERVED7[0x940 - 0x908]; + FWK_RW uint32_t TCU_CLK_ENABLE; + FWK_RW uint32_t NCI_CLK_ENABLE; + uint8_t RESERVED8[0xA00 - 0x948]; + FWK_R uint32_t CLKFORCE_STATUS; + FWK_W uint32_t CLKFORCE_SET; + FWK_W uint32_t CLKFORCE_CLR; + uint8_t RESERVED9[0xB10 - 0xA0C]; + FWK_RW uint32_t IOMACRO_OVERRIDE; + FWK_RW uint32_t RSEPSI_STATUS; + FWK_RW uint32_t RSESAM_STATUS0; + FWK_RW uint32_t RSESAM_STATUS1; + FWK_RW uint32_t RSELCM_STATUS; + uint8_t RESERVED10[0xFC0 - 0xB24]; + FWK_R uint32_t PIK_CONFIG; + uint8_t RESERVED11[0xFD0 - 0xFC4]; + FWK_R uint32_t PID4; + FWK_R uint32_t PID5; + FWK_R uint32_t PID6; + FWK_R uint32_t PID7; + FWK_R uint32_t PID0; + FWK_R uint32_t PID1; + FWK_R uint32_t PID2; + FWK_R uint32_t PID3; + FWK_R uint32_t ID0; + FWK_R uint32_t ID1; + FWK_R uint32_t ID2; + FWK_R uint32_t ID3; +}; +// clang-format on + +/* Pointer to SCP System PIK register block */ +#define SYSTEM_PIK_PTR ((struct system_pik_reg *)SCP_SYSTEM_PIK_BASE) + +#endif /* SYSTEM_PIK_H */ -- GitLab From 8be081378b4caefe69cc140202654e7d5eea175c Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 26 Apr 2024 22:31:43 +0100 Subject: [PATCH 06/43] automotive-rd/rd1ae: Add generic timer module configurations The configuration data for generic timer driver includes the base addresses of timer register, counter register and control register along with the initial frequency and the id of clock device on which the timer depends. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_gtimer.c | 51 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 3 ++ 4 files changed, 56 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 98d3fa31b..9889b5638 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -19,6 +19,7 @@ target_include_directories( target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index daf211d42..a541526d3 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -31,3 +31,4 @@ list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") +list(APPEND SCP_MODULES "gtimer") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c b/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c new file mode 100644 index 000000000..1a2071546 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c @@ -0,0 +1,51 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'gtimer'. + */ + +#include "scp_mmap.h" + +#include + +#include +#include +#include +#include + +#define MOD_GTIMER_ELEMENT_COUNT 2 + +/* REF_CLK input clock speed */ +#define CLOCK_RATE_REFCLK (100UL * FWK_MHZ) + +/* + * System Counter per-tick increment value required for 100MHz clock speed as + * required for SBSA compliance. That is, (100MHz / CLOCK_RATE_REFCLK) = 1. + */ +#define SYSCNT_INCR 1 + +/* Generic timer driver config */ +static const struct fwk_element gtimer_dev_table[MOD_GTIMER_ELEMENT_COUNT] = { + [0] = { .name = "REFCLK", + .data = &((struct mod_gtimer_dev_config){ + .hw_timer = SCP_REFCLK_CNTBASE0_BASE, + .hw_counter = SCP_REFCLK_CNTCTL_BASE, + .control = SCP_REFCLK_CNTCONTROL_BASE, + .frequency = (CLOCK_RATE_REFCLK * SYSCNT_INCR), + .clock_id = FWK_ID_NONE_INIT, + }) }, + [1] = { 0 }, +}; + +const struct fwk_module_config config_gtimer = { + .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(gtimer_dev_table), +}; + +struct fwk_time_driver fmw_time_driver(const void **ctx) +{ + return mod_gtimer_driver(ctx, config_gtimer.elements.table[0].data); +} diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 3e38392e4..69cdccbde 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -21,6 +21,9 @@ /* SCP sub-system peripherals */ #define SCP_POWER_CONTROL_BASE (0x50000000UL) +#define SCP_REFCLK_CNTCONTROL_BASE (0x2A430000UL) +#define SCP_REFCLK_CNTCTL_BASE (0x44000000UL) +#define SCP_REFCLK_CNTBASE0_BASE (0x44001000UL) #define SCP_SYSTEM_PIK_BASE (0x50040000UL) #define SCP_UART_BASE (0x44002000UL) -- GitLab From f68658cee1afd1e16cf9c8d201cd2c6588dc211d Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 19:26:51 +0100 Subject: [PATCH 07/43] automotive-rd/rd1ae: Add timer HAL module configurations Provide the configuration data for timer HAL which includes the id for the timer element and the IRQ number. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 3 +- .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_timer.c | 45 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/fmw_cmsis.h | 3 ++ .../rd1ae/scp_ramfw/include/scp_cfgd_timer.h | 19 ++++++++ 5 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_timer.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 9889b5638..ea5132463 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -22,7 +22,8 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" - "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c") + "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") # # Some of our firmware includes require CMSIS. diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index a541526d3..4b30c05a8 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -32,3 +32,4 @@ list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "gtimer") +list(APPEND SCP_MODULES "timer") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_timer.c b/product/automotive-rd/rd1ae/scp_ramfw/config_timer.c new file mode 100644 index 000000000..314eaa336 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_timer.c @@ -0,0 +1,45 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'timer'. + */ + +#include "scp_cfgd_timer.h" + +#include + +#include +#include +#include +#include + +#include + +#define MOD_TIMER_ELEMENT_COUNT 2 + +/* Timer HAL config */ +static const struct fwk_element timer_dev_table[MOD_TIMER_ELEMENT_COUNT] = { + [0] = { + .name = "REFCLK", + .data = &((struct mod_timer_dev_config) { + .id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_GTIMER, 0), + .timer_irq = REFCLK_GTIMER_IRQ, + }), + .sub_element_count = + SCP_CFGD_MOD_TIMER_ALARM_IDX_COUNT, /* Number of alarms */ + }, + [1] = { 0 }, +}; + +static const struct fwk_element *timer_get_dev_table(fwk_id_t module_id) +{ + return timer_dev_table; +} + +const struct fwk_module_config config_timer = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(timer_get_dev_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h index 3d6b3dfa5..3e91ac766 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h @@ -36,6 +36,9 @@ typedef enum IRQn { PendSV_IRQn = -2, SysTick_IRQn = -1, + /* SCP REFCLK Physical Timer */ + REFCLK_GTIMER_IRQ = 32, + IRQn_MAX = INT16_MAX, } IRQn_Type; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h new file mode 100644 index 000000000..a8ed5a635 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h @@ -0,0 +1,19 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for timer module configuration data in SCP firmware. + */ + +#ifndef SCP_CFGD_TIMER_H +#define SCP_CFGD_TIMER_H + +/* Sub-element indexes (alarms) for SCP timer device */ +enum scp_cfgd_mod_timer_alarm_idx { + SCP_CFGD_MOD_TIMER_ALARM_IDX_COUNT, +}; + +#endif /* SCP_CFGD_TIMER_H */ -- GitLab From bf83f5ca58a5da52e2b972dda383a4ead2dbc360 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 26 Apr 2024 21:49:36 +0100 Subject: [PATCH 08/43] automotive-rd/rd1ae: Add PPU v1 module configurations 1- Provide the configuration data of all the available PPU instances to the PPU v1 driver. The PPU instances of CPUs, Clusters and the SYSTOP are included in the configuration data. 2- Add helpers to obtain platform topology in scp_ramfw. Add functions to obtain the platform topology information such as core count and cluster count. These functions can be used in module config data to obtain platform topology. 3- As the PPUv1 module requires the notifications framework, enable it and add the maximum number of active notifications. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 3 + .../rd1ae/scp_ramfw/config_ppu_v1.c | 140 ++++++++++++++++++ .../scp_ramfw/include/fmw_notification.h | 16 ++ .../rd1ae/scp_ramfw/include/platform_core.h | 38 +++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 13 ++ 6 files changed, 211 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/fmw_notification.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index ea5132463..2c99f4fe1 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 4b30c05a8..55a86302b 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -17,6 +17,8 @@ set(SCP_TOOLCHAIN_INIT "GNU") set(SCP_GENERATE_FLAT_BINARY_INIT TRUE) +set(SCP_ENABLE_NOTIFICATIONS_INIT TRUE) + # Disable Interprocedural optimization set(SCP_ENABLE_IPO_INIT FALSE) @@ -29,6 +31,7 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) # Any change in the order will cause firmware initialization errors. list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") +list(APPEND SCP_MODULES "ppu-v1") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "gtimer") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c new file mode 100644 index 000000000..feef45034 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c @@ -0,0 +1,140 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'ppu_v1'. + */ + +#include "platform_core.h" +#include "scp_mmap.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PPU_STATIC_ELEMENT_COUNT 1 +#define PPU_CORE_NAME_SIZE 12 +#define PPU_CLUS_NAME_SIZE 7 + +/* List of static PPU elements */ +static struct fwk_element ppu_element_table[PPU_STATIC_ELEMENT_COUNT] = { + { + .name = "SYS0", + .data = &((struct mod_ppu_v1_pd_config){ + .pd_type = MOD_PD_TYPE_SYSTEM, + .ppu.reg_base = SCP_PPU_SYS0_BASE, + .default_power_on = true, + .observer_id = FWK_ID_NONE_INIT, + }), + }, +}; + +static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) +{ + struct fwk_element *element_table; + struct mod_ppu_v1_pd_config *pd_config_table; + unsigned int cluster_idx; + unsigned int core_count; + unsigned int cluster_count; + unsigned int core_element_count = 0; + unsigned int number_elements; + int snprintf_ret_val; + + core_count = platform_get_core_count(); + cluster_count = platform_get_cluster_count(); + + /* + * Allocate element descriptors based on: + * Number of cores + * + Number of cluster descriptors + * + Number of system power domain descriptors + * + 1 terminator descriptor + */ + number_elements = core_count + cluster_count + FWK_ARRAY_SIZE(ppu_element_table) + 1; + element_table = fwk_mm_calloc(number_elements, sizeof(struct fwk_element)); + + pd_config_table = fwk_mm_calloc( + core_count + cluster_count, sizeof(struct mod_ppu_v1_pd_config)); + + for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { + struct fwk_element *element; + struct mod_ppu_v1_pd_config *pd_config; + unsigned int core_idx; + + for (core_idx = 0; + core_idx < platform_get_core_per_cluster_count(cluster_idx); + core_idx++) { + element = &element_table[core_element_count]; + pd_config = &pd_config_table[core_element_count]; + + element->name = fwk_mm_alloc(PPU_CORE_NAME_SIZE, 1); + + snprintf_ret_val = snprintf( + (char *)element->name, + PPU_CORE_NAME_SIZE, + "CLUS%uCORE%u", + cluster_idx, + core_idx); + + fwk_assert( + (snprintf_ret_val >= 0) && + (snprintf_ret_val <= PPU_CORE_NAME_SIZE)); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CORE; + pd_config->ppu.reg_base = + SCP_CLUSTER_UTILITY_CORE_PPU_BASE(cluster_idx); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_idx)); + pd_config->observer_id = FWK_ID_NONE; + core_element_count++; + } + + element = &element_table[core_count + cluster_idx]; + pd_config = &pd_config_table[core_count + cluster_idx]; + + element->name = fwk_mm_alloc(PPU_CLUS_NAME_SIZE, 1); + + snprintf_ret_val = snprintf( + (char *)element->name, PPU_CLUS_NAME_SIZE, "CLUS%u", cluster_idx); + + fwk_assert( + (snprintf_ret_val >= 0) && + (snprintf_ret_val <= PPU_CLUS_NAME_SIZE)); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CLUSTER; + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->observer_id = FWK_ID_NONE; + pd_config->observer_api = FWK_ID_NONE; + pd_config->ppu.reg_base = + SCP_CLUSTER_UTILITY_CLUSTER_PPU_BASE(cluster_idx); + } + + fwk_str_memcpy( + &element_table[core_count + cluster_count], + ppu_element_table, + sizeof(ppu_element_table)); + + return element_table; +} + +const struct fwk_module_config config_ppu_v1 = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(ppu_v1_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_notification.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_notification.h new file mode 100644 index 000000000..3f1717c53 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_notification.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP RAM firmware notification configuration. + */ + +#ifndef FMW_NOTIFICATION_H +#define FMW_NOTIFICATION_H + +#define FMW_NOTIFICATION_MAX 128 + +#endif /* FMW_NOTIFICATION_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h b/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h new file mode 100644 index 000000000..57a5236f6 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h @@ -0,0 +1,38 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Platform generic definitions. + */ + +#ifndef PLATFORM_CORE_H +#define PLATFORM_CORE_H + +#include + +#define CORES_PER_CLUSTER 1 +#define NUMBER_OF_CLUSTERS 16 + +static inline unsigned int platform_get_cluster_count(void) +{ + return NUMBER_OF_CLUSTERS; +} + +static inline unsigned int platform_get_core_per_cluster_count( + unsigned int cluster) +{ + fwk_assert(cluster < platform_get_cluster_count()); + + return CORES_PER_CLUSTER; +} + +static inline unsigned int platform_get_core_count(void) +{ + return platform_get_core_per_cluster_count(0) * + platform_get_cluster_count(); +} + +#endif /* PLATFORM_CORE_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 69cdccbde..abba47679 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -21,6 +21,7 @@ /* SCP sub-system peripherals */ #define SCP_POWER_CONTROL_BASE (0x50000000UL) +#define SCP_PPU_SYS0_BASE (0x50041000UL) #define SCP_REFCLK_CNTCONTROL_BASE (0x2A430000UL) #define SCP_REFCLK_CNTCTL_BASE (0x44000000UL) #define SCP_REFCLK_CNTBASE0_BASE (0x44001000UL) @@ -54,10 +55,22 @@ * to each cluster in the system. */ #define SCP_CLUSTER_UTILITY_CORE_MANAGER_OFFSET (0x80000UL) +#define SCP_CLUSTER_UTILITY_CLUSTER_PPU_OFFSET (0x130000UL) +#define SCP_CLUSTER_UTILITY_CORE_PPU_OFFSET (0x180000UL) /* Core Manager base address for a cluster 'n' */ #define SCP_CLUSTER_UTILITY_CORE_MANAGER_BASE(n) \ (SCP_ATW0_CLUSTER_UTILITY_BASE + (n * SCP_CLUSTER_UTILITY_SIZE) + \ SCP_CLUSTER_UTILITY_CORE_MANAGER_OFFSET) +/* Cluster PPU base address */ +#define SCP_CLUSTER_UTILITY_CLUSTER_PPU_BASE(n) \ + (SCP_ATW0_CLUSTER_UTILITY_BASE + (n * SCP_CLUSTER_UTILITY_SIZE) + \ + SCP_CLUSTER_UTILITY_CLUSTER_PPU_OFFSET) + +/* Application core PPU base address */ +#define SCP_CLUSTER_UTILITY_CORE_PPU_BASE(n) \ + (SCP_ATW0_CLUSTER_UTILITY_BASE + (n * SCP_CLUSTER_UTILITY_SIZE) + \ + SCP_CLUSTER_UTILITY_CORE_PPU_OFFSET) + #endif /* SCP_MMAP_H */ -- GitLab From 04dc904b133beae9853b13f2abd505a3e6c147c0 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 7 Jun 2024 10:25:52 +0100 Subject: [PATCH 09/43] automotive-rd/rd1ae: Add System PIK module Add a platform module for System PIK register which initializes the IOMACRO_OVERRIDE register. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/module/system_pik/CMakeLists.txt | 13 +++++ .../rd1ae/module/system_pik/Module.cmake | 9 +++ .../system_pik/include/mod_system_pik.h | 25 +++++++++ .../module/system_pik/src/mod_system_pik.c | 55 +++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/system_pik/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/system_pik/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/system_pik/include/mod_system_pik.h create mode 100644 product/automotive-rd/rd1ae/module/system_pik/src/mod_system_pik.c diff --git a/product/automotive-rd/rd1ae/module/system_pik/CMakeLists.txt b/product/automotive-rd/rd1ae/module/system_pik/CMakeLists.txt new file mode 100644 index 000000000..5d29f5e65 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/system_pik/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_system_pik.c") diff --git a/product/automotive-rd/rd1ae/module/system_pik/Module.cmake b/product/automotive-rd/rd1ae/module/system_pik/Module.cmake new file mode 100644 index 000000000..cc9d71339 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/system_pik/Module.cmake @@ -0,0 +1,9 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "system-pik") +set(SCP_MODULE_TARGET "module_system_pik") diff --git a/product/automotive-rd/rd1ae/module/system_pik/include/mod_system_pik.h b/product/automotive-rd/rd1ae/module/system_pik/include/mod_system_pik.h new file mode 100644 index 000000000..c3b63ef8d --- /dev/null +++ b/product/automotive-rd/rd1ae/module/system_pik/include/mod_system_pik.h @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_SYSTEM_PIK_H +#define MOD_SYSTEM_PIK_H + +#include "system_pik.h" + +#include + +#define TCU_L0GPTSZ_SHIFT 2UL +#define L0GPTSZ_16GIB 0x04UL + +struct mod_system_pik_device_config { + /*! Base address of the system PIK register */ + uintptr_t system_pik_base; + /*! Level 0 Granule Protection Table size */ + uint32_t l0_gpt_size; +}; + +#endif /* MOD_SYSTEM_PIK_H */ diff --git a/product/automotive-rd/rd1ae/module/system_pik/src/mod_system_pik.c b/product/automotive-rd/rd1ae/module/system_pik/src/mod_system_pik.c new file mode 100644 index 000000000..539270917 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/system_pik/src/mod_system_pik.c @@ -0,0 +1,55 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * System PIK device driver. + */ + +#include + +#include +#include + +struct mod_system_pik_ctx { + struct system_pik_reg *system_pik_reg; +}; + +/* System PIK module context */ +static struct mod_system_pik_ctx system_pik_ctx; + +/* + * Framework handlers + */ +static int mod_system_pik_init( + fwk_id_t module_id, + unsigned int device_count, + const void *data) +{ + struct mod_system_pik_device_config *config = + (struct mod_system_pik_device_config *)data; + + system_pik_ctx.system_pik_reg = + (struct system_pik_reg *)config->system_pik_base; + + if (config->l0_gpt_size != 0) { + system_pik_ctx.system_pik_reg->IOMACRO_OVERRIDE = + (config->l0_gpt_size << TCU_L0GPTSZ_SHIFT); + } + + return FWK_SUCCESS; +} + +static int mod_system_pik_start(fwk_id_t id) +{ + return FWK_SUCCESS; +} + +/* System PIK module definition */ +const struct fwk_module module_system_pik = { + .type = FWK_MODULE_TYPE_DRIVER, + .init = mod_system_pik_init, + .start = mod_system_pik_start, +}; -- GitLab From ee6a565cc00f9b7927ac3bb9ac051608e9efe322 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 7 Jun 2024 10:26:36 +0100 Subject: [PATCH 10/43] automotive-rd/rd1ae: Add System PIK module configurations Add System PIK module configurations. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 5 ++++ .../rd1ae/scp_ramfw/config_system_pik.c | 24 +++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_system_pik.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 2c99f4fe1..72906aa62 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -23,6 +23,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 55a86302b..534b0d82b 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -26,11 +26,16 @@ set(SCP_ARCHITECTURE "arm-m") set(SCP_ENABLE_NEWLIB_NANO FALSE) +list(PREPEND SCP_MODULE_PATHS + "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") + + # The order of the modules in the following list is the order in which the # modules are initialized, bound, started during the pre-runtime phase. # Any change in the order will cause firmware initialization errors. list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") +list(APPEND SCP_MODULES "system-pik") list(APPEND SCP_MODULES "ppu-v1") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_system_pik.c b/product/automotive-rd/rd1ae/scp_ramfw/config_system_pik.c new file mode 100644 index 000000000..c46f0ce8f --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_system_pik.c @@ -0,0 +1,24 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'system_pik'. + */ + +#include + +#include + +#include + +static const struct mod_system_pik_device_config system_pik_data = { + .system_pik_base = (uintptr_t)SYSTEM_PIK_PTR, + .l0_gpt_size = L0GPTSZ_16GIB, +}; + +struct fwk_module_config config_system_pik = { + .data = &system_pik_data, +}; -- GitLab From 20855649f95046a143b98a5cab5d052ca6ffa3ae Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Tue, 23 Apr 2024 17:26:31 +0100 Subject: [PATCH 11/43] automotive-rd/rd1ae: Add SID module configurations 1- The SID peripheral provides information about the platform and its configuration. So, add the configuration data for sid module in scp ramfw. The configuration data includes the expected value of its PID/CID registers for identification. PID5, PID6 and PID7 are not implemented by this peripheral and this is indicated using the valid register bitmap. 2- Enable the PCID module as it is a dependency of the SID module. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 2 + .../rd1ae/scp_ramfw/config_sid.c | 63 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 1 + 4 files changed, 67 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_sid.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 72906aa62..080fa7329 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -23,6 +23,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 534b0d82b..bf2fd9ae8 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -41,3 +41,5 @@ list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "gtimer") list(APPEND SCP_MODULES "timer") +list(APPEND SCP_MODULES "pcid") +list(APPEND SCP_MODULES "sid") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_sid.c b/product/automotive-rd/rd1ae/scp_ramfw/config_sid.c new file mode 100644 index 000000000..54aa7d0cf --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_sid.c @@ -0,0 +1,63 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'sid'. + */ + +#include "scp_mmap.h" + +#include + +#include +#include +#include + +#define RD1AE_PART_NUMBER 0x73E + +#define MOD_SID_ELEMENT_COUNT 2 + +static const struct fwk_element subsystem_table[MOD_SID_ELEMENT_COUNT] = { + { .name = "RD1AE", + .data = + &(struct mod_sid_subsystem_config){ + .part_number = RD1AE_PART_NUMBER, + } }, + { 0 }, +}; + +static const struct fwk_element *get_subsystem_table(fwk_id_t id) +{ + return subsystem_table; +} + +const struct fwk_module_config config_sid = { + .data = &(struct mod_sid_config) { + .sid_base = SCP_SID_BASE, + .valid_pcid_registers = + MOD_PCID_REGISTER_PID0 | + MOD_PCID_REGISTER_PID1 | + MOD_PCID_REGISTER_PID2 | + MOD_PCID_REGISTER_PID3 | + MOD_PCID_REGISTER_PID4 | + MOD_PCID_REGISTER_CID0 | + MOD_PCID_REGISTER_CID1 | + MOD_PCID_REGISTER_CID2 | + MOD_PCID_REGISTER_CID3, + .pcid_expected = { + .PID0 = 0xBCU, + .PID1 = 0xB0U, + .PID2 = 0x0BU, + .PID3 = 0x00U, + .PID4 = 0x04U, + .CID0 = 0x0DU, + .CID1 = 0xF0U, + .CID2 = 0x05U, + .CID3 = 0xB1U, + }, + }, + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_subsystem_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index abba47679..c7a01262f 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -25,6 +25,7 @@ #define SCP_REFCLK_CNTCONTROL_BASE (0x2A430000UL) #define SCP_REFCLK_CNTCTL_BASE (0x44000000UL) #define SCP_REFCLK_CNTBASE0_BASE (0x44001000UL) +#define SCP_SID_BASE (0x2A4A0000UL) #define SCP_SYSTEM_PIK_BASE (0x50040000UL) #define SCP_UART_BASE (0x44002000UL) -- GitLab From b8c9aba4e4a5eef14b7117b620c829aa17c6ba7f Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Tue, 23 Apr 2024 17:31:16 +0100 Subject: [PATCH 12/43] automotive-rd/rd1ae: Add System Info module configurations System Info module provides API to obtain platform configuration data in a platform independent manner. So, add configuration data for system info module in scp ramfw. The configuration data specifies the PID module as the driver to obtain the platform configuration data. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_system_info.c | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_system_info.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 080fa7329..942ef6329 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -24,6 +24,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_system_info.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index bf2fd9ae8..19a11e01d 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -43,3 +43,4 @@ list(APPEND SCP_MODULES "gtimer") list(APPEND SCP_MODULES "timer") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") +list(APPEND SCP_MODULES "system-info") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_system_info.c b/product/automotive-rd/rd1ae/scp_ramfw/config_system_info.c new file mode 100644 index 000000000..d910f4d2a --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_system_info.c @@ -0,0 +1,25 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'system_info'. + */ + +#include +#include + +#include +#include +#include + +const struct fwk_module_config config_system_info = { + .data = &((struct mod_system_info_config){ + .system_info_driver_module_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SID), + .system_info_driver_data_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SID, + MOD_SID_SYSTEM_INFO_DRIVER_DATA_API_IDX), + }), +}; -- GitLab From 3572d7e67ea2e777c3a26799b9b6f10d918b359a Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 20:22:16 +0100 Subject: [PATCH 13/43] automotive-rd/rd1ae: Add Transport and MHUv3 module configurations Two transport channels are required for supporting platform boot - channel for communicating PSCI messages with the application core, channel for requesting the secure platform agent firmware to configure the ATU. Add these as configuration data for the transport module. MHUv3 module configurations: Two instances of the MHUv3 doorbell channel are being initially added as configuration data for the MHUv3 module. The first doorbell channel is used to send messages between AP and SCP while the second doorbell channel used between RSE and SCP. The configuration data for these channels include the interrupt number and the base addresses of the corresponding Postbox and Mailbox. Also add the AP Trusted SRAM region to the list of MPU regions. Signed-off-by: Luca Fancellu Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 4 +- .../rd1ae/scp_ramfw/Firmware.cmake | 4 + .../rd1ae/scp_ramfw/config_armv7m_mpu.c | 19 ++++- .../rd1ae/scp_ramfw/config_mhu3.c | 84 +++++++++++++++++++ .../rd1ae/scp_ramfw/config_transport.c | 67 +++++++++++++++ .../rd1ae/scp_ramfw/include/fmw_cmsis.h | 4 + .../rd1ae/scp_ramfw/include/scp_cfgd_mhu3.h | 21 +++++ .../scp_ramfw/include/scp_cfgd_transport.h | 21 +++++ .../rd1ae/scp_ramfw/include/scp_fw_mmap.h | 35 ++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 11 +++ 10 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_transport.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_mhu3.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 942ef6329..b8ac8e51c 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" @@ -27,7 +28,8 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_system_info.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" - "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c") + "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_transport.c") # # Some of our firmware includes require CMSIS. diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 19a11e01d..c5de17a49 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -26,6 +26,8 @@ set(SCP_ARCHITECTURE "arm-m") set(SCP_ENABLE_NEWLIB_NANO FALSE) +set(SCP_ENABLE_OUTBAND_MSG_SUPPORT TRUE) + list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -41,6 +43,8 @@ list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "gtimer") list(APPEND SCP_MODULES "timer") +list(APPEND SCP_MODULES "mhu3") +list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") list(APPEND SCP_MODULES "system-info") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c b/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c index 995d5fe10..0f0243f39 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_armv7m_mpu.c @@ -8,6 +8,7 @@ * Configuration data for module 'armv7m_mpu'. */ +#include "scp_fw_mmap.h" #include "scp_mmap.h" #include @@ -15,7 +16,7 @@ #include #include -#define SCP_MPU_REGION_COUNT 3 +#define SCP_MPU_REGION_COUNT 4 static const ARM_MPU_Region_t regions[SCP_MPU_REGION_COUNT] = { { @@ -57,6 +58,22 @@ static const ARM_MPU_Region_t regions[SCP_MPU_REGION_COUNT] = { 0, ARM_MPU_REGION_SIZE_256KB), }, + { + /* + * 0x7000_0000 - 0x7000_1FFF + * This is mapped to 0x0000_0000 - 0x0000_1FFF in AP memory map. + */ + .RBAR = ARM_MPU_RBAR(0x3UL, SCP_AP_PERIPHERAL_SRAM_TRUSTED_BASE), + .RASR = ARM_MPU_RASR( + 1, + ARM_MPU_AP_PRIV, + 0, + 1, + 1, + 1, + 0, + ARM_MPU_REGION_SIZE_8KB), + }, }; const struct fwk_module_config config_armv7m_mpu = { diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c new file mode 100644 index 000000000..8eddcaf5a --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c @@ -0,0 +1,84 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'mhu3'. + */ + +#include "scp_cfgd_mhu3.h" +#include "scp_mmap.h" + +#include + +#include +#include +#include + +#include + +#define MOD_MHU3_ELEMENT_COUNT (SCP_CFGD_MOD_MHU3_EIDX_COUNT + 1) + +/* + * Timeout to wait for the receiver to clear the MHUv3 channel status + * register so the channel can become available again. + */ +#define RESP_WAIT_TIMEOUT_US (30 * 1000) + +/* AP<-->SCP Secure MHUv3 doorbell channel configuration */ +struct mod_mhu3_channel_config scp2ap_s_dbch_config[1] = { + /* PBX CH 0, FLAG 0, MBX CH 0, FLAG 0 */ + [0] = MOD_MHU3_INIT_DBCH(0, 0, 0, 0), +}; + +/* SCP<-->RSE Secure MHUv3 Doorbell channel configuration */ +struct mod_mhu3_channel_config scp2rse_s_dbch_config[1] = { + /* PBX CH 0, FLAG 0, MBX CH 0, FLAG 0 */ + [0] = MOD_MHU3_INIT_DBCH(0, 0, 0, 0), +}; + +/* AP<-->SCP Secure MHUv3 doorbell channel count */ +#define SCP2AP_S_DBCH_COUNT FWK_ARRAY_SIZE(scp2ap_s_dbch_config) + +/* SCP<-->RSE Secure MHUv3 Doorbell channel count */ +#define SCP2RSE_S_DBCH_COUNT FWK_ARRAY_SIZE(scp2rse_s_dbch_config) + +/* Module element table */ +static const struct fwk_element mhu_element_table[MOD_MHU3_ELEMENT_COUNT] = { + [SCP_CFGD_MOD_MHU3_EIDX_SCP_AP_S] = { + .name = "SCP2AP_S_MHU_DBCH", + .sub_element_count = SCP2AP_S_DBCH_COUNT, + .data = &(struct mod_mhu3_device_config) { + .irq = (unsigned int) MHU3_AP2SCP_IRQ_S, + .in = SCP_AP2SCP_MHUV3_RCV_S_BASE, + .out = SCP_SCP2AP_MHUV3_SEND_S_BASE, + .channels = &scp2ap_s_dbch_config[0], + .timer_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0), + .resp_wait_timeout_us = RESP_WAIT_TIMEOUT_US, + }, + }, + [SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S] = { + .name = "SCP2RSE_S_MHU_DBCH", + .sub_element_count = SCP2RSE_S_DBCH_COUNT, + .data = &(struct mod_mhu3_device_config) { + .irq = (unsigned int) MHU3_RSE2SCP_IRQ_S, + .in = SCP_RSE2SCP_MHUV3_RCV_S_BASE, + .out = SCP_SCP2RSE_MHUV3_SEND_S_BASE, + .channels = &scp2rse_s_dbch_config[0], + .timer_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0), + .resp_wait_timeout_us = RESP_WAIT_TIMEOUT_US, + }, + }, + [SCP_CFGD_MOD_MHU3_EIDX_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_element_table(fwk_id_t module_id) +{ + return mhu_element_table; +} + +struct fwk_module_config config_mhu3 = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c new file mode 100644 index 000000000..adb4a0517 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c @@ -0,0 +1,67 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'transport'. + */ + +#include "platform_core.h" +#include "scp_cfgd_mhu3.h" +#include "scp_cfgd_transport.h" +#include "scp_clock.h" +#include "scp_fw_mmap.h" + +#include +#include + +#include +#include +#include +#include + +#include + +/* Module 'transport' element count */ +#define MOD_TRANSPORT_ELEMENT_COUNT (SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT + 1) + +/* Secure transport channel with mailbox initialization policy */ +#define TRANSPORT_CH_SEC_MBX_INIT \ + (MOD_TRANSPORT_POLICY_INIT_MAILBOX | MOD_TRANSPORT_POLICY_SECURE) + +/* Module 'transport' element configuration table */ +static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { + [SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI] = { + .name = "PSCI", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_OUT_BAND, + .policies = TRANSPORT_CH_SEC_MBX_INIT, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .out_band_mailbox_address = + (uintptr_t) SCP_SCMI_PAYLOAD_S_A2P_BASE, + .out_band_mailbox_size = SCP_SCMI_PAYLOAD_SIZE, + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_AP_S, + 0), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT] = { 0 }, +}; + +static const struct fwk_element *transport_get_element_table(fwk_id_t module_id) +{ + return element_table; +} + +const struct fwk_module_config config_transport = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(transport_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h index 3e91ac766..8753b70aa 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_cmsis.h @@ -38,6 +38,10 @@ typedef enum IRQn { /* SCP REFCLK Physical Timer */ REFCLK_GTIMER_IRQ = 32, + /* MHUv3 secure IRQ between SCP and AP */ + MHU3_AP2SCP_IRQ_S = 83, + /* MHUv3 secure IRQ between SCP and RSE */ + MHU3_RSE2SCP_IRQ_S = 86, IRQn_MAX = INT16_MAX, } IRQn_Type; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_mhu3.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_mhu3.h new file mode 100644 index 000000000..7f8722443 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_mhu3.h @@ -0,0 +1,21 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for MHUv3 module configuration data in SCP firmware. + */ + +#ifndef SCP_CFGD_MHU3_H +#define SCP_CFGD_MHU3_H + +/* MHUv3 device indices */ +enum scp_cfgd_mod_mhu3_device_idx { + SCP_CFGD_MOD_MHU3_EIDX_SCP_AP_S, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + SCP_CFGD_MOD_MHU3_EIDX_COUNT +}; + +#endif /* SCP_CFGD_MHU3_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h new file mode 100644 index 000000000..1fb9b4b2d --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h @@ -0,0 +1,21 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for transport module configuration data in SCP + * firmware. + */ + +#ifndef SCP_CFGD_TRANSPORT_H +#define SCP_CFGD_TRANSPORT_H + +/* Module 'transport' element indexes */ +enum scp_cfgd_mod_transport_element_idx { + SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI, + SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT, +}; + +#endif /* SCP_CFGD_TRANSPORT_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h new file mode 100644 index 000000000..454942aec --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h @@ -0,0 +1,35 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Base address and size definitions for the various SCP's firmware defined + * memory carveouts. + */ + +#ifndef SCP_FW_MMAP_H +#define SCP_FW_MMAP_H + +#include "scp_mmap.h" + +/* AP Peripheral trusted SRAM base in SCP's memory map (4KB) */ +#define SCP_AP_PERIPHERAL_SRAM_TRUSTED_BASE SCP_ATW0_AP_PERIPHERAL_SRAM_BASE + +/* Secure Shared memory between AP and SCP */ +#define SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_BASE \ + (SCP_AP_PERIPHERAL_SRAM_TRUSTED_BASE) + +/* + * SDS Memory Region inside Secure AP Peripheral SRAM that is shared between + * AP and SCP. + */ +#define SCP_SDS_SECURE_BASE (SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_BASE) +#define SCP_SDS_SECURE_SIZE (3520) + +/* SCMI Secure Payload Area */ +#define SCP_SCMI_PAYLOAD_S_A2P_BASE (SCP_SDS_SECURE_BASE + SCP_SDS_SECURE_SIZE) +#define SCP_SCMI_PAYLOAD_SIZE (128) + +#endif /* SCP_FW_MMAP_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index c7a01262f..58d95d105 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -20,11 +20,15 @@ #define SCP_DTC_RAM_SIZE (256 * 1024) /* SCP sub-system peripherals */ +#define SCP_AP2SCP_MHUV3_RCV_S_BASE (0x45030000UL) #define SCP_POWER_CONTROL_BASE (0x50000000UL) #define SCP_PPU_SYS0_BASE (0x50041000UL) #define SCP_REFCLK_CNTCONTROL_BASE (0x2A430000UL) #define SCP_REFCLK_CNTCTL_BASE (0x44000000UL) #define SCP_REFCLK_CNTBASE0_BASE (0x44001000UL) +#define SCP_RSE2SCP_MHUV3_RCV_S_BASE (0x46010000UL) +#define SCP_SCP2AP_MHUV3_SEND_S_BASE (0x45020000UL) +#define SCP_SCP2RSE_MHUV3_SEND_S_BASE (0x46000000UL) #define SCP_SID_BASE (0x2A4A0000UL) #define SCP_SYSTEM_PIK_BASE (0x50040000UL) #define SCP_UART_BASE (0x44002000UL) @@ -39,11 +43,18 @@ * Offsets within SCP's Address Translation Window0 * __________________________ * | | + * | SHARED SRAM 128M | + * |__________________________| 0x70000000 + * | | * | CLUSTER UTIL 256M | * |__________________________| 0x60000000 */ +#define SCP_ATW0_CLUSTER_UTILITY_SIZE (256 * FWK_MIB) + #define SCP_ATW0_CLUSTER_UTILITY_BASE SCP_ADDRESS_TRANSLATION_WINDOW0_BASE +#define SCP_ATW0_AP_PERIPHERAL_SRAM_BASE \ + (SCP_ATW0_CLUSTER_UTILITY_BASE + SCP_ATW0_CLUSTER_UTILITY_SIZE) /* * Size of SCP's view of per-cluster utility memory region. -- GitLab From 03fa1afa647687d05265eabe35e2f163066163fc Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 22:20:03 +0100 Subject: [PATCH 14/43] automotive-rd/rd1ae: Add SCP platform module and configurations Add scp_platform module. This module performs the following functions: - SCP-RSE handshake. - Notifies modules that have subscribed to relavant event that the subsystem initialization is complete. Those modules on receiving the event notification can complete any pending setup that depend on access to any address space outside of the SCP subsystem. - Turn on primary AP core. Provide configuration data for the scp_platform module which includes the transport channel id, timer id and the timeout value. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj Signed-off-by: Luca Fancellu --- .../rd1ae/module/scp_platform/CMakeLists.txt | 21 ++ .../rd1ae/module/scp_platform/Module.cmake | 10 + .../include/internal/scp_platform.h | 90 ++++++++ .../scp_platform/include/mod_scp_platform.h | 88 ++++++++ .../scp_platform/src/mod_scp_platform.c | 202 ++++++++++++++++++ .../scp_platform/src/platform_power_mgmt.c | 49 +++++ .../module/scp_platform/src/platform_rse.c | 140 ++++++++++++ .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 2 + .../rd1ae/scp_ramfw/config_scp_platform.c | 31 +++ .../rd1ae/scp_ramfw/config_transport.c | 23 ++ .../scp_ramfw/include/scp_cfgd_transport.h | 1 + 12 files changed, 658 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c create mode 100644 product/automotive-rd/rd1ae/module/scp_platform/src/platform_rse.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_scp_platform.c diff --git a/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt b/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt new file mode 100644 index 000000000..71f1d9a58 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources( + ${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_scp_platform.c" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/platform_power_mgmt.c" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/platform_rse.c") + +target_link_libraries( + ${SCP_MODULE_TARGET} + PRIVATE module-power-domain module-system-power + module-system-info module-transport module-timer) diff --git a/product/automotive-rd/rd1ae/module/scp_platform/Module.cmake b/product/automotive-rd/rd1ae/module/scp_platform/Module.cmake new file mode 100644 index 000000000..4faf2676b --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/Module.cmake @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "scp-platform") + +set(SCP_MODULE_TARGET "module-scp-platform") diff --git a/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h b/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h new file mode 100644 index 000000000..dddb46c29 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h @@ -0,0 +1,90 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP sub-system support. + */ + +#ifndef SCP_PLATFORM_H +#define SCP_PLATFORM_H + +#include + +#define MOD_NAME "[SCP_PLATFORM]" + +/* SRAM address where AP binary will be preloaded */ +#define AP_BOOT_ADDRESS (0x42000U) + +/* + * RSE communication interface helper functions. + */ + +/*! + * \brief Helper function to return platform system transport signal API. + * + * \param None. + * + * \return Pointer to the scp platform transport signal API. + */ +const void *get_platform_transport_signal_api(void); + +/*! + * \brief Helper function to notify RSE and wait for response. + * + * \details Notify RSE that SYSTOP is powered up so it can enable GPC bypass in + * the system control block. + * + * \param None. + * + * \retval ::FWK_SUCCESS Operation succeeded. + * \return One of the standard error codes for implementation-defined errors. + */ +int notify_rse_and_wait_for_response(void); + +/*! + * \brief Helper function to bind to transport and timer module APIs. + * + * \param config Pointer to the module config data. + * + * \retval ::FWK_SUCCESS Operation succeeded. + * \return One of the standard error codes for implementation-defined errors. + */ +int platform_rse_bind(const struct mod_scp_platform_config *config); + +/* + * Power management interface helper functions. + */ + +/*! + * \brief Helper function to return platform system power driver API. + * + * \param None. + * + * \return Pointer to the scp platform system power driver API. + */ +const void *get_platform_system_power_driver_api(void); + +/*! + * \brief Helper function to bind to power domain restricted API. + * + * \param None. + * + * \retval ::FWK_SUCCESS Operation succeeded. + * \return One of the standard error codes for implementation-defined errors. + */ +int platform_power_mgmt_bind(void); + +/*! + * \brief Power on the given AP core. + * + * \param core_idx AP core index. + * + * \retval ::FWK_SUCCESS Operation succeeded. + * \return One of the standard error codes for implementation-defined errors. + */ +int init_ap_core(uint8_t core_idx); + +#endif /* SCP_PLATFORM_H */ diff --git a/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h b/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h new file mode 100644 index 000000000..e5371de22 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h @@ -0,0 +1,88 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP Platform Support + */ + +#ifndef MOD_SCP_PLATFORM_H +#define MOD_SCP_PLATFORM_H + +#include +#include + +#include + +/*! + * \addtogroup GroupPLATFORMModule PLATFORM Product Modules + * @{ + */ + +/*! + * \defgroup GroupSCPPlatform SCP Platform Support + * @{ + */ + +/*! + * \brief Indices of the interfaces exposed by the module. + */ +enum mod_scp_platform_api_idx { + /*! API index for the driver interface of the SYSTEM POWER module */ + MOD_SCP_PLATFORM_API_IDX_SYSTEM_POWER_DRIVER, + + /*! Interface for Transport module */ + MOD_SCP_PLATFORM_API_IDX_TRANSPORT_SIGNAL, + + /*! Number of exposed interfaces */ + MOD_SCP_PLATFORM_API_COUNT +}; + +/*! + * \brief Notification indices. + */ +enum mod_scp_platform_notification_idx { + /*! SCP subsystem initialization completion notification */ + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED, + + /*! Number of notifications defined by the module */ + MOD_SCP_PLATFORM_NOTIFICATION_COUNT, +}; + +/*! + * \brief Identifier for the + * ::MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED notification. + */ +static const fwk_id_t mod_scp_platform_notification_subsys_init = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED); + +/*! + * \brief SCP platform configuration data. + */ +struct mod_scp_platform_config { + /*! Timer identifier */ + fwk_id_t timer_id; + + /*! Transport channel identifier */ + fwk_id_t transport_id; + + /*! + * Maximum amount of time, in microseconds, to wait for the RSE handshake + * event. + */ + uint32_t rse_sync_wait_us; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_SCP_PLATFORM_H */ diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c b/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c new file mode 100644 index 000000000..e627cf61c --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c @@ -0,0 +1,202 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP platform sub-system initialization support. + */ + +#include "core_manager.h" +#include "platform_core.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define L0GPTSZ_SHIFT 0x9 +#define L0GPTSZ_16GB 0x4 + +/* Module context */ +struct scp_platform_ctx { + /* Module config data */ + const struct mod_scp_platform_config *config; + + /* System Information HAL API pointer */ + struct mod_system_info_get_info_api *system_info_api; +}; + +/* Module context data */ +static struct scp_platform_ctx scp_platform_ctx; + +static void platform_update_gpt_size(void) +{ + unsigned int n; + + /* Set Level 0 Granule Protection Table size to 16GB for all cores */ + for (n = 0; n < platform_get_core_count(); n++) { + volatile uint32_t *pe_static_config = + (volatile uint32_t *)(&SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(n) + ->PE_STATIC_CONFIG); + *pe_static_config |= (L0GPTSZ_16GB << L0GPTSZ_SHIFT); + } +} + +/* Helper function to program the AP Core RVBAR */ +static void program_ap_rvbar() +{ + uint8_t core_idx; + + for (core_idx = 0; core_idx < platform_get_core_count(); core_idx++) { + /* Set RVBAR to boot SRAM address */ + SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(core_idx)->PE_RVBARADDR_LW = + AP_BOOT_ADDRESS; + SCP_CLUSTER_UTILITY_CORE_MANAGER_PTR(core_idx)->PE_RVBARADDR_UP = 0; + } +} + +/* + * Framework handlers + */ +static int scp_platform_mod_init( + fwk_id_t module_id, + unsigned int unused, + const void *data) +{ + const struct mod_scp_platform_config *config; + + config = (struct mod_scp_platform_config *)data; + + if (!fwk_id_type_is_valid(config->timer_id) || + !fwk_id_type_is_valid(config->transport_id)) { + return FWK_E_DATA; + } + + /* Save the config data in the module context */ + scp_platform_ctx.config = config; + + return FWK_SUCCESS; +} + +static int scp_platform_bind(fwk_id_t id, unsigned int round) +{ + int status; + fwk_id_t mod_system_info_api_id_get_info; + + if (round > 0) { + return FWK_SUCCESS; + } + + /* Bind to modules required to handshake with RSE */ + status = platform_rse_bind(scp_platform_ctx.config); + if (status != FWK_SUCCESS) { + return status; + } + + /* Bind to modules required for power management */ + status = platform_power_mgmt_bind(); + if (status != FWK_SUCCESS) { + return status; + } + + mod_system_info_api_id_get_info = + FWK_ID_API(FWK_MODULE_IDX_SYSTEM_INFO, MOD_SYSTEM_INFO_GET_API_IDX); + + /* Bind to System Info HAL API */ + return fwk_module_bind( + fwk_module_id_system_info, + mod_system_info_api_id_get_info, + &scp_platform_ctx.system_info_api); +} + +static int scp_platform_process_bind_request( + fwk_id_t requester_id, + fwk_id_t target_id, + fwk_id_t api_id, + const void **api) +{ + int status; + enum mod_scp_platform_api_idx api_id_type; + + api_id_type = (enum mod_scp_platform_api_idx)fwk_id_get_api_idx(api_id); + + switch (api_id_type) { + case MOD_SCP_PLATFORM_API_IDX_SYSTEM_POWER_DRIVER: + *api = get_platform_system_power_driver_api(); + status = FWK_SUCCESS; + break; + + case MOD_SCP_PLATFORM_API_IDX_TRANSPORT_SIGNAL: + *api = get_platform_transport_signal_api(); + status = FWK_SUCCESS; + break; + + default: + status = FWK_E_PARAM; + } + + return status; +} + +static int scp_platform_start(fwk_id_t id) +{ + int status; + struct fwk_event event = { 0 }; + unsigned int event_count; + + /* Notify RSE that SYSTOP is powered up and wait for RSE doorbell */ + status = notify_rse_and_wait_for_response(); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "Error! SCP-RSE handshake failed"); + return FWK_E_PANIC; + } + + /* SCP subsystem initialization completion notification */ + event.id = mod_scp_platform_notification_subsys_init; + event.source_id = id; + + /* + * RSE has now setup GPC bypass in the system control block. Notify other + * modules that are waiting to access memory regions outside the SCP + * subsystem (which otherwise would have generated a fault). + */ + status = fwk_notification_notify(&event, &event_count); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "Error! Subsystem init notification failed"); + return FWK_E_PANIC; + } + + /* Update L0GPTSZ for all cores */ + platform_update_gpt_size(); + + FWK_LOG_INFO(MOD_NAME "Initializing the primary core..."); + + program_ap_rvbar(); + + status = init_ap_core(0); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "Error! Failed to initialize primary core"); + fwk_trap(); + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_scp_platform = { + .type = FWK_MODULE_TYPE_DRIVER, + .api_count = MOD_SCP_PLATFORM_API_COUNT, + .notification_count = MOD_SCP_PLATFORM_NOTIFICATION_COUNT, + .init = scp_platform_mod_init, + .bind = scp_platform_bind, + .process_bind_request = scp_platform_process_bind_request, + .start = scp_platform_start, +}; diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c new file mode 100644 index 000000000..797f54746 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c @@ -0,0 +1,49 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP Platform Support - Power Management + */ + +#include + +#include + +#include + +#include + +/* System shutdown function */ +static int platform_shutdown(enum mod_pd_system_shutdown system_shutdown) +{ + while (1) { + __WFI(); + } + + return FWK_E_DEVICE; +} + +/* Module 'system_power' driver interface */ +const struct mod_system_power_driver_api platform_system_pwr_drv_api = { + .system_shutdown = platform_shutdown, +}; + +const void *get_platform_system_power_driver_api(void) +{ + return &platform_system_pwr_drv_api; +} + +int platform_power_mgmt_bind(void) +{ + /* To be implemented */ + return FWK_E_HANDLER; +} + +int init_ap_core(uint8_t core_idx) +{ + /* To be implemented */ + return FWK_E_ACCESS; +} diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_rse.c b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_rse.c new file mode 100644 index 000000000..85b529e28 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_rse.c @@ -0,0 +1,140 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * SCP Platform Support - implements support for communication with RSE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* Platform RSE context */ +struct platform_rse_ctx { + /* Pointer to the module config data */ + const struct mod_scp_platform_config *config; + + /* Transport API to send/respond to a message */ + const struct mod_transport_firmware_api *transport_api; + + /* Timer API */ + const struct mod_timer_api *timer_api; + + /* Flag to indicate that the RSE doorbell has been received */ + volatile bool rse_doorbell_received; +}; + +static struct platform_rse_ctx ctx; + +/* Utility function to check if SCP platform has received doorbell from RSE */ +static bool is_rse_doorbell_received(void *unused) +{ + return ctx.rse_doorbell_received; +} + +/* + * Module 'transport' signal interface implementation. + */ +static int signal_error(fwk_id_t unused) +{ + FWK_LOG_ERR(MOD_NAME "Error! Invalid response received from RSE"); + + ctx.transport_api->release_transport_channel_lock(ctx.config->transport_id); + + return FWK_SUCCESS; +} + +static int signal_message(fwk_id_t unused) +{ + FWK_LOG_INFO(MOD_NAME "Received doorbell event from RSE"); + + ctx.transport_api->release_transport_channel_lock(ctx.config->transport_id); + + /* Set the flag to indicate that the RSE initialization is complete */ + ctx.rse_doorbell_received = true; + + return FWK_SUCCESS; +} + +const struct mod_transport_firmware_signal_api platform_transport_signal_api = { + .signal_error = signal_error, + .signal_message = signal_message, +}; + +/* + * Helper function to retrieve the 'transport' module signal API. + */ +const void *get_platform_transport_signal_api(void) +{ + return &platform_transport_signal_api; +} + +/* + * RSE has to be notified that SYSTOP is powered up and so it can enable GPC + * bypass in the system control block. + */ +int notify_rse_and_wait_for_response(void) +{ + int status; + + /* + * Trigger doorbell to RSE to indicate that the SYSTOP domain is ON. + */ + status = ctx.transport_api->trigger_interrupt(ctx.config->transport_id); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME + "Error! Failed to send SYSTOP enabled message to RSE"); + return status; + } + + /* + * Wait till a doorbell from RSE is received. This doorbell event indicates + * that the RSE has initialized the GPC adnd completed the peripheral + * NI-Tower setup. + */ + status = ctx.timer_api->wait( + ctx.config->timer_id, + ctx.config->rse_sync_wait_us, + is_rse_doorbell_received, + NULL); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "Error! No response from RSE for SYSTOP sync"); + } + + return status; +} + +/* + * Bind to timer and transport module to communicate with RSE. + */ +int platform_rse_bind(const struct mod_scp_platform_config *config) +{ + int status; + fwk_id_t timer_api_id; + fwk_id_t transport_api_id; + + ctx.config = config; + + timer_api_id = FWK_ID_API(FWK_MODULE_IDX_TIMER, MOD_TIMER_API_IDX_TIMER); + status = fwk_module_bind(config->timer_id, timer_api_id, &ctx.timer_api); + if (status != FWK_SUCCESS) { + return status; + } + + transport_api_id = + FWK_ID_API(FWK_MODULE_IDX_TRANSPORT, MOD_TRANSPORT_API_IDX_FIRMWARE); + return fwk_module_bind( + config->transport_id, transport_api_id, &ctx.transport_api); +} diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index b8ac8e51c..6e2c45a37 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -24,6 +24,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_scp_platform.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_info.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index c5de17a49..e4021c006 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -29,6 +29,7 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) set(SCP_ENABLE_OUTBAND_MSG_SUPPORT TRUE) list(PREPEND SCP_MODULE_PATHS + "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -48,3 +49,4 @@ list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") list(APPEND SCP_MODULES "system-info") +list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scp_platform.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scp_platform.c new file mode 100644 index 000000000..b2baae48c --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scp_platform.c @@ -0,0 +1,31 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'scp_platform'. + */ + +#include "scp_cfgd_transport.h" + +#include + +#include +#include +#include + +#define RSE_SYNC_WAIT_TIMEOUT_US (800 * 1000) + +static const struct mod_scp_platform_config platform_config_data = { + .timer_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0), + .rse_sync_wait_us = RSE_SYNC_WAIT_TIMEOUT_US, + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM), +}; + +struct fwk_module_config config_scp_platform = { + .data = &platform_config_data, +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c index adb4a0517..7f048fb54 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c @@ -15,6 +15,7 @@ #include "scp_fw_mmap.h" #include +#include #include #include @@ -54,6 +55,28 @@ static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { MOD_MHU3_API_IDX_TRANSPORT_DRIVER), }), }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM] = { + .name = "SCP_PLATFORM_TRANSPORT", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_NONE, + .policies = MOD_TRANSPORT_POLICY_NONE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .signal_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_API_IDX_TRANSPORT_SIGNAL), + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 0), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, [SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT] = { 0 }, }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h index 1fb9b4b2d..3b1dc9f68 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h @@ -15,6 +15,7 @@ /* Module 'transport' element indexes */ enum scp_cfgd_mod_transport_element_idx { SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI, + SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM, SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT, }; -- GitLab From 5bdc1892020f9e8418092c541d597a47c7818da3 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 21:13:49 +0100 Subject: [PATCH 15/43] automotive-rd/rd1ae: Add System Power and Power Domain modules configurations 1- The system power driver manages the SYSTOP power domain. The configuration data includes the system PPU id, system PPU API id, system PPU power state table, system shutdown driver id, system shutdown driver API id and the initial system power state after power-on. 2- Provide the configuration data of all the available power domains to the power domain HAL. The configuration data includes details of all the supported CPU, cluster and the SYSTOP power domain. 3- Given the introduction of the power domain module, complete the initialization of the PL011 configurations structure with the value of the field pd_id. Signed-off-by: Luca Fancellu Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 2 + .../rd1ae/scp_ramfw/Firmware.cmake | 2 + .../rd1ae/scp_ramfw/config_pl011.c | 1 + .../rd1ae/scp_ramfw/config_power_domain.c | 104 ++++++++++++++++++ .../rd1ae/scp_ramfw/config_ppu_v1.c | 17 +++ .../rd1ae/scp_ramfw/config_system_power.c | 93 ++++++++++++++++ .../scp_ramfw/include/scp_cfgd_power_domain.h | 29 +++++ 7 files changed, 248 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_system_power.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_power_domain.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 6e2c45a37..c0cb67b50 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -23,12 +23,14 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scp_platform.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_info.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pll.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_system_power.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_timer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_transport.c") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index e4021c006..414c418ba 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -40,6 +40,8 @@ list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "system-pik") list(APPEND SCP_MODULES "ppu-v1") +list(APPEND SCP_MODULES "system-power") +list(APPEND SCP_MODULES "power-domain") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "gtimer") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c index 9c3749615..7b6373031 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c @@ -26,6 +26,7 @@ static const struct fwk_element pl011_table[MOD_PL011_ELEMENT_COUNT] = { .reg_base = SCP_UART_BASE, .baud_rate_bps = 115200, .clock_rate_hz = 24 * FWK_MHZ, + .pd_id = FWK_ID_NONE_INIT, }, }, { 0 }, diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c b/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c new file mode 100644 index 000000000..d4119cf1e --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c @@ -0,0 +1,104 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'power_domain'. + */ + +#include "platform_core.h" +#include "scp_cfgd_power_domain.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define PD_STATIC_ELEMENT_COUNT (PD_STATIC_DEV_IDX_SYSTOP + 1) + +/* Allowed PD state count */ +#define SYSTOP_PD_STATE_COUNT 1 +#define CLUS_PD_STATE_COUNT 2 +#define CORE_PD_STATE_COUNT 2 + +/* Mask for the cluster valid power states */ +#define CLUSTER_VALID_STATE_MASK (MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK) + +/* Mask for the core valid power states */ +#define CORE_VALID_STATE_MASK (MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK) + +/* Mask of the allowed states for the systop power domain */ +static const uint32_t systop_allowed_state_mask_table[SYSTOP_PD_STATE_COUNT] = { + [0] = MOD_PD_STATE_ON_MASK +}; + +/* + * Mask of the allowed states for the cluster power domain depending on the + * system states. + */ +static const uint32_t + cluster_pd_allowed_state_mask_table[CLUS_PD_STATE_COUNT] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK, + [MOD_PD_STATE_ON] = CLUSTER_VALID_STATE_MASK, + }; + +/* Mask of the allowed states for a core depending on the cluster states. */ +static const uint32_t core_pd_allowed_state_mask_table[CORE_PD_STATE_COUNT] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = CORE_VALID_STATE_MASK, +}; + +/* Power module specific configuration data (none) */ +static const struct mod_power_domain_config platform_power_domain_config = { + 0 +}; + +static struct fwk_element pd_static_element_table[PD_STATIC_ELEMENT_COUNT] = { + [PD_STATIC_DEV_IDX_SYSTOP] = { + .name = "SYSTOP", + .data = &((struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_SYSTEM, + .parent_idx = PD_STATIC_DEV_IDX_NONE, + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SYSTEM_POWER, + MOD_SYSTEM_POWER_API_IDX_PD_DRIVER), + .allowed_state_mask_table = systop_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(systop_allowed_state_mask_table) + }), + }, +}; + +static const struct fwk_element *platform_power_domain_get_element_table( + fwk_id_t module_id) +{ + const struct fwk_element *elements = create_power_domain_element_table( + platform_get_core_count(), + platform_get_cluster_count(), + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER, + core_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table), + cluster_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table), + pd_static_element_table, + FWK_ARRAY_SIZE(pd_static_element_table)); + + return elements; +} + +const struct fwk_module_config config_power_domain = { + .data = &platform_power_domain_config, + .elements = + FWK_MODULE_DYNAMIC_ELEMENTS(platform_power_domain_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c index feef45034..d3ebdc868 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c @@ -9,6 +9,7 @@ */ #include "platform_core.h" +#include "scp_cfgd_power_domain.h" #include "scp_mmap.h" #include @@ -29,6 +30,13 @@ #define PPU_CORE_NAME_SIZE 12 #define PPU_CLUS_NAME_SIZE 7 +/* Module configuration data */ +static struct mod_ppu_v1_config ppu_v1_config_data = { + .pd_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION), +}; + /* List of static PPU elements */ static struct fwk_element ppu_element_table[PPU_STATIC_ELEMENT_COUNT] = { { @@ -132,9 +140,18 @@ static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) ppu_element_table, sizeof(ppu_element_table)); + /* + * Configure pd_source_id with the SYSTOP identifier from the power domain + * module which is dynamically defined based on the number of cores. + */ + ppu_v1_config_data.pd_source_id = fwk_id_build_element_id( + fwk_module_id_power_domain, + core_count + cluster_count + PD_STATIC_DEV_IDX_SYSTOP); + return element_table; } const struct fwk_module_config config_ppu_v1 = { + .data = &ppu_v1_config_data, .elements = FWK_MODULE_DYNAMIC_ELEMENTS(ppu_v1_get_element_table), }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_system_power.c b/product/automotive-rd/rd1ae/scp_ramfw/config_system_power.c new file mode 100644 index 000000000..9457d838c --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_system_power.c @@ -0,0 +1,93 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'system_power'. + */ + +#include "platform_core.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* Indices for system power module elements */ +enum cfgd_mod_system_power_element_idx { + CFGD_MOD_SYSTEM_POWER_EIDX_SYS_PPU, + CFGD_MOD_SYSTEM_POWER_EIDX_COUNT +}; + +/* Module 'system_power' element count */ +#define MOD_SYSTEM_POWER_ELEMENT_COUNT (CFGD_MOD_SYSTEM_POWER_EIDX_COUNT + 1) + +#define SYS_PWR_STATE_TABLE_COUNT (MOD_SYSTEM_POWER_POWER_STATE_SLEEP0 + 1) + +static const uint8_t sys_pwr_state_table[SYS_PWR_STATE_TABLE_COUNT] = { + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_OFF, +}; + +static struct fwk_element element_table[MOD_SYSTEM_POWER_ELEMENT_COUNT] = { + [CFGD_MOD_SYSTEM_POWER_EIDX_SYS_PPU] = { + .name = "SYS-PPU-0", + .data = &((struct mod_system_power_dev_config) { + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .sys_state_table = sys_pwr_state_table, + }), + }, + [CFGD_MOD_SYSTEM_POWER_EIDX_COUNT] = { 0 }, /* Termination description */ +}; + +static const struct fwk_element *system_power_get_element_table(fwk_id_t unused) +{ + unsigned int ppu_idx_base; + unsigned int core_count; + unsigned int cluster_count; + unsigned int i; + + core_count = platform_get_core_count(); + cluster_count = platform_get_cluster_count(); + + /* The system PPUs are placed after the core and cluster PPUs */ + ppu_idx_base = core_count + cluster_count; + + /* Configure System PPU id */ + for (i = 0; i < (FWK_ARRAY_SIZE(element_table) - 1); i++) { + struct mod_system_power_dev_config *dev_config = + (struct mod_system_power_dev_config *)element_table[i].data; + + dev_config->sys_ppu_id = + fwk_id_build_element_id(fwk_module_id_ppu_v1, ppu_idx_base + i); + } + + return element_table; +} + +static struct mod_system_power_config system_power_config = { + .soc_wakeup_irq = FWK_INTERRUPT_NONE, + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .driver_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_API_IDX_SYSTEM_POWER_DRIVER), + .initial_system_power_state = MOD_PD_STATE_ON, +}; + +const struct fwk_module_config config_system_power = { + .data = &system_power_config, + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(system_power_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_power_domain.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_power_domain.h new file mode 100644 index 000000000..4c1a43de1 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_power_domain.h @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for power domain module configuration data in SCP-firmware. + */ + +#ifndef SCP_CFGD_POWER_DOMAIN_H +#define SCP_CFGD_POWER_DOMAIN_H + +#include + +/* + * Power domain indices for the statically defined domains used for: + * - Indexing the domains in the platform_power_domain_static_element_table + * - Indexing the SYSTOP children in the power domain tree + * + * When calculating a power domain element index, use the formula: + * core_count + cluster_count + pd_static_dev_idx + */ +enum pd_static_dev_idx { + PD_STATIC_DEV_IDX_SYSTOP, + PD_STATIC_DEV_IDX_NONE = UINT32_MAX +}; + +#endif /* SCP_CFGD_POWER_DOMAIN_H */ -- GitLab From 167d662fd7892453081f213293d7e79d105bca74 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 3 Jun 2024 14:55:00 +0100 Subject: [PATCH 16/43] automotive-rd/rd1ae: Wire SCP platform module to power-domain module The SCP Platform module used the power-domain module in order to boot the AP cores. Signed-off-by: Luca Fancellu Signed-off-by: Ziad Elhanafy --- .../scp_platform/src/platform_power_mgmt.c | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c index 797f54746..d58b91522 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c @@ -10,12 +10,20 @@ #include +#include #include +#include +#include #include #include +#include + +/* Module 'power_domain' restricted API pointer */ +static struct mod_pd_restricted_api *pd_restricted_api; + /* System shutdown function */ static int platform_shutdown(enum mod_pd_system_shutdown system_shutdown) { @@ -38,12 +46,26 @@ const void *get_platform_system_power_driver_api(void) int platform_power_mgmt_bind(void) { - /* To be implemented */ - return FWK_E_HANDLER; + return fwk_module_bind( + fwk_module_id_power_domain, + mod_pd_api_id_restricted, + &pd_restricted_api); } int init_ap_core(uint8_t core_idx) { - /* To be implemented */ - return FWK_E_ACCESS; + bool resp_requested; + uint32_t pd_state; + fwk_id_t pd_id; + + pd_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, core_idx); + + /* Notification event at the end of request processing is not required */ + resp_requested = false; + + /* Composite Power Domain state to be set for the AP */ + pd_state = MOD_PD_COMPOSITE_STATE( + MOD_PD_LEVEL_2, 0, MOD_PD_STATE_ON, MOD_PD_STATE_ON, MOD_PD_STATE_ON); + + return pd_restricted_api->set_state(pd_id, resp_requested, pd_state); } -- GitLab From f4c3e61385391553c43dc7b04f3c250ed3e2e4df Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 20:17:10 +0100 Subject: [PATCH 17/43] automotive-rd/rd1ae: Add SDS module configurations SDS module is used to pass runtime data from SCP firmware to the AP core firmware using shared memory. Provide the base address, size and the payloads to be passed as configuration data for the SDS module. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_sds.c | 133 ++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_cfgd_sds.h | 63 +++++++++ 4 files changed, 198 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_sds.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index c0cb67b50..3fb167904 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -26,6 +26,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scp_platform.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_sds.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_info.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_system_pik.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 414c418ba..6151f75e7 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -51,4 +51,5 @@ list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") list(APPEND SCP_MODULES "system-info") +list(APPEND SCP_MODULES "sds") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c new file mode 100644 index 000000000..43e48b1d1 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c @@ -0,0 +1,133 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'sds'. + */ + +#include "scp_cfgd_sds.h" +#include "scp_clock.h" +#include "scp_fw_mmap.h" +#include "scp_pwrctrl.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define MOD_SDS_ELEMENT_COUNT (SCP_CFGD_MOD_SDS_EIDX_COUNT + 1) +#define SDS_REGION_COUNT SCP_CFGD_MOD_SDS_REGION_IDX_COUNT + +static const uint32_t version_packed = FWK_BUILD_VERSION; +static const uint32_t feature_flags; + +static const struct mod_sds_region_desc sds_regions[SDS_REGION_COUNT] = { + [SCP_CFGD_MOD_SDS_REGION_IDX_SECURE] = { + .base = (void*)SCP_SDS_SECURE_BASE, + .size = SCP_SDS_SECURE_SIZE, + }, +}; + +static_assert( + FWK_ARRAY_SIZE(sds_regions) == SCP_CFGD_MOD_SDS_REGION_IDX_COUNT, + "Mismatch between number of SDS regions and number of regions " + "provided by the SDS configuration."); + +const struct mod_sds_config sds_module_config = { + .regions = sds_regions, + .region_count = SCP_CFGD_MOD_SDS_REGION_IDX_COUNT, + .clock_id = FWK_ID_NONE_INIT, +}; + +static struct fwk_element sds_element_table[MOD_SDS_ELEMENT_COUNT] = { + [SCP_CFGD_MOD_SDS_EIDX_CPU_INFO] = { + .name = "CPU Info", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_AP_CPU_INFO_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_CPU_INFO_SIZE, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_EIDX_ROM_VERSION] = { + .name = "ROM firmware version", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_ROM_VERSION_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_ROM_VERSION_SIZE, + .payload = &version_packed, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_EIDX_RAM_VERSION] = { + .name = "RAM firmware version", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_RAM_VERSION_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_RAM_VERSION_SIZE, + .payload = &version_packed, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_EIDX_RESET_SYNDROME] = { + .name = "Reset Syndrome", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_RESET_SYNDROME_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_RESET_SYNDROME_SIZE, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_EIDX_FEATURE_AVAILABILITY] = { + .name = "Feature Availability", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_FEATURE_AVAIL_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_FEATURE_AVAILABILITY_SIZE, + .payload = &feature_flags, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID] = { + .name = "Isolated CPU MPID List", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_ISOLATED_CPU_MPID_STRUCT_ID, + .size = SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID_SIZE, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, + [SCP_CFGD_MOD_SDS_EIDX_COUNT] = { 0 }, /* Termination description. */ +}; + +static_assert( + SCP_SDS_SECURE_SIZE > SCP_CFGD_MOD_SDS_CPU_INFO_SIZE + + SCP_CFGD_MOD_SDS_ROM_VERSION_SIZE + + SCP_CFGD_MOD_SDS_RAM_VERSION_SIZE + + SCP_CFGD_MOD_SDS_RESET_SYNDROME_SIZE + + SCP_CFGD_MOD_SDS_FEATURE_AVAILABILITY_SIZE + + SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID_SIZE, + "SDS structures too large for SDS SRAM.\n"); + +static const struct fwk_element *sds_get_element_table(fwk_id_t module_id) +{ + static_assert(BUILD_VERSION_MAJOR < UINT8_MAX, "Invalid version size"); + static_assert(BUILD_VERSION_MINOR < UINT8_MAX, "Invalid version size"); + static_assert(BUILD_VERSION_PATCH < UINT16_MAX, "Invalid version size"); + + return sds_element_table; +} + +struct fwk_module_config config_sds = { + .data = &sds_module_config, + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(sds_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h new file mode 100644 index 000000000..a52df0827 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h @@ -0,0 +1,63 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for SDS module configuration data in SCP firmware. + */ + +#ifndef SCP_CFGD_SDS_H +#define SCP_CFGD_SDS_H + +#include + +#include + +#include + +#define SDS_STRUCT_ID(idx) (idx | 1 << MOD_SDS_ID_VERSION_MAJOR_POS) + +/* SDS structure identifiers. */ +enum scp_cfgd_mod_sds_struct_id { + SDS_AP_CPU_INFO_STRUCT_ID = SDS_STRUCT_ID(1), + SDS_ROM_VERSION_STRUCT_ID = SDS_STRUCT_ID(2), + SDS_RAM_VERSION_STRUCT_ID = SDS_STRUCT_ID(3), + SDS_RESET_SYNDROME_STRUCT_ID = SDS_STRUCT_ID(5), + SDS_FEATURE_AVAIL_STRUCT_ID = SDS_STRUCT_ID(6), + SDS_ISOLATED_CPU_MPID_STRUCT_ID = SDS_STRUCT_ID(128), +}; + +/* Memory region identifiers that hold the SDS structures. */ +enum scp_cfgd_mod_sds_region_idx { + SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + SCP_CFGD_MOD_SDS_REGION_IDX_COUNT, +}; + +/* Module 'sds' element indexes (SDS region descriptors) */ +enum scp_cfgd_mod_sds_element_idx { + SCP_CFGD_MOD_SDS_EIDX_CPU_INFO, + SCP_CFGD_MOD_SDS_EIDX_ROM_VERSION, + SCP_CFGD_MOD_SDS_EIDX_RAM_VERSION, + SCP_CFGD_MOD_SDS_EIDX_RESET_SYNDROME, + SCP_CFGD_MOD_SDS_EIDX_FEATURE_AVAILABILITY, + SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID, + SCP_CFGD_MOD_SDS_EIDX_COUNT +}; + +/* SDS region descriptor structure sizes. */ +#define SCP_CFGD_MOD_SDS_CPU_INFO_SIZE 4 +#define SCP_CFGD_MOD_SDS_ROM_VERSION_SIZE 4 +#define SCP_CFGD_MOD_SDS_RAM_VERSION_SIZE 4 +#define SCP_CFGD_MOD_SDS_RESET_SYNDROME_SIZE 4 +#define SCP_CFGD_MOD_SDS_FEATURE_AVAILABILITY_SIZE 4 + +/* + * Max size of structure listing the MPID of the isolated CPUs. + * size = (Number of CPUs * sizeof MPID register) + sizeof CPU count variable + */ +#define SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID_SIZE \ + ((NUMBER_OF_CLUSTERS * sizeof(uint64_t)) + sizeof(uint64_t)) + +#endif /* SCP_CFGD_SDS_H */ -- GitLab From eee7dfb2b59487d9838b60f3661368ae36bd376e Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 20:45:55 +0100 Subject: [PATCH 18/43] automotive-rd/rd1ae: Add SCMI module configurations SCMI messages for PSCI operations are delivered via a transport channel to a SCMI agent. Add configuration data for SCMI module to setup this interface. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_scmi.c | 68 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_cfgd_scmi.h | 27 ++++++++ 4 files changed, 97 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 3fb167904..6ca57e6fb 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -25,6 +25,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scp_platform.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sds.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 6151f75e7..11a4f194c 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -51,5 +51,6 @@ list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") list(APPEND SCP_MODULES "system-info") +list(APPEND SCP_MODULES "scmi") list(APPEND SCP_MODULES "sds") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c new file mode 100644 index 000000000..920b4d934 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c @@ -0,0 +1,68 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'scmi'. + */ + +#include "scp_cfgd_scmi.h" +#include "scp_cfgd_transport.h" + +#include +#include + +#include +#include +#include +#include +#include + +#define MOD_SCMI_ELEMENT_COUNT (SCP_CFGD_MOD_SCMI_EIDX_COUNT + 1) + +static const struct fwk_element service_table[MOD_SCMI_ELEMENT_COUNT] = { + [SCP_CFGD_MOD_SCMI_EIDX_PSCI] = { + .name = "SERVICE0", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_API_IDX_SCMI_TO_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_NOTIFICATION_IDX_INITIALIZED), + .scmi_agent_id = SCP_SCMI_AGENT_IDX_PSCI, + .scmi_p2a_id = FWK_ID_NONE_INIT, + }), + }, + [SCP_CFGD_MOD_SCMI_EIDX_COUNT] = { 0 } +}; + +static const struct fwk_element *get_service_table(fwk_id_t module_id) +{ + return service_table; +} + +static struct mod_scmi_agent agent_table[SCP_SCMI_AGENT_IDX_COUNT] = { + [SCP_SCMI_AGENT_IDX_PSCI] = { + .type = SCMI_AGENT_TYPE_PSCI, + .name = "PSCI", + }, +}; + +const struct fwk_module_config config_scmi = { + .data = + &(struct mod_scmi_config){ + .protocol_count_max = 4, + .agent_count = FWK_ARRAY_SIZE(agent_table) - 1, + .agent_table = agent_table, + .vendor_identifier = "arm", + .sub_vendor_identifier = "arm", + }, + + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_service_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h new file mode 100644 index 000000000..82775ade6 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h @@ -0,0 +1,27 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Definitions for SCMI module configuration data in SCP firmware. + */ + +#ifndef SCP_CFGD_SCMI_H +#define SCP_CFGD_SCMI_H + +/* SCMI agent identifier indexes in the SCMI agent table */ +enum scp_scmi_agent_idx { + /* 0 is reserved for the platform */ + SCP_SCMI_AGENT_IDX_PSCI = 1, + SCP_SCMI_AGENT_IDX_COUNT, +}; + +/* Module 'scmi' element indexes (SCMI services supported) */ +enum scp_cfgd_mod_scmi_element_idx { + SCP_CFGD_MOD_SCMI_EIDX_PSCI, + SCP_CFGD_MOD_SCMI_EIDX_COUNT, +}; + +#endif /* SCP_CFGD_SCMI_H */ -- GitLab From 4957d3520d093a81cc9faa121c747a42c52b13d5 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 26 Apr 2024 22:04:39 +0100 Subject: [PATCH 19/43] automotive-rd/rd1ae: Add clock HAL module configurations 1- Provide the configuration data for clock HAL which includes the clock driver id, api id and the power domain source for the CPUs and the coherent interconnect clock. 2- Given the introduction of the clock HAL module, complete the initialization of the PL011 configurations structure with the value of the field clock_id. Signed-off-by: Ziad Elhanafy Signed-off-by: Luca Fancellu --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_clock.c | 103 ++++++++++++++++++ .../rd1ae/scp_ramfw/config_pl011.c | 1 + .../rd1ae/scp_ramfw/include/scp_clock.h | 24 ++++ 5 files changed, 130 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_clock.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 6ca57e6fb..817cf2950 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -19,6 +19,7 @@ target_include_directories( target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 11a4f194c..e0cb71648 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -44,6 +44,7 @@ list(APPEND SCP_MODULES "system-power") list(APPEND SCP_MODULES "power-domain") list(APPEND SCP_MODULES "system-pll") list(APPEND SCP_MODULES "pik-clock") +list(APPEND SCP_MODULES "clock") list(APPEND SCP_MODULES "gtimer") list(APPEND SCP_MODULES "timer") list(APPEND SCP_MODULES "mhu3") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_clock.c b/product/automotive-rd/rd1ae/scp_ramfw/config_clock.c new file mode 100644 index 000000000..f67435573 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_clock.c @@ -0,0 +1,103 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'clock'. + */ + +#include "platform_core.h" +#include "scp_cfgd_power_domain.h" +#include "scp_clock.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Module 'clock' element count */ +#define MOD_CLOCK_ELEMENT_COUNT (CFGD_MOD_CLOCK_EIDX_COUNT + 1) + +/* + * Helper macro to instantiate 'clock' module element config data. + */ +#define CFGD_MOD_CLOCK_ELEMENT_CPU(n) \ + [CFGD_MOD_CLOCK_EIDX_CPU##n] = { \ + .name = "CPU" #n, \ + .data = &((struct mod_clock_dev_config){ \ + .driver_id = FWK_ID_ELEMENT_INIT( \ + FWK_MODULE_IDX_PIK_CLOCK, CFGD_MOD_PIK_CLOCK_EIDX_CPU##n), \ + .api_id = FWK_ID_API_INIT( \ + FWK_MODULE_IDX_PIK_CLOCK, MOD_PIK_CLOCK_API_TYPE_CLOCK), \ + .default_on = true, \ + }), \ + } + +/* + * Module 'clock' element configuration data. + */ +static const struct fwk_element clock_dev_table[MOD_CLOCK_ELEMENT_COUNT] = { + CFGD_MOD_CLOCK_ELEMENT_CPU(0), + CFGD_MOD_CLOCK_ELEMENT_CPU(1), + CFGD_MOD_CLOCK_ELEMENT_CPU(2), + CFGD_MOD_CLOCK_ELEMENT_CPU(3), + CFGD_MOD_CLOCK_ELEMENT_CPU(4), + CFGD_MOD_CLOCK_ELEMENT_CPU(5), + CFGD_MOD_CLOCK_ELEMENT_CPU(6), + CFGD_MOD_CLOCK_ELEMENT_CPU(7), + CFGD_MOD_CLOCK_ELEMENT_CPU(8), + CFGD_MOD_CLOCK_ELEMENT_CPU(9), + CFGD_MOD_CLOCK_ELEMENT_CPU(10), + CFGD_MOD_CLOCK_ELEMENT_CPU(11), + CFGD_MOD_CLOCK_ELEMENT_CPU(12), + CFGD_MOD_CLOCK_ELEMENT_CPU(13), + CFGD_MOD_CLOCK_ELEMENT_CPU(14), + CFGD_MOD_CLOCK_ELEMENT_CPU(15), + [CFGD_MOD_CLOCK_EIDX_CMN] = { + .name = "CMN-Cyprus", + .data = &((struct mod_clock_dev_config) { + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, + CFGD_MOD_PIK_CLOCK_EIDX_CMN), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PIK_CLOCK, + MOD_PIK_CLOCK_API_TYPE_CLOCK), + }), + }, + { 0 }, +}; + +static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id) +{ + unsigned int i; + + for (i = 0; i < CFGD_MOD_CLOCK_EIDX_COUNT; i++) { + struct mod_clock_dev_config *dev_config = + (struct mod_clock_dev_config *)clock_dev_table[i].data; + dev_config->pd_source_id = fwk_id_build_element_id( + fwk_module_id_power_domain, + platform_get_core_count() + platform_get_cluster_count() + + PD_STATIC_DEV_IDX_SYSTOP); + } + + return clock_dev_table; +} + +const struct fwk_module_config config_clock = { + .data = + &(struct mod_clock_config){ + .pd_transition_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION), + .pd_pre_transition_notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_POWER_DOMAIN, + MOD_PD_NOTIFICATION_IDX_POWER_STATE_PRE_TRANSITION), + }, + + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_dev_desc_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c index 7b6373031..7b94c4db3 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_pl011.c @@ -26,6 +26,7 @@ static const struct fwk_element pl011_table[MOD_PL011_ELEMENT_COUNT] = { .reg_base = SCP_UART_BASE, .baud_rate_bps = 115200, .clock_rate_hz = 24 * FWK_MHZ, + .clock_id = FWK_ID_NONE_INIT, .pd_id = FWK_ID_NONE_INIT, }, }, diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h index c062a7a2e..7d6c6e1ba 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_clock.h @@ -53,4 +53,28 @@ enum clock_pik_idx { CFGD_MOD_PIK_CLOCK_EIDX_COUNT }; +/* + * Module 'clock' element indexes + */ +enum cfgd_mod_clock_element_idx { + CFGD_MOD_CLOCK_EIDX_CPU0, + CFGD_MOD_CLOCK_EIDX_CPU1, + CFGD_MOD_CLOCK_EIDX_CPU2, + CFGD_MOD_CLOCK_EIDX_CPU3, + CFGD_MOD_CLOCK_EIDX_CPU4, + CFGD_MOD_CLOCK_EIDX_CPU5, + CFGD_MOD_CLOCK_EIDX_CPU6, + CFGD_MOD_CLOCK_EIDX_CPU7, + CFGD_MOD_CLOCK_EIDX_CPU8, + CFGD_MOD_CLOCK_EIDX_CPU9, + CFGD_MOD_CLOCK_EIDX_CPU10, + CFGD_MOD_CLOCK_EIDX_CPU11, + CFGD_MOD_CLOCK_EIDX_CPU12, + CFGD_MOD_CLOCK_EIDX_CPU13, + CFGD_MOD_CLOCK_EIDX_CPU14, + CFGD_MOD_CLOCK_EIDX_CPU15, + CFGD_MOD_CLOCK_EIDX_CMN, + CFGD_MOD_CLOCK_EIDX_COUNT +}; + #endif /* SCP_CLOCK_H */ -- GitLab From b3cb67baa059063debcb6e4d59d127fc472f4ae5 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 26 Apr 2024 22:24:32 +0100 Subject: [PATCH 20/43] automotive-rd/rd1ae: Add CMN Cyprus configurations CMN-Cyprus is the interconnect used in RD1AE platform. Add config data such as base address, memory region map, SNF table and mesh size. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_cmn_cyprus.c | 263 ++++++++++++++++++ .../rd1ae/scp_ramfw/include/cmn_node_id.h | 47 ++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 13 + 5 files changed, 325 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_cmn_cyprus.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/cmn_node_id.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 817cf2950..738c623db 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_cmn_cyprus.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index e0cb71648..4db86ff53 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -47,6 +47,7 @@ list(APPEND SCP_MODULES "pik-clock") list(APPEND SCP_MODULES "clock") list(APPEND SCP_MODULES "gtimer") list(APPEND SCP_MODULES "timer") +list(APPEND SCP_MODULES "cmn-cyprus") list(APPEND SCP_MODULES "mhu3") list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_cmn_cyprus.c b/product/automotive-rd/rd1ae/scp_ramfw/config_cmn_cyprus.c new file mode 100644 index 000000000..fb97bf780 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_cmn_cyprus.c @@ -0,0 +1,263 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'cmn_cyprus'. + */ + +#include "cmn_node_id.h" +#include "scp_exp_mmap.h" +#include "scp_mmap.h" + +#include + +#include +#include +#include +#include + +#include + +#define MMAP_TABLE_COUNT 17 +#define SNF_TABLE_COUNT 32 + +static const unsigned int snf_table[SNF_TABLE_COUNT] = { + MEM_CNTRL0_ID, /* Maps to HN-F logical node 0 */ + MEM_CNTRL0_ID, /* Maps to HN-F logical node 1 */ + MEM_CNTRL0_ID, /* Maps to HN-F logical node 2 */ + MEM_CNTRL0_ID, /* Maps to HN-F logical node 3 */ + MEM_CNTRL1_ID, /* Maps to HN-F logical node 4 */ + MEM_CNTRL1_ID, /* Maps to HN-F logical node 5 */ + MEM_CNTRL1_ID, /* Maps to HN-F logical node 6 */ + MEM_CNTRL1_ID, /* Maps to HN-F logical node 7 */ + MEM_CNTRL2_ID, /* Maps to HN-F logical node 8 */ + MEM_CNTRL2_ID, /* Maps to HN-F logical node 9 */ + MEM_CNTRL2_ID, /* Maps to HN-F logical node 10 */ + MEM_CNTRL2_ID, /* Maps to HN-F logical node 11 */ + MEM_CNTRL3_ID, /* Maps to HN-F logical node 12 */ + MEM_CNTRL3_ID, /* Maps to HN-F logical node 13 */ + MEM_CNTRL3_ID, /* Maps to HN-F logical node 14 */ + MEM_CNTRL3_ID, /* Maps to HN-F logical node 15 */ + MEM_CNTRL4_ID, /* Maps to HN-F logical node 16 */ + MEM_CNTRL4_ID, /* Maps to HN-F logical node 17 */ + MEM_CNTRL4_ID, /* Maps to HN-F logical node 18 */ + MEM_CNTRL4_ID, /* Maps to HN-F logical node 19 */ + MEM_CNTRL5_ID, /* Maps to HN-F logical node 20 */ + MEM_CNTRL5_ID, /* Maps to HN-F logical node 21 */ + MEM_CNTRL5_ID, /* Maps to HN-F logical node 22 */ + MEM_CNTRL5_ID, /* Maps to HN-F logical node 23 */ + MEM_CNTRL6_ID, /* Maps to HN-F logical node 24 */ + MEM_CNTRL6_ID, /* Maps to HN-F logical node 25 */ + MEM_CNTRL6_ID, /* Maps to HN-F logical node 26 */ + MEM_CNTRL6_ID, /* Maps to HN-F logical node 27 */ + MEM_CNTRL7_ID, /* Maps to HN-F logical node 28 */ + MEM_CNTRL7_ID, /* Maps to HN-F logical node 29 */ + MEM_CNTRL7_ID, /* Maps to HN-F logical node 30 */ + MEM_CNTRL7_ID, /* Maps to HN-F logical node 31 */ +}; + +static const struct mod_cmn_cyprus_mem_region_map mmap[MMAP_TABLE_COUNT] = { + { + /* + * System cache backed region + * Map: 0x0000_0000_0000 - 0xFFFF_FFFF_FFFF (256 TiB) + */ + .base = UINT64_C(0x000000000000), + .size = UINT64_C(256) * FWK_TIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_SYSCACHE, + .hns_pos_start = { 0, 0, 0 }, + .hns_pos_end = { MESH_SIZE_X - 1, MESH_SIZE_Y - 1, 1 }, + }, + { + /* + * Shared SRAM + * Map: 0x0000_0000_0000 - 0x0000_07FF_FFFF (128 MB) + */ + .base = UINT64_C(0x000000000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_SYSCACHE_SUB, + .node_id = NODE_ID_SBSX, + }, + { + /* + * Boot Flash + * Map: 0x00_0800_0000 - 0x00_0FFF_FFFF (128 MB) + */ + .base = UINT64_C(0x0008000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HNT1, + }, + { + /* + * Peripherals + * Map: 0x00_1000_0000 - 0x00_2EFF_FFFF (496 MB) + */ + .base = UINT64_C(0x0010000000), + .size = UINT64_C(496) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Shared SRAM + * Map: 0x00_2F00_0000 - 0x00_2F3F_FFFF (4 MB) + */ + .base = UINT64_C(0x002F000000), + .size = UINT64_C(4) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_SYSCACHE_SUB, + .node_id = NODE_ID_SBSX, + }, + { + /* + * Peripherals + * Map: 0x00_2F40_0000 - 0x00_5FFF_FFFF (780 MB) + */ + .base = UINT64_C(0x002F400000), + .size = UINT64_C(780) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * CMN_CYPRUS GPV + * Map: 0x01_0000_0000 - 0x01_3FFF_FFFF (1 GB) + */ + .base = UINT64_C(0x0100000000), + .size = UINT64_C(1) * FWK_GIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Cluster Utility Memory region + * Map: 0x2_0000_0000 - 0x2_3FFF_FFFF (1 GB) + */ + .base = UINT64_C(0x200000000), + .size = UINT64_C(1) * FWK_GIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals - Memory Controller + * Map: 0x2_4000_0000 - 0x2_4FFF_FFFF (256 MB) + */ + .base = UINT64_C(0x240000000), + .size = UINT64_C(256) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Peripherals, NCI GPV Memory Map 0 + * Map: 0x02_8000_0000 - 0x02_87FF_FFFF (128 MB) + */ + .base = UINT64_C(0x0280000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = IOVB_NODE_ID0, + }, + { + /* + * Peripherals, NCI GPV Memory Map 1 + * Map: 0x02_8800_0000 - 0x02_8FFF_FFFF (128 MB) + */ + .base = UINT64_C(0x0288000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = IOVB_NODE_ID1, + }, + { + /* + * Peripherals, NCI GPV Memory Map 2 + * Map: 0x02_9000_0000 - 0x02_97FF_FFFF (128 MB) + */ + .base = UINT64_C(0x0290000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = IOVB_NODE_ID2, + }, + { + /* + * Peripherals, NCI GPV Memory Map 3 + * Map: 0x02_9800_0000 - 0x02_9FFF_FFFF (128 MB) + */ + .base = UINT64_C(0x0298000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = IOVB_NODE_ID3, + }, + { + /* + * Peripherals, NCI GPV Memory Map 4 + * Map: 0x02_A000_0000 - 0x02_A7FF_FFFF (128 MB) + */ + .base = UINT64_C(0x02A0000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = IOVB_NODE_ID4, + }, + { + /* + * GPC_SMMU region + * Map: 0x03_0000_0000 - 0x03_07FF_FFFF (128 MB) + */ + .base = UINT64_C(0x300000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Non Secure NOR Flash 0/1 + * Map: 0x06_0000_0000 - 0x06_07FF_FFFF (128 MB) + */ + .base = UINT64_C(0x0600000000), + .size = UINT64_C(128) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, + { + /* + * Ethernet Controller PL91x + * Map: 0x06_0C00_0000 - 0x06_0FFF_FFFF (64 MB) + */ + .base = UINT64_C(0x060C000000), + .size = UINT64_C(64) * FWK_MIB, + .type = MOD_CMN_CYPRUS_MEM_REGION_TYPE_IO, + .node_id = NODE_ID_HND, + }, +}; + +static struct mod_cmn_cyprus_config cmn_config_table[1] = { + [0] = { + .periphbase = SCP_CMN_BASE, + .mesh_size_x = MESH_SIZE_X, + .mesh_size_y = MESH_SIZE_Y, + .mmap_table = mmap, + .mmap_count = FWK_ARRAY_SIZE(mmap), + .hns_cal_mode = true, + .hnf_sam_config = { + .snf_table = snf_table, + .snf_count = FWK_ARRAY_SIZE(snf_table), + .hnf_sam_mode = MOD_CMN_CYPRUS_HNF_SAM_MODE_DIRECT_MAPPING, + }, + .rnsam_scg_config = { + .scg_hashing_mode = MOD_CMN_CYPRUS_RNSAM_SCG_POWER_OF_TWO_HASHING, + }, + }, +}; + +static struct mod_cmn_cyprus_config_table cmn_config_data = { + .chip_config_data = cmn_config_table, + .chip_count = 1U, + .timer_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_TIMER, 0), +}; + +const struct fwk_module_config config_cmn_cyprus = { + .data = (void *)&cmn_config_data, +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/cmn_node_id.h b/product/automotive-rd/rd1ae/scp_ramfw/include/cmn_node_id.h new file mode 100644 index 000000000..34c389c68 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/cmn_node_id.h @@ -0,0 +1,47 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * CMN node ID. + */ + +#ifndef CMN_NODE_ID +#define CMN_NODE_ID + +/* + * CMN node ids + */ +#define MEM_CNTRL0_ID 64 +#define MEM_CNTRL1_ID 128 +#define MEM_CNTRL2_ID 192 +#define MEM_CNTRL3_ID 256 +#define MEM_CNTRL4_ID 104 +#define MEM_CNTRL5_ID 168 +#define MEM_CNTRL6_ID 232 +#define MEM_CNTRL7_ID 296 + +#define NODE_ID_HND 300 + +#define NODE_ID_HNT0 4 +#define NODE_ID_HNT1 260 +#define NODE_ID_HNT2 44 + +#define NODE_ID_HNP0 324 +#define NODE_ID_HNP2 340 +#define NODE_ID_HNP4 356 + +#define NODE_ID_SBSX 172 + +#define MESH_SIZE_X 7 +#define MESH_SIZE_Y 6 + +#define IOVB_NODE_ID0 NODE_ID_HNP0 +#define IOVB_NODE_ID1 NODE_ID_HNP2 +#define IOVB_NODE_ID2 NODE_ID_HNP4 +#define IOVB_NODE_ID3 NODE_ID_HNT0 +#define IOVB_NODE_ID4 NODE_ID_HNT2 + +#endif /* CMN_NODE_ID */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 58d95d105..0f8e51cec 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -38,6 +38,7 @@ /* SCP addresses mapped via ATU into address translation windows */ #define SCP_ADDRESS_TRANSLATION_WINDOW0_BASE (0x60000000UL) +#define SCP_ADDRESS_TRANSLATION_WINDOW1_BASE (0xA0000000UL) /* * Offsets within SCP's Address Translation Window0 @@ -56,6 +57,15 @@ #define SCP_ATW0_AP_PERIPHERAL_SRAM_BASE \ (SCP_ATW0_CLUSTER_UTILITY_BASE + SCP_ATW0_CLUSTER_UTILITY_SIZE) +/* + * Offsets within SCP's Address Translation Window1 + * __________________________ + * | | + * | CMN 1G | + * |__________________________| 0xA0000000 + */ +#define SCP_ATW1_CMN_BASE (SCP_ADDRESS_TRANSLATION_WINDOW1_BASE) + /* * Size of SCP's view of per-cluster utility memory region. */ @@ -85,4 +95,7 @@ (SCP_ATW0_CLUSTER_UTILITY_BASE + (n * SCP_CLUSTER_UTILITY_SIZE) + \ SCP_CLUSTER_UTILITY_CORE_PPU_OFFSET) +/* CMN config space is mapped in the SCP address translation window 1 */ +#define SCP_CMN_BASE SCP_ATW1_CMN_BASE + #endif /* SCP_MMAP_H */ -- GitLab From 5eb60cbb1e4ce9f548acade0b056ca7de2cc38e0 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 20:04:22 +0100 Subject: [PATCH 21/43] automotive-rd/rd1ae: Add APContext module configurations Provide the configuration data for apcontext module which includes the base address and the size of the memory region to be cleared and the platform notification id that the module should subscribe to. Upon receiving the platform notification, the specified area will be cleared by the apcontext module. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/CMakeLists.txt | 3 ++- .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_apcontext.c | 27 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_fw_mmap.h | 10 +++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 738c623db..0e3841a45 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -18,7 +18,8 @@ target_include_directories( target_sources( rd1ae-bl2 - PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_apcontext.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_cmn_cyprus.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 4db86ff53..c5d68c8e9 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -53,6 +53,7 @@ list(APPEND SCP_MODULES "transport") list(APPEND SCP_MODULES "pcid") list(APPEND SCP_MODULES "sid") list(APPEND SCP_MODULES "system-info") +list(APPEND SCP_MODULES "apcontext") list(APPEND SCP_MODULES "scmi") list(APPEND SCP_MODULES "sds") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c b/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c new file mode 100644 index 000000000..5da0af3e8 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c @@ -0,0 +1,27 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'apcontext'. + */ + +#include "scp_clock.h" +#include "scp_fw_mmap.h" + +#include + +#include +#include + +static const struct mod_apcontext_config apcontext_data = { + .base = SCP_AP_CONTEXT_BASE, + .size = SCP_AP_CONTEXT_SIZE, + .clock_id = FWK_ID_NONE_INIT, +}; + +struct fwk_module_config config_apcontext = { + .data = &apcontext_data, +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h index 454942aec..3f22cb440 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h @@ -20,6 +20,16 @@ /* Secure Shared memory between AP and SCP */ #define SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_BASE \ (SCP_AP_PERIPHERAL_SRAM_TRUSTED_BASE) +#define SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_SIZE (4 * FWK_KIB) + +/* + * AP Context Memory Region inside Secure AP Peripheral SRAM that is shared + * between AP and SCP. + */ +#define SCP_AP_CONTEXT_SIZE (64) +#define SCP_AP_CONTEXT_BASE \ + (SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_BASE + \ + SCP_AP_PERIPHERAL_SRAM_SHARED_SECURE_SIZE - SCP_AP_CONTEXT_SIZE) /* * SDS Memory Region inside Secure AP Peripheral SRAM that is shared between -- GitLab From 9b1d7bfdcc09d0ecb5e40b6ca6ae9511065064a9 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Sun, 28 Apr 2024 20:55:19 +0100 Subject: [PATCH 22/43] automotive-rd/rd1ae: Add SCMI Power Domain module configurations There is no specific configuration data to be supplied to the scmi power domain module. So, leave the config empty. Add SCMI System Power module configurations Provide the configuration data for scmi system power module in scp ramfw to manage system states. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 2 ++ .../rd1ae/scp_ramfw/Firmware.cmake | 2 ++ .../scp_ramfw/config_scmi_power_domain.c | 14 +++++++++++++ .../scp_ramfw/config_scmi_system_power.c | 21 +++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_scmi_power_domain.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 0e3841a45..92b5e3c54 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -29,6 +29,8 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_power_domain.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_system_power.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scp_platform.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sds.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_sid.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index c5d68c8e9..286b5db18 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -56,4 +56,6 @@ list(APPEND SCP_MODULES "system-info") list(APPEND SCP_MODULES "apcontext") list(APPEND SCP_MODULES "scmi") list(APPEND SCP_MODULES "sds") +list(APPEND SCP_MODULES "scmi-power-domain") +list(APPEND SCP_MODULES "scmi-system-power") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_power_domain.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_power_domain.c new file mode 100644 index 000000000..26d40c7f7 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_power_domain.c @@ -0,0 +1,14 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'scmi_power_domain'. + */ + +#include + +/* No elements, no module configuration data */ +struct fwk_module_config config_scmi_power_domain = { 0 }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c new file mode 100644 index 000000000..3abc63db9 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c @@ -0,0 +1,21 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'scmi_system_power'. + */ + +#include +#include + +#include + +const struct fwk_module_config config_scmi_system_power = { + .data = &((struct mod_scmi_system_power_config){ + .system_view = MOD_SCMI_SYSTEM_VIEW_FULL, + .system_suspend_state = MOD_SYSTEM_POWER_POWER_STATE_SLEEP0, + }), +}; -- GitLab From 1bf2dd89139e5c625bc8a141346ff18b56c19fe1 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 08:53:06 +0100 Subject: [PATCH 23/43] automotive-rd/rd1ae: Let modules subscribe to platform notifications Three modules are dependent on the security engine on the platform to setup the GPC in the control block to be enabled so that these modules can access addresses outside the SCP subsystem address space. These three modules are apcontext, sds and transport. So update the config data of these modules to subscribe to the platform notification. Signed-off-by: Ziad Elhanafy --- .../automotive-rd/rd1ae/scp_ramfw/config_apcontext.c | 9 +++++++++ product/automotive-rd/rd1ae/scp_ramfw/config_sds.c | 8 ++++++++ .../automotive-rd/rd1ae/scp_ramfw/config_transport.c | 11 +++++++++++ 3 files changed, 28 insertions(+) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c b/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c index 5da0af3e8..833224195 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_apcontext.c @@ -12,14 +12,23 @@ #include "scp_fw_mmap.h" #include +#include #include #include +#include static const struct mod_apcontext_config apcontext_data = { .base = SCP_AP_CONTEXT_BASE, .size = SCP_AP_CONTEXT_SIZE, .clock_id = FWK_ID_NONE_INIT, + .platform_notification = { + .notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED), + .source_id = FWK_ID_MODULE_INIT( + FWK_MODULE_IDX_SCP_PLATFORM), + }, }; struct fwk_module_config config_apcontext = { diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c index 43e48b1d1..ffd2a38c0 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c @@ -13,6 +13,7 @@ #include "scp_fw_mmap.h" #include "scp_pwrctrl.h" +#include #include #include @@ -46,6 +47,13 @@ const struct mod_sds_config sds_module_config = { .regions = sds_regions, .region_count = SCP_CFGD_MOD_SDS_REGION_IDX_COUNT, .clock_id = FWK_ID_NONE_INIT, + .platform_notification = { + .notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED), + .source_id = FWK_ID_MODULE_INIT( + FWK_MODULE_IDX_SCP_PLATFORM), + }, }; static struct fwk_element sds_element_table[MOD_SDS_ELEMENT_COUNT] = { diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c index 7f048fb54..e97787a5d 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c @@ -32,6 +32,12 @@ #define TRANSPORT_CH_SEC_MBX_INIT \ (MOD_TRANSPORT_POLICY_INIT_MAILBOX | MOD_TRANSPORT_POLICY_SECURE) +/* Subsystem initialized notification id (platform notification) */ +#define PLATFORM_SCP_NOTIFICATION_ID \ + FWK_ID_NOTIFICATION_INIT( \ + FWK_MODULE_IDX_SCP_PLATFORM, \ + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED) + /* Module 'transport' element configuration table */ static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { [SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI] = { @@ -53,6 +59,11 @@ static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { FWK_ID_API_INIT( FWK_MODULE_IDX_MHU3, MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + .platform_notification = { + .notification_id = PLATFORM_SCP_NOTIFICATION_ID, + .source_id = FWK_ID_MODULE_INIT( + FWK_MODULE_IDX_SCP_PLATFORM), + }, }), }, [SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM] = { -- GitLab From f80e5c399b55de549c714b76e03c8e47e172b239 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 09:27:57 +0100 Subject: [PATCH 24/43] automotive-rd/rd1ae: Configure system counter implementation 1- Add a file which defines the impdef register offsets in the system counter register frame. 2- Provide the table of impdef register offsets and its corresponding values in the gtimer module config data. Signed-off-by: Ziad Elhanafy --- .../rd1ae/include/syscnt_impdef.h | 21 +++++++++++++++++++ .../rd1ae/scp_ramfw/CMakeLists.txt | 3 ++- .../rd1ae/scp_ramfw/config_gtimer.c | 18 ++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/include/syscnt_impdef.h diff --git a/product/automotive-rd/rd1ae/include/syscnt_impdef.h b/product/automotive-rd/rd1ae/include/syscnt_impdef.h new file mode 100644 index 000000000..bd17249c0 --- /dev/null +++ b/product/automotive-rd/rd1ae/include/syscnt_impdef.h @@ -0,0 +1,21 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * System counter implementation specific register defnitions. + */ + +#ifndef RD1AE_SYSCNT_IMPDEF_H +#define RD1AE_SYSCNT_IMPDEF_H + +/* + * Offsets of the system counter implementation defined registers found on + * RD1AE. + */ +#define RD1AE_SYSCNT_IMPDEF0_CNTENCR 0xC0U +#define RD1AE_SYSCNT_IMPDEF0_CNTINCR 0xD0U + +#endif /* RD1AE_SYSCNT_IMPDEF_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 92b5e3c54..2768c5fd9 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -14,7 +14,8 @@ add_executable(rd1ae-bl2) target_include_directories( rd1ae-bl2 - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../include") target_sources( rd1ae-bl2 diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c b/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c index 1a2071546..7b3385796 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_gtimer.c @@ -9,11 +9,13 @@ */ #include "scp_mmap.h" +#include "syscnt_impdef.h" #include #include #include +#include #include #include @@ -28,6 +30,20 @@ */ #define SYSCNT_INCR 1 +/* + * System counter implementation defined register config data. + */ +static struct mod_gtimer_syscounter_impdef_config syscnt_impdef_cfg[2] = { + [0] = { + .offset = RD1AE_SYSCNT_IMPDEF0_CNTENCR, + .value = 0, + }, + [1] = { + .offset = RD1AE_SYSCNT_IMPDEF0_CNTINCR, + .value = SYSCNT_INCR, + }, +}; + /* Generic timer driver config */ static const struct fwk_element gtimer_dev_table[MOD_GTIMER_ELEMENT_COUNT] = { [0] = { .name = "REFCLK", @@ -37,6 +53,8 @@ static const struct fwk_element gtimer_dev_table[MOD_GTIMER_ELEMENT_COUNT] = { .control = SCP_REFCLK_CNTCONTROL_BASE, .frequency = (CLOCK_RATE_REFCLK * SYSCNT_INCR), .clock_id = FWK_ID_NONE_INIT, + .syscnt_impdef_cfg = syscnt_impdef_cfg, + .syscnt_impdef_cfg_cnt = FWK_ARRAY_SIZE(syscnt_impdef_cfg), }) }, [1] = { 0 }, }; -- GitLab From 10e9f65c7656f44ffd60a7d3036b928408ef1377 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 13:05:50 +0100 Subject: [PATCH 25/43] automotive-rd/rd1ae: Enable SCMI System Power notifications Enable notifications for the SCMI system power management protocol at the SCP. The SCP utilizes this notification mechanism to inform the management agent about system power state transitions. Signed-off-by: Ziad Elhanafy --- product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake | 2 ++ .../rd1ae/scp_ramfw/config_scmi_system_power.c | 11 +++++++++++ .../rd1ae/scp_ramfw/include/scp_cfgd_timer.h | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 286b5db18..0feb2e31a 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -28,6 +28,8 @@ set(SCP_ENABLE_NEWLIB_NANO FALSE) set(SCP_ENABLE_OUTBAND_MSG_SUPPORT TRUE) +set(SCP_ENABLE_SCMI_NOTIFICATIONS TRUE) + list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c index 3abc63db9..14f5840a0 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi_system_power.c @@ -8,14 +8,25 @@ * Configuration data for module 'scmi_system_power'. */ +#include "scp_cfgd_timer.h" + #include #include +#include #include +#include const struct fwk_module_config config_scmi_system_power = { .data = &((struct mod_scmi_system_power_config){ .system_view = MOD_SCMI_SYSTEM_VIEW_FULL, .system_suspend_state = MOD_SYSTEM_POWER_POWER_STATE_SLEEP0, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + .alarm_id = FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_TIMER, + SCP_ALARM_ELEMENT_IDX, + SCP_CFGD_SCMI_NOTIFICATION_ALARM_IDX), + .graceful_timeout = 1000, /* ms */ +#endif }), }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h index a8ed5a635..3f62fe745 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_timer.h @@ -11,8 +11,13 @@ #ifndef SCP_CFGD_TIMER_H #define SCP_CFGD_TIMER_H +#define SCP_ALARM_ELEMENT_IDX 0 + /* Sub-element indexes (alarms) for SCP timer device */ enum scp_cfgd_mod_timer_alarm_idx { +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + SCP_CFGD_SCMI_NOTIFICATION_ALARM_IDX, +#endif SCP_CFGD_MOD_TIMER_ALARM_IDX_COUNT, }; -- GitLab From 687196fda6bda71163139d9db7a2553d4feb9956 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Thu, 16 May 2024 23:22:42 +0100 Subject: [PATCH 26/43] automotive-rd/rd1ae: Add ATU module configurations Add config data for ATU driver module in scp ramfw. The config data selects 'managed' mode of operation, that is, SCP configures the ATU with required region mappings. The regions that have to be setup at boot as listed in the config data. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 3 + .../rd1ae/scp_ramfw/config_atu.c | 104 ++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 16 +++ 4 files changed, 124 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_atu.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 2768c5fd9..f5eecad0d 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -21,6 +21,7 @@ target_sources( rd1ae-bl2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_apcontext.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_atu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_cmn_cyprus.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 0feb2e31a..6aeae4218 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -30,6 +30,8 @@ set(SCP_ENABLE_OUTBAND_MSG_SUPPORT TRUE) set(SCP_ENABLE_SCMI_NOTIFICATIONS TRUE) +set(SCP_ENABLE_ATU_MANAGE TRUE) + list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -40,6 +42,7 @@ list(PREPEND SCP_MODULE_PATHS # Any change in the order will cause firmware initialization errors. list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") +list(APPEND SCP_MODULES "atu") list(APPEND SCP_MODULES "system-pik") list(APPEND SCP_MODULES "ppu-v1") list(APPEND SCP_MODULES "system-power") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_atu.c b/product/automotive-rd/rd1ae/scp_ramfw/config_atu.c new file mode 100644 index 000000000..2beb4e734 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_atu.c @@ -0,0 +1,104 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'atu'. + */ + +#include "scp_mmap.h" + +#include +#include + +#include +#include +#include +#include +#include + +/* Indices for ATU module elements */ +enum cfgd_mod_atu_element_idx { + CFGD_MOD_ATU_EIDX_ATU0, + CFGD_MOD_ATU_EIDX_COUNT +}; + +#define MOD_ATU_ELEMENT_COUNT (CFGD_MOD_ATU_EIDX_COUNT + 1) + +/* Indices for translation regions to be configured in the ATU */ +enum atu_regions_idx { + /* ATU region to access CMN CFGM */ + ATU_REGION_IDX_CMN = 0, + /* ATU region to access AP Cluster Utility space */ + ATU_REGION_IDX_CLUSTER_UTIL, + /* ATU region to access AP shared SRAM */ + ATU_REGION_IDX_SHARED_SRAM, + /* ATU region to GPC SMMU register space */ + ATU_REGION_IDX_GPC_SMMU, + /* ATU region to RSM SRAM region */ + ATU_REGION_IDX_RSM_SRAM, + /* ATU region count */ + ATU_REGION_IDX_COUNT, +}; + +const struct atu_region_map atu_regions[ATU_REGION_IDX_COUNT] = { + [ATU_REGION_IDX_CMN] = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .log_addr_base = SCP_ATW1_CMN_BASE, + .phy_addr_base = 0x100000000ULL, + .region_size = SCP_ATW1_CMN_SIZE, + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + }, + [ATU_REGION_IDX_CLUSTER_UTIL] = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .log_addr_base = SCP_ATW0_CLUSTER_UTILITY_BASE, + .phy_addr_base = 0x200000000ULL, + .region_size = SCP_ATW0_CLUSTER_UTILITY_SIZE, + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + }, + [ATU_REGION_IDX_SHARED_SRAM] = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .log_addr_base = SCP_ATW0_AP_PERIPHERAL_SRAM_BASE, + .phy_addr_base = 0x00000000ULL, + .region_size = SCP_ATW0_AP_PERIPHERAL_SRAM_SIZE, + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + }, + [ATU_REGION_IDX_GPC_SMMU] = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .log_addr_base = SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_BASE, + .phy_addr_base = 0x300000000ULL, + .region_size = SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE, + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + }, + [ATU_REGION_IDX_RSM_SRAM] = { + .region_owner_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + .log_addr_base = SCP_ATW0_SHARED_SRAM_RSM_BASE, + .phy_addr_base = 0x2F000000ULL, + .region_size = SCP_ATW0_SHARED_SRAM_RSM_SIZE, + .attributes = ATU_ENCODE_ATTRIBUTES_SECURE_PAS, + }, +}; + +static const struct fwk_element element_table[MOD_ATU_ELEMENT_COUNT] = { + [CFGD_MOD_ATU_EIDX_ATU0] = { + .name = "SCP_ATU", + .data = &(struct mod_atu_device_config) { + .is_atu_delegated = false, + .atu_base = SCP_ATU_BASE, + .atu_region_config_table = atu_regions, + .atu_region_count = FWK_ARRAY_SIZE(atu_regions), + }, + }, + [CFGD_MOD_ATU_EIDX_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_element_table(fwk_id_t module_id) +{ + return element_table; +} + +struct fwk_module_config config_atu = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 0f8e51cec..30477b9e7 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -21,6 +21,7 @@ /* SCP sub-system peripherals */ #define SCP_AP2SCP_MHUV3_RCV_S_BASE (0x45030000UL) +#define SCP_ATU_BASE (0x50010000UL) #define SCP_POWER_CONTROL_BASE (0x50000000UL) #define SCP_PPU_SYS0_BASE (0x50041000UL) #define SCP_REFCLK_CNTCONTROL_BASE (0x2A430000UL) @@ -44,6 +45,12 @@ * Offsets within SCP's Address Translation Window0 * __________________________ * | | + * | RSM_SRAM 4M | + * |__________________________| 0x78100000 + * | | + * | GPC_MMU 1M | + * |__________________________| 0x78000000 + * | | * | SHARED SRAM 128M | * |__________________________| 0x70000000 * | | @@ -52,10 +59,18 @@ */ #define SCP_ATW0_CLUSTER_UTILITY_SIZE (256 * FWK_MIB) +#define SCP_ATW0_AP_PERIPHERAL_SRAM_SIZE (128 * FWK_MIB) +#define SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE (1 * FWK_MIB) +#define SCP_ATW0_SHARED_SRAM_RSM_SIZE (4 * FWK_MIB) #define SCP_ATW0_CLUSTER_UTILITY_BASE SCP_ADDRESS_TRANSLATION_WINDOW0_BASE #define SCP_ATW0_AP_PERIPHERAL_SRAM_BASE \ (SCP_ATW0_CLUSTER_UTILITY_BASE + SCP_ATW0_CLUSTER_UTILITY_SIZE) +#define SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_BASE \ + (SCP_ATW0_AP_PERIPHERAL_SRAM_BASE + SCP_ATW0_AP_PERIPHERAL_SRAM_SIZE) +#define SCP_ATW0_SHARED_SRAM_RSM_BASE \ + (SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_BASE + \ + SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE) /* * Offsets within SCP's Address Translation Window1 @@ -65,6 +80,7 @@ * |__________________________| 0xA0000000 */ #define SCP_ATW1_CMN_BASE (SCP_ADDRESS_TRANSLATION_WINDOW1_BASE) +#define SCP_ATW1_CMN_SIZE (1 * FWK_GIB) /* * Size of SCP's view of per-cluster utility memory region. -- GitLab From 93597c3fa60bd97a1c30922a12c4ed54ca926671 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 13:12:53 +0100 Subject: [PATCH 27/43] automotive-rd/rd1ae: Add new SCP-RSE MHU outband channel Add new MHU outband channel between SCP and RSE. This channel will be used by SCP to inform RSE regarding system shutdown and cold reboot. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/config_mhu3.c | 4 +- .../rd1ae/scp_ramfw/config_transport.c | 49 +++++++++++++++++++ .../scp_ramfw/include/scp_cfgd_transport.h | 2 + .../rd1ae/scp_ramfw/include/scp_fw_mmap.h | 4 ++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 6 +++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c index 8eddcaf5a..2daa07f98 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c @@ -34,9 +34,11 @@ struct mod_mhu3_channel_config scp2ap_s_dbch_config[1] = { }; /* SCP<-->RSE Secure MHUv3 Doorbell channel configuration */ -struct mod_mhu3_channel_config scp2rse_s_dbch_config[1] = { +struct mod_mhu3_channel_config scp2rse_s_dbch_config[2] = { /* PBX CH 0, FLAG 0, MBX CH 0, FLAG 0 */ [0] = MOD_MHU3_INIT_DBCH(0, 0, 0, 0), + /* PBX CH 1, FLAG 0, MBX CH 1, FLAG 0, used by scp platform for shutdown */ + [1] = MOD_MHU3_INIT_DBCH(1, 0, 1, 0), }; /* AP<-->SCP Secure MHUv3 doorbell channel count */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c index e97787a5d..b68c26aca 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c @@ -15,6 +15,7 @@ #include "scp_fw_mmap.h" #include +#include #include #include @@ -88,6 +89,54 @@ static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { MOD_MHU3_API_IDX_TRANSPORT_DRIVER), }), }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_SEND] = { + .name = "SCP_PLATFORM_TRANSPORT_POWER_STATE_RSE_SEND", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_OUT_BAND, + .policies = MOD_TRANSPORT_POLICY_INIT_MAILBOX | + MOD_TRANSPORT_POLICY_SECURE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_REQUESTER, + .out_band_mailbox_address = + (uintptr_t) SCP_RSE_TRANSPORT_PAYLOAD_BASE, + .out_band_mailbox_size = SCP_RSE_TRANSPORT_PAYLOAD_SIZE, + .signal_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_SCMI, + MOD_SCMI_API_IDX_TRANSPORT), + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 1), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_RECV] = { + .name = "SCP_PLATFORM_TRANSPORT_POWER_STATE_RSE_RECV", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_OUT_BAND, + .policies = MOD_TRANSPORT_POLICY_INIT_MAILBOX | + MOD_TRANSPORT_POLICY_SECURE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .out_band_mailbox_address = + (uintptr_t) SCP_RSE_TRANSPORT_PAYLOAD_BASE, + .out_band_mailbox_size = SCP_RSE_TRANSPORT_PAYLOAD_SIZE, + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 1), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, [SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT] = { 0 }, }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h index 3b1dc9f68..1d9be255a 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h @@ -16,6 +16,8 @@ enum scp_cfgd_mod_transport_element_idx { SCP_CFGD_MOD_TRANSPORT_EIDX_PSCI, SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM, + SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_SEND, + SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_RECV, SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT, }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h index 3f22cb440..a131d2055 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_fw_mmap.h @@ -42,4 +42,8 @@ #define SCP_SCMI_PAYLOAD_S_A2P_BASE (SCP_SDS_SECURE_BASE + SCP_SDS_SECURE_SIZE) #define SCP_SCMI_PAYLOAD_SIZE (128) +/* Payload Area for SCP-RSE outband message */ +#define SCP_RSE_TRANSPORT_PAYLOAD_BASE (SCP_SHARED_SRAM_RSM_BASE) +#define SCP_RSE_TRANSPORT_PAYLOAD_SIZE (128) + #endif /* SCP_FW_MMAP_H */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 30477b9e7..99f5a9382 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -114,4 +114,10 @@ /* CMN config space is mapped in the SCP address translation window 1 */ #define SCP_CMN_BASE SCP_ATW1_CMN_BASE +/* + * Shared RSM SRAM (shared between RSE and SCP) is mapped by ATU in + * the SCP address translation window 0 at the address 0x7810_0000. + */ +#define SCP_SHARED_SRAM_RSM_BASE (SCP_ATW0_SHARED_SRAM_RSM_BASE) + #endif /* SCP_MMAP_H */ -- GitLab From f1ae04b35998d6601dbeffe4bd9e4ad15d7eb767 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 13:27:26 +0100 Subject: [PATCH 28/43] automotive-rd/rd1ae: Add SCP-RSE SCMI channel Add SCMI channel between SCP and RSE. SCP will use this channel to inform shutdown/reboot request to RSE. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/config_scmi.c | 41 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_cfgd_scmi.h | 5 +++ 2 files changed, 46 insertions(+) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c index 920b4d934..c94196659 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_scmi.c @@ -39,6 +39,42 @@ static const struct fwk_element service_table[MOD_SCMI_ELEMENT_COUNT] = { .scmi_p2a_id = FWK_ID_NONE_INIT, }), }, + [SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_SEND] = { + .name = "SERVICE_RSE_POWER_DOWN_SEND", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_SEND), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_API_IDX_SCMI_TO_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_NOTIFICATION_IDX_INITIALIZED), + .scmi_agent_id = SCP_SCMI_AGENT_IDX_RSE, + .scmi_p2a_id = FWK_ID_NONE_INIT, + }), + }, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + [SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_RECV] = { + .name = "SERVICE_RSE_POWER_DOWN_RECV", + .data = &((struct mod_scmi_service_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_RECV), + .transport_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_API_IDX_SCMI_TO_TRANSPORT), + .transport_notification_init_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_TRANSPORT, + MOD_TRANSPORT_NOTIFICATION_IDX_INITIALIZED), + .scmi_agent_id = SCP_SCMI_AGENT_IDX_RSE, + .scmi_p2a_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_SCMI, + SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_SEND), + }), + }, +#endif [SCP_CFGD_MOD_SCMI_EIDX_COUNT] = { 0 } }; @@ -52,12 +88,17 @@ static struct mod_scmi_agent agent_table[SCP_SCMI_AGENT_IDX_COUNT] = { .type = SCMI_AGENT_TYPE_PSCI, .name = "PSCI", }, + [SCP_SCMI_AGENT_IDX_RSE] = { + .type = SCMI_AGENT_TYPE_MANAGEMENT, + .name = "RSE", + }, }; const struct fwk_module_config config_scmi = { .data = &(struct mod_scmi_config){ .protocol_count_max = 4, + .protocol_requester_count_max = 1, .agent_count = FWK_ARRAY_SIZE(agent_table) - 1, .agent_table = agent_table, .vendor_identifier = "arm", diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h index 82775ade6..f26f71ec7 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h @@ -15,12 +15,17 @@ enum scp_scmi_agent_idx { /* 0 is reserved for the platform */ SCP_SCMI_AGENT_IDX_PSCI = 1, + SCP_SCMI_AGENT_IDX_RSE, SCP_SCMI_AGENT_IDX_COUNT, }; /* Module 'scmi' element indexes (SCMI services supported) */ enum scp_cfgd_mod_scmi_element_idx { SCP_CFGD_MOD_SCMI_EIDX_PSCI, + SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_SEND, +#ifdef BUILD_HAS_SCMI_NOTIFICATIONS + SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_RECV, +#endif SCP_CFGD_MOD_SCMI_EIDX_COUNT, }; -- GitLab From a48aea6228353c5205f504a9a1b318053ec83144 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Fri, 7 Jun 2024 10:17:41 +0100 Subject: [PATCH 29/43] automotive-rd/rd1ae: Add ATU MMIO module configurations ATU MMIO service is used by PCIe setup module to access IO virtualisation block configuration in AP's address space. Add the configuration data for the ATU MMIO module and enable the build for scp_ram firmware. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 3 +- .../rd1ae/scp_ramfw/Firmware.cmake | 1 + .../rd1ae/scp_ramfw/config_atu_mmio.c | 29 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 6 ++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_atu_mmio.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index f5eecad0d..819b49c4b 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -19,7 +19,8 @@ target_include_directories( target_sources( rd1ae-bl2 - PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_apcontext.c" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_atu_mmio.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_apcontext.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_armv7m_mpu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_atu.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 6aeae4218..7ae6dbed1 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -43,6 +43,7 @@ list(PREPEND SCP_MODULE_PATHS list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "atu") +list(APPEND SCP_MODULES "atu-mmio") list(APPEND SCP_MODULES "system-pik") list(APPEND SCP_MODULES "ppu-v1") list(APPEND SCP_MODULES "system-power") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_atu_mmio.c b/product/automotive-rd/rd1ae/scp_ramfw/config_atu_mmio.c new file mode 100644 index 000000000..aec8a480e --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_atu_mmio.c @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'atu_mmio'. + */ + +#include "scp_mmap.h" + +#include +#include + +#include +#include +#include + +static struct mod_atu_mmio_config atu_mmio_module_config = { + .window_address = SCP_ATW0_ATU_MMIO_BASE, + .map_size = SCP_ATW0_ATU_MMIO_SIZE, + .atu_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), + .atu_api_id = FWK_ID_API(FWK_MODULE_IDX_ATU, MOD_ATU_API_IDX_ATU), +}; + +struct fwk_module_config config_atu_mmio = { + .data = &atu_mmio_module_config, +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index 99f5a9382..da31c511d 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -45,6 +45,9 @@ * Offsets within SCP's Address Translation Window0 * __________________________ * | | + * | ATU MMIO (1M) | + * |__________________________| 0x78500000 + * | | * | RSM_SRAM 4M | * |__________________________| 0x78100000 * | | @@ -62,6 +65,7 @@ #define SCP_ATW0_AP_PERIPHERAL_SRAM_SIZE (128 * FWK_MIB) #define SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE (1 * FWK_MIB) #define SCP_ATW0_SHARED_SRAM_RSM_SIZE (4 * FWK_MIB) +#define SCP_ATW0_ATU_MMIO_SIZE (1 * FWK_MIB) #define SCP_ATW0_CLUSTER_UTILITY_BASE SCP_ADDRESS_TRANSLATION_WINDOW0_BASE #define SCP_ATW0_AP_PERIPHERAL_SRAM_BASE \ @@ -71,6 +75,8 @@ #define SCP_ATW0_SHARED_SRAM_RSM_BASE \ (SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_BASE + \ SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE) +#define SCP_ATW0_ATU_MMIO_BASE \ + (SCP_ATW0_SHARED_SRAM_RSM_BASE + SCP_ATW0_SHARED_SRAM_RSM_SIZE) /* * Offsets within SCP's Address Translation Window1 -- GitLab From 58b07e53f1cf5baf2f77d486429b881a366eec31 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 11:50:30 +0100 Subject: [PATCH 30/43] automotive-rd/rd1ae: Add IO block driver This driver acts as an abstraction layer between common IO Block programming logic and driver of the underlying hardware. On RD1AE, IO Block contains NI-Tower, TCU, PCIe and Non PCIe blocks. The NOC S3 is configurable network interconnect unit and connects rest of the blocks to the CMN. This driver defines IO Block layout for RD1AE platform. The layout info is passed through the mapping config info and is used by the module to program a region in NoC. Enable the support to add static memory mappings in NoC and export APIs for runtime configuration. Add a generic interface for IO block drivers. Add IO block interface header for the IO block driver to consume and define its APIs. Signed-off-by: Ziad Elhanafy --- .../rd1ae/interface/io_block/doc/io_block.md | 28 ++ .../interface/io_block/interface_io_block.h | 118 ++++++ .../rd1ae/module/io_block/CMakeLists.txt | 17 + .../rd1ae/module/io_block/Module.cmake | 10 + .../module/io_block/include/mod_io_block.h | 97 +++++ .../rd1ae/module/io_block/src/mod_io_block.c | 371 ++++++++++++++++++ 6 files changed, 641 insertions(+) create mode 100644 product/automotive-rd/rd1ae/interface/io_block/doc/io_block.md create mode 100644 product/automotive-rd/rd1ae/interface/io_block/interface_io_block.h create mode 100644 product/automotive-rd/rd1ae/module/io_block/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/io_block/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/io_block/include/mod_io_block.h create mode 100644 product/automotive-rd/rd1ae/module/io_block/src/mod_io_block.c diff --git a/product/automotive-rd/rd1ae/interface/io_block/doc/io_block.md b/product/automotive-rd/rd1ae/interface/io_block/doc/io_block.md new file mode 100644 index 000000000..0e76beb4e --- /dev/null +++ b/product/automotive-rd/rd1ae/interface/io_block/doc/io_block.md @@ -0,0 +1,28 @@ +# IO Block Interface + +Copyright (c) 2024, Arm Limited. All rights reserved. + +## Overview +The IO Block interface provides a standard API to be implemented by multiple +modules (IO Block drivers). + +This will allow multiple modules to have the same interface. +but having different internal implementations. +i.e. It abstracts the knowledge of the API user from the implementation, + which makes it more flexible and platform-agnostic. + +## Use + To use the IO Block interface it requires to add the include path in the + respective module `CMakeLists.txt` file. + ``` CMAKE + target_include_directories(${SCP_MODULE_TARGET} PUBLIC + "${CMAKE_SOURCE_DIR}/product/automotive-rd/rd1ae/interface/io_block/") + ``` + Then simply include `interface_io_block.h` file to use all IO Block + interface definitions. + +### Example + ```C + /* `api` holds the concrete implementation of the interface. */ + api->map_region(struct interface_io_block_setup_mmap *mmap); + ``` diff --git a/product/automotive-rd/rd1ae/interface/io_block/interface_io_block.h b/product/automotive-rd/rd1ae/interface/io_block/interface_io_block.h new file mode 100644 index 000000000..a0662ea37 --- /dev/null +++ b/product/automotive-rd/rd1ae/interface/io_block/interface_io_block.h @@ -0,0 +1,118 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef INTERFACE_IO_BLOCK +#define INTERFACE_IO_BLOCK + +#include +#include + +/*! + * \addtogroup GroupInterfaces Interfaces + * @{ + */ + +/*! + * \defgroup GroupIoBlock IO Block module interface + * + * \brief Interface definition for IO Block drivers. + * + * \details This provides an generic interface for the modules to bind to a + * platform specific IO Block driver module. + * @{ + */ + +/*! + * \brief List the types of carveouts supported by the IO Blocks. + */ +enum interface_io_block_carveout_type { + /*! IO Block carveout type ECAM. */ + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_ECAM, + /*! IO Block carveout type MMIOL. */ + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_MMIOL, + /*! IO Block carveout type MMIOH. */ + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_MMIOH, + /*! Maximum number of carveouts types. */ + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_MAX, +}; + +/*! + * \brief List the types of access allowed on the mapped carveouts. + */ +enum interface_io_block_access_type { + /*! IO Block Access type Non secure. */ + INTERFACE_IO_BLOCK_ACCESS_TYPE_NS, + /*! IO Block Access type Secure. */ + INTERFACE_IO_BLOCK_ACCESS_TYPE_S, + /*! IO Block Access type Realm. */ + INTERFACE_IO_BLOCK_ACCESS_TYPE_RL, + /*! IO Block Access type Root. */ + INTERFACE_IO_BLOCK_ACCESS_TYPE_RT, + /*! Maximum numbers of access types. */ + INTERFACE_IO_BLOCK_ACCESS_TYPE_MAX +}; + +/*! + * \brief Defines base address and size of carveout. + */ +struct interface_io_block_carveout_info { + /*! Start of the carveout. */ + uint64_t base; + /*! Size of the carveout. */ + uint64_t size; + /*! Carveout type: ECAM, MMIOL, MMIOH. */ + enum interface_io_block_carveout_type carveout_type; + /*! Type of access allowed on the carveout. */ + enum interface_io_block_access_type access_type; + /*! + * Target node id. The rootport node to be programmed when bifurcation mode + * is enabled. + */ + uint16_t target_id; + /*! Index of mapped carveout region. */ + uint8_t region_id; +}; + +struct interface_io_block_setup_mmap { + /*! Base register address for the IO Block. */ + uint64_t io_block_address; + /*! Regions to be mapped in the IO Block. */ + struct interface_io_block_carveout_info *carveout_info; + /*! Number of regions. */ + size_t region_count; + /*! Source node ID. Regions are programmed in source node. */ + uint16_t source_id; +}; + +/*! + * \brief IO Block interface to manage mappings in the NCI block. + */ +struct interface_io_block_memmap_api { + /*! + * \brief Program the given memory carveout in the IO Block. + * + * \param mmap Memory map information of the regions to be mapped in the IO + * Block. + * + * \retval ::FWK_SUCCESS on successfully mapping the region. + * \retval ::FWK_E_DATA if mapping region is invalid. + * \return One of the standard framework status codes. + */ + int (*map_region)(struct interface_io_block_setup_mmap *mmap); + /*! + * \brief Remove the careout mapping from the IO block. + * + * \param mmap Memory map information of the regions mapped in the IO Block. + * + * \retval ::FWK_SUCCESS on successfully mapping the region. + * \retval ::FWK_E_DATA if mapping region is invalid. + * \return One of the standard framework status codes. + */ + int (*unmap_region)(struct interface_io_block_setup_mmap *mmap); +}; + +#endif /* INTERFACE_IO_BLOCK */ diff --git a/product/automotive-rd/rd1ae/module/io_block/CMakeLists.txt b/product/automotive-rd/rd1ae/module/io_block/CMakeLists.txt new file mode 100644 index 000000000..5da6fd554 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/io_block/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + PUBLIC "${CMAKE_SOURCE_DIR}/product/automotive-rd/rd1ae/interface/io_block/" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") + +target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_io_block.c") + +target_link_libraries(${SCP_MODULE_TARGET} PRIVATE module-noc-s3 module-atu) diff --git a/product/automotive-rd/rd1ae/module/io_block/Module.cmake b/product/automotive-rd/rd1ae/module/io_block/Module.cmake new file mode 100644 index 000000000..18e14f890 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/io_block/Module.cmake @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "io-block") + +set(SCP_MODULE_TARGET "module-io-block") diff --git a/product/automotive-rd/rd1ae/module/io_block/include/mod_io_block.h b/product/automotive-rd/rd1ae/module/io_block/include/mod_io_block.h new file mode 100644 index 000000000..4f964aaed --- /dev/null +++ b/product/automotive-rd/rd1ae/module/io_block/include/mod_io_block.h @@ -0,0 +1,97 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * IO Block driver module to define IO block configuration.. + */ + +#ifndef MOD_IO_BLOCK_H +#define MOD_IO_BLOCK_H + +#include + +#include + +#include +#include + +/*! + * \addtogroup GroupModules Modules + * \{ + */ + +/*! + * \ingroup GroupModules Modules + * \defgroup GroupModuleIOBlock IO Block + * + * \brief IO Block module. + * + * \details This module implements IO Block layout for the platform. + * \{ + */ + +/*! + * \brief Module API indices + */ +enum mod_io_block_api_idx { + /*! Interface to configure a region in the target IO block */ + MOD_IO_BLOCK_API_IDX_MAP_REGION, + /*! Total API count */ + MOD_IO_BLOCK_API_IDX_MAX, +}; + +/*! + * \brief Info of each IO block and regions to be programmed in it. + */ +struct mod_io_block_element_config { + /*! Number of mapping for the IO Block */ + uint32_t region_mem_maps_count; + /*! List of the mapping to be done for the IO Block */ + struct interface_io_block_setup_mmap *region_mem_maps; +}; + +/*! + * \brief Used for capturing notification ID and source ID of the platform + * module. + */ +struct mod_io_block_platform_notification { + /*! Identifier of the notification id */ + const fwk_id_t notification_id; + /*! Identifier of the module sending the notification */ + const fwk_id_t source_id; +}; + +/*! + * \brief IO Block module configuration data + */ +struct mod_io_block_config { + /*! NCI module ID */ + fwk_id_t nci_id; + /*! NCI module address mapping API ID */ + fwk_id_t nci_api_id; + /*! ATU module ID */ + fwk_id_t atu_id; + /*! ATU module address mapping API ID */ + fwk_id_t atu_api_id; + /*! Platform notification and source ID */ + struct mod_io_block_platform_notification plat_notification; + /*! + * Logical address used to map 64 bit IO Block register address to a 32 bit + * window + */ + uintptr_t logical_region_base; + /*! size of the region */ + size_t logical_region_size; +}; + +/*! + * \} + */ + +/*! + * \} + */ +#endif /* MOD_IO_BLOCK_H */ diff --git a/product/automotive-rd/rd1ae/module/io_block/src/mod_io_block.c b/product/automotive-rd/rd1ae/module/io_block/src/mod_io_block.c new file mode 100644 index 000000000..bdff7aaf5 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/io_block/src/mod_io_block.c @@ -0,0 +1,371 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * IO Block module. + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MOD_NAME "[IO_BLOCK] " + +/* Module Context */ +struct io_block_context { + /*! IO block module config. */ + const struct mod_io_block_config *config; + /*! IO block element config. */ + const struct mod_io_block_element_config **element_config; + /*! NCI driver map/unmap APIs. */ + struct mod_noc_s3_memmap_api *nci_memmap_api; + /*! ATU map/unmap APIs. */ + struct mod_atu_api *atu_api; +}; + +static struct io_block_context ctx; + +static int map_region_in_nci( + uint64_t base, + uint32_t target_id, + uint32_t source_id, + uint64_t address, + uint64_t size, + uint8_t *region_idx) +{ + struct mod_noc_s3_psam_region psam_regions = { + .target_id = target_id, + .base_address = address, + .size = size, + }; + struct mod_noc_s3_comp_config comp_config = { + .type = MOD_NOC_S3_NODE_TYPE_ASNI, + .id = source_id, + .psam_regions = &psam_regions, + .psam_region_count = 1, + }; + struct mod_noc_s3_dev dev = { + .periphbase = base, + }; + + return ctx.nci_memmap_api->map_region_in_psam( + &dev, &comp_config, region_idx); +} + +static int unmap_region_in_nci( + uint64_t base, + uint32_t source_id, + uint8_t region_idx) +{ + struct mod_noc_s3_dev dev = { + .periphbase = ctx.config->logical_region_base, + }; + struct mod_noc_s3_comp_config comp_config = { + .type = MOD_NOC_S3_NODE_TYPE_ASNI, + .id = source_id, + }; + + return ctx.nci_memmap_api->unmap_region_in_psam( + &dev, &comp_config, region_idx); +} + +static int map_region(struct interface_io_block_setup_mmap *mmap) +{ + struct atu_region_map atu_map = { + .region_owner_id = FWK_ID_MODULE(FWK_MODULE_IDX_IO_BLOCK), + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + .log_addr_base = ctx.config->logical_region_base, + .region_size = ctx.config->logical_region_size, + }; + uint8_t region_idx; + size_t idx; + int status; + + if (mmap == NULL) { + return FWK_E_PARAM; + } + atu_map.phy_addr_base = mmap->io_block_address; + + status = ctx.atu_api->add_region( + &atu_map, FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), ®ion_idx); + if (status != FWK_SUCCESS) { + return status; + } + + for (idx = 0; idx < mmap->region_count; idx++) { + status = map_region_in_nci( + atu_map.log_addr_base, + mmap->carveout_info[idx].target_id, + mmap->source_id, + mmap->carveout_info[idx].base, + mmap->carveout_info[idx].size, + &mmap->carveout_info[idx].region_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + status = ctx.atu_api->remove_region( + region_idx, + FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), + atu_map.region_owner_id); + + return status; +} + +static int unmap_region(struct interface_io_block_setup_mmap *mmap) +{ + struct atu_region_map atu_map = { + .region_owner_id = FWK_ID_MODULE(FWK_MODULE_IDX_IO_BLOCK), + .attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS, + .log_addr_base = ctx.config->logical_region_base, + .region_size = ctx.config->logical_region_size, + }; + uint8_t region_idx; + size_t idx; + int status; + + if (mmap == NULL) { + return FWK_E_PARAM; + } + atu_map.phy_addr_base = mmap->io_block_address; + + status = ctx.atu_api->add_region( + &atu_map, FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), ®ion_idx); + if (status != FWK_SUCCESS) { + return status; + } + + for (idx = 0; idx < mmap->region_count; idx++) { + status = unmap_region_in_nci( + atu_map.log_addr_base, + mmap->source_id, + mmap->carveout_info[idx].region_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + status = ctx.atu_api->remove_region( + region_idx, + FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), + atu_map.region_owner_id); + + return status; +} + +static struct interface_io_block_memmap_api memmap_api = { + .map_region = map_region, + .unmap_region = unmap_region, +}; + +static int map_static_mappings(unsigned int element_idx) +{ + const struct mod_io_block_element_config *element_config; + struct atu_region_map atu_map; + uint32_t mapping_idx; + + atu_map.region_owner_id = FWK_ID_MODULE(FWK_MODULE_IDX_IO_BLOCK); + atu_map.attributes = ATU_ENCODE_ATTRIBUTES_ROOT_PAS; + atu_map.log_addr_base = ctx.config->logical_region_base; + atu_map.region_size = ctx.config->logical_region_size; + + element_config = ctx.element_config[element_idx]; + + for (mapping_idx = 0; mapping_idx < element_config->region_mem_maps_count; + mapping_idx++) { + struct interface_io_block_setup_mmap *mapping; + uint32_t region_idx; + uint8_t atu_region_idx; + uint8_t nci_region_idx; + int status; + + atu_map.phy_addr_base = + element_config->region_mem_maps[mapping_idx].io_block_address; + + status = ctx.atu_api->add_region( + &atu_map, FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), &atu_region_idx); + if (status != FWK_SUCCESS) { + return status; + } + + mapping = &element_config->region_mem_maps[mapping_idx]; + for (region_idx = 0; region_idx < mapping->region_count; region_idx++) { + status = map_region_in_nci( + atu_map.log_addr_base, + mapping->carveout_info[region_idx].target_id, + mapping->source_id, + mapping->carveout_info[region_idx].base, + mapping->carveout_info[region_idx].size, + &nci_region_idx); + if (status != FWK_SUCCESS) { + return status; + } + } + + status = ctx.atu_api->remove_region( + atu_region_idx, + FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), + atu_map.region_owner_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + return FWK_SUCCESS; +} + +/* + * Framework Handlers. + */ +static int mod_io_block_init( + fwk_id_t module_id, + unsigned int element_count, + const void *config) +{ + ctx.config = config; + if (element_count == 0) { + return FWK_SUCCESS; + } + + ctx.element_config = fwk_mm_calloc( + element_count, sizeof(struct mod_io_block_element_config)); + + return FWK_SUCCESS; +} + +static int mod_io_block_element_init( + fwk_id_t element_id, + unsigned int unused, + const void *data) +{ + const struct mod_io_block_element_config *element_config; + + element_config = (struct mod_io_block_element_config *)data; + if ((element_config->region_mem_maps_count == 0) || + (element_config->region_mem_maps == NULL)) { + fwk_unexpected(); + return FWK_E_DATA; + } + + ctx.element_config[fwk_id_get_element_idx(element_id)] = element_config; + + return FWK_SUCCESS; +} + +static int mod_io_block_bind(fwk_id_t id, unsigned int round) +{ + int status; + + status = fwk_module_bind( + ctx.config->atu_id, ctx.config->atu_api_id, &ctx.atu_api); + if (status != FWK_SUCCESS) { + return status; + } + + return fwk_module_bind( + ctx.config->nci_id, ctx.config->nci_api_id, &ctx.nci_memmap_api); +} + +static int mod_io_block_start(fwk_id_t id) +{ + /* Nothing to be done for module start call */ + if (fwk_id_get_type(id) == FWK_ID_TYPE_MODULE) { + return FWK_SUCCESS; + } + + if (fwk_id_type_is_valid(ctx.config->plat_notification.source_id)) { + /* + * Bind to the platform notification that is needed to start module + * configuration. + */ + return fwk_notification_subscribe( + ctx.config->plat_notification.notification_id, + ctx.config->plat_notification.source_id, + id); + } + + return map_static_mappings(fwk_id_get_element_idx(id)); +} + +static int mod_io_block_process_bind_request( + fwk_id_t requester_id, + fwk_id_t id, + fwk_id_t api_id, + const void **api) +{ + int status; + enum mod_io_block_api_idx api_idx; + + status = FWK_SUCCESS; + api_idx = (enum mod_io_block_api_idx)fwk_id_get_api_idx(api_id); + + switch (api_idx) { + case MOD_IO_BLOCK_API_IDX_MAP_REGION: + *api = &memmap_api; + break; + default: + status = FWK_E_PARAM; + break; + }; + + return status; +} + +static int mod_io_block_process_notification( + const struct fwk_event *event, + struct fwk_event *resp_event) +{ + unsigned int element_idx; + int status; + + if (fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)) { + return FWK_E_PARAM; + } + + if (fwk_id_is_equal( + event->id, ctx.config->plat_notification.notification_id)) { + status = fwk_notification_unsubscribe( + event->id, event->source_id, event->target_id); + if (status != FWK_SUCCESS) { + return status; + } + + element_idx = fwk_id_get_element_idx(event->target_id); + status = map_static_mappings(element_idx); + if (status != FWK_SUCCESS) { + return status; + } + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_io_block = { + .type = FWK_MODULE_TYPE_HAL, + .init = mod_io_block_init, + .api_count = MOD_IO_BLOCK_API_IDX_MAX, + .element_init = mod_io_block_element_init, + .bind = mod_io_block_bind, + .start = mod_io_block_start, + .process_bind_request = mod_io_block_process_bind_request, + .process_notification = mod_io_block_process_notification, +}; -- GitLab From af6611f6a7f419b45a573f06cfe01d61df20676a Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 12:16:45 +0100 Subject: [PATCH 31/43] automotive-rd/rd1ae: Enable IO block driver IO block driver represents the layout in which IO virtualisation block is laid out on the platform. This driver is needed to configure PCIe rootport attached to the IO virtualisation block. Add the configuration files for Tower NCI and IO Block modules and enable them for scp_ram firmware. Also enable NoC S3 module as it is a dependency of the IO block module. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/CMakeLists.txt | 2 + .../rd1ae/scp_ramfw/Firmware.cmake | 3 + .../rd1ae/scp_ramfw/config_io_block.c | 86 +++++++++++++++++++ .../rd1ae/scp_ramfw/config_noc_s3.c | 18 ++++ .../rd1ae/scp_ramfw/include/io_macro_layout.h | 75 ++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_mmap.h | 15 ++++ 6 files changed, 199 insertions(+) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_io_block.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_noc_s3.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/io_macro_layout.h diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 819b49c4b..5d5d9cc01 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -26,7 +26,9 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_cmn_cyprus.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_gtimer.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_io_block.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_noc_s3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 7ae6dbed1..308604bbd 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -33,6 +33,7 @@ set(SCP_ENABLE_SCMI_NOTIFICATIONS TRUE) set(SCP_ENABLE_ATU_MANAGE TRUE) list(PREPEND SCP_MODULE_PATHS + "${CMAKE_CURRENT_LIST_DIR}/../module/io_block" "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -43,6 +44,7 @@ list(PREPEND SCP_MODULE_PATHS list(APPEND SCP_MODULES "armv7m-mpu") list(APPEND SCP_MODULES "pl011") list(APPEND SCP_MODULES "atu") +list(APPEND SCP_MODULES "noc-s3") list(APPEND SCP_MODULES "atu-mmio") list(APPEND SCP_MODULES "system-pik") list(APPEND SCP_MODULES "ppu-v1") @@ -64,4 +66,5 @@ list(APPEND SCP_MODULES "scmi") list(APPEND SCP_MODULES "sds") list(APPEND SCP_MODULES "scmi-power-domain") list(APPEND SCP_MODULES "scmi-system-power") +list(APPEND SCP_MODULES "io-block") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_io_block.c b/product/automotive-rd/rd1ae/scp_ramfw/config_io_block.c new file mode 100644 index 000000000..2e18b2840 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_io_block.c @@ -0,0 +1,86 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'io_block'. + */ + +#include "io_macro_layout.h" +#include "scp_fw_mmap.h" +#include "scp_mmap.h" + +#include +#include +#include +#include + +#include +#include +#include + +#define IO_MACRO_ELEMENT_CONFIG(idx) \ + { \ + .name = "IO Macro " #idx, \ + .data = &((struct mod_io_block_element_config){ \ + .region_mem_maps_count = 2, \ + .region_mem_maps = ((struct interface_io_block_setup_mmap[2]){ \ + [0] = { .io_block_address = NCI_GVP_BLOCK_BASE(idx), \ + .source_id = ASNI_CMN, \ + .region_count = 1, \ + .carveout_info = \ + &((struct interface_io_block_carveout_info){ \ + .base = TCU_REG_BASE(idx), \ + .size = TCU_REG_SIZE, \ + .target_id = AMNI_PMNI_TCU_APB, \ + .region_id = 0, \ + }) }, \ + [1] = { .io_block_address = NCI_GVP_BLOCK_BASE(idx), \ + .source_id = ASNI_CMN, \ + .region_count = 1, \ + .carveout_info = \ + &((struct interface_io_block_carveout_info){ \ + .base = CTRL_REG_BASE(idx), \ + .size = CTRL_REG_SIZE, \ + .target_id = AMNI_PMNI_CTRL_REG_APB, \ + .region_id = 0, \ + }) }, \ + }), \ + }) \ + } + +static struct mod_io_block_config io_block_module_config = { + .nci_id = FWK_ID_MODULE(FWK_MODULE_IDX_NOC_S3), + .nci_api_id = + FWK_ID_API(FWK_MODULE_IDX_NOC_S3, MOD_NOC_S3_API_SETUP_PSAM), + .atu_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_ATU, 0), + .atu_api_id = FWK_ID_API(FWK_MODULE_IDX_ATU, MOD_ATU_API_IDX_ATU), + .plat_notification = { + .notification_id = FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_SCP_PLATFORM, + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED), + .source_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SCP_PLATFORM), + }, + .logical_region_base = SCP_ATW0_AP_IO_BLOCK_NCI_BASE, + .logical_region_size = SCP_ATW0_AP_IO_BLOCK_NCI_SIZE +}; + +static const struct fwk_element io_block_element_table[5] = { + [0] = IO_MACRO_ELEMENT_CONFIG(0), + [1] = IO_MACRO_ELEMENT_CONFIG(1), + [2] = IO_MACRO_ELEMENT_CONFIG(2), + [3] = IO_MACRO_ELEMENT_CONFIG(3), + [4] = { 0 }, +}; + +static const struct fwk_element *io_block_get_element_table(fwk_id_t module_id) +{ + return io_block_element_table; +} + +struct fwk_module_config config_io_block = { + .data = &io_block_module_config, + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(io_block_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_noc_s3.c b/product/automotive-rd/rd1ae/scp_ramfw/config_noc_s3.c new file mode 100644 index 000000000..307218ab5 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_noc_s3.c @@ -0,0 +1,18 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'noc_s3'. + */ + +#include + +#include +#include + +struct fwk_module_config config_noc_s3 = { + .elements = FWK_MODULE_STATIC_ELEMENTS({ { 0 } }) +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/io_macro_layout.h b/product/automotive-rd/rd1ae/scp_ramfw/include/io_macro_layout.h new file mode 100644 index 000000000..b9b0cb6f8 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/io_macro_layout.h @@ -0,0 +1,75 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Base address definitions for the SCP's sub-system and access extending + * into the rest of the CSS. + */ + +#ifndef IO_MACRO_LAYOUT +#define IO_MACRO_LAYOUT + +#include "scp_mmap.h" + +/* Calculate the base address of NCI GVP for IO Block using its index. */ +#define NCI_GVP_BLOCK_BASE(idx) \ + (SCP_IO_BLOCK_NCI_GVP_BASE + (idx * SCP_IO_BLOCK_REGISTER_SIZE)) +/* Calculate the base address for the TCU in IO block using IO block's index. */ +#define TCU_REG_BASE(idx) \ + (SCP_IO_BLOCK_BASE + (idx * SCP_IO_BLOCK_REGISTER_SIZE)) +#define TCU_REG_SIZE (0x4000000UL) +/* Calculate the base address of IO control register bank. */ +#define CTRL_REG_BASE(idx) \ + (SCP_IO_BLOCK_CONTROL_REG + (idx * SCP_IO_BLOCK_REGISTER_SIZE)) +#define CTRL_REG_SIZE (0x10000UL) + +enum asni_domain_id { + /*! CMN completer Node ID. */ + ASNI_CMN, + /*! PCIe X1 completer Node ID. */ + ASNI_PCIEX1_0, + /*! PCIe X2_1 completer Node ID. */ + ASNI_PCIEX2_1, + /*! Maximum number of completer Node IDs*/ + ASNI_DOMAIN_MAX_ID +}; + +enum amni_domain_id { + /*! requester Node ID. */ + AMNI_CMN, + /*! Inline IO configuration requester Node ID. */ + AMNI_INLINE_IO_CFG, + /*! Inline IO requester Node ID. */ + AMNI_INLINE_IO, + /*! PCIE x1_0 configurtion requester Node ID. */ + AMNI_PCIEX1_0_CFG, + /*! PCIe x1_0 requester Node ID. */ + AMNI_PCIEX1_0, + /*! PCIE x2_0 configurtion requester Node ID. */ + AMNI_PCIEX2_0_CFG, + /*! PCIe x2_0 requester Node ID. */ + AMNI_PCIEX2_0, + /*! PCIE x2_1 configurtion requester Node ID. */ + AMNI_PCIEX2_1_CFG, + /*! PCIe x2_1 requester Node ID. */ + AMNI_PCIEX2_1, + /*! PCIE x4 configurtion requester Node ID. */ + AMNI_PCIEX4_0_CFG, + /*! PCIe x4 requester Node ID. */ + AMNI_PCIEX4_0, + /*! PCIE x8 configurtion requester Node ID. */ + AMNI_PCIEX8_0_CFG, + /*! PCIe x8 requester Node ID. */ + AMNI_PCIEX8_0, + /*! PMNI Control requester Node ID. */ + AMNI_PMNI_CTRL_REG_APB, + /*! TCU APB requester Node ID. */ + AMNI_PMNI_TCU_APB, + /*! Maximum numbers of requester Node ID. */ + AMNI_DOMAIN_MAX_ID +}; + +#endif /* IO_MACRO_LAYOUT */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h index da31c511d..505301ab2 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_mmap.h @@ -45,6 +45,9 @@ * Offsets within SCP's Address Translation Window0 * __________________________ * | | + * | IO Block NCI 16M | + * |__________________________| 0x78600000 + * | | * | ATU MMIO (1M) | * |__________________________| 0x78500000 * | | @@ -66,6 +69,7 @@ #define SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE (1 * FWK_MIB) #define SCP_ATW0_SHARED_SRAM_RSM_SIZE (4 * FWK_MIB) #define SCP_ATW0_ATU_MMIO_SIZE (1 * FWK_MIB) +#define SCP_ATW0_AP_IO_BLOCK_NCI_SIZE (16 * FWK_MIB) #define SCP_ATW0_CLUSTER_UTILITY_BASE SCP_ADDRESS_TRANSLATION_WINDOW0_BASE #define SCP_ATW0_AP_PERIPHERAL_SRAM_BASE \ @@ -77,6 +81,8 @@ SCP_ATW0_AP_PERIPHERAL_GPC_SMMU_SIZE) #define SCP_ATW0_ATU_MMIO_BASE \ (SCP_ATW0_SHARED_SRAM_RSM_BASE + SCP_ATW0_SHARED_SRAM_RSM_SIZE) +#define SCP_ATW0_AP_IO_BLOCK_NCI_BASE \ + SCP_ATW0_ATU_MMIO_BASE + SCP_ATW0_ATU_MMIO_SIZE /* * Offsets within SCP's Address Translation Window1 @@ -126,4 +132,13 @@ */ #define SCP_SHARED_SRAM_RSM_BASE (SCP_ATW0_SHARED_SRAM_RSM_BASE) +/* Base address of the IO block register bank. */ +#define SCP_IO_BLOCK_BASE (0x280000000UL) +/* Base address of the NCI in the IO block. */ +#define SCP_IO_BLOCK_NCI_GVP_BASE (SCP_IO_BLOCK_BASE + 0x4000000UL) +/* Size of the register bank of IO block. */ +#define SCP_IO_BLOCK_REGISTER_SIZE (0x8000000UL) +/* Base address of th Control register set. */ +#define SCP_IO_BLOCK_CONTROL_REG (SCP_IO_BLOCK_BASE + 0x5B00000UL) + #endif /* SCP_MMAP_H */ -- GitLab From 3a5605bf3f80552e81048dc7e6dfa879ddf856db Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Thu, 9 Dec 2021 23:18:43 +0000 Subject: [PATCH 32/43] automotive-rd/rd1ae: Add support to do device discovery Currently, The ECAM and MMIO (L and H) regions available on platform are divided equally between all of root ports and their configuration values are hardcoded. This is the initial patch to enable dynamic calculation of PCIe ECAM and MMIO (L and H) regions and configuration of the same in CMN. This adds the support to enumerate and calculate the MMIO carveouts size requirement for all the devices present under a given root port. This can further reduce the number of devices that can be attached to the device tree and user may not be able to move the device from one RP to another RP. Signed-off-by: Nishant Sharma Signed-off-by: Ziad Elhanafy --- .../module/pcie_discovery/CMakeLists.txt | 16 + .../rd1ae/module/pcie_discovery/Module.cmake | 9 + .../include/mod_pcie_discovery.h | 112 ++++++ .../pcie_discovery/src/mod_pcie_discovery.c | 341 ++++++++++++++++++ 4 files changed, 478 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/pcie_discovery/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/pcie_discovery/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/pcie_discovery/include/mod_pcie_discovery.h create mode 100644 product/automotive-rd/rd1ae/module/pcie_discovery/src/mod_pcie_discovery.c diff --git a/product/automotive-rd/rd1ae/module/pcie_discovery/CMakeLists.txt b/product/automotive-rd/rd1ae/module/pcie_discovery/CMakeLists.txt new file mode 100644 index 000000000..b7ad3a930 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_discovery/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories( + ${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources( + ${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_pcie_discovery.c") diff --git a/product/automotive-rd/rd1ae/module/pcie_discovery/Module.cmake b/product/automotive-rd/rd1ae/module/pcie_discovery/Module.cmake new file mode 100644 index 000000000..e37e66bb2 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_discovery/Module.cmake @@ -0,0 +1,9 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "pcie_discovery") +set(SCP_MODULE_TARGET "module-pcie_discovery") diff --git a/product/automotive-rd/rd1ae/module/pcie_discovery/include/mod_pcie_discovery.h b/product/automotive-rd/rd1ae/module/pcie_discovery/include/mod_pcie_discovery.h new file mode 100644 index 000000000..faf3987b0 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_discovery/include/mod_pcie_discovery.h @@ -0,0 +1,112 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_PCIE_DISCOVERY_H +#define MOD_PCIE_DISCOVERY_H + +#include + +#include +#include + +/*! + * \brief Module API indices + */ +enum mod_pcie_discovery_api_idx { + /*! + * Interface to calculate ECAM, MMIOL and MMIOH resource size by doing PCIe + * Bus Walk. + */ + MOD_PCIE_DISCOVERY_API_IDX_CALCULATE_RESOURCES, + /*! Total API Count */ + MOD_PCIE_DISCOVERY_API_IDX_MAP +}; + +/*! + * \brief APIs to perform memory read and write operations. + */ +struct pcie_discovery_rw_api { + /*! + * \brief Read a byte from the given memory address + * + * \param addr Memory address + * + * \return byte value read from the memory address + */ + uint8_t (*read8)(uint64_t addr); + + /*! + * \brief Write a byte to the given memory address + * + * \param addr Memory address. + * \param value Byte value to be written. + */ + void (*write8)(uint64_t addr, uint8_t value); + + /*! + * \brief Read a word from the given memory address + * + * \param addr Memory address + * + * \return word value read from the memory address + */ + uint32_t (*read32)(uint64_t addr); + + /*! + * \brief Write a word to the given memory address + * + * \param addr Memory address. + * \param value Word value to be written. + */ + void (*write32)(uint64_t addr, uint32_t value); +}; + +/*! + * Datastructure to capture the size of memory required by all of the devices + * present under the given host bridge. + */ +struct pcie_mmap_size { + /*! ECAM region size */ + uint64_t ecam; + + /*! 32-bit MMIO space start size */ + uint64_t mmiol; + + /*! 64-bit MMIO space size */ + uint64_t mmioh; + + /*! Range of bus numbers consumed by the Root port */ + uint8_t bus; +}; + +struct mod_pcie_discovery_api { + /*! + * \brief Captures the size of memory required by the devices present in the + * tree. + * This does a depth first search, identify the device and then + * capture the memory required by the device in ECAM, MMIOL and MMIOH + * regions. + * + * \param ecam_base_address Base address of RP's ECAM region + * \param mmap_size Placeholder for filling IO memory carveout sizes + * required by all the endpoints under the given RP. + * \param primary_bus_number Starting bus number. + * \param rw_api Customised APIs use to do MMIO transactions in AP memory + * region. NOTE: The default read/write + * APIs are used this is NULL. + * + * \return FWK_E_PARAM If the ecam address and mmap_size are not valid. + * \return FWK_SUCCESS On successful completion. + */ + int (*calculate_resource)( + uint64_t ecam_base_address, + struct pcie_mmap_size *mmap_size, + uint8_t primary_bus_number, + struct pcie_discovery_rw_api *rw_api); +}; + +#endif /* MOD_PCIE_DISCOVERY_H */ diff --git a/product/automotive-rd/rd1ae/module/pcie_discovery/src/mod_pcie_discovery.c b/product/automotive-rd/rd1ae/module/pcie_discovery/src/mod_pcie_discovery.c new file mode 100644 index 000000000..ae12c9c39 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_discovery/src/mod_pcie_discovery.c @@ -0,0 +1,341 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/* PCIe configuration space offset definitions */ +#define PCIE_BAR_OFFSET 0x10 + +#define PCIE_BAR_SIZE 0x4 + +/* + * ECAM space per bus + * 32 devices * 8 functions * 4kB config space = 1MB + */ +#define MAX_ECAM_SPACE_PER_BUS (FWK_MIB) + +/* + * MAX ECAM space + * MAX ECAM space per bus * Max numbers of bus(256) + */ +#define MAX_ECAM_SPACE (256 * MAX_ECAM_SPACE_PER_BUS) + +/* PCIe configuration space offset definitions */ +#define PCIE_HEADER_TYPE_OFFSET 0xE +#define PCIE_PRIMARY_BUS_NUM_OFFSET 0x18 +#define PCIE_SECONDARY_BUS_NUM_OFFSET 0x19 +#define PCIE_SUBORDINATE_BUS_NUM_OFFSET 0x1A + +#define PCIE_HEADER_TYPE_MASK 0x7F +#define PCIE_HEADER_TYPE_ENDPOINT 0 +#define PCIE_HEADER_TYPE_BRIDGE 1 + +/* BDF table offsets for PCIe & CCIX controllers */ +#define PCIE_BDF_TABLE_OFFSET 0 + +/* PCIe standard definitions */ +#define PCIE_BUS_NUM_MAX 0xFF +#define DEVICES_PER_BUS_MAX 32 +#define FUNCTIONS_PER_DEVICE_MAX 8 +#define BRIDGE_BAR_COUNT 2 +#define DEVICE_BAR_COUNT 6 + +#define BDF_ADDR_SHIFT_BUS 20 +#define BDF_ADDR_SHIFT_DEVICE 15 +#define BDF_ADDR_SHIFT_FUNCTION 12 + +#define PCIE_MEM_TYPE_MASK 0x06 +#define PCIE_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCIE_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCIE_MEM_MASK ~(0xFULL) + +#define PCIE_GET_MMIO_SIZE64(BAR) (~(BAR & PCIE_MEM_MASK) + 1) +#define PCIE_GET_MMIO_SIZE32(BAR) (~((uint32_t)(BAR & PCIE_MEM_MASK)) + 1) + +#define PCIE_BRIDGE_MEM_WINDOW_ALIGNMENT (1UL << 20) + +/* Default API to do 1 byte read */ +uint8_t read8(uint64_t addr) +{ + return *((volatile uint8_t *)(uint32_t)addr); +} + +/* Default API to do 1 byte write */ +void write8(uint64_t addr, uint8_t value) +{ + *((volatile uint8_t *)(uint32_t)addr) = value; +} + +/* Default API to do 4 byte read */ +uint32_t read32(uint64_t addr) +{ + return *((volatile uint32_t *)(uint32_t)addr); +} + +/* Default API to do 4 byte write */ +void write32(uint64_t addr, uint32_t value) +{ + *((volatile uint32_t *)(uint32_t)addr) = value; +} + +struct pcie_discovery_rw_api default_rw_api = { + .read8 = read8, + .write8 = write8, + .read32 = read32, + .write32 = write32, +}; + +/* The bridge expects the mmio window address to be 1M align */ +static void align_address_for_bridge_window(struct pcie_mmap_size *mmap_size) +{ + mmap_size->mmiol = + FWK_ALIGN_NEXT(mmap_size->mmiol, PCIE_BRIDGE_MEM_WINDOW_ALIGNMENT); + mmap_size->mmioh = + FWK_ALIGN_NEXT(mmap_size->mmioh, PCIE_BRIDGE_MEM_WINDOW_ALIGNMENT); +} + +/* Program sequence to get the configuration size of a PCIe device */ +static void get_mmio_memory_size( + uint64_t ecam_addr, + struct pcie_mmap_size *mmap_size, + struct pcie_discovery_rw_api *rw_api, + uint8_t num_bar) +{ + uint8_t idx; + uint64_t pcie_bar_addr; + uint64_t mmio_size; + + /* + * Write 0xFFFFFFFF to all the BARs sequentially to get the configuration + * size. + */ + pcie_bar_addr = ecam_addr + PCIE_BAR_OFFSET; + for (idx = 0; idx < num_bar; idx++) { + rw_api->write32(pcie_bar_addr, 0xFFFFFFFF); + pcie_bar_addr += PCIE_BAR_SIZE; + } + + /* + * This section treats IO and Memory address space as Memory address space. + */ + pcie_bar_addr = ecam_addr + PCIE_BAR_OFFSET; + for (idx = 0; idx < num_bar; idx++) { + mmio_size = rw_api->read32(pcie_bar_addr); + if ((mmio_size != 0) && (mmio_size != 0xFFFFFFFF)) { + if ((mmio_size & PCIE_MEM_TYPE_MASK) == PCIE_MEM_TYPE_64) { + /* + * Device supports 64 bit addressing. Increase the counter and + * address and read the next 32 bits of 64 bit mmap size. + */ + idx++; + pcie_bar_addr += PCIE_BAR_SIZE; + mmio_size |= ((uint64_t)(rw_api->read32(pcie_bar_addr))) << 32; + mmio_size = PCIE_GET_MMIO_SIZE64(mmio_size); + mmap_size->mmioh = FWK_ALIGN_NEXT(mmap_size->mmioh, mmio_size); + mmap_size->mmioh += mmio_size; + } else { + /* Device supports 32 bit addressing. */ + mmio_size = PCIE_GET_MMIO_SIZE32(mmio_size); + mmap_size->mmiol = FWK_ALIGN_NEXT(mmap_size->mmiol, mmio_size); + mmap_size->mmiol += mmio_size; + } + } + pcie_bar_addr += PCIE_BAR_SIZE; + } +} + +/* + * Procedure to do PCIe bus walk. This will also calculate the total mmio region + * size required for each root port. + */ +static uint8_t pcie_bus_scan( + uint64_t ecam_addr, + uint8_t pri_bnum, + uint8_t sec_bnum, + struct pcie_mmap_size *mmap_size, + struct pcie_discovery_rw_api *rw_api) +{ + int dev_num; + int fn_num; + uint8_t bar_count; + uint8_t header_type; + uint8_t sub_bnum; + uint32_t df_addr; + uint32_t vid; + uint64_t config_addr; + + sub_bnum = pri_bnum; + /* Loop over all devices on pri_bnum bus */ + for (dev_num = 0; dev_num < DEVICES_PER_BUS_MAX; dev_num++) { + /* Loop over all functions on dev_num device */ + for (fn_num = 0; fn_num < FUNCTIONS_PER_DEVICE_MAX; fn_num++) { + df_addr = (dev_num << BDF_ADDR_SHIFT_DEVICE) | + (fn_num << BDF_ADDR_SHIFT_FUNCTION); + config_addr = ecam_addr + df_addr; + + vid = rw_api->read32(config_addr); + /* If function 0 of any device has invalid VID break the loop */ + if ((vid & 0xFFFF) == 0xFFFF) { + if (fn_num == 0) { + break; + } else { + continue; + } + } + + FWK_LOG_LOCAL( + "[PCIE]: Found device: %d:%d:%d\n", pri_bnum, dev_num, fn_num); + + /* + * Read the header type to identify if the device + * is an endpoint or a PCI-PCI bridge. + */ + header_type = rw_api->read8(config_addr + PCIE_HEADER_TYPE_OFFSET); + if ((header_type & PCIE_HEADER_TYPE_MASK) == + PCIE_HEADER_TYPE_BRIDGE) { + /* + * PCI-PCI bridge is identified. Set primary and secondary bus + * numbers. Let subordinate bus number be max possible bus + * number as we need to further identify devices downstream. + */ + rw_api->write8( + config_addr + PCIE_PRIMARY_BUS_NUM_OFFSET, pri_bnum); + rw_api->write8( + config_addr + PCIE_SECONDARY_BUS_NUM_OFFSET, sec_bnum); + rw_api->write8( + config_addr + PCIE_SUBORDINATE_BUS_NUM_OFFSET, + PCIE_BUS_NUM_MAX); + /* + * Recursively call the scan function with incremented + * primary and secondary bus numbers. + */ + sub_bnum = pcie_bus_scan( + ecam_addr + ((sec_bnum - pri_bnum) << BDF_ADDR_SHIFT_BUS), + sec_bnum, + sec_bnum + 1, + mmap_size, + rw_api); + /* + * The recursive call has returned from an endpoint + * identification so use the returned bus number as the + * bridge's subordinate bus number. + */ + rw_api->write8( + config_addr + PCIE_SUBORDINATE_BUS_NUM_OFFSET, sub_bnum); + sec_bnum = sub_bnum + 1; + bar_count = BRIDGE_BAR_COUNT; + /* Memory carveout under bridge should be 1 MB aligned. */ + align_address_for_bridge_window(mmap_size); + } else { + /* + * Endpoint is identified. Proceed to other functions & + * devices in this bus and return to previous recursive call. + */ + sub_bnum = sec_bnum - 1; + bar_count = DEVICE_BAR_COUNT; + } + get_mmio_memory_size(config_addr, mmap_size, rw_api, bar_count); + } + } + /* Return the subordinate bus number to previous recursive call */ + return sub_bnum; +} + +static int calculate_resource( + uint64_t ecam_base_address, + struct pcie_mmap_size *mmap_size, + uint8_t primary_bus_number, + struct pcie_discovery_rw_api *rw_api) +{ + uint8_t pri_bnum; + uint8_t sec_bnum; + uint8_t sub_bnum; + + if ((ecam_base_address == 0) || (mmap_size == NULL) || + (primary_bus_number == UINT8_MAX)) { + return FWK_E_PARAM; + } + + if (rw_api == NULL) { + if (ecam_base_address > UINT32_MAX) { + return FWK_E_PARAM; + } + + rw_api = &default_rw_api; + } + + pri_bnum = primary_bus_number; + sec_bnum = primary_bus_number + 1; + + sub_bnum = + pcie_bus_scan(ecam_base_address, pri_bnum, sec_bnum, mmap_size, rw_api); + + mmap_size->bus = (sub_bnum - pri_bnum) + 1; + mmap_size->ecam = mmap_size->bus * MAX_ECAM_SPACE_PER_BUS; + + /* + * Linux/EDK2 expects the mmiol size to be minumum size of + * (Number of bus * 1M) + */ + mmap_size->mmiol = FWK_ALIGN_NEXT( + mmap_size->mmiol, mmap_size->bus * MAX_ECAM_SPACE_PER_BUS); + + /* Align for host bridge */ + align_address_for_bridge_window(mmap_size); + + return FWK_SUCCESS; +} + +static int pcie_discovery_init( + fwk_id_t module_id, + unsigned int unused, + const void *unused2) +{ + return FWK_SUCCESS; +} + +static struct mod_pcie_discovery_api pcie_discovery_api = { + .calculate_resource = calculate_resource, +}; + +static int pcie_discovery_process_bind_request( + fwk_id_t requester_id, + fwk_id_t id, + fwk_id_t api_id, + const void **api) +{ + enum mod_pcie_discovery_api_idx api_idx; + + api_idx = (enum mod_pcie_discovery_api_idx)fwk_id_get_api_idx(api_id); + if (api_idx != MOD_PCIE_DISCOVERY_API_IDX_CALCULATE_RESOURCES) { + return FWK_E_PARAM; + } + + *api = &pcie_discovery_api; + return FWK_SUCCESS; +} + +const struct fwk_module module_pcie_discovery = { + .type = FWK_MODULE_TYPE_SERVICE, + .api_count = MOD_PCIE_DISCOVERY_API_IDX_MAP, + .init = pcie_discovery_init, + .process_bind_request = pcie_discovery_process_bind_request, +}; + +const struct fwk_module_config config_pcie_discovery = { 0 }; -- GitLab From 3be8d337ef68847671c6d3eb6c9a86cfb66ee800 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 12:30:34 +0100 Subject: [PATCH 33/43] automotive-rd/rd1ae: Enable IO virtualisation block programming The IO virtualisation block is made up of the SystemMemory Management Unit (SMMU), Tower NCI and Generic Interrupt Controller (GIC) IPs. It provides address translation support for IO devices. This driver enables the support to configure the block dynamically. The driver temporarily maps the entire memory carveout to a block and does PCIe buswalk. During PCIe buswalk, the pcie_enumeration module checks and cputures the resource requirement of each of the PCIe end point. The module then uses this data to calculate and allocate carveout regions for ECAM, MMIOL and MMIOH regions and program/update the same in NCI and CMN. Signed-off-by: Ziad Elhanafy --- .../rd1ae/module/pcie_setup/CMakeLists.txt | 19 + .../rd1ae/module/pcie_setup/Module.cmake | 10 + .../pcie_setup/include/mod_pcie_setup.h | 181 +++++ .../module/pcie_setup/src/mod_pcie_setup.c | 734 ++++++++++++++++++ 4 files changed, 944 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/pcie_setup/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/pcie_setup/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/pcie_setup/include/mod_pcie_setup.h create mode 100644 product/automotive-rd/rd1ae/module/pcie_setup/src/mod_pcie_setup.c diff --git a/product/automotive-rd/rd1ae/module/pcie_setup/CMakeLists.txt b/product/automotive-rd/rd1ae/module/pcie_setup/CMakeLists.txt new file mode 100644 index 000000000..1e25faaed --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_setup/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + PUBLIC "${CMAKE_SOURCE_DIR}/interface/address_remapper/" + PUBLIC "${CMAKE_SOURCE_DIR}/interface/cmn" + PUBLIC "${CMAKE_SOURCE_DIR}/product/automotive-rd/rd1ae/interface/io_block/") + +target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_pcie_setup.c") + +target_link_libraries(${SCP_MODULE_TARGET} + PRIVATE module-system-info module-pcie_discovery module-sds) diff --git a/product/automotive-rd/rd1ae/module/pcie_setup/Module.cmake b/product/automotive-rd/rd1ae/module/pcie_setup/Module.cmake new file mode 100644 index 000000000..c28f8e2b9 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_setup/Module.cmake @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "pcie-setup") + +set(SCP_MODULE_TARGET "module-pcie-setup") diff --git a/product/automotive-rd/rd1ae/module/pcie_setup/include/mod_pcie_setup.h b/product/automotive-rd/rd1ae/module/pcie_setup/include/mod_pcie_setup.h new file mode 100644 index 000000000..2cc72e369 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_setup/include/mod_pcie_setup.h @@ -0,0 +1,181 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Module for configuring PCIe rootports and its memory map. + */ + +#ifndef MOD_PCIE_SETUP_H +#define MOD_PCIE_SETUP_H + +#include +#include + +#include +#include +#include + +/*! + * \brief PCIe setup notification indices. + */ +enum mod_pcie_setup_notification_idx { + /*! PCIe initialisation completed. */ + MOD_PCIE_SETUP_NOTIFICATION_IDX_INITIALISED, + /*! Number of defined notification. */ + MOD_PCIE_SETUP_NOTIFICATION_IDX_COUNT +}; + +/*! + * \brief Defines base address and size of carveout. + */ + +struct mod_pcie_setup_carveout { + /*! Start of the carveout */ + uint64_t start; + /*! Size of the carveout */ + uint64_t size; +}; + +/*! + * \brief Defines regions for ECAM, MMIOL, MMIOH and Bus. + */ +struct mod_pcie_setup_mmap { + struct mod_pcie_setup_carveout ecam; + struct mod_pcie_setup_carveout mmiol; + struct mod_pcie_setup_carveout mmioh; + struct mod_pcie_setup_carveout bus; + uint64_t interrupt_id; +}; + +/*! + * \brief Placeholder to put ECAM, MMIOL, MMIOH and Bus number info for each RP. + */ +struct mod_pcie_setup_block_mmap { + uint64_t id; + uint64_t segment; + uint64_t translation; + uint64_t smmu_base; + uint64_t ep_count; + struct mod_pcie_setup_mmap ep[]; +}; + +/*! + * \brief Placeholder to put information of all the block present on the + * platform. + */ +struct mod_pcie_setup_block_mmap_list { + uint64_t block_count; + uint64_t table_size; + struct mod_pcie_setup_block_mmap blocks[]; +}; + +/*! + * \brief configuration for a single end point and memory map for non io macro. + */ +struct mod_pcie_setup_ep_config { + /*! Valid flag to indicate if the mapping is valid to program */ + bool valid; + /*! Allow non-secure access + * + * By default only secure accesses are allowed. Set this to true to allow + * non-secure access as well. + */ + bool allow_ns_access; + /*! ID of the Root port node. */ + uint8_t rp_node_id; +}; + +/*! + * \brief Configuration information used for programming IO virtualisation + * block. + */ +struct mod_pcie_setup_config { + /*! NCI GVP base */ + uint64_t reg_base; + /*! ID of the node in the CMN mesh configuration */ + unsigned int cmn_node_id; + /*!* ID of the source node in NCI */ + uint8_t nci_source_node_id; + /*!* ID of the Io Virtualization block. */ + uint8_t block_id; + /*! Identifier of the SDS structure to place PCIE mmap info. */ + uint32_t sds_struct_id; + /*! SMMU base address for the block. */ + uint64_t smmu_base; + /*! End point config for RPs */ + struct mod_pcie_setup_ep_config *ep_config; +}; + +/*! + * \brief Platform notification source and notification id + * + * \details On platforms that require platform configuration to access the SDS + * memory regions, the platform notification can be subscribed. This is + * optional for a platform and if provided as module configuration + * data, the configuration will be done only after this notification is + * processed. + */ +struct mod_pcie_setup_platform_notification { + /*! Identifier of the notification id */ + const fwk_id_t notification_id; + + /*! Identifier of the module sending the notification */ + const fwk_id_t source_id; +}; + +/*! + * \brief Module configuration data used for per chip resource allocation. + */ +struct mod_pcie_setup_resource_info { + /*! ID of concrete implementation of CMN interface. */ + fwk_id_t cmn_id; + /*! ID of concrete implementation of IO Block interface. */ + fwk_id_t io_block_id; + /*! ID of concrete implementation of ATU MMIO. */ + fwk_id_t atu_mmio_id; + /*! ID of CMN map_io_region api. */ + fwk_id_t cmn_api_id; + /*! ID of IO Block io_block_setup api. */ + fwk_id_t io_block_api_id; + /*! ID of IO Block ATU MMIO rw api. */ + fwk_id_t atu_mmio_api_id; + /*! Offset added to the address. */ + uint64_t translation; + /*! Bank for allocating carveouts for ECAM, MMIOL and MMIOH. */ + struct mod_pcie_setup_mmap mmap; + /*! Number of endpoints in each IO Block. */ + uint8_t ep_count; + /*! Platform notification source and notification id */ + struct mod_pcie_setup_platform_notification plat_notification; + /*! Structure ID for PCIe configuration info in SDS table. */ + uint32_t sds_struct_id; + /*! List of the interrupt IDs for the end points. */ + uint64_t *ep_interrupt_ids; +}; + +/*! + * \brief Module configuration. + */ +struct mod_pcie_setup_module_config { + /*! Number of resource information configuration. One per chip. */ + size_t resource_info_count; + /*! + * Resource configuration common for all the IO virtualsation blocks in a + * chip. + */ + struct mod_pcie_setup_resource_info *resource_info; +}; + +/*! + * \brief Identifiers for the ::MOD_PCIE_SETUP_NOTIFICATION_IDX_INITIALISED + * notification. + */ +static const fwk_id_t mod_pcie_setup_notification_initialised = + FWK_ID_NOTIFICATION_INIT( + FWK_MODULE_IDX_PCIE_SETUP, + MOD_PCIE_SETUP_NOTIFICATION_IDX_INITIALISED); + +#endif /* MOD_PCIE_SETUP_H */ diff --git a/product/automotive-rd/rd1ae/module/pcie_setup/src/mod_pcie_setup.c b/product/automotive-rd/rd1ae/module/pcie_setup/src/mod_pcie_setup.c new file mode 100644 index 000000000..d2d0e6b0e --- /dev/null +++ b/product/automotive-rd/rd1ae/module/pcie_setup/src/mod_pcie_setup.c @@ -0,0 +1,734 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * RD-1 AE PCIe Setup. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define MOD_NAME "[PCIE_SETUP] " + +struct mod_pcie_setup_context { + /* Pointer to the element configuration pointers (table) */ + struct mod_pcie_setup_config **config; + + /* APIs required to do PCIe bus walk and resource discovery */ + struct mod_pcie_discovery_api *pcie_discovery_api; + + /* Pointer to the module config. */ + const void *module_config; + + /* Pointer to the chip specific module info. */ + struct mod_pcie_setup_resource_info resource_info; + + /* Pointer to system info APIs */ + struct mod_system_info_get_info_api *system_info_api; + + /* Pointer to system info configuration. */ + const struct mod_system_info *system_info; + + /* API to program PCIe memory region in GVP NCI. */ + struct interface_io_block_memmap_api *io_block_memmap_api; + + /* APIs to configure CMN moudle. */ + struct interface_cmn_memmap_rnsam_api *cmn_memmap_rnsam_api; + + /* AP remap Address read write APIs */ + struct interface_address_remapper_rw_api *remapper_rw_api; + + /* APIs to program PCIe memory map configuration info in SDS. */ + struct mod_sds_api *sds_api; + + /* + * Size of block config. This depends on the number of rootport in + * the block. + */ + size_t block_config_size; + + /* Number of IO Blocks . */ + size_t block_count; +}; + +static struct mod_pcie_setup_context pcie_setup_context; + +static int pcie_setup_send_initialised_notification(void) +{ + struct fwk_event notification_event = { 0 }; + unsigned int notification_count; + + notification_event.id = mod_pcie_setup_notification_initialised; + notification_event.source_id = fwk_module_id_pcie_setup; + + FWK_LOG_INFO(MOD_NAME + "Sending PCIe initialisation completion notification."); + return fwk_notification_notify(¬ification_event, ¬ification_count); +} + +static int pcie_setup_update_sds( + struct mod_pcie_setup_block_mmap *block_info, + struct mod_pcie_setup_config *config) +{ + static uint32_t offset = sizeof(struct mod_pcie_setup_block_mmap_list); + static uint64_t count = 0; + static uint64_t table_size = sizeof(struct mod_pcie_setup_block_mmap_list); + size_t block_size; + int status; + + count++; + status = pcie_setup_context.sds_api->struct_write( + config->sds_struct_id, + offsetof(struct mod_pcie_setup_block_mmap_list, block_count), + &count, + sizeof(((struct mod_pcie_setup_block_mmap_list *)0)->block_count)); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR("Block count: SDS Update failed, error:%d", status); + return status; + } + + block_size = sizeof(struct mod_pcie_setup_block_mmap) + + (block_info->ep_count * sizeof(struct mod_pcie_setup_mmap)); + + table_size += block_size; + status = pcie_setup_context.sds_api->struct_write( + config->sds_struct_id, + offsetof(struct mod_pcie_setup_block_mmap_list, table_size), + &table_size, + sizeof(((struct mod_pcie_setup_block_mmap_list *)0)->table_size)); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR("Table Size: SDS Update failed, error:%d", status); + return status; + } + + status = pcie_setup_context.sds_api->struct_write( + config->sds_struct_id, offset, block_info, block_size); + offset += block_size; + if (status != FWK_SUCCESS) { + FWK_LOG_ERR("PCIe Table: SDS Update failed, error:%d", status); + } + + return status; +} + +static void allocate_ecam_address( + struct mod_pcie_setup_mmap *mmap, + struct pcie_mmap_size *mmap_size) +{ + struct mod_pcie_setup_resource_info *res_info; + + res_info = &pcie_setup_context.resource_info; + + if (mmap_size->ecam != 0) { + if (mmap_size->ecam > res_info->mmap.ecam.size) { + FWK_LOG_ERR(MOD_NAME "No memory left to allocate for ECAM"); + fwk_unexpected(); + } + mmap->ecam.start = res_info->mmap.ecam.start; + mmap->ecam.size = mmap_size->ecam; + res_info->mmap.ecam.start += mmap_size->ecam; + res_info->mmap.ecam.size -= mmap_size->ecam; + } else { + /* + * Reset the values to zero to prevent caller from using garbage values. + */ + mmap->ecam.start = 0; + mmap->ecam.size = 0; + } +} + +static void allocate_mmiol_address( + struct mod_pcie_setup_mmap *mmap, + struct pcie_mmap_size *mmap_size) +{ + struct mod_pcie_setup_resource_info *res_info; + + res_info = &pcie_setup_context.resource_info; + + if (mmap_size->mmiol != 0) { + if (mmap_size->mmiol > res_info->mmap.mmiol.size) { + FWK_LOG_ERR(MOD_NAME "No memory left to allocate for MMIOL"); + fwk_unexpected(); + } + mmap->mmiol.start = res_info->mmap.mmiol.start; + mmap->mmiol.size = mmap_size->mmiol; + res_info->mmap.mmiol.start += mmap_size->mmiol; + res_info->mmap.mmiol.size -= mmap_size->mmiol; + } else { + /* + * Reset the values to zero to prevent caller from using garbage values. + */ + mmap->mmiol.start = 0; + mmap->mmiol.size = 0; + } +} + +static void allocate_mmioh_address( + struct mod_pcie_setup_mmap *mmap, + struct pcie_mmap_size *mmap_size) +{ + struct mod_pcie_setup_resource_info *res_info; + + res_info = &pcie_setup_context.resource_info; + + if (mmap_size->mmioh != 0) { + if (mmap_size->mmioh > res_info->mmap.mmioh.size) { + FWK_LOG_ERR(MOD_NAME "No memory left to allocate for MMIOH"); + fwk_unexpected(); + } + mmap->mmioh.start = res_info->mmap.mmioh.start; + mmap->mmioh.size = mmap_size->mmioh; + res_info->mmap.mmioh.start += mmap_size->mmioh; + res_info->mmap.mmioh.size -= mmap_size->mmioh; + } else { + /* + * Reset the values to zero to prevent caller from using garbage values. + */ + mmap->mmioh.start = 0; + mmap->mmioh.size = 0; + } +} + +static void allocate_bus( + struct mod_pcie_setup_mmap *mmap, + struct pcie_mmap_size *mmap_size) +{ + struct mod_pcie_setup_resource_info *res_info; + + res_info = &pcie_setup_context.resource_info; + + if (mmap_size->bus != 0) { + if (mmap_size->bus > res_info->mmap.bus.size) { + FWK_LOG_ERR(MOD_NAME "No bus left to allocate"); + fwk_unexpected(); + } + mmap->bus.start = res_info->mmap.bus.start; + mmap->bus.size = mmap_size->bus; + res_info->mmap.bus.start += mmap_size->bus; + res_info->mmap.bus.size -= mmap_size->bus; + } else { + /* + * Reset the values to zero to prevent caller from using garbage values. + */ + mmap->bus.start = 0; + mmap->bus.size = 0; + } +} + +/* + * This takes in the size required for each of the region and then allocates + * regions for them from platform provided configuration. + */ +static inline void get_address_range( + struct mod_pcie_setup_mmap *mmap, + struct pcie_mmap_size *mmap_size) +{ + allocate_ecam_address(mmap, mmap_size); + allocate_mmiol_address(mmap, mmap_size); + allocate_mmioh_address(mmap, mmap_size); + allocate_bus(mmap, mmap_size); +} + +static int map_region_in_io_block( + enum interface_io_block_carveout_type carveout_type, + struct mod_pcie_setup_config *config, + uint64_t address, + uint64_t size, + uint8_t index, + uint8_t *region) +{ + struct interface_io_block_carveout_info carveout_info = { + .base = address, + .size = size, + .carveout_type = carveout_type, + .target_id = config->ep_config[index].rp_node_id + }; + struct interface_io_block_setup_mmap mmap_info = { + .io_block_address = config->reg_base, + .carveout_info = &carveout_info, + .region_count = 1, + .source_id = config->nci_source_node_id, + }; + int status; + + status = pcie_setup_context.io_block_memmap_api->map_region(&mmap_info); + if (status == FWK_SUCCESS) { + *region = carveout_info.region_id; + } + + return status; +} + +static int unmap_region_in_io_block( + struct mod_pcie_setup_config *config, + uint8_t region) +{ + struct interface_io_block_carveout_info carveout_info = { + .region_id = region, + }; + struct interface_io_block_setup_mmap mmap_info = { + .io_block_address = config->reg_base, + .carveout_info = &carveout_info, + .region_count = 1, + .source_id = config->nci_source_node_id, + }; + int status; + + status = pcie_setup_context.io_block_memmap_api->unmap_region(&mmap_info); + + return status; +} + +static int discover_and_configure_pcie_device( + struct mod_pcie_setup_config *config, + uint8_t index, + struct mod_pcie_setup_mmap *mmap) +{ + struct interface_address_remapper_rw_api *remapper_rw_api; + struct mod_pcie_discovery_api *pcie_discovery_api; + struct mod_pcie_setup_resource_info *res_info; + struct pcie_discovery_rw_api pcie_rw_api; + struct pcie_mmap_size mmap_size = { 0 }; + uint64_t ecam_adjusted_address; + uint8_t region; + int status; + + res_info = &pcie_setup_context.resource_info; + + status = map_region_in_io_block( + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_ECAM, + config, + res_info->mmap.ecam.start, + res_info->mmap.ecam.size, + index, + ®ion); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "NCI mapping failed"); + return status; + } + + remapper_rw_api = pcie_setup_context.remapper_rw_api; + pcie_rw_api.read8 = remapper_rw_api->read8; + pcie_rw_api.write8 = remapper_rw_api->write8; + pcie_rw_api.read32 = remapper_rw_api->read32; + pcie_rw_api.write32 = remapper_rw_api->write32; + + ecam_adjusted_address = res_info->mmap.ecam.start; + + if (res_info->mmap.ecam.start < res_info->translation) { + ecam_adjusted_address += res_info->translation; + } + pcie_discovery_api = pcie_setup_context.pcie_discovery_api; + pcie_discovery_api->calculate_resource( + ecam_adjusted_address - (res_info->mmap.bus.start * FWK_MIB), + &mmap_size, + res_info->mmap.bus.start, + &pcie_rw_api); + get_address_range(mmap, &mmap_size); + + status = unmap_region_in_io_block(config, region); + if (status != FWK_SUCCESS) { + return status; + } + + if (mmap->ecam.size != 0) { + status = map_region_in_io_block( + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_ECAM, + config, + mmap->ecam.start, + mmap->ecam.size, + index, + ®ion); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "ECAM Mapping in NCI failed"); + return status; + } + } + + if (mmap->mmiol.size != 0) { + status = map_region_in_io_block( + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_MMIOL, + config, + mmap->mmiol.start, + mmap->mmiol.size, + index, + ®ion); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "MMIOL Mapping in NCI failed"); + return status; + } + } + + if (mmap->mmioh.size != 0) { + status = map_region_in_io_block( + INTERFACE_IO_BLOCK_CARVEOUT_TYPE_MMIOH, + config, + mmap->mmioh.start, + mmap->mmioh.size, + index, + ®ion); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "MMIOH Mapping in NCI failed"); + return status; + } + } + + return FWK_SUCCESS; +} + +static int configure_pcie_endpoint( + struct mod_pcie_setup_config *config, + struct mod_pcie_setup_block_mmap *block_mmap) +{ + struct interface_cmn_memmap_rnsam_api *cmn_memmap_rnsam_api; + struct mod_pcie_setup_resource_info *res_info; + uint64_t ecam_start; + uint64_t mmiol_start; + uint64_t mmioh_start; + size_t ecam_size; + size_t mmiol_size; + size_t mmioh_size; + uint8_t index; + int status; + + res_info = &pcie_setup_context.resource_info; + + ecam_start = res_info->mmap.ecam.start; + mmiol_start = res_info->mmap.mmiol.start; + mmioh_start = res_info->mmap.mmioh.start; + ecam_size = 0; + mmiol_size = 0; + mmioh_size = 0; + + cmn_memmap_rnsam_api = pcie_setup_context.cmn_memmap_rnsam_api; + status = cmn_memmap_rnsam_api->map_io_region( + res_info->mmap.ecam.start, + res_info->mmap.ecam.size, + config->cmn_node_id); + if (status != FWK_SUCCESS) { + return status; + } + + for (index = 0; index < res_info->ep_count; index++) { + if (config->ep_config[index].valid) { + struct mod_pcie_setup_mmap *ep_mmap = + &block_mmap->ep[block_mmap->ep_count]; + block_mmap->ep_count++; + status = discover_and_configure_pcie_device(config, index, ep_mmap); + if (status != FWK_SUCCESS) { + return status; + } + ecam_size += ep_mmap->ecam.size; + mmiol_size += ep_mmap->mmiol.size; + mmioh_size += ep_mmap->mmioh.size; + ep_mmap->interrupt_id = res_info->ep_interrupt_ids[index]; + block_mmap->segment = pcie_setup_context.system_info->chip_id; + block_mmap->translation = res_info->translation; + block_mmap->smmu_base = config->smmu_base; + } + } + + status = pcie_setup_update_sds(block_mmap, config); + if (status != FWK_SUCCESS) { + return status; + } + + if (ecam_size != 0) { + status = cmn_memmap_rnsam_api->map_io_region( + ecam_start, ecam_size, config->cmn_node_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + if (mmiol_size != 0) { + status = cmn_memmap_rnsam_api->map_io_region( + mmiol_start, mmiol_size, config->cmn_node_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + if (mmioh_size != 0) { + status = cmn_memmap_rnsam_api->map_io_region( + mmioh_start, mmioh_size, config->cmn_node_id); + if (status != FWK_SUCCESS) { + return status; + } + } + + return FWK_SUCCESS; +} + +static int configure_pcie_ecam_mmio_space( + struct mod_pcie_setup_config *config, + unsigned int element) +{ + struct mod_pcie_setup_block_mmap *block_mmap; + unsigned int chip_id; + int status = FWK_SUCCESS; + + FWK_LOG_INFO(MOD_NAME "Configuring PCIe: %d", element); + block_mmap = fwk_mm_calloc(pcie_setup_context.block_config_size, 1); + if (block_mmap == NULL) { + return FWK_E_NOMEM; + } + chip_id = pcie_setup_context.system_info->chip_id; + block_mmap->id = + config->block_id + (chip_id * pcie_setup_context.block_count); + status = configure_pcie_endpoint(config, block_mmap); + fwk_mm_free(block_mmap); + + if (status != FWK_SUCCESS) { + FWK_LOG_ERR(MOD_NAME "PCIe(%d) Setup Failed.", element); + return status; + } + + if (element == (pcie_setup_context.block_count - 1)) { + status = pcie_setup_send_initialised_notification(); + } + + return status; +} + +/* Framework APIs. */ +static int mod_pcie_setup_init( + fwk_id_t module_id, + unsigned int block_count, + const void *data) +{ + const struct mod_pcie_setup_module_config *module_config; + size_t block_config_size; + + module_config = data; + if ((module_config == NULL) || (module_config->resource_info_count == 0)) { + return FWK_E_PARAM; + } + + /* + * Copy first instance of the resource info for binding. + */ + pcie_setup_context.module_config = data; + memcpy( + &pcie_setup_context.resource_info, + module_config->resource_info, + sizeof(pcie_setup_context.resource_info)); + + if (block_count == 0) { + return FWK_SUCCESS; + } + + pcie_setup_context.block_count = block_count; + pcie_setup_context.config = + fwk_mm_calloc(block_count, sizeof(struct mod_pcie_setup_config *)); + if (pcie_setup_context.config == NULL) { + return FWK_E_NOMEM; + } + + block_config_size = sizeof(struct mod_pcie_setup_block_mmap) + + (sizeof(struct mod_pcie_setup_mmap) * + pcie_setup_context.resource_info.ep_count); + pcie_setup_context.block_config_size = block_config_size; + + return FWK_SUCCESS; +} + +static int mod_pcie_setup_element_init( + fwk_id_t element_id, + unsigned int unused, + const void *data) +{ + struct mod_pcie_setup_config *config; + + config = (struct mod_pcie_setup_config *)data; + if ((config == NULL) || (config->reg_base == 0)) { + fwk_unexpected(); + return FWK_E_DATA; + } + + pcie_setup_context.config[fwk_id_get_element_idx(element_id)] = config; + + return FWK_SUCCESS; +} + +static int mod_pcie_setup_bind(fwk_id_t id, unsigned int round) +{ + struct mod_pcie_setup_resource_info *res_info; + int status; + + res_info = &pcie_setup_context.resource_info; + + status = fwk_module_bind( + res_info->atu_mmio_id, + res_info->atu_mmio_api_id, + &pcie_setup_context.remapper_rw_api); + if (status != FWK_SUCCESS) { + return status; + } + + status = fwk_module_bind( + res_info->cmn_id, + res_info->cmn_api_id, + &pcie_setup_context.cmn_memmap_rnsam_api); + if (status != FWK_SUCCESS) { + return status; + } + + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_SYSTEM_INFO), + FWK_ID_API(FWK_MODULE_IDX_SYSTEM_INFO, MOD_SYSTEM_INFO_GET_API_IDX), + &pcie_setup_context.system_info_api); + if (status != FWK_SUCCESS) { + return status; + } + + status = fwk_module_bind( + res_info->io_block_id, + res_info->io_block_api_id, + &pcie_setup_context.io_block_memmap_api); + if (status != FWK_SUCCESS) { + return status; + } + + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_PCIE_DISCOVERY), + FWK_ID_API( + FWK_MODULE_IDX_PCIE_DISCOVERY, + MOD_PCIE_DISCOVERY_API_IDX_CALCULATE_RESOURCES), + &pcie_setup_context.pcie_discovery_api); + if (status != FWK_SUCCESS) { + return status; + } + + if (pcie_setup_context.sds_api == NULL) { + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_SDS), + FWK_ID_API(FWK_MODULE_IDX_SDS, 0), + &pcie_setup_context.sds_api); + if (status != FWK_SUCCESS) { + return status; + } + } + + return status; +} + +static int mod_pcie_setup_start(fwk_id_t id) +{ + struct mod_pcie_setup_resource_info *res_info; + unsigned int element; + int status; + + if (fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) { + const struct mod_pcie_setup_module_config *module_config; + unsigned int chip_id; + + status = pcie_setup_context.system_info_api->get_system_info( + &pcie_setup_context.system_info); + if (status != FWK_SUCCESS) { + return status; + } + + chip_id = pcie_setup_context.system_info->chip_id; + module_config = pcie_setup_context.module_config; + if (chip_id >= module_config->resource_info_count) { + FWK_LOG_ERR(MOD_NAME "Module configuration not valid."); + return FWK_E_PARAM; + } + + memcpy( + &pcie_setup_context.resource_info, + &module_config->resource_info[chip_id], + sizeof(pcie_setup_context.resource_info)); + + return FWK_SUCCESS; + } + + fwk_assert(fwk_module_is_valid_element_id(id)); + + element = fwk_id_get_element_idx(id); + + res_info = &pcie_setup_context.resource_info; + + if (fwk_id_type_is_valid(res_info->plat_notification.source_id)) { + /* Bind to the platform notification that is needed to start module + * configuration. */ + status = fwk_notification_subscribe( + res_info->plat_notification.notification_id, + res_info->plat_notification.source_id, + id); + } else { + struct mod_pcie_setup_config *config; + config = pcie_setup_context.config[element]; + status = configure_pcie_ecam_mmio_space(config, element); + } + + return status; +} + +static int mod_pcie_setup_process_notification( + const struct fwk_event *event, + struct fwk_event *resp_event) +{ + struct mod_pcie_setup_resource_info *res_info; + struct mod_pcie_setup_config *config; + + fwk_assert(!fwk_id_is_type(event->target_id, FWK_ID_TYPE_MODULE)); + + res_info = &pcie_setup_context.resource_info; + if (fwk_id_is_equal( + event->id, res_info->plat_notification.notification_id)) { + unsigned int element; + int status; + + status = fwk_notification_unsubscribe( + event->id, event->source_id, event->target_id); + if (status != FWK_SUCCESS) { + return status; + } + + element = fwk_id_get_element_idx(event->target_id); + config = pcie_setup_context.config[element]; + status = configure_pcie_ecam_mmio_space(config, element); + if (status != FWK_SUCCESS) { + return status; + } + } + + return FWK_SUCCESS; +} + +const struct fwk_module module_pcie_setup = { + .type = FWK_MODULE_TYPE_DRIVER, + .init = mod_pcie_setup_init, + .element_init = mod_pcie_setup_element_init, + .bind = mod_pcie_setup_bind, + .start = mod_pcie_setup_start, + .notification_count = (unsigned int)MOD_PCIE_SETUP_NOTIFICATION_IDX_COUNT, + .process_notification = mod_pcie_setup_process_notification, +}; -- GitLab From b8236fa1f946d8b76bbc772d55dc279d31179c40 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 12:47:42 +0100 Subject: [PATCH 34/43] automotive-rd/rd1ae: Add PCIE Setup module configurations This enables the support for pcie_setup module by adding the relavent configuration information and adding the module for RD1AE scp_ram firmware. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 4 + .../rd1ae/scp_ramfw/config_pcie_setup.c | 143 ++++++++++++++++++ .../rd1ae/scp_ramfw/config_sds.c | 13 +- .../rd1ae/scp_ramfw/include/platform_core.h | 4 + .../rd1ae/scp_ramfw/include/scp_cfgd_sds.h | 8 + 6 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_pcie_setup.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 5d5d9cc01..1a9bafd34 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -29,6 +29,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_io_block.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_mhu3.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_noc_s3.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_pcie_setup.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pik_clock.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index 308604bbd..e57a18760 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -34,6 +34,8 @@ set(SCP_ENABLE_ATU_MANAGE TRUE) list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/io_block" + "${CMAKE_CURRENT_LIST_DIR}/../module/pcie_discovery" + "${CMAKE_CURRENT_LIST_DIR}/../module/pcie_setup" "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -67,4 +69,6 @@ list(APPEND SCP_MODULES "sds") list(APPEND SCP_MODULES "scmi-power-domain") list(APPEND SCP_MODULES "scmi-system-power") list(APPEND SCP_MODULES "io-block") +list(APPEND SCP_MODULES "pcie_discovery") +list(APPEND SCP_MODULES "pcie-setup") list(APPEND SCP_MODULES "scp-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_pcie_setup.c b/product/automotive-rd/rd1ae/scp_ramfw/config_pcie_setup.c new file mode 100644 index 000000000..0d4bc5e4f --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_pcie_setup.c @@ -0,0 +1,143 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "cmn_node_id.h" +#include "io_macro_layout.h" +#include "scp_cfgd_sds.h" +#include "scp_fw_mmap.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* PCIe ECAM and MMIO addresses */ +#define ECAM_SIZE (UINT64_C(256) * FWK_MIB) +#define CHIP_ECAM_OFFSET(idx) (idx * ECAM_SIZE) +#define CHIP_ECAM_BASE_ADDRESS(idx) (0x4000000000ULL + CHIP_ECAM_OFFSET(idx)) + +#define MMIOH_SIZE (UINT64_C(64) * FWK_GIB) +#define CHIP_MMIOH_OFFSET(idx) (idx * MMIOH_SIZE) +#define CHIP_MMIOH_BASE_ADDRESS(idx) (0x4040000000ULL + CHIP_MMIOH_OFFSET(idx)) +#define CHIP_PCIE_BUS_SIZE 256 +#define CHIP_PCIE_MMIOL_SIZE (0x20000000UL) +#define CHIP0_PCIE_MMIOL_BASE (0x60000000UL) +#define CHIP1_PCIE_MMIOL_BASE (CHIP0_PCIE_MMIOL_BASE + CHIP_PCIE_MMIOL_SIZE) +#define CHIP2_PCIE_MMIOL_BASE (CHIP1_PCIE_MMIOL_BASE + CHIP_PCIE_MMIOL_SIZE) +#define NUMBER_OF_ENDPOINTS 5 +#define NUMBER_OF_CHIPS 1 + +#define CHIP_MEMMAP(idx) \ + { \ + .mmap = { \ + .ecam = { \ + .start = CHIP_ECAM_BASE_ADDRESS(idx), \ + .size = ECAM_SIZE, \ + }, \ + .mmiol = { \ + .start = CHIP##idx##_PCIE_MMIOL_BASE, \ + .size = CHIP_PCIE_MMIOL_SIZE, \ + }, \ + .mmioh = { \ + .start = CHIP_MMIOH_BASE_ADDRESS(idx), \ + .size = MMIOH_SIZE \ + }, \ + .bus = { \ + .start = 0, \ + .size = CHIP_PCIE_BUS_SIZE \ + } \ + }, \ + .cmn_id = FWK_ID_MODULE(FWK_MODULE_IDX_CMN_CYPRUS), \ + .io_block_id = FWK_ID_MODULE(FWK_MODULE_IDX_IO_BLOCK), \ + .cmn_api_id = FWK_ID_API(FWK_MODULE_IDX_CMN_CYPRUS, \ + MOD_CMN_CYPRUS_API_IDX_MAP_IO_REGION), \ + .io_block_api_id = FWK_ID_API(FWK_MODULE_IDX_IO_BLOCK, \ + MOD_IO_BLOCK_API_IDX_MAP_REGION), \ + .atu_mmio_id = FWK_ID_MODULE(FWK_MODULE_IDX_ATU_MMIO), \ + .atu_mmio_api_id = FWK_ID_API(FWK_MODULE_IDX_ATU_MMIO, \ + MOD_ATU_MMIO_API_IDX_MEM_RW),\ + .plat_notification = { \ + .notification_id = FWK_ID_NOTIFICATION_INIT( \ + FWK_MODULE_IDX_SCP_PLATFORM, \ + MOD_SCP_PLATFORM_NOTIFICATION_IDX_SUBSYS_INITIALIZED), \ + .source_id = FWK_ID_MODULE_INIT( \ + FWK_MODULE_IDX_SCP_PLATFORM), \ + }, \ + .ep_count = NUMBER_OF_ENDPOINTS, \ + .ep_interrupt_ids = ((uint64_t [NUMBER_OF_ENDPOINTS]) { \ + [0] = 0, \ + [1] = 0x10000U, \ + [2] = 0x20000U, \ + [3] = 0x30000U, \ + [4] = 0x40000U, \ + }), \ + } + +#define IO_MACRO_EP_CONFIG(x1_en, x20_en, x21_en, x4_en, x8_en) \ + ((struct mod_pcie_setup_ep_config[NUMBER_OF_ENDPOINTS]){ \ + [0] = { .valid = x8_en, \ + .allow_ns_access = true, \ + .rp_node_id = AMNI_PCIEX8_0 }, \ + [1] = { .valid = x4_en, \ + .allow_ns_access = true, \ + .rp_node_id = AMNI_PCIEX4_0 }, \ + [2] = { .valid = x21_en, \ + .allow_ns_access = true, \ + .rp_node_id = AMNI_PCIEX2_1 }, \ + [3] = { .valid = x20_en, \ + .allow_ns_access = true, \ + .rp_node_id = AMNI_PCIEX2_0 }, \ + [4] = { .valid = x1_en, \ + .allow_ns_access = true, \ + .rp_node_id = AMNI_PCIEX1_0 }, \ + }) + +#define IO_MACRO_PCIE_ELEMENT_CONFIG(idx, x1_en, x20_en, x21_en, x4_en, x8_en) \ + { \ + .name = "IO Macro " #idx, \ + .data = &((struct mod_pcie_setup_config){ \ + .reg_base = NCI_GVP_BLOCK_BASE(idx), \ + .cmn_node_id = IOVB_NODE_ID##idx, \ + .nci_source_node_id = ASNI_CMN, \ + .block_id = idx, \ + .smmu_base = TCU_REG_BASE(idx), \ + .sds_struct_id = SDS_PCIE_MMAP, \ + .ep_config = \ + IO_MACRO_EP_CONFIG(x1_en, x20_en, x21_en, x4_en, x8_en) }) \ + } + +static const struct fwk_element pcie_setup_element_table[2] = { + [0] = IO_MACRO_PCIE_ELEMENT_CONFIG(0, true, true, true, true, true), + + [1] = { 0 }, +}; + +static struct mod_pcie_setup_resource_info resource_info = CHIP_MEMMAP(0); + +static const struct mod_pcie_setup_module_config module_config = { + .resource_info_count = NUMBER_OF_CHIPS, + .resource_info = (struct mod_pcie_setup_resource_info *)&resource_info, +}; + +static const struct fwk_element *pcie_setup_get_element_table( + fwk_id_t module_id) +{ + return pcie_setup_element_table; +} + +struct fwk_module_config config_pcie_setup = { + .data = &module_config, + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(pcie_setup_get_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c index ffd2a38c0..d6cde40db 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_sds.c @@ -114,12 +114,21 @@ static struct fwk_element sds_element_table[MOD_SDS_ELEMENT_COUNT] = { .finalize = true, }), }, + [SCP_CFGD_MOD_SDS_EIDX_PCIE_MMAP] = { + .name = "PCIe Mmap", + .data = &((struct mod_sds_structure_desc){ + .id = SDS_PCIE_MMAP, + .size = SCP_CFGD_MOD_SDS_PCIE_MMAP_SIZE, + .region_id = SCP_CFGD_MOD_SDS_REGION_IDX_SECURE, + .finalize = true, + }), + }, [SCP_CFGD_MOD_SDS_EIDX_COUNT] = { 0 }, /* Termination description. */ }; static_assert( - SCP_SDS_SECURE_SIZE > SCP_CFGD_MOD_SDS_CPU_INFO_SIZE + - SCP_CFGD_MOD_SDS_ROM_VERSION_SIZE + + SCP_SDS_SECURE_SIZE > SCP_CFGD_MOD_SDS_PCIE_MMAP_SIZE + + SCP_CFGD_MOD_SDS_CPU_INFO_SIZE + SCP_CFGD_MOD_SDS_ROM_VERSION_SIZE + SCP_CFGD_MOD_SDS_RAM_VERSION_SIZE + SCP_CFGD_MOD_SDS_RESET_SYNDROME_SIZE + SCP_CFGD_MOD_SDS_FEATURE_AVAILABILITY_SIZE + diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h b/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h index 57a5236f6..88dba1a11 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/platform_core.h @@ -13,9 +13,13 @@ #include +#define NUMBER_OF_ROOTPORTS 5 + #define CORES_PER_CLUSTER 1 #define NUMBER_OF_CLUSTERS 16 +#define NUM_PCIE_INTEG_CTRL 4 + static inline unsigned int platform_get_cluster_count(void) { return NUMBER_OF_CLUSTERS; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h index a52df0827..d8dc77a45 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_sds.h @@ -13,6 +13,7 @@ #include +#include #include #include @@ -27,6 +28,7 @@ enum scp_cfgd_mod_sds_struct_id { SDS_RESET_SYNDROME_STRUCT_ID = SDS_STRUCT_ID(5), SDS_FEATURE_AVAIL_STRUCT_ID = SDS_STRUCT_ID(6), SDS_ISOLATED_CPU_MPID_STRUCT_ID = SDS_STRUCT_ID(128), + SDS_PCIE_MMAP = SDS_STRUCT_ID(129), }; /* Memory region identifiers that hold the SDS structures. */ @@ -43,6 +45,7 @@ enum scp_cfgd_mod_sds_element_idx { SCP_CFGD_MOD_SDS_EIDX_RESET_SYNDROME, SCP_CFGD_MOD_SDS_EIDX_FEATURE_AVAILABILITY, SCP_CFGD_MOD_SDS_ISOLATED_CPU_MPID, + SCP_CFGD_MOD_SDS_EIDX_PCIE_MMAP, SCP_CFGD_MOD_SDS_EIDX_COUNT }; @@ -52,6 +55,11 @@ enum scp_cfgd_mod_sds_element_idx { #define SCP_CFGD_MOD_SDS_RAM_VERSION_SIZE 4 #define SCP_CFGD_MOD_SDS_RESET_SYNDROME_SIZE 4 #define SCP_CFGD_MOD_SDS_FEATURE_AVAILABILITY_SIZE 4 +#define SCP_CFGD_MOD_SDS_PCIE_MMAP_SIZE \ + (sizeof(struct mod_pcie_setup_block_mmap_list)) + \ + (NUM_PCIE_INTEG_CTRL * \ + (sizeof(struct mod_pcie_setup_block_mmap) + \ + (sizeof(struct mod_pcie_setup_mmap) * NUMBER_OF_ROOTPORTS))) /* * Max size of structure listing the MPID of the isolated CPUs. -- GitLab From 7216f024e2bd9fa34821a5314d92e235df1ebbdd Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 13:41:06 +0100 Subject: [PATCH 35/43] automotive-rd/rd1ae: Bind SCP platform module to SCMI module When platform module binds to SCMI module, SCMI module will try to bind back to platform module. Add support for the bind back APIs. Bind SCP module with SCP-RSE SCMI channel. SCP platform module to bind with SCP-RSS SCMI channel. SCP uses this channel to report shutdown and cold reboot requests to RSE. Signed-off-by: Ziad Elhanafy Signed-off-by: Divin Raj --- .../rd1ae/module/scp_platform/CMakeLists.txt | 2 +- .../include/internal/scp_platform.h | 13 ++++ .../scp_platform/include/mod_scp_platform.h | 3 + .../scp_platform/src/mod_scp_platform.c | 5 ++ .../scp_platform/src/platform_power_mgmt.c | 61 +++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt b/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt index 71f1d9a58..b3a36b7f1 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/module/scp_platform/CMakeLists.txt @@ -17,5 +17,5 @@ target_sources( target_link_libraries( ${SCP_MODULE_TARGET} - PRIVATE module-power-domain module-system-power + PRIVATE module-power-domain module-system-power module-scmi module-system-info module-transport module-timer) diff --git a/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h b/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h index dddb46c29..8463a9bce 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h +++ b/product/automotive-rd/rd1ae/module/scp_platform/include/internal/scp_platform.h @@ -67,6 +67,19 @@ int platform_rse_bind(const struct mod_scp_platform_config *config); */ const void *get_platform_system_power_driver_api(void); +/* + * SCMI interface helper functions. + */ + +/*! + * \brief Helper function to return platform system SCMI API. + * + * \param None. + * + * \return Pointer to the SCP platform system SCMI API. + */ +const void *get_platform_scmi_power_down_api(void); + /*! * \brief Helper function to bind to power domain restricted API. * diff --git a/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h b/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h index e5371de22..30bf7db10 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h +++ b/product/automotive-rd/rd1ae/module/scp_platform/include/mod_scp_platform.h @@ -30,6 +30,9 @@ * \brief Indices of the interfaces exposed by the module. */ enum mod_scp_platform_api_idx { + /*! API index for the powerdown interface of SCMI module */ + MOD_SCP_PLATFORM_API_IDX_SCMI_POWER_DOWN, + /*! API index for the driver interface of the SYSTEM POWER module */ MOD_SCP_PLATFORM_API_IDX_SYSTEM_POWER_DRIVER, diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c b/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c index e627cf61c..bcd911d79 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/mod_scp_platform.c @@ -130,6 +130,11 @@ static int scp_platform_process_bind_request( api_id_type = (enum mod_scp_platform_api_idx)fwk_id_get_api_idx(api_id); switch (api_id_type) { + case MOD_SCP_PLATFORM_API_IDX_SCMI_POWER_DOWN: + *api = get_platform_scmi_power_down_api(); + status = FWK_SUCCESS; + break; + case MOD_SCP_PLATFORM_API_IDX_SYSTEM_POWER_DRIVER: *api = get_platform_system_power_driver_api(); status = FWK_SUCCESS; diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c index d58b91522..5329a9b27 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c @@ -8,9 +8,13 @@ * SCP Platform Support - Power Management */ +#include "scp_cfgd_scmi.h" + #include #include +#include +#include #include #include @@ -21,6 +25,9 @@ #include +/*! SCMI protocol API */ +static const struct mod_scmi_from_protocol_req_api *scmi_protocol_req_api; + /* Module 'power_domain' restricted API pointer */ static struct mod_pd_restricted_api *pd_restricted_api; @@ -44,8 +51,62 @@ const void *get_platform_system_power_driver_api(void) return &platform_system_pwr_drv_api; } +/* + * SCMI module -> SCP platform module interface + */ +static int platform_system_get_scmi_protocol_id( + fwk_id_t protocol_id, + uint8_t *scmi_protocol_id) +{ + *scmi_protocol_id = (uint8_t)MOD_SCMI_PROTOCOL_ID_SYS_POWER; + + return FWK_SUCCESS; +} + +/* + * Upon binding the scp_platform module to the SCMI module, the SCMI module + * will also bind back to the scp_platform module, anticipating the presence of + * .get_scmi_protocol_id() and .message_handler() APIs. + * + * In the current implementation of scp_platform module, only sending SCMI + * message is implemented, and the scp_platform module is not intended to + * receive any SCMI messages. Therefore, it is necessary to include a minimal + * .message_handler() API to ensure the successful binding of the SCMI module. + */ +static int platform_system_scmi_message_handler( + fwk_id_t protocol_id, + fwk_id_t service_id, + const uint32_t *payload, + size_t payload_size, + unsigned int message_id) +{ + return FWK_SUCCESS; +} + +/* SCMI driver interface */ +const struct mod_scmi_to_protocol_api platform_system_scmi_api = { + .get_scmi_protocol_id = platform_system_get_scmi_protocol_id, + .message_handler = platform_system_scmi_message_handler, +}; + +const void *get_platform_scmi_power_down_api(void) +{ + return &platform_system_scmi_api; +} + int platform_power_mgmt_bind(void) { + int status; + + /* Bind to SCMI module for RSE communication */ + status = fwk_module_bind( + FWK_ID_MODULE(FWK_MODULE_IDX_SCMI), + FWK_ID_API(FWK_MODULE_IDX_SCMI, MOD_SCMI_API_IDX_PROTOCOL_REQ), + &scmi_protocol_req_api); + if (status != FWK_SUCCESS) { + return status; + } + return fwk_module_bind( fwk_module_id_power_domain, mod_pd_api_id_restricted, -- GitLab From 365632b97a272a94e41a4e6d207a3866b01884dd Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 14:05:23 +0100 Subject: [PATCH 36/43] automotive-rd/rd1ae: Report power down to RSE Add support in SCP to report a shutdown or cold reboot to RSE. SCP uses MHU outband communication, and uses SCMI messaging format to communicate with RSE. Signed-off-by: Ziad Elhanafy --- .../scp_platform/src/platform_power_mgmt.c | 32 +++++++++++++++++++ .../rd1ae/scp_ramfw/include/scp_cfgd_scmi.h | 7 ++++ 2 files changed, 39 insertions(+) diff --git a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c index 5329a9b27..12f3a775f 100644 --- a/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c +++ b/product/automotive-rd/rd1ae/module/scp_platform/src/platform_power_mgmt.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,37 @@ static struct mod_pd_restricted_api *pd_restricted_api; /* System shutdown function */ static int platform_shutdown(enum mod_pd_system_shutdown system_shutdown) { + int status; + fwk_id_t rse_scmi_prot_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_SCMI, SCP_CFGD_MOD_SCMI_RSE_POWER_DOWN_SEND); + struct scp_cfgd_scmi_sys_power_state_set_payload scp_scmi_payload; + + scp_scmi_payload.flags = 0; + scp_scmi_payload.system_state = (uint32_t)system_shutdown; + + /* + * The current RSE firmware lacks SCMI support, preventing the RSE platform + * firmware from sending SCMI power state notify messages to the SCP or + * subscribing to SCMI notifications. To address this limitation, notify + * the RSE about system power down using the SCMI system power state set + * message. As this message can be decoded in the RSE firmware with minimal + * SCMI message parsing logic. + */ + status = scmi_protocol_req_api->scmi_send_message( + MOD_SCMI_SYS_POWER_STATE_SET, + MOD_SCMI_PROTOCOL_ID_SYS_POWER, + 0, + rse_scmi_prot_id, + (void *)&scp_scmi_payload, + sizeof(scp_scmi_payload), + false); + + if (status != FWK_SUCCESS) { + FWK_LOG_ERR( + "[SCP_PLATFORM] ERROR! Unable to send shutdown request to RSE"); + return status; + } + while (1) { __WFI(); } diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h index f26f71ec7..337fe9445 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_scmi.h @@ -11,6 +11,8 @@ #ifndef SCP_CFGD_SCMI_H #define SCP_CFGD_SCMI_H +#include + /* SCMI agent identifier indexes in the SCMI agent table */ enum scp_scmi_agent_idx { /* 0 is reserved for the platform */ @@ -29,4 +31,9 @@ enum scp_cfgd_mod_scmi_element_idx { SCP_CFGD_MOD_SCMI_EIDX_COUNT, }; +struct scp_cfgd_scmi_sys_power_state_set_payload { + uint32_t flags; + uint32_t system_state; +}; + #endif /* SCP_CFGD_SCMI_H */ -- GitLab From 7cb644879402a423144975ffe4ebf3244bb18fce Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 14:46:22 +0100 Subject: [PATCH 37/43] automotive-rd/rd1ae: Add Safety Island platform module Introduce Safety Island platform module which receives signals in order to power on each Safety Island cluster. Also increase the maximum number of columns per log line to 100 as some log messages from the Safety Island platform module exceed the default limit. Signed-off-by: Ziad Elhanafy Signed-off-by: Peter Hoyes --- .../safety_island_platform/CMakeLists.txt | 18 ++ .../safety_island_platform/Module.cmake | 10 + .../include/mod_safety_island_platform.h | 65 +++++ .../src/mod_safety_island_platform.c | 244 ++++++++++++++++++ .../rd1ae/scp_ramfw/include/fmw_log.h | 16 ++ 5 files changed, 353 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/Module.cmake create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/include/mod_safety_island_platform.h create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/src/mod_safety_island_platform.c create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/include/fmw_log.h diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/CMakeLists.txt b/product/automotive-rd/rd1ae/module/safety_island_platform/CMakeLists.txt new file mode 100644 index 000000000..639379938 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +add_library(${SCP_MODULE_TARGET} SCP_MODULE) + +target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + +target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_safety_island_platform.c") + +target_link_libraries( + ${SCP_MODULE_TARGET} + PRIVATE module-power-domain module-transport) diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/Module.cmake b/product/automotive-rd/rd1ae/module/safety_island_platform/Module.cmake new file mode 100644 index 000000000..0b00723b6 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/Module.cmake @@ -0,0 +1,10 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(SCP_MODULE "safety-island-platform") + +set(SCP_MODULE_TARGET "module-safety-island-platform") diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/include/mod_safety_island_platform.h b/product/automotive-rd/rd1ae/module/safety_island_platform/include/mod_safety_island_platform.h new file mode 100644 index 000000000..75a14614b --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/include/mod_safety_island_platform.h @@ -0,0 +1,65 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Safety Island Support + */ + +#ifndef MOD_SAFETY_ISLAND_PLATFORM_H +#define MOD_SAFETY_ISLAND_PLATFORM_H + +#include +#include + +#include + +#include + +/*! + * \brief Indices of the interfaces exposed by the module. + */ +enum mod_safety_island_platform_api_idx { + MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER, + + /*! Number of exposed interfaces */ + MOD_SAFETY_ISLAND_PLATFORM_API_COUNT +}; + +/*! + * \brief Safety Island cluster layout. + */ +struct safety_island_platform_cluster_layout { + /*! Safety Island cluster ID */ + uint32_t id; + /*! Safety Island cluster number of cores */ + uint32_t num_cores; + /*! Safety Island cluster core offset */ + uint32_t core_offset; +}; + +/*! + * \brief Safety Island cluster configuration data. + */ +struct safety_island_cluster_config { + /*! Safety Island cluster transport channel identifier */ + const fwk_id_t transport_id; + /* Safety Island cluster layout */ + const struct safety_island_platform_cluster_layout cluster_layout; +}; + +/*! + * \brief Safety Island cluster context data. + */ +struct safety_island_cluster_ctx { + /*! Safety Island cluster configuration data */ + struct safety_island_cluster_config *config; + /* Transport API to send/respond to a message */ + struct mod_transport_firmware_api *transport_api; + /* Power Domain restricted API pointer */ + struct mod_pd_restricted_api *pd_restricted_api; +}; + +#endif /* MOD_SAFETY_ISLAND_PLATFORM_H */ diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/src/mod_safety_island_platform.c b/product/automotive-rd/rd1ae/module/safety_island_platform/src/mod_safety_island_platform.c new file mode 100644 index 000000000..0fb19b3e0 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/src/mod_safety_island_platform.c @@ -0,0 +1,244 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Safety Island Platform Module. + */ + +#include "platform_core.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MOD_NAME "[SAFETY_ISLAND_PLATFORM]" + +/* Module context */ +struct safety_island_platform_ctx { + /* Safety Island Cluster config data */ + struct safety_island_cluster_ctx *safety_island_ctx_table; + /* Number of Safety Island clusters */ + uint32_t safety_island_cluster_count; +}; + +static struct safety_island_platform_ctx ctx; + +static int init_si_cluster_cores(fwk_id_t safety_island_cluster_idx) +{ + uint32_t pd_state; + uint32_t core; + struct safety_island_cluster_ctx *safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx( + safety_island_cluster_idx)]; + uint32_t cluster_offset = + safety_island_cluster_ctx->config->cluster_layout.core_offset; + uint32_t num_cores = + safety_island_cluster_ctx->config->cluster_layout.num_cores; + + uint32_t start_id = platform_get_core_count() + + platform_get_cluster_count() + cluster_offset; + + /* Composite Power Domain state to be set for the Safety Island */ + pd_state = MOD_PD_COMPOSITE_STATE( + MOD_PD_LEVEL_1, 0, 0, MOD_PD_STATE_ON, MOD_PD_STATE_ON); + + for (core = 0; core < num_cores; core++) { + fwk_id_t pd_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, start_id + core); + int status = safety_island_cluster_ctx->pd_restricted_api->set_state( + pd_id, false, pd_state); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR( + MOD_NAME "Failed to intialize %s core %lu", + fwk_module_get_element_name(safety_island_cluster_idx), + (unsigned long)core); + return status; + } + } + + return FWK_SUCCESS; +} + +static int signal_error(fwk_id_t safety_island_cluster_idx) +{ + struct safety_island_cluster_ctx *safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx( + safety_island_cluster_idx)]; + FWK_LOG_ERR( + MOD_NAME "Error! Invalid response received to boot %s", + fwk_module_get_element_name(safety_island_cluster_idx)); + safety_island_cluster_ctx->transport_api->release_transport_channel_lock( + safety_island_cluster_ctx->config->transport_id); + + return FWK_SUCCESS; +} + +static int signal_message(fwk_id_t safety_island_cluster_idx) +{ + int status; + struct safety_island_cluster_ctx *safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx( + safety_island_cluster_idx)]; + + FWK_LOG_INFO( + MOD_NAME "Received doorbell event to boot %s", + fwk_module_get_element_name(safety_island_cluster_idx)); + FWK_LOG_INFO( + MOD_NAME "Initializing %s cores...", + fwk_module_get_element_name(safety_island_cluster_idx)); + status = init_si_cluster_cores(safety_island_cluster_idx); + if (status != FWK_SUCCESS) { + FWK_LOG_ERR( + MOD_NAME "Error! Failed to initialize %s cores", + fwk_module_get_element_name(safety_island_cluster_idx)); + fwk_trap(); + } + safety_island_cluster_ctx->transport_api->release_transport_channel_lock( + safety_island_cluster_ctx->config->transport_id); + + return FWK_SUCCESS; +} + +static const struct mod_transport_firmware_signal_api + platform_transport_signal_api = { + .signal_error = signal_error, + .signal_message = signal_message, + }; + +/* + * Framework handlers + */ +static int safety_island_platform_mod_init( + fwk_id_t module_id, + unsigned int safety_island_cluster_count, + const void *unused) +{ + if (safety_island_cluster_count == 0) { + return FWK_E_PARAM; + } + + ctx.safety_island_ctx_table = fwk_mm_calloc( + safety_island_cluster_count, sizeof(ctx.safety_island_ctx_table[0])); + + ctx.safety_island_cluster_count = safety_island_cluster_count; + + return FWK_SUCCESS; +} + +static int safety_island_platform_cluster_init( + fwk_id_t safety_island_cluster_idx, + unsigned int sub_element_count, + const void *data) +{ + struct safety_island_cluster_config *config; + struct safety_island_cluster_ctx *safety_island_cluster_ctx; + + config = (struct safety_island_cluster_config *)data; + + if (config == NULL) { + return FWK_E_DATA; + } + + safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx( + safety_island_cluster_idx)]; + safety_island_cluster_ctx->config = config; + + return FWK_SUCCESS; +} + +static int safety_island_platform_bind(fwk_id_t id, unsigned int round) +{ + struct safety_island_cluster_ctx *safety_island_cluster_ctx; + fwk_id_t transport_api_id; + int status; + + if ((round != 0) || (fwk_id_is_type(id, FWK_ID_TYPE_MODULE))) { + return FWK_SUCCESS; + } + + safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx(id)]; + + transport_api_id = + FWK_ID_API(FWK_MODULE_IDX_TRANSPORT, MOD_TRANSPORT_API_IDX_FIRMWARE); + + status = fwk_module_bind( + safety_island_cluster_ctx->config->transport_id, + transport_api_id, + &safety_island_cluster_ctx->transport_api); + + if (status != FWK_SUCCESS) { + return status; + } + + return fwk_module_bind( + fwk_module_id_power_domain, + mod_pd_api_id_restricted, + &safety_island_cluster_ctx->pd_restricted_api); + + return FWK_SUCCESS; +} + +static int safety_island_platform_process_bind_request( + fwk_id_t source_id, + fwk_id_t target_id, + fwk_id_t api_id, + const void **api) +{ + int status; + enum mod_safety_island_platform_api_idx api_id_type; + struct safety_island_cluster_ctx *safety_island_cluster_ctx; + + if (!fwk_id_is_type(target_id, FWK_ID_TYPE_ELEMENT)) { + /* Only binding to an element is allowed */ + fwk_unexpected(); + return FWK_E_ACCESS; + } + + safety_island_cluster_ctx = + &ctx.safety_island_ctx_table[fwk_id_get_element_idx(target_id)]; + + api_id_type = + (enum mod_safety_island_platform_api_idx)fwk_id_get_api_idx(api_id); + + switch (api_id_type) { + case MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER: + if (fwk_id_is_equal( + source_id, safety_island_cluster_ctx->config->transport_id)) { + *api = &platform_transport_signal_api; + status = FWK_SUCCESS; + } else { + status = FWK_E_PARAM; + } + break; + default: + status = FWK_E_PARAM; + break; + } + + return status; +} + +const struct fwk_module module_safety_island_platform = { + .type = FWK_MODULE_TYPE_HAL, + .api_count = MOD_SAFETY_ISLAND_PLATFORM_API_COUNT, + .init = safety_island_platform_mod_init, + .element_init = safety_island_platform_cluster_init, + .bind = safety_island_platform_bind, + .process_bind_request = safety_island_platform_process_bind_request, +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_log.h b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_log.h new file mode 100644 index 000000000..dc7890b3e --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/fmw_log.h @@ -0,0 +1,16 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FMW_LOG_H +#define FMW_LOG_H + +/* + * Number of columns per line the framework will limit itself to. + */ +#define FMW_LOG_COLUMNS 100 + +#endif /* FMW_LOG_H */ -- GitLab From 5fd858f2007f10d4b8a2a023b6dacf736da90128 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 14:59:01 +0100 Subject: [PATCH 38/43] automotive-rd/rd1ae: Add Safety Island platform module configurations 1- Provide configuration data for the safety_island_platform module which includes the safety island clusters layout and transport channels. 2- Add additional MHUv3 channels from RSE to SCP to boot each Safety Island cluster. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/CMakeLists.txt | 1 + .../rd1ae/scp_ramfw/Firmware.cmake | 2 + .../rd1ae/scp_ramfw/config_mhu3.c | 11 ++- .../scp_ramfw/config_safety_island_platform.c | 82 +++++++++++++++++++ .../rd1ae/scp_ramfw/config_transport.c | 67 +++++++++++++++ .../scp_ramfw/include/scp_cfgd_transport.h | 3 + 6 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 product/automotive-rd/rd1ae/scp_ramfw/config_safety_island_platform.c diff --git a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt index 1a9bafd34..3d09d365d 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt +++ b/product/automotive-rd/rd1ae/scp_ramfw/CMakeLists.txt @@ -34,6 +34,7 @@ target_sources( "${CMAKE_CURRENT_SOURCE_DIR}/config_pl011.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_ppu_v1.c" + "${CMAKE_CURRENT_SOURCE_DIR}/config_safety_island_platform.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_power_domain.c" "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_system_power.c" diff --git a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake index e57a18760..cc1bcfa35 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake +++ b/product/automotive-rd/rd1ae/scp_ramfw/Firmware.cmake @@ -36,6 +36,7 @@ list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/io_block" "${CMAKE_CURRENT_LIST_DIR}/../module/pcie_discovery" "${CMAKE_CURRENT_LIST_DIR}/../module/pcie_setup" + "${CMAKE_CURRENT_LIST_DIR}/../module/safety_island_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/scp_platform" "${CMAKE_CURRENT_LIST_DIR}/../module/system_pik") @@ -72,3 +73,4 @@ list(APPEND SCP_MODULES "io-block") list(APPEND SCP_MODULES "pcie_discovery") list(APPEND SCP_MODULES "pcie-setup") list(APPEND SCP_MODULES "scp-platform") +list(APPEND SCP_MODULES "safety-island-platform") diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c index 2daa07f98..c9fdbb375 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_mhu3.c @@ -34,11 +34,20 @@ struct mod_mhu3_channel_config scp2ap_s_dbch_config[1] = { }; /* SCP<-->RSE Secure MHUv3 Doorbell channel configuration */ -struct mod_mhu3_channel_config scp2rse_s_dbch_config[2] = { +struct mod_mhu3_channel_config scp2rse_s_dbch_config[5] = { /* PBX CH 0, FLAG 0, MBX CH 0, FLAG 0 */ [0] = MOD_MHU3_INIT_DBCH(0, 0, 0, 0), /* PBX CH 1, FLAG 0, MBX CH 1, FLAG 0, used by scp platform for shutdown */ [1] = MOD_MHU3_INIT_DBCH(1, 0, 1, 0), + /* PBX CH 2, FLAG 0, MBX CH 2, FLAG 0, used by scp platform for SI CL0 boot + */ + [2] = MOD_MHU3_INIT_DBCH(2, 0, 2, 0), + /* PBX CH 2, FLAG 1, MBX CH 2, FLAG 1, used by scp platform for SI CL1 boot + */ + [3] = MOD_MHU3_INIT_DBCH(2, 1, 2, 1), + /* PBX CH 2, FLAG 2, MBX CH 2, FLAG 2, used by scp platform for SI CL2 boot + */ + [4] = MOD_MHU3_INIT_DBCH(2, 2, 2, 2), }; /* AP<-->SCP Secure MHUv3 doorbell channel count */ diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_safety_island_platform.c b/product/automotive-rd/rd1ae/scp_ramfw/config_safety_island_platform.c new file mode 100644 index 000000000..7b13e0f51 --- /dev/null +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_safety_island_platform.c @@ -0,0 +1,82 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'safety_island_platform'. + */ + +#include "scp_cfgd_transport.h" + +#include + +#include +#include +#include + +/* Safety Island Cluster 0 layout */ +#define SI_CL0_ID 0U +#define SI_CL0_CORE_NUM 1U +#define SI_CL0_CORE_OFS SI_CL0_CORE_NUM + +/* Safety Island Cluster 1 layout */ +#define SI_CL1_ID SI_CL0_ID + 1U +#define SI_CL1_CORE_NUM 2U +#define SI_CL1_CORE_OFS SI_CL0_CORE_NUM + SI_CL1_CORE_NUM + +/* Safety Island Cluster 2 layout */ +#define SI_CL2_ID SI_CL1_ID + 1U +#define SI_CL2_CORE_NUM 4U +#define SI_CL2_CORE_OFS SI_CL1_CORE_NUM + SI_CL2_CORE_NUM + +enum safety_island_cluster_idx { + SI_CL0_IDX, + SI_CL1_IDX, + SI_CL2_IDX, + SI_CL_COUNT, +}; + +static const struct fwk_element + safety_island_platform_element_table[SI_CL_COUNT + 1] = { + [SI_CL0_IDX] = { + .name = "Safety Island Cluster 0", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0), + .cluster_layout = {SI_CL0_ID, SI_CL0_CORE_NUM, SI_CL0_CORE_OFS}, + }), + }, + [SI_CL1_IDX] = { + .name = "Safety Island Cluster 1", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1), + .cluster_layout = {SI_CL1_ID, SI_CL1_CORE_NUM, SI_CL1_CORE_OFS}, + }), + }, + [SI_CL2_IDX] = { + .name = "Safety Island Cluster 2", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2), + .cluster_layout = {SI_CL2_ID, SI_CL2_CORE_NUM, SI_CL2_CORE_OFS}, + }), + }, + [SI_CL_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_safety_island_platform_element_table( + fwk_id_t module_id) +{ + return safety_island_platform_element_table; +} + +const struct fwk_module_config config_safety_island_platform = { + .elements = + FWK_MODULE_DYNAMIC_ELEMENTS(get_safety_island_platform_element_table), +}; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c index b68c26aca..93dee5116 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_transport.c @@ -15,6 +15,7 @@ #include "scp_fw_mmap.h" #include +#include #include #include #include @@ -137,6 +138,72 @@ static const struct fwk_element element_table[MOD_TRANSPORT_ELEMENT_COUNT] = { MOD_MHU3_API_IDX_TRANSPORT_DRIVER), }), }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0] = { + .name = "SCP_PLATFORM_BOOT_SI_CLUS0", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_NONE, + .policies = MOD_TRANSPORT_POLICY_NONE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .signal_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER), + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 2), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1] = { + .name = "SCP_PLATFORM_BOOT_SI_CLUS1", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_NONE, + .policies = MOD_TRANSPORT_POLICY_NONE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .signal_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER), + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 3), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, + [SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2] = { + .name = "SCP_PLATFORM_BOOT_SI_CLUS2", + .data = &(( + struct mod_transport_channel_config) { + .transport_type = MOD_TRANSPORT_CHANNEL_TRANSPORT_TYPE_NONE, + .policies = MOD_TRANSPORT_POLICY_NONE, + .channel_type = MOD_TRANSPORT_CHANNEL_TYPE_COMPLETER, + .signal_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER), + .driver_id = + FWK_ID_SUB_ELEMENT_INIT( + FWK_MODULE_IDX_MHU3, + SCP_CFGD_MOD_MHU3_EIDX_SCP_RSE_S, + 4), + .driver_api_id = + FWK_ID_API_INIT( + FWK_MODULE_IDX_MHU3, + MOD_MHU3_API_IDX_TRANSPORT_DRIVER), + }), + }, [SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT] = { 0 }, }; diff --git a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h index 1d9be255a..ccbe061f6 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h +++ b/product/automotive-rd/rd1ae/scp_ramfw/include/scp_cfgd_transport.h @@ -18,6 +18,9 @@ enum scp_cfgd_mod_transport_element_idx { SCP_CFGD_MOD_TRANSPORT_EIDX_SYSTEM, SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_SEND, SCP_CFGD_MOD_TRANSPORT_EIDX_POWER_STATE_RSE_RECV, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2, SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT, }; -- GitLab From 9e3b5ead89f59651b88306928016a920b32517ae Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 29 Apr 2024 15:21:13 +0100 Subject: [PATCH 39/43] automotive-rd/rd1ae: Add Safety Island power domain and PPU configurations 1- Provide the configuration data of the available Safety Island clusters power domains to the power domain HAL. 2- Provide the configuration data of the available Safety Island clusters PPU instances to the PPU v1 driver. Signed-off-by: Ziad Elhanafy --- .../rd1ae/scp_ramfw/config_power_domain.c | 199 +++++++++++++++++- .../rd1ae/scp_ramfw/config_ppu_v1.c | 121 ++++++++++- 2 files changed, 317 insertions(+), 3 deletions(-) diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c b/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c index d4119cf1e..886eab1a8 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_power_domain.c @@ -20,8 +20,12 @@ #include #include #include +#include #include #include +#include + +#include #define PD_STATIC_ELEMENT_COUNT (PD_STATIC_DEV_IDX_SYSTOP + 1) @@ -82,7 +86,19 @@ static struct fwk_element pd_static_element_table[PD_STATIC_ELEMENT_COUNT] = { static const struct fwk_element *platform_power_domain_get_element_table( fwk_id_t module_id) { - const struct fwk_element *elements = create_power_domain_element_table( + const struct fwk_element *systop_elements = NULL; + const struct fwk_element *si_clus0_elements = NULL; + const struct fwk_element *si_clus1_elements = NULL; + const struct fwk_element *si_clus2_elements = NULL; + struct fwk_element *all_elements = NULL; + struct fwk_element tmp_table[1] = { 0 }; + unsigned int element_idx; + struct mod_power_domain_element_config *pd_config; + unsigned int systop_elements_count, si_clus0_elements_count, + si_clus1_elements_count, si_clus2_elements_count; + + /* Create power doamin elements for SYSTOP */ + systop_elements = create_power_domain_element_table( platform_get_core_count(), platform_get_cluster_count(), FWK_MODULE_IDX_PPU_V1, @@ -94,7 +110,186 @@ static const struct fwk_element *platform_power_domain_get_element_table( pd_static_element_table, FWK_ARRAY_SIZE(pd_static_element_table)); - return elements; + if (systop_elements == NULL) { + return NULL; + } + + /* Create power domain elements for SYSTOP_SI. + * Now 7 core in 3 cluster is supported. + */ + si_clus0_elements = create_power_domain_element_table( + 1, + 1, + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER, + core_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table), + cluster_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table), + tmp_table, + 0); + + if (si_clus0_elements == NULL) { + return NULL; + } + + si_clus1_elements = create_power_domain_element_table( + 2, + 1, + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER, + core_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table), + cluster_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table), + tmp_table, + 0); + + if (si_clus1_elements == NULL) { + return NULL; + } + + si_clus2_elements = create_power_domain_element_table( + 4, + 1, + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER, + core_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table), + cluster_pd_allowed_state_mask_table, + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table), + tmp_table, + 0); + + if (si_clus2_elements == NULL) { + return NULL; + } + + systop_elements_count = platform_get_core_count() + + platform_get_cluster_count() + FWK_ARRAY_SIZE(pd_static_element_table); + + si_clus0_elements_count = 2; + si_clus1_elements_count = 3; + si_clus2_elements_count = 5; + /* Create an array for all elements */ + all_elements = fwk_mm_calloc( + systop_elements_count + si_clus0_elements_count + + si_clus1_elements_count + si_clus2_elements_count + 1, + sizeof(struct fwk_element)); + + if (all_elements == NULL) { + return NULL; + } + + /* Copy SYSTOP elements to the new array */ + fwk_str_memcpy( + all_elements, + systop_elements, + systop_elements_count * sizeof(struct fwk_element)); + /* Copy the SI_clus0 elements to the new array. + * SI elements follow SYSTOP elements. */ + fwk_str_memcpy( + all_elements + systop_elements_count, + si_clus0_elements, + si_clus0_elements_count * sizeof(struct fwk_element)); + /* Copy the SI_clus1 elements to the new array. + * SI elements follow SYSTOP elements. */ + fwk_str_memcpy( + all_elements + systop_elements_count + si_clus0_elements_count, + si_clus1_elements, + si_clus1_elements_count * sizeof(struct fwk_element)); + /* Copy the SI_clus2 elements to the new array. + * SI elements follow SYSTOP elements. */ + fwk_str_memcpy( + all_elements + systop_elements_count + si_clus0_elements_count + + si_clus1_elements_count, + si_clus2_elements, + si_clus2_elements_count * sizeof(struct fwk_element)); + + /* The parent indices of SI elements need to be updated + * because they are in a new array, their indices are not zero based. */ + + /* Update CL0CORE0 */ + element_idx = systop_elements_count; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = element_idx + 1; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL0 */ + element_idx = element_idx + 1; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = PD_STATIC_DEV_IDX_NONE; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL1CORE0 */ + element_idx = systop_elements_count + 2; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 4; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL1CORE1 */ + element_idx = systop_elements_count + 3; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 4; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL1 */ + element_idx = systop_elements_count + 4; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = PD_STATIC_DEV_IDX_NONE; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL2CORE0 */ + element_idx = systop_elements_count + 5; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 9; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL2CORE1 */ + element_idx = systop_elements_count + 6; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 9; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL2CORE2 */ + element_idx = systop_elements_count + 7; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 9; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL2CORE3 */ + element_idx = systop_elements_count + 8; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = systop_elements_count + 9; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + /* Update CL2 */ + element_idx = systop_elements_count + 9; + pd_config = + (struct mod_power_domain_element_config *)all_elements[element_idx] + .data; + pd_config->parent_idx = PD_STATIC_DEV_IDX_NONE; + pd_config->driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, element_idx); + + return all_elements; } const struct fwk_module_config config_power_domain = { diff --git a/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c index d3ebdc868..83be56595 100644 --- a/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c +++ b/product/automotive-rd/rd1ae/scp_ramfw/config_ppu_v1.c @@ -30,6 +30,18 @@ #define PPU_CORE_NAME_SIZE 12 #define PPU_CLUS_NAME_SIZE 7 +/* Safety Island CPU PPU base addresses */ +#define SCP_PPU_SI_CLUS0 (0x56010000UL) +#define SCP_PPU_SI_CLUS0CORE0 (0x56040000UL) +#define SCP_PPU_SI_CLUS1 (0x56410000UL) +#define SCP_PPU_SI_CLUS1CORE0 (0x56440000UL) +#define SCP_PPU_SI_CLUS1CORE1 (0x56540000UL) +#define SCP_PPU_SI_CLUS2 (0x56810000UL) +#define SCP_PPU_SI_CLUS2CORE0 (0x56840000UL) +#define SCP_PPU_SI_CLUS2CORE1 (0x56940000UL) +#define SCP_PPU_SI_CLUS2CORE2 (0x56A40000UL) +#define SCP_PPU_SI_CLUS2CORE3 (0x56B40000UL) + /* Module configuration data */ static struct mod_ppu_v1_config ppu_v1_config_data = { .pd_notification_id = FWK_ID_NOTIFICATION_INIT( @@ -69,9 +81,14 @@ static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) * Number of cores * + Number of cluster descriptors * + Number of system power domain descriptors + * + Number of SI power domain descriptors + * (10 for now: cluster0-core0, cluster0 + * cluster1-core0,1, cluster1 + * cluster2-core0-3, cluster2) * + 1 terminator descriptor */ - number_elements = core_count + cluster_count + FWK_ARRAY_SIZE(ppu_element_table) + 1; + number_elements = + core_count + cluster_count + FWK_ARRAY_SIZE(ppu_element_table) + 10 + 1; element_table = fwk_mm_calloc(number_elements, sizeof(struct fwk_element)); pd_config_table = fwk_mm_calloc( @@ -140,6 +157,108 @@ static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) ppu_element_table, sizeof(ppu_element_table)); + /* Setting SI elements */ + /* Allocate pd_config for SI elements */ + pd_config_table = fwk_mm_calloc(10, sizeof(struct mod_ppu_v1_pd_config)); + + /* SI Cluster 0 Core 0 */ + pd_config_table[0].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[0].ppu.reg_base = SCP_PPU_SI_CLUS0CORE0; + pd_config_table[0].ppu.irq = FWK_INTERRUPT_NONE; + /* 8 cores + 8 clusters + 1 systop + 1 si-core */ + pd_config_table[0].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 1)); + pd_config_table[0].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 1].name = "CLUS0CORE0"; + element_table[core_count + cluster_count + 1].data = &pd_config_table[0]; + + /* SI Cluster 0 */ + pd_config_table[1].pd_type = MOD_PD_TYPE_CLUSTER; + pd_config_table[1].ppu.reg_base = SCP_PPU_SI_CLUS0; + pd_config_table[1].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[1].observer_id = FWK_ID_NONE; + pd_config_table[1].observer_api = FWK_ID_NONE; + element_table[core_count + cluster_count + 2].name = "CLUS0"; + element_table[core_count + cluster_count + 2].data = &pd_config_table[1]; + + /* SI Cluster 1 Core 0 */ + pd_config_table[2].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[2].ppu.reg_base = SCP_PPU_SI_CLUS1CORE0; + pd_config_table[2].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[2].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 2)); + pd_config_table[2].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 3].name = "CLUS1CORE0"; + element_table[core_count + cluster_count + 3].data = &pd_config_table[2]; + + /* SI Cluster 1 Core 1 */ + pd_config_table[3].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[3].ppu.reg_base = SCP_PPU_SI_CLUS1CORE1; + pd_config_table[3].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[3].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 2)); + pd_config_table[3].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 4].name = "CLUS1CORE1"; + element_table[core_count + cluster_count + 4].data = &pd_config_table[3]; + + /* SI Cluster 1 */ + pd_config_table[4].pd_type = MOD_PD_TYPE_CLUSTER; + pd_config_table[4].ppu.reg_base = SCP_PPU_SI_CLUS1; + pd_config_table[4].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[4].observer_id = FWK_ID_NONE; + pd_config_table[4].observer_api = FWK_ID_NONE; + element_table[core_count + cluster_count + 5].name = "CLUS1"; + element_table[core_count + cluster_count + 5].data = &pd_config_table[4]; + + /* SI Cluster 2 Core 0 */ + pd_config_table[5].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[5].ppu.reg_base = SCP_PPU_SI_CLUS2CORE0; + pd_config_table[5].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[5].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 3 + 4)); + pd_config_table[5].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 6].name = "CLUS2CORE0"; + element_table[core_count + cluster_count + 6].data = &pd_config_table[5]; + + /* SI Cluster 2 Core 1 */ + pd_config_table[6].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[6].ppu.reg_base = SCP_PPU_SI_CLUS2CORE1; + pd_config_table[6].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[6].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 3 + 4)); + pd_config_table[6].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 7].name = "CLUS2CORE1"; + element_table[core_count + cluster_count + 7].data = &pd_config_table[6]; + + /* SI Cluster 2 Core 2 */ + pd_config_table[7].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[7].ppu.reg_base = SCP_PPU_SI_CLUS2CORE2; + pd_config_table[7].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[7].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 3 + 4)); + pd_config_table[7].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 8].name = "CLUS2CORE2"; + element_table[core_count + cluster_count + 8].data = &pd_config_table[7]; + + /* SI Cluster 2 Core 3 */ + pd_config_table[8].pd_type = MOD_PD_TYPE_CORE; + pd_config_table[8].ppu.reg_base = SCP_PPU_SI_CLUS2CORE3; + pd_config_table[8].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[8].cluster_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + cluster_count + 1 + 2 + 3 + 4)); + pd_config_table[8].observer_id = FWK_ID_NONE; + element_table[core_count + cluster_count + 9].name = "CLUS2CORE3"; + element_table[core_count + cluster_count + 9].data = &pd_config_table[8]; + + /* SI Cluster 2 */ + pd_config_table[9].pd_type = MOD_PD_TYPE_CLUSTER; + pd_config_table[9].ppu.reg_base = SCP_PPU_SI_CLUS2; + pd_config_table[9].ppu.irq = FWK_INTERRUPT_NONE; + pd_config_table[9].observer_id = FWK_ID_NONE; + pd_config_table[9].observer_api = FWK_ID_NONE; + element_table[core_count + cluster_count + 10].name = "CLUS2"; + element_table[core_count + cluster_count + 10].data = &pd_config_table[9]; + /* * Configure pd_source_id with the SYSTOP identifier from the power domain * module which is dynamically defined based on the number of cores. -- GitLab From 4746cd87aebaa8745065f98e0b477aadc7c44a44 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 17 Jun 2024 11:49:11 +0100 Subject: [PATCH 40/43] automotive-rd/rd1ae: Add target to CI Add RD-1 AE target to CI. Signed-off-by: Ziad Elhanafy --- .gitlab/templates/build-test.yml | 4 ++-- tools/config/check_build/default_products_build.yml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitlab/templates/build-test.yml b/.gitlab/templates/build-test.yml index c6fcfec7f..2da117f5e 100644 --- a/.gitlab/templates/build-test.yml +++ b/.gitlab/templates/build-test.yml @@ -38,7 +38,7 @@ matrix: - BUILD_PRODUCT: [host, juno, morello, n1sdp, rcar, rdv3, rdv1, rdv1mc, rdn1e1, rdn2, - sgi575, sgm775, sgm776, synquacer, tc2] + sgi575, sgm775, sgm776, synquacer, tc2, rd1ae] .build-products-all-products-all-log-levels: extends: .build-products @@ -46,7 +46,7 @@ matrix: - BUILD_PRODUCT: [host, juno, morello, n1sdp, rcar, rdv3, rdv1, rdv1mc, rdn1e1, rdn2, - sgi575, sgm775, sgm776, synquacer, tc2] + sgi575, sgm775, sgm776, synquacer, tc2, rd1ae] BUILD_PRODUCTS_LOG_LEVEL: [DEBUG, INFO, WARN, ERROR, CRIT, DISABLED] diff --git a/tools/config/check_build/default_products_build.yml b/tools/config/check_build/default_products_build.yml index 3175bd487..be443eb1a 100644 --- a/tools/config/check_build/default_products_build.yml +++ b/tools/config/check_build/default_products_build.yml @@ -56,3 +56,6 @@ - name: 0 - name: 1 product_group: totalcompute + +- product: rd1ae + product_group: automotive-rd -- GitLab From 34a2046eee61099f034b2d95656ad3983aa9969b Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Mon, 17 Jun 2024 12:05:26 +0100 Subject: [PATCH 41/43] maintainers: Add maintainers for Automotive RD platforms This patch add the maintainers for the Automotive RD platforms which is the RD-1 AE platform only currently. Signed-off-by: Ziad Elhanafy --- maintainers.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/maintainers.md b/maintainers.md index d41e435cc..c496c5f63 100644 --- a/maintainers.md +++ b/maintainers.md @@ -39,6 +39,12 @@ contributions. Arm platforms typically come under the maintainership of the project core maintainers. The platforms listed here represent the exceptions to this rule. +#### Automotive RD platforms (rd1ae) + +- [Diego Sueiro](https://gitlab.arm.com/Diego.Sueiro) +- [Peter Hoyes](https://gitlab.arm.com/Peter.Hoyes) +- [Ziad Elhanafy](https://gitlab.arm.com/Ziad.Elhanafy) + #### Morello (morello) - [Deepak Pandey](https://gitlab.arm.com/Deepak.Pandey) -- GitLab From ded65b7ca93fc3eddd17b94e4488c7082921a3ca Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Wed, 12 Jun 2024 13:02:02 +0100 Subject: [PATCH 42/43] automotive_rd/rd1ae: Add Safety Island platform unit tests Add unit tests for the Safety Island platform module. Signed-off-by: Ziad Elhanafy --- .../test/CMakeLists.txt | 30 ++ .../test/config_safety_island_platform.h | 82 +++++ .../test/config_transport.h | 14 + .../test/fwk_module_idx.h | 31 ++ .../mod_safety_island_platform_unit_test.c | 312 ++++++++++++++++++ .../test/platform_core.h | 42 +++ product/test/CMakeLists.txt | 1 + 7 files changed, 512 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/CMakeLists.txt create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/config_safety_island_platform.h create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/config_transport.h create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/fwk_module_idx.h create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/mod_safety_island_platform_unit_test.c create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/test/platform_core.h diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/CMakeLists.txt b/product/automotive-rd/rd1ae/module/safety_island_platform/test/CMakeLists.txt new file mode 100644 index 000000000..f76a32d9d --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# Arm SCP/MCP Software +# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set(TEST_SRC mod_safety_island_platform) +set(TEST_FILE mod_safety_island_platform) + +set(UNIT_TEST_TARGET mod_safety_island_platform_unit_test) + +set(MODULE_SRC ${PRODUCT_ROOT}/${TEST_MODULE}/src) +set(MODULE_INC ${PRODUCT_ROOT}/${TEST_MODULE}/include) + +list(APPEND OTHER_MODULE_INC ${MODULE_ROOT}/power_domain/include) +list(APPEND OTHER_MODULE_INC ${MODULE_ROOT}/transport/include) + +set(MODULE_UT_SRC ${CMAKE_CURRENT_LIST_DIR}) +set(MODULE_UT_INC ${CMAKE_CURRENT_LIST_DIR}) + +list(APPEND MOCK_REPLACEMENTS fwk_id) +list(APPEND MOCK_REPLACEMENTS fwk_module) + +include(${SCP_ROOT}/unit_test/module_common.cmake) + +target_compile_definitions(${UNIT_TEST_TARGET} PUBLIC + "BUILD_HAS_MOD_POWER_DOMAIN") +target_compile_definitions(${UNIT_TEST_TARGET} PUBLIC + "BUILD_HAS_MOD_TRANSPORT") diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_safety_island_platform.h b/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_safety_island_platform.h new file mode 100644 index 000000000..d640a89b2 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_safety_island_platform.h @@ -0,0 +1,82 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Configuration data for module 'safety_island_platform'. + */ + +#include "config_transport.h" + +#include + +#include +#include +#include + +/* Safety Island Cluster 0 layout */ +#define SI_CL0_ID 0U +#define SI_CL0_CORE_NUM 1U +#define SI_CL0_CORE_OFS SI_CL0_CORE_NUM + +/* Safety Island Cluster 1 layout */ +#define SI_CL1_ID SI_CL0_ID + 1U +#define SI_CL1_CORE_NUM 2U +#define SI_CL1_CORE_OFS SI_CL0_CORE_NUM + SI_CL1_CORE_NUM + +/* Safety Island Cluster 2 layout */ +#define SI_CL2_ID SI_CL1_ID + 1U +#define SI_CL2_CORE_NUM 4U +#define SI_CL2_CORE_OFS SI_CL1_CORE_NUM + SI_CL2_CORE_NUM + +enum safety_island_cluster_idx { + SI_CL0_IDX, + SI_CL1_IDX, + SI_CL2_IDX, + SI_CL_COUNT, +}; + +static const struct fwk_element + safety_island_platform_element_table[SI_CL_COUNT + 1] = { + [SI_CL0_IDX] = { + .name = "Safety Island Cluster 0", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0), + .cluster_layout = {SI_CL0_ID, SI_CL0_CORE_NUM, SI_CL0_CORE_OFS}, + }), + }, + [SI_CL1_IDX] = { + .name = "Safety Island Cluster 1", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1), + .cluster_layout = {SI_CL1_ID, SI_CL1_CORE_NUM, SI_CL1_CORE_OFS}, + }), + }, + [SI_CL2_IDX] = { + .name = "Safety Island Cluster 2", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2), + .cluster_layout = {SI_CL2_ID, SI_CL2_CORE_NUM, SI_CL2_CORE_OFS}, + }), + }, + [SI_CL_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_safety_island_platform_element_table( + fwk_id_t module_id) +{ + return safety_island_platform_element_table; +} + +const struct fwk_module_config config_safety_island_platform = { + .elements = + FWK_MODULE_DYNAMIC_ELEMENTS(get_safety_island_platform_element_table), +}; diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_transport.h b/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_transport.h new file mode 100644 index 000000000..af9288fea --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/config_transport.h @@ -0,0 +1,14 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Module 'transport' element indexes */ +enum scp_cfgd_mod_transport_element_idx { + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2, + SCP_CFGD_MOD_TRANSPORT_EIDX_COUNT, +}; diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/fwk_module_idx.h b/product/automotive-rd/rd1ae/module/safety_island_platform/test/fwk_module_idx.h new file mode 100644 index 000000000..2a77dceca --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/fwk_module_idx.h @@ -0,0 +1,31 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_FWK_MODULE_MODULE_IDX_H +#define TEST_FWK_MODULE_MODULE_IDX_H + +enum fwk_module_idx { + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + FWK_MODULE_IDX_TRANSPORT, + FWK_MODULE_IDX_POWER_DOMAIN, + FWK_MODULE_IDX_FAKE, + FWK_MODULE_IDX_COUNT, +}; + +static const fwk_id_t fwk_module_id_safety_island_platform = + FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM); + +static const fwk_id_t fwk_module_id_transport = + FWK_ID_MODULE_INIT(FWK_MODULE_IDX_TRANSPORT); + +static const fwk_id_t fwk_module_id_power_domain = + FWK_ID_MODULE_INIT(FWK_MODULE_IDX_POWER_DOMAIN); + +static const fwk_id_t fwk_module_id_fake = + FWK_ID_MODULE_INIT(FWK_MODULE_IDX_FAKE); + +#endif /* TEST_FWK_MODULE_MODULE_IDX_H */ diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/mod_safety_island_platform_unit_test.c b/product/automotive-rd/rd1ae/module/safety_island_platform/test/mod_safety_island_platform_unit_test.c new file mode 100644 index 000000000..c1b08bd4d --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/mod_safety_island_platform_unit_test.c @@ -0,0 +1,312 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "unity.h" + +#include +#include + +#include +#include +#include + +#include + +#include UNIT_TEST_SRC +#include "config_safety_island_platform.h" + +#include +#include +#include + +static int release_transport_channel_lock_success(fwk_id_t channel_id) +{ + return FWK_SUCCESS; +} + +static int pd_set_state_success( + fwk_id_t pd_id, + bool response_requested, + uint32_t state) +{ + return FWK_SUCCESS; +} + +static struct mod_transport_firmware_api transport_api = { + .release_transport_channel_lock = release_transport_channel_lock_success, +}; +static struct mod_pd_restricted_api pd_restricted_api = { + .set_state = pd_set_state_success, +}; + +void setUp(void) +{ + /* Do Nothing */ +} + +void tearDown(void) +{ + /* Do Nothing */ +} + +/*! + * \brief Safety Island Platform unit test: safety_platform_mod_init(), + invalid number of safety island clusters. + * + * \details Handle case in safety_platform_mod_init() where number of + * safety island clusters is passed. + */ +void test_safety_island_platform_mod_init_fail(void) +{ + int status = 0; + + status = safety_island_platform_mod_init( + fwk_module_id_safety_island_platform, 0, NULL); + + TEST_ASSERT_EQUAL(status, FWK_E_PARAM); +} + +/*! + * \brief Safety Island Platform unit test: safety_platform_mod_init(), + valid number of safety island clusters. + * + * \details Handle case in safety_platform_mod_init() where valid number of + * safety island clusters is passed. + */ +void test_safety_island_platform_mod_init_success(void) +{ + int status; + + status = safety_island_platform_mod_init( + fwk_module_id_safety_island_platform, SI_CL_COUNT, NULL); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); +} + +/*! + * \brief Safety Island Platform unit test: + * safety_island_platform_cluster_init(), invalid config data. + * + * \details Handle case in safety_island_platform_cluster_init() where invalid + * config data is passed. + */ +void test_safety_island_platform_cluster_init_fail(void) +{ + int status = 0; + + status = safety_island_platform_mod_init( + fwk_module_id_safety_island_platform, SI_CL_COUNT, NULL); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + status = safety_island_platform_cluster_init( + FWK_ID_ELEMENT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, 0), 1, NULL); + + TEST_ASSERT_EQUAL(status, FWK_E_DATA); +} + +/*! + * \brief Safety Island Platform unit test: + * safety_island_platform_cluster_init(), valid config data. + * + * \details Handle case in safety_island_platform_cluster_init() where valid + * config data is passed. + */ +void test_safety_island_platform_cluster_init_success(void) +{ + int status = 0; + uint32_t idx; + + status = safety_island_platform_mod_init( + fwk_module_id_safety_island_platform, SI_CL_COUNT, NULL); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + for (idx = 0; idx < SI_CL_COUNT; idx++) { + fwk_id_t element_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, idx); + fwk_id_get_element_idx_ExpectAndReturn(element_id, idx); + status = safety_island_platform_cluster_init( + element_id, + 1, + (const void *)safety_island_platform_element_table[idx].data); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + } +} + +/*! + * \brief Safety Island Platform unit test: safety_island_platform_bind(), + module binding failure. + * + * \details Handle case in safety_island_platform_bind() when module binding + * fails + */ +void test_safety_island_platform_bind_fail(void) +{ + int status; + fwk_id_t element_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, 0U); + + fwk_id_is_type_ExpectAndReturn(element_id, FWK_ID_TYPE_MODULE, false); + fwk_id_get_element_idx_ExpectAndReturn(element_id, 0U); + fwk_module_bind_ExpectAnyArgsAndReturn(1); + + status = safety_island_platform_bind(element_id, 0U); + + TEST_ASSERT_NOT_EQUAL(status, FWK_SUCCESS); +} + +/*! + * \brief Safety Island Platform unit test: safety_island_platform_bind(), + valid config data and arguments. + * + * \details Handle case in safety_island_platform_bind() where valid config + * data is passed and arguments are passed. + */ +void test_safety_island_platform_bind_success(void) +{ + int status; + fwk_id_t element_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, 0U); + + /* Attempt binding with a non zero round */ + status = safety_island_platform_bind(element_id, 1U); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Attempt binding for the module and not a cluster */ + fwk_id_is_type_ExpectAndReturn( + fwk_module_id_safety_island_platform, FWK_ID_TYPE_MODULE, true); + status = + safety_island_platform_bind(fwk_module_id_safety_island_platform, 0U); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Bind the safety island cluster correctly */ + fwk_id_is_type_ExpectAndReturn(element_id, FWK_ID_TYPE_MODULE, false); + fwk_id_get_element_idx_ExpectAndReturn(element_id, 0U); + fwk_module_bind_IgnoreAndReturn(FWK_SUCCESS); + status = safety_island_platform_bind(element_id, 0U); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); +} + +/*! + * \brief Safety Island Platform unit test: + safety_island_platform_process_bind_request(), invalid arguments. + * + * \details Handle case in safety_island_platform_process_bind_request() where + * invalid arguments are passed. + */ +void test_safety_island_platform_process_bind_request_fail(void) +{ + int status; + const void *api = NULL; + fwk_id_t api_id = FWK_ID_API( + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + MOD_SAFETY_ISLAND_PLATFORM_API_COUNT); + fwk_id_is_type_ExpectAndReturn( + fwk_module_id_safety_island_platform, FWK_ID_TYPE_ELEMENT, false); + status = safety_island_platform_process_bind_request( + fwk_module_id_fake, fwk_module_id_safety_island_platform, api_id, &api); + TEST_ASSERT_EQUAL(status, FWK_E_ACCESS); + TEST_ASSERT_NULL(api); +} + +/*! + * \brief Safety Island Platform unit test: + safety_island_platform_process_bind_request(), valid config data + and arguments. + * + * \details Handle case in safety_island_platform_process_bind_request() where + * valid config and arguments are passed. + */ +void test_safety_island_platform_process_bind_request_success(void) +{ + int status; + uint32_t idx; + + /* Initialize the module */ + status = safety_island_platform_mod_init( + fwk_module_id_safety_island_platform, SI_CL_COUNT, NULL); + + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + for (idx = 0; idx < SI_CL_COUNT; idx++) { + const struct safety_island_cluster_config *config = + safety_island_platform_element_table[idx].data; + fwk_id_t api_id = FWK_ID_API( + FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, + MOD_SAFETY_ISLAND_PLATFORM_API_COUNT); + const struct mod_transport_firmware_signal_api *api; + fwk_id_t element_id = + FWK_ID_ELEMENT(FWK_MODULE_IDX_SAFETY_ISLAND_PLATFORM, idx); + + /* Intiailize the Safety Island cluster */ + fwk_id_get_element_idx_ExpectAndReturn(element_id, idx); + status = safety_island_platform_cluster_init( + element_id, + 1, + (const void *)safety_island_platform_element_table[idx].data); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Bind the safety island cluster */ + fwk_id_is_type_ExpectAndReturn(element_id, FWK_ID_TYPE_MODULE, false); + fwk_id_get_element_idx_ExpectAndReturn(element_id, idx); + fwk_module_bind_IgnoreAndReturn(FWK_SUCCESS); + status = safety_island_platform_bind(element_id, 0U); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Call Process Bind Request on the Safety Island Cluster */ + fwk_id_is_type_ExpectAndReturn(element_id, FWK_ID_TYPE_ELEMENT, true); + fwk_id_get_element_idx_ExpectAndReturn(element_id, idx); + fwk_id_get_api_idx_ExpectAndReturn( + api_id, MOD_SAFETY_ISLAND_PLATFORM_API_IDX_BOOT_CLUSTER); + fwk_id_is_equal_ExpectAndReturn( + fwk_module_id_fake, config->transport_id, true); + + /* Set Transport and Power Domain APIs */ + ctx.safety_island_ctx_table[idx].transport_api = &transport_api; + ctx.safety_island_ctx_table[idx].pd_restricted_api = &pd_restricted_api; + + status = safety_island_platform_process_bind_request( + fwk_module_id_fake, element_id, api_id, (const void **)&api); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + TEST_ASSERT_NOT_NULL(api); + + /* Test signal_message */ + fwk_id_get_element_idx_IgnoreAndReturn(idx); + fwk_module_get_element_name_IgnoreAndReturn("Test"); + status = api->signal_message(api_id); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + + /* Test signal_error */ + fwk_id_get_element_idx_IgnoreAndReturn(idx); + fwk_module_get_element_name_IgnoreAndReturn("Test"); + status = api->signal_error(api_id); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); + } +} + +int safety_island_platform_test_main(void) +{ + UNITY_BEGIN(); + + RUN_TEST(test_safety_island_platform_mod_init_fail); + RUN_TEST(test_safety_island_platform_mod_init_success); + RUN_TEST(test_safety_island_platform_cluster_init_fail); + RUN_TEST(test_safety_island_platform_cluster_init_success); + RUN_TEST(test_safety_island_platform_bind_fail); + RUN_TEST(test_safety_island_platform_bind_success); + RUN_TEST(test_safety_island_platform_process_bind_request_fail); + RUN_TEST(test_safety_island_platform_process_bind_request_success); + + return UNITY_END(); +} + +int main(void) +{ + return safety_island_platform_test_main(); +} diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/test/platform_core.h b/product/automotive-rd/rd1ae/module/safety_island_platform/test/platform_core.h new file mode 100644 index 000000000..88dba1a11 --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/test/platform_core.h @@ -0,0 +1,42 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Description: + * Platform generic definitions. + */ + +#ifndef PLATFORM_CORE_H +#define PLATFORM_CORE_H + +#include + +#define NUMBER_OF_ROOTPORTS 5 + +#define CORES_PER_CLUSTER 1 +#define NUMBER_OF_CLUSTERS 16 + +#define NUM_PCIE_INTEG_CTRL 4 + +static inline unsigned int platform_get_cluster_count(void) +{ + return NUMBER_OF_CLUSTERS; +} + +static inline unsigned int platform_get_core_per_cluster_count( + unsigned int cluster) +{ + fwk_assert(cluster < platform_get_cluster_count()); + + return CORES_PER_CLUSTER; +} + +static inline unsigned int platform_get_core_count(void) +{ + return platform_get_core_per_cluster_count(0) * + platform_get_cluster_count(); +} + +#endif /* PLATFORM_CORE_H */ diff --git a/product/test/CMakeLists.txt b/product/test/CMakeLists.txt index c5558f1b3..d0fc9fb57 100644 --- a/product/test/CMakeLists.txt +++ b/product/test/CMakeLists.txt @@ -110,6 +110,7 @@ list(APPEND SCP_UNITY_SRC ${SCP_ROOT}/unit_test/unity_mocks/scp_unity.c) #Append common unit tests under product/ below here (alphabetical order) list(APPEND UNIT_PRODUCT optee/common/module/mbx) +list(APPEND UNIT_PRODUCT automotive-rd/rd1ae/module/safety_island_platform) list(LENGTH UNIT_PRODUCT UNIT_PRODUCT_MAX) -- GitLab From 24508039df820586da6752da738f812cf5b05204 Mon Sep 17 00:00:00 2001 From: Ziad Elhanafy Date: Thu, 11 Jul 2024 17:00:26 +0100 Subject: [PATCH 43/43] automotive_rd/rd1ae: Add Safety Island platform module documentation Introduce documentation for the Safety Island platform module including an overview, design and configuration example. Signed-off-by: Ziad Elhanafy --- .../doc/safety_island_platform.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 product/automotive-rd/rd1ae/module/safety_island_platform/doc/safety_island_platform.md diff --git a/product/automotive-rd/rd1ae/module/safety_island_platform/doc/safety_island_platform.md b/product/automotive-rd/rd1ae/module/safety_island_platform/doc/safety_island_platform.md new file mode 100644 index 000000000..7157f4eaa --- /dev/null +++ b/product/automotive-rd/rd1ae/module/safety_island_platform/doc/safety_island_platform.md @@ -0,0 +1,108 @@ +\ingroup GroupModules Modules +\defgroup GroupSafetyIslandPlatform SafetyIslandPlatform + +# Module Safety Island Platform Architecture + +Copyright (c) 2024, Arm Limited. All rights reserved. + +## Overview + +The Safety Island Platform provides means of receiving inter-processor messages +in order to boot a Safety Island Cluster. + +## Module Design + +``` + +--------+ +---------+ +------------------------+ +--------------+ + | DRIVER | |TRANSPORT| | SAFETY ISLAND PLATFORM | | POWER DOMAIN | + +---+----+ +----+----+ +-----------+------------+ +------+-------+ + | | | | + Interrupt | | | | +----------->+---+ | | | + | | isr() | | | + | | | | | + |<--+ | | | + | signal_message() | | | + +------------------------------->| | | + | | signal_message() | | + | +------------------------------->| | + | | | For each cluster core | + | | | set_state() | + | | +---------------------------------->| + | | | +------+ + | | | | | Set the power domain state of + | | | | | the Safety Island Cluster core + | | | return status |<-----+ + | | |<----------------------------------+ + | | | | + | |transport_release_channel_lock()| | + | |<-------------------------------+ | + | | | | + | | return status | | + | +------------------------------->| | + | | | | + | | return status | | + | return status |<-------------------------------+ | + |<-------------------------------+ | | + | | | | + | | | | +``` + +## Configuration Example + +The following examples demonstrate how to populate the configuration data for +the Safety Island Platform module. + +```config_safety_island_platform.c``` + +```C +static const struct fwk_element + safety_island_platform_element_table[SI_CL_COUNT + 1] = { + [SI_CL0_IDX] = { + .name = "Safety Island Cluster 0", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS0), + .cluster_layout = {SI_CL0_ID, SI_CL0_CORE_NUM, SI_CL0_CORE_OFS}, + }), + }, + [SI_CL1_IDX] = { + .name = "Safety Island Cluster 1", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS1), + .cluster_layout = {SI_CL1_ID, SI_CL1_CORE_NUM, SI_CL1_CORE_OFS}, + }), + }, + [SI_CL2_IDX] = { + .name = "Safety Island Cluster 2", + .data = &((struct safety_island_cluster_config) { + .transport_id = FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_TRANSPORT, + SCP_CFGD_MOD_TRANSPORT_EIDX_BOOT_SI_CLUS2), + .cluster_layout = {SI_CL2_ID, SI_CL2_CORE_NUM, SI_CL2_CORE_OFS}, + }), + }, + [SI_CL_COUNT] = { 0 }, +}; + +static const struct fwk_element *get_safety_island_platform_element_table( + fwk_id_t module_id) +{ + return safety_island_platform_element_table; +} + +const struct fwk_module_config config_safety_island_platform = { + .elements = + FWK_MODULE_DYNAMIC_ELEMENTS(get_safety_island_platform_element_table), +}; +``` + +Configuration data must also be provided for each Safety Island Cluster in +each of the following modules: +1. Power Domain module +2. PPU module +3. Tansport module +4. Communication Driver such as MHU -- GitLab