diff --git a/module/ppu_v1/include/mod_ppu_v1.h b/module/ppu_v1/include/mod_ppu_v1.h index fba746a59..5006ea54e 100644 --- a/module/ppu_v1/include/mod_ppu_v1.h +++ b/module/ppu_v1/include/mod_ppu_v1.h @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -119,6 +119,9 @@ struct mod_ppu_v1_config { /*! Number of cores in this cluster */ uint32_t num_of_cores_in_cluster; + + /*! Set to true if the PPU is configured to operate in dynamic mode. */ + bool is_cluster_ppu_dynamic_mode_configured; }; /*! diff --git a/module/ppu_v1/src/mod_ppu_v1.c b/module/ppu_v1/src/mod_ppu_v1.c index 596a4dbd2..098c83950 100644 --- a/module/ppu_v1/src/mod_ppu_v1.c +++ b/module/ppu_v1/src/mod_ppu_v1.c @@ -1,6 +1,6 @@ /* * Arm SCP/MCP Software - * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -79,6 +79,9 @@ struct ppu_v1_ctx { /* Number of power domains */ size_t pd_ctx_table_size; + /* Set to true if the PPU is configured to operate in dynamic mode. */ + bool is_cluster_ppu_dynamic_mode_configured; + /*! Maximum number of cores within a cluster */ uint8_t max_num_cores_per_cluster; }; @@ -486,7 +489,13 @@ static void cluster_on(struct ppu_v1_pd_ctx *pd_ctx) ppu_v1_request_operating_mode(ppu, pd_ctx->config->opmode); - ppu_v1_set_power_mode(ppu, PPU_V1_MODE_ON, pd_ctx->timer_ctx); + if (ppu_v1_ctx.is_cluster_ppu_dynamic_mode_configured) { + ppu_v1_lock_off_enable(ppu); + ppu_v1_dynamic_enable(ppu, PPU_V1_MODE_OFF); + } else { + ppu_v1_set_power_mode(ppu, PPU_V1_MODE_ON, pd_ctx->timer_ctx); + } + status = pd_ctx->pd_driver_input_api->report_power_state_transition( pd_ctx->bound_id, MOD_PD_STATE_ON); fwk_assert(status == FWK_SUCCESS); @@ -521,6 +530,10 @@ static int ppu_v1_cluster_pd_init(struct ppu_v1_pd_ctx *pd_ctx) ppu_v1_set_input_edge_sensitivity(ppu, PPU_V1_MODE_ON, PPU_V1_EDGE_SENSITIVITY_FALLING_EDGE); + + if (ppu_v1_ctx.is_cluster_ppu_dynamic_mode_configured) { + ppu_v1_dynamic_enable(ppu, PPU_V1_MODE_OFF); + } } return FWK_SUCCESS; @@ -560,13 +573,26 @@ static int ppu_v1_cluster_pd_set_state(fwk_id_t cluster_pd_id, } #endif -static void cluster_pd_ppu_interrupt_handler(struct ppu_v1_pd_ctx *pd_ctx) +static void cluster_pd_ppu_dyn_policy_min_int_handler( + struct ppu_v1_pd_ctx *pd_ctx) { int status; - struct ppu_v1_reg *ppu; - enum ppu_v1_mode current_mode; - fwk_assert(pd_ctx != NULL); + ppu_v1_ack_interrupt(pd_ctx->ppu, PPU_V1_ISR_DYN_POLICY_MIN_IRQ); + ppu_v1_interrupt_mask(pd_ctx->ppu, PPU_V1_IMR_DYN_POLICY_MIN_IRQ_MASK); + + status = pd_ctx->pd_driver_input_api->report_power_state_transition( + pd_ctx->bound_id, MOD_PD_STATE_SLEEP); + fwk_assert(status == FWK_SUCCESS); + (void)status; + return; +} + +static void cluster_pd_ppu_normal_mode_int_handler(struct ppu_v1_pd_ctx *pd_ctx) +{ + int status; + enum ppu_v1_mode current_mode; + struct ppu_v1_reg *ppu; ppu = pd_ctx->ppu; @@ -620,6 +646,18 @@ static void cluster_pd_ppu_interrupt_handler(struct ppu_v1_pd_ctx *pd_ctx) } } +static void cluster_pd_ppu_interrupt_handler(struct ppu_v1_pd_ctx *pd_ctx) +{ + fwk_assert(pd_ctx != NULL); + + /* Minimum policy reached interrupt */ + if (ppu_v1_is_dyn_policy_min_interrupt(pd_ctx->ppu)) { + return cluster_pd_ppu_dyn_policy_min_int_handler(pd_ctx); + } + + return cluster_pd_ppu_normal_mode_int_handler(pd_ctx); +} + #ifdef BUILD_HAS_MOD_POWER_DOMAIN static const struct mod_pd_driver_api cluster_pd_driver = { .set_state = ppu_v1_cluster_pd_set_state, @@ -700,6 +738,9 @@ static int ppu_v1_mod_init( module_config->num_of_cores_in_cluster; } + ppu_v1_ctx.is_cluster_ppu_dynamic_mode_configured = + module_config->is_cluster_ppu_dynamic_mode_configured; + return FWK_SUCCESS; } diff --git a/tools/cppcheck_suppress_list.txt b/tools/cppcheck_suppress_list.txt index 7eed1f2c2..58353debe 100755 --- a/tools/cppcheck_suppress_list.txt +++ b/tools/cppcheck_suppress_list.txt @@ -64,9 +64,9 @@ nullPointerRedundantCheck:*module/dmc500/src/mod_dmc500.c:65 nullPointerRedundantCheck:*module/mhu2/src/mod_mhu2.c:90 nullPointerRedundantCheck:*module/pl011/src/mod_pl011.c:135 nullPointerRedundantCheck:*module/pl011/src/mod_pl011.c:136 -nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:638 -nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:1014 -nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:1015 +nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:676 +nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:1055 +nullPointerRedundantCheck:*module/ppu_v1/src/mod_ppu_v1.c:1056 nullPointerRedundantCheck:*module/reg_sensor/src/mod_reg_sensor.c:52 nullPointerRedundantCheck:*module/sds/src/mod_sds.c:273 nullPointerRedundantCheck:*module/sds/src/mod_sds.c:279