From 32e5abd00e484b0d35d65437c6331163e2b9b6fd Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Mon, 22 Jan 2024 16:49:06 +0000 Subject: module: system_power: Add DT configuration support Update system_power SCP module to support device tree configuration. Signed-off-by: Mike Leach --- module/system_power/CMakeLists.txt | 10 ++ module/system_power/src/config_dt_system_power.c | 153 +++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 module/system_power/src/config_dt_system_power.c diff --git a/module/system_power/CMakeLists.txt b/module/system_power/CMakeLists.txt index 3178be7738d8..fb457b5513ce 100644 --- a/module/system_power/CMakeLists.txt +++ b/module/system_power/CMakeLists.txt @@ -13,4 +13,14 @@ target_include_directories(${SCP_MODULE_TARGET} target_sources(${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_system_power.c") +if(SCP_MODULE IN_LIST SCP_DT_CONFIG_MODULES_ALL) + target_sources(${SCP_MODULE_TARGET} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/config_dt_system_power.c") + + # add header file to list used to generate defines for dt include + list(APPEND SCP_DT_BIND_H_GEN_FROM_INCL "${CMAKE_CURRENT_SOURCE_DIR}/include/mod_system_power.h") + set(SCP_DT_BIND_H_GEN_FROM_INCL "${SCP_DT_BIND_H_GEN_FROM_INCL}" PARENT_SCOPE) +endif() + + target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-power-domain) diff --git a/module/system_power/src/config_dt_system_power.c b/module/system_power/src/config_dt_system_power.c new file mode 100644 index 000000000000..499a03b55779 --- /dev/null +++ b/module/system_power/src/config_dt_system_power.c @@ -0,0 +1,153 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include +#include + +#include + +/* Generates system power configuation tables, and system power state + tables from the device tree */ + +/* generate system power tables . + * +e.g. creates: + + static const uint8_t sys_power_to_ppu_state[] = { + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = + (uint8_t)MOD_SYSTEM_POWER_POWER_STATE_SLEEP0, + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, + }; + +from + + + sys_pwr_state_table: sys-pwr-table@0 { + compatible = "scp,sys-power-table"; + label = "sys_power_to_ppu_state"; + power-states = ; + power-values = ; + }; + +Note: this creates a 4 element array, with indexs 0, 1, 3 filled in. + +*/ + +#define SPT_COMPAT scp_sys_power_table +#define SPT_NODE_ID(n) DT_INST(n, SPT_COMPAT) + +#define SPT_TABLE_NAME(n) DT_STRING_TOKEN(SPT_NODE_ID(n), label) + +/* generate a single table entry */ +#define SPT_TABLE_ENTRY(node_id, prop, idx) \ + [DT_PROP_BY_IDX(node_id, power_states, idx)] = (uint8_t)DT_PROP_BY_IDX(node_id, prop, idx), + +/* generator for a single table */ +#define SPT_TABLE_INIT(n) \ +static const uint8_t SPT_TABLE_NAME(n)[] = { \ + DT_FOREACH_PROP_ELEM(SPT_NODE_ID(n), power_values, SPT_TABLE_ENTRY) \ +}; + +/* generate all arm_scp_pd_mask_table table instances */ +DT_FOREACH_OKAY_INST_scp_sys_power_table(SPT_TABLE_INIT) + +/* generate system power device configuration */ +/* + + sys-pwr-device@0 { + compatible = "scp,sys-power-dev"; + label = "system_power"; + scp-ids = <&elem_id FWK_MODULE_IDX_JUNO_PPU JUNO_PPU_DEV_IDX_SYSTOP>, + <&elem_id FWK_MODULE_IDX_JUNO_PPU MOD_JUNO_PPU_API_IDX_PD>; + sys-state-table = <&sys_pwr_state_table>; + }; + +generates: + + static const struct fwk_element system_power_element_table[] = { + [0] = { + .name = "", + .data = &((struct mod_system_power_dev_config) { + .sys_ppu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_JUNO_PPU, + JUNO_PPU_DEV_IDX_SYSTOP), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_JUNO_PPU, + MOD_JUNO_PPU_API_IDX_PD), + .sys_state_table = sys_power_to_ppu_state, + }), + }, + + [1] = { 0 }, +};*/ + +#define SPD_COMPAT scp_sys_power_dev +#define SPD_PROP(n, prop) FWK_DT_INST_PROP(SPD_COMPAT, n , prop) + +#define SPD_ELEM_DATA(n) \ + .sys_ppu_id = FWK_DT_PH_IDX_SCP_ID_ELEM(SPD_COMPAT, n, 0), \ + .api_id = FWK_DT_PH_IDX_SCP_ID_API(SPD_COMPAT, n, 1), \ + .sys_state_table = DT_STRING_TOKEN(SPD_PROP(n, sys_state_table), label), \ + +/* single element table entry */ +#define SPD_ELEM_INIT(n) \ + [n] = { \ + .name = SPD_PROP(n, label), \ + .data = &(struct mod_system_power_dev_config) { \ + SPD_ELEM_DATA(n) \ + } \ + }, + +/* system power dev table generator */ +static struct fwk_element element_table[] = { + /* Macro for array elements */ + DT_FOREACH_OKAY_INST_scp_sys_power_dev(SPD_ELEM_INIT) + /* last null element */ + [DT_N_INST_scp_sys_power_dev_NUM_OKAY] = { 0 }, +}; + +/* generate system power init data */ +/* + system-power-config@0 { + compatible = "scp,system-power"; + soc-wakeup-irq = ; + scp-ids = <&module_id FWK_MODULE_IDX_JUNO_SYSTEM>, + <&elem_id FWK_MODULE_IDX_JUNO_SYSTEM 0>; + init-pwr-state = ; + + }; + +initialises the sys_pwr_config_data structure. + +*/ +#define SYSPWR_COMPAT scp_system_power +#define SYSP_PROP(n, prop) FWK_DT_INST_PROP(SYSPWR_COMPAT, n ,prop) + +static struct mod_system_power_config sys_pwr_config_data = { + .soc_wakeup_irq = SYSP_PROP(0, soc_wakeup_irq), + .driver_id = FWK_DT_PH_IDX_SCP_ID_MOD(SYSPWR_COMPAT, 0, 0), + .driver_api_id = FWK_DT_PH_IDX_SCP_ID_API(SYSPWR_COMPAT, 0, 1), + .initial_system_power_state = SYSP_PROP(0, init_pwr_state), +}; + +/* access data table from dynamic element callback */ +#ifdef FWK_MODULE_GEN_DYNAMIC_SYSTEM_POWER +const struct fwk_element *_static_get_element_table_system_power() { + return element_table; +} +#endif + +/* config dt structure */ +struct fwk_module_config config_dt_system_power = { + .data = &sys_pwr_config_data, +#ifdef FWK_MODULE_GEN_DYNAMIC_SYSTEM_POWER + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dyn_get_element_table_system_power), +#else + .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(element_table), +#endif +}; -- cgit v1.2.3