diff options
author | Anurag Koul <anurag.koul@arm.com> | 2020-06-08 02:59:17 +0100 |
---|---|---|
committer | jimqui01 <54316584+jimqui01@users.noreply.github.com> | 2020-09-15 17:03:53 +0100 |
commit | ca4748098fda8e2a22d102e1f45c59ebe2c95d6c (patch) | |
tree | d0735ed336a981e9fe59712eed7cfbd9c47e58e5 /product/morello | |
parent | 413e91b737cd7a2e474baf165158097ed82249fc (diff) |
morello/scp_ramfw_fvp: add power mgmt config data
Define and add configs for system power domains, PPUs, etc.
Change-Id: Ibad28c2efc703837f32e0a1e76059aa53ff95320
Signed-off-by: Anurag Koul <anurag.koul@arm.com>
Diffstat (limited to 'product/morello')
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_power_domain.c | 231 | ||||
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_power_domain.h | 29 | ||||
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_ppu_v0.c | 43 | ||||
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_ppu_v0.h | 13 | ||||
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_ppu_v1.c | 178 | ||||
-rw-r--r-- | product/morello/scp_ramfw_fvp/config_system_power.c | 100 |
6 files changed, 594 insertions, 0 deletions
diff --git a/product/morello/scp_ramfw_fvp/config_power_domain.c b/product/morello/scp_ramfw_fvp/config_power_domain.c new file mode 100644 index 00000000..a27c9a27 --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_power_domain.c @@ -0,0 +1,231 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "config_ppu_v0.h" +#include "morello_core.h" +#include "morello_power_domain.h" + +#include <mod_power_domain.h> +#include <mod_ppu_v1.h> +#include <mod_system_power.h> + +#include <fwk_element.h> +#include <fwk_id.h> +#include <fwk_macros.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> + +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +/* Maximum power domain name size including the null terminator */ +#define PD_NAME_SIZE 16 + +/* Mask of the allowed states for the systop power domain */ +static const uint32_t systop_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK, + [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK | + (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP0) | + (1 << MOD_SYSTEM_POWER_POWER_STATE_SLEEP1) +}; + +/* + * Mask of the allowed states for the top level power domains + * (but the cluster power domains) depending on the system states. + */ +static const uint32_t toplevel_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK, + [MOD_PD_STATE_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_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[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = MORELLO_CLUSTER_VALID_STATE_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = MOD_PD_STATE_OFF_MASK, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP1] = MOD_PD_STATE_OFF_MASK +}; + +/* Mask of the allowed states for a core depending on the cluster states. */ +static const uint32_t core_pd_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = MORELLO_CORE_VALID_STATE_MASK, + [MOD_PD_STATE_SLEEP] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MORELLO_POWER_DOMAIN_STATE_FUNC_RET] = MORELLO_CORE_VALID_STATE_MASK, + [MORELLO_POWER_DOMAIN_STATE_MEM_RET] = MOD_PD_STATE_OFF_MASK +}; + +/* Power module specific configuration data (none) */ +static const struct mod_power_domain_config morello_power_domain_config = { 0 }; + +/* Power domain element table pointer */ +struct fwk_element *element_table = NULL; + +/* Power domain element configuration table pointer */ +struct mod_power_domain_element_config *pd_config_table = NULL; + +/* + * The SCP's view of PD tree in a single chip mode looks like below: + * + * ---SYSTOP0-- + * / | \ + * / | \ + * / | \ + * CLUS0 CLUS1 DBGTOP0 + * / \ / \ + * CPU0--CPU1--CPU2--CPU3 + * + */ + +static struct fwk_element morello_pd_single_chip_element_table[] = { + [PD_SINGLE_CHIP_IDX_CLUS0CORE0] = + { + .name = "CLUS0CORE0", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CORE, + .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER0, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 0), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = core_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_CLUS0CORE1] = + { + .name = "CLUS0CORE1", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CORE, + .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER0, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 1), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = core_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_CLUS1CORE0] = + { + .name = "CLUS1CORE0", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CORE, + .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER1, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 2), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = core_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_CLUS1CORE1] = + { + .name = "CLUS1CORE1", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CORE, + .parent_idx = PD_SINGLE_CHIP_IDX_CLUSTER1, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 3), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = core_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_CLUSTER0] = + { + .name = "CLUS0", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CLUSTER, + .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 4), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = cluster_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_CLUSTER1] = + { + .name = "CLUS1", + .data = &((struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_CLUSTER, + .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0, + .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V1, 5), + .api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + .allowed_state_mask_table = cluster_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(cluster_pd_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_DBGTOP0] = + { + .name = "DBGTOP0", + .data = + &( + (struct mod_power_domain_element_config){ + .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG, + .parent_idx = PD_SINGLE_CHIP_IDX_SYSTOP0, + .driver_id = + FWK_ID_ELEMENT_INIT( + FWK_MODULE_IDX_PPU_V0, + PPU_V0_ELEMENT_IDX_DBGTOP), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), + .allowed_state_mask_table = + toplevel_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE( + toplevel_allowed_state_mask_table) }), + }, + [PD_SINGLE_CHIP_IDX_SYSTOP0] = + { + .name = "SYSTOP0", + .data = &((struct mod_power_domain_element_config){ .attributes.pd_type = MOD_PD_TYPE_SYSTEM, + .parent_idx = PD_SINGLE_CHIP_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) }), + }, + [PD_SINGLE_CHIP_IDX_COUNT] = { 0 }, +}; + +/* + * Function definitions with internal linkage + */ +static const struct fwk_element *morello_power_domain_get_element_table( + fwk_id_t module_id) +{ + return morello_pd_single_chip_element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_power_domain = { + .elements = + FWK_MODULE_DYNAMIC_ELEMENTS(morello_power_domain_get_element_table), + .data = &morello_power_domain_config, +}; diff --git a/product/morello/scp_ramfw_fvp/config_power_domain.h b/product/morello/scp_ramfw_fvp/config_power_domain.h new file mode 100644 index 00000000..75b1bccd --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_power_domain.h @@ -0,0 +1,29 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_POWER_DOMAIN_H +#define CONFIG_POWER_DOMAIN_H + +#include <stdint.h> + +/* + * Power domain indices in single chip use case + */ +enum pd_single_chip_idx { + PD_SINGLE_CHIP_IDX_CLUS0CORE0, + PD_SINGLE_CHIP_IDX_CLUS0CORE1, + PD_SINGLE_CHIP_IDX_CLUS1CORE0, + PD_SINGLE_CHIP_IDX_CLUS1CORE1, + PD_SINGLE_CHIP_IDX_CLUSTER0, + PD_SINGLE_CHIP_IDX_CLUSTER1, + PD_SINGLE_CHIP_IDX_DBGTOP0, + PD_SINGLE_CHIP_IDX_SYSTOP0, + PD_SINGLE_CHIP_IDX_COUNT, + PD_SINGLE_CHIP_IDX_NONE = UINT32_MAX +}; + +#endif /* CONFIG_POWER_DOMAIN_H */ diff --git a/product/morello/scp_ramfw_fvp/config_ppu_v0.c b/product/morello/scp_ramfw_fvp/config_ppu_v0.c new file mode 100644 index 00000000..8aa56118 --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_ppu_v0.c @@ -0,0 +1,43 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_ppu_v0.h" +#include "morello_scp_mmap.h" + +#include <mod_power_domain.h> +#include <mod_ppu_v0.h> + +#include <fwk_element.h> +#include <fwk_id.h> +#include <fwk_module.h> + +#include <stdbool.h> + +static struct fwk_element ppu_v0_element_table[] = { + [PPU_V0_ELEMENT_IDX_DBGTOP] = + { + .name = "DBGTOP", + .data = &((struct mod_ppu_v0_pd_config){ + .pd_type = MOD_PD_TYPE_DEVICE_DEBUG, + .ppu.reg_base = SCP_PPU_DEBUG_BASE, + .default_power_on = true, + }), + }, + [PPU_V0_ELEMENT_IDX_COUNT] = { 0 }, /* Termination entry */ +}; + +static const struct fwk_element *ppu_v0_get_element_table(fwk_id_t module_id) +{ + return ppu_v0_element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_ppu_v0 = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(ppu_v0_get_element_table), +}; diff --git a/product/morello/scp_ramfw_fvp/config_ppu_v0.h b/product/morello/scp_ramfw_fvp/config_ppu_v0.h new file mode 100644 index 00000000..409d7cd0 --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_ppu_v0.h @@ -0,0 +1,13 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_PPU_V0_H +#define CONFIG_PPU_V0_H + +enum ppu_v0_element_idx { PPU_V0_ELEMENT_IDX_DBGTOP, PPU_V0_ELEMENT_IDX_COUNT }; + +#endif /* CONFIG_PPU_V0_H */ diff --git a/product/morello/scp_ramfw_fvp/config_ppu_v1.c b/product/morello/scp_ramfw_fvp/config_ppu_v1.c new file mode 100644 index 00000000..21fc8b43 --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_ppu_v1.c @@ -0,0 +1,178 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config_power_domain.h" +#include "morello_core.h" +#include "morello_scp_mmap.h" + +#include <mod_cmn_skeena.h> +#include <mod_power_domain.h> +#include <mod_ppu_v1.h> + +#include <fwk_assert.h> +#include <fwk_element.h> +#include <fwk_id.h> +#include <fwk_interrupt.h> +#include <fwk_macros.h> +#include <fwk_mm.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +/* Maximum PPU core name size including the null terminator */ +#define PPU_CORE_NAME_SIZE 16 + +/* Maximum PPU cluster name size including the null terminator */ +#define PPU_CLUS_NAME_SIZE 8 + +/* Lookup table for translating cluster indicies into CMN_SKEENA node IDs */ +static const unsigned int cluster_idx_to_node_id[] = { 192, 140 }; + +/* 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), +}; + +static struct fwk_element ppu_v1_system_element_table[] = { + [0] = + { + .name = "SYS0", + .data = &((struct mod_ppu_v1_pd_config){ + .pd_type = MOD_PD_TYPE_SYSTEM, + .ppu.reg_base = SCP_PPU_SYS0_BASE, + .observer_id = FWK_ID_NONE_INIT, + .default_power_on = true, + }), + }, + [1] = + { + .name = "SYS1", + .data = &((struct mod_ppu_v1_pd_config){ + .pd_type = MOD_PD_TYPE_SYSTEM, + .ppu.reg_base = SCP_PPU_SYS1_BASE, + .observer_id = FWK_ID_NONE_INIT, + .default_power_on = true, + }), + }, +}; + +static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) +{ + struct fwk_element *element_table, *element; + struct mod_ppu_v1_pd_config *pd_config_table, *pd_config; + unsigned int core_idx; + unsigned int cluster_idx; + unsigned int core_count; + unsigned int cluster_count; + unsigned int core_element_count = 0; + + core_count = morello_core_get_core_count(); + cluster_count = morello_core_get_cluster_count(); + + assert(cluster_count == FWK_ARRAY_SIZE(cluster_idx_to_node_id)); + + /* + * Allocate element descriptors based on: + * Number of cores + * + Number of cluster descriptors + * + Number of system power domain descriptors + * + 1 terminator descriptor + */ + element_table = fwk_mm_calloc( + core_count + cluster_count + + FWK_ARRAY_SIZE(ppu_v1_system_element_table) + 1, + sizeof(struct fwk_element)); + if (element_table == NULL) + return NULL; + + pd_config_table = fwk_mm_calloc( + core_count + cluster_count, sizeof(struct mod_ppu_v1_pd_config)); + if (pd_config_table == NULL) + return NULL; + + for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { + for (core_idx = 0; + core_idx < morello_core_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); + if (element->name == NULL) + return NULL; + + snprintf( + (char *)element->name, + PPU_CORE_NAME_SIZE, + "CLUS%uCORE%u", + (uint8_t)cluster_idx, + (uint8_t)core_idx); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CORE; + pd_config->ppu.reg_base = SCP_PPU_CORE_BASE(cluster_idx, core_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); + if (element->name == NULL) + return NULL; + + snprintf( + (char *)element->name, + PPU_CLUS_NAME_SIZE, + "CLUS%u", + (uint8_t)cluster_idx); + + element->data = pd_config; + + pd_config->pd_type = MOD_PD_TYPE_CLUSTER; + pd_config->ppu.reg_base = SCP_PPU_CLUSTER_BASE(cluster_idx); + pd_config->ppu.irq = FWK_INTERRUPT_NONE; + pd_config->observer_id = fwk_module_id_cmn_skeena; + pd_config->observer_api = FWK_ID_API( + FWK_MODULE_IDX_CMN_SKEENA, MOD_CMN_SKEENA_API_IDX_PPU_OBSERVER); + pd_config->post_ppu_on_param = + (void *)&cluster_idx_to_node_id[cluster_idx]; + } + + memcpy( + &element_table[core_count + cluster_count], + ppu_v1_system_element_table, + sizeof(ppu_v1_system_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, PD_SINGLE_CHIP_IDX_SYSTOP0); + + return element_table; +} + +/* + * Power module configuration data + */ +const struct fwk_module_config config_ppu_v1 = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(ppu_v1_get_element_table), + .data = &ppu_v1_config_data, +}; diff --git a/product/morello/scp_ramfw_fvp/config_system_power.c b/product/morello/scp_ramfw_fvp/config_system_power.c new file mode 100644 index 00000000..2f4c79d9 --- /dev/null +++ b/product/morello/scp_ramfw_fvp/config_system_power.c @@ -0,0 +1,100 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "morello_core.h" + +#include <mod_morello_system.h> +#include <mod_power_domain.h> +#include <mod_ppu_v1.h> +#include <mod_system_power.h> + +#include <fwk_element.h> +#include <fwk_id.h> +#include <fwk_macros.h> +#include <fwk_module.h> +#include <fwk_module_idx.h> + +#include <fmw_cmsis.h> + +#include <stdint.h> + +static const uint8_t system_power_to_sys_ppu0_state[] = { + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_OFF, + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, +}; + +static const uint8_t system_power_to_sys_ppu1_state[] = { + [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON, + [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_ON, + [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF, +}; + +static struct fwk_element system_power_element_table[] = { + [0] = + { + .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 = system_power_to_sys_ppu0_state, + }), + }, + + [1] = + { + .name = "SYS-PPU-1", + .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 = system_power_to_sys_ppu1_state, + }), + }, + + [2] = { 0 }, /* Termination description */ +}; + +static struct mod_system_power_config system_power_config = { + .soc_wakeup_irq = SCP_EXT_IRQ, + + /* System driver */ + .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MORELLO_SYSTEM), + .driver_api_id = FWK_ID_API_INIT( + FWK_MODULE_IDX_MORELLO_SYSTEM, + MOD_MORELLO_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + + /* Initial system state */ + .initial_system_power_state = MOD_PD_STATE_OFF, +}; + +static const struct fwk_element *morello_system_get_element_table( + fwk_id_t unused) +{ + struct mod_system_power_dev_config *dev_config_table; + unsigned int i; + + /* The system PPUs are placed after the core and cluster PPUs */ + unsigned int ppu_idx_base = + morello_core_get_core_count() + morello_core_get_cluster_count(); + + for (i = 0; i < (FWK_ARRAY_SIZE(system_power_element_table) - 1); i++) { + dev_config_table = + (struct mod_system_power_dev_config *)system_power_element_table[i] + .data; + dev_config_table->sys_ppu_id = + fwk_id_build_element_id(fwk_module_id_ppu_v1, ppu_idx_base + i); + } + + return system_power_element_table; +} + +const struct fwk_module_config config_system_power = { + .elements = FWK_MODULE_DYNAMIC_ELEMENTS(morello_system_get_element_table), + .data = &system_power_config, +}; |