/* * Arm SCP/MCP Software * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "config_power_domain.h" #include "config_ppu_v1.h" #include "sgm776_core.h" #include #include #include #include #include #include #include #include #include #include #include #include /* Mask of the allowed states for the systop power domain */ static const uint32_t systop_allowed_state_mask_table[] = { [0] = 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_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK | MOD_PD_STATE_SLEEP_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_ON] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_ON_MASK | MOD_PD_STATE_SLEEP_MASK, [MOD_PD_STATE_SLEEP] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, }; /* Power module specific configuration data (none) */ static const struct mod_power_domain_config sgm776_power_domain_config = { 0 }; static struct fwk_element sgm776_power_domain_static_element_table[] = { [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DBGTOP] = { .name = "DBGTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG, .driver_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_DBGTOP), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), .allowed_state_mask_table = toplevel_allowed_state_mask_table, .allowed_state_mask_table_size = FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table) }), }, [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_DPUTOP] = { .name = "DPUTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_DEVICE, .driver_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_DPUTOP), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), .allowed_state_mask_table = toplevel_allowed_state_mask_table, .allowed_state_mask_table_size = FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table) }), }, [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_GPUTOP] = { .name = "GPUTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_DEVICE, .driver_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_GPUTOP), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), .allowed_state_mask_table = toplevel_allowed_state_mask_table, .allowed_state_mask_table_size = FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table) }), }, [CONFIG_POWER_DOMAIN_SYSTOP_CHILD_VPUTOP] = { .name = "VPUTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_DEVICE, .driver_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_PPU_V1, PPU_V1_ELEMENT_IDX_VPUTOP), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), .allowed_state_mask_table = toplevel_allowed_state_mask_table, .allowed_state_mask_table_size = FWK_ARRAY_SIZE(toplevel_allowed_state_mask_table) }), }, [CONFIG_POWER_DOMAIN_SYSTOP_SYSTEM] = { .name = "SYSTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_SYSTEM, .parent_idx = CONFIG_POWER_DOMAIN_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) }), }, }; /* * Function definitions with internal linkage */ static const struct fwk_element *sgm776_power_domain_get_element_table (fwk_id_t module_id) { unsigned int elem_idx; struct mod_power_domain_element_config *pd_config; size_t static_table_size = FWK_ARRAY_SIZE(sgm776_power_domain_static_element_table); for (elem_idx = 0; elem_idx < (static_table_size - 1); elem_idx++) { pd_config = (struct mod_power_domain_element_config *) sgm776_power_domain_static_element_table[elem_idx] .data; pd_config->driver_id = FWK_ID_ELEMENT( FWK_MODULE_IDX_PPU_V1, elem_idx + sgm776_core_get_count() + sgm776_cluster_get_count()); } return create_power_domain_element_table( sgm776_core_get_count(), sgm776_cluster_get_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), sgm776_power_domain_static_element_table, FWK_ARRAY_SIZE(sgm776_power_domain_static_element_table)); } /* * Power module configuration data */ struct fwk_module_config config_power_domain = { .data = &sgm776_power_domain_config, .elements = FWK_MODULE_DYNAMIC_ELEMENTS(sgm776_power_domain_get_element_table), };