diff --git a/module/system_power/include/mod_system_power.h b/module/system_power/include/mod_system_power.h index 95c7382757f46b375635d2529a273bb132933599..eb12d490531ec3ce517439fa8a9dab9d313b4094 100644 --- a/module/system_power/include/mod_system_power.h +++ b/module/system_power/include/mod_system_power.h @@ -37,20 +37,26 @@ struct mod_system_power_ext_ppu_config { fwk_id_t api_id; }; +/*! Element configuration */ +struct mod_system_power_dev_config { + /*! Identifier of the system PPU */ + fwk_id_t sys_ppu_id; + + /*! System PPU API identifier */ + fwk_id_t api_id; + + /*! + * \brief Pointer to a table defining the power states this system PPU will + * be set for each system state. + */ + const uint8_t *sys_state_table; +}; + /*! Module configuration */ struct mod_system_power_config { /*! SoC wakeup IRQ number */ unsigned int soc_wakeup_irq; - /*! System 0 PPU element ID */ - fwk_id_t ppu_sys0_id; - - /*! System 1 PPU element ID */ - fwk_id_t ppu_sys1_id; - - /*! System PPUs API ID */ - fwk_id_t ppu_sys_api_id; - /*! Number of extended PPUs */ size_t ext_ppus_count; @@ -67,6 +73,18 @@ struct mod_system_power_config { /*! System shutdown driver API identifier */ fwk_id_t driver_api_id; + + /*! Initial System Power state after power-on */ + enum mod_pd_state initial_system_power_state; +}; + +/*! Platform-specific interrupt commands indices */ +enum mod_system_power_platform_interrupt_cmd { + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_INIT, + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_ENABLE, + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_DISABLE, + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_CLEAR_PENDING, + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_COUNT, }; /*! @@ -84,6 +102,23 @@ struct mod_system_power_driver_api { * \retval One of the driver-defined error code. */ int (*system_shutdown)(enum mod_pd_system_shutdown system_shutdown); + + /*! + * \brief Pointer to the platform interrupt management function. + * + * \details This function allows the driver to manage additional + * platform-specific interrupts. + * + * \note This function is \b optional. + * + * \param isr_cmd Type of command requested. + * + * \retval ::FWK_E_PARAM The interrupt command is not valid. + * \retval ::FWK_SUCCESS The operation succeeded. + * \return One of the standard framework error codes. + */ + int (*platform_interrupts)(enum mod_system_power_platform_interrupt_cmd + isr_cmd); }; /*! diff --git a/module/system_power/src/mod_system_power.c b/module/system_power/src/mod_system_power.c index 2b7eaca1c87d5f7f0d3218d5608f54a709adaa29..fbe980d69dcdd4ef32d59a2421c50126d3259286 100644 --- a/module/system_power/src/mod_system_power.c +++ b/module/system_power/src/mod_system_power.c @@ -20,16 +20,37 @@ #include #include +/* SoC wakeup composite state */ +#define MOD_SYSTEM_POWER_SOC_WAKEUP_STATE \ + MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, \ + 0, \ + MOD_PD_STATE_ON, \ + MOD_PD_STATE_ON, \ + MOD_PD_STATE_ON) + +/* SoC wakeup Power Domain Identifier */ +static const fwk_id_t mod_system_power_soc_wakeup_pd_id = + FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_POWER_DOMAIN, 0); + +/* Element context */ +struct system_power_dev_ctx { + /* Element configuration data pointer */ + const struct mod_system_power_dev_config *config; + + /* Power domain driver API pointer */ + const struct mod_pd_driver_api *sys_ppu_api; +}; + /* Module context */ struct system_power_ctx { /* Log API pointer */ const struct mod_log_api *log_api; - /* SYS0 power domain driver API pointer */ - const struct mod_pd_driver_api *sys0_api; + /* System power element context table */ + struct system_power_dev_ctx *dev_ctx_table; - /* SYS1 power domain driver API pointer*/ - const struct mod_pd_driver_api *sys1_api; + /* Number of elements */ + unsigned int dev_count; /* Pointer to array of extended PPU power domain driver APIs */ const struct mod_pd_driver_api **ext_ppu_apis; @@ -49,17 +70,19 @@ struct system_power_ctx { /* Current system-level power state */ unsigned int state; + /* Requested power state */ + unsigned int requested_state; + /* Pointer to module config */ const struct mod_system_power_config *config; }; -struct system_power_isr { - unsigned int interrupt; - void (*handler)(void); -}; - static struct system_power_ctx system_power_ctx; +/* + * Static helpers + */ + static void ext_ppus_set_state(enum mod_pd_state state) { unsigned int i; @@ -71,6 +94,27 @@ static void ext_ppus_set_state(enum mod_pd_state state) } } +static int set_system_power_state(unsigned int state) +{ + int status; + unsigned int i; + struct system_power_dev_ctx *dev_ctx; + const uint8_t *sys_state_table; + + for (i = 0; i < system_power_ctx.dev_count; i++) { + dev_ctx = &system_power_ctx.dev_ctx_table[i]; + + sys_state_table = dev_ctx->config->sys_state_table; + + status = dev_ctx->sys_ppu_api->set_state(dev_ctx->config->sys_ppu_id, + sys_state_table[state]); + if (status != FWK_SUCCESS) + return status; + } + + return FWK_SUCCESS; +} + /* * Functions fulfilling the Power Domain module's driver API */ @@ -78,19 +122,33 @@ static void ext_ppus_set_state(enum mod_pd_state state) static int system_power_set_state(fwk_id_t pd_id, unsigned int state) { int status; + unsigned int soc_wakeup_irq; status = fwk_module_check_call(pd_id); if (status != FWK_SUCCESS) return status; + if (!fwk_expect(state < MOD_SYSTEM_POWER_POWER_STATE_COUNT)) + return FWK_E_PARAM; + + soc_wakeup_irq = system_power_ctx.config->soc_wakeup_irq; + + system_power_ctx.requested_state = state; + switch (state) { case MOD_PD_STATE_ON: - fwk_interrupt_disable(system_power_ctx.config->soc_wakeup_irq); + fwk_interrupt_disable(soc_wakeup_irq); + + if (system_power_ctx.driver_api->platform_interrupts != NULL) { + status = system_power_ctx.driver_api->platform_interrupts( + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_DISABLE); + if (status != FWK_SUCCESS) + return FWK_E_DEVICE; + } - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys0_id, MOD_PD_STATE_ON); - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys1_id, MOD_PD_STATE_ON); + status = set_system_power_state(state); + if (status != FWK_SUCCESS) + return status; ext_ppus_set_state(MOD_PD_STATE_ON); @@ -99,23 +157,46 @@ static int system_power_set_state(fwk_id_t pd_id, unsigned int state) case MOD_SYSTEM_POWER_POWER_STATE_SLEEP0: ext_ppus_set_state(MOD_PD_STATE_OFF); - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys0_id, MOD_PD_STATE_OFF); - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys1_id, MOD_PD_STATE_ON); + fwk_interrupt_clear_pending(soc_wakeup_irq); - fwk_interrupt_enable(system_power_ctx.config->soc_wakeup_irq); + if (system_power_ctx.driver_api->platform_interrupts != NULL) { + status = + system_power_ctx.driver_api->platform_interrupts( + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_CLEAR_PENDING); + if (status != FWK_SUCCESS) + return FWK_E_DEVICE; + } + + status = set_system_power_state(state); + if (status != FWK_SUCCESS) + return status; + + fwk_interrupt_enable(soc_wakeup_irq); + + if (system_power_ctx.driver_api->platform_interrupts != NULL) { + status = system_power_ctx.driver_api->platform_interrupts( + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_ENABLE); + if (status != FWK_SUCCESS) + return FWK_E_DEVICE; + } break; case MOD_PD_STATE_OFF: - fwk_interrupt_disable(system_power_ctx.config->soc_wakeup_irq); + fwk_interrupt_disable(soc_wakeup_irq); + + if (system_power_ctx.driver_api->platform_interrupts != NULL) { + status = system_power_ctx.driver_api->platform_interrupts( + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_DISABLE); + if (status != FWK_SUCCESS) + return FWK_E_DEVICE; + } + ext_ppus_set_state(MOD_PD_STATE_OFF); - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys0_id, MOD_PD_STATE_OFF); - system_power_ctx.sys0_api->set_state( - system_power_ctx.config->ppu_sys1_id, MOD_PD_STATE_OFF); + status = set_system_power_state(state); + if (status != FWK_SUCCESS) + return status; break; @@ -159,18 +240,12 @@ static int system_power_shutdown(fwk_id_t pd_id, static void soc_wakeup_handler(void) { int status; - fwk_id_t pd_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, 0); - uint32_t state = MOD_PD_COMPOSITE_STATE(MOD_PD_LEVEL_2, - 0, - MOD_PD_STATE_ON, - MOD_PD_STATE_ON, - MOD_PD_STATE_ON); + uint32_t state = MOD_SYSTEM_POWER_SOC_WAKEUP_STATE; status = system_power_ctx.mod_pd_restricted_api->set_composite_state_async( - pd_id, false, state); - assert(status == FWK_SUCCESS); - (void)status; + mod_system_power_soc_wakeup_pd_id, false, state); + fwk_expect(status == FWK_SUCCESS); } static const struct mod_pd_driver_api system_power_power_domain_driver_api = { @@ -184,32 +259,28 @@ static const struct mod_pd_driver_api system_power_power_domain_driver_api = { * Functions fulfilling the Power Domain module's driver input API */ -static int system_power_report_power_state_transition(fwk_id_t module_id, +static int system_power_report_power_state_transition(fwk_id_t dev_id, unsigned int state) { int status; - unsigned int sys0_state, sys1_state; + static unsigned int sys_ppu_transition_count = 0; - system_power_ctx.sys0_api->get_state(system_power_ctx.config->ppu_sys0_id, - &sys0_state); - system_power_ctx.sys1_api->get_state(system_power_ctx.config->ppu_sys1_id, - &sys1_state); + status = fwk_module_check_call(dev_id); + if (status != FWK_SUCCESS) + return status; - if ((sys0_state == MOD_PD_STATE_ON) && (sys1_state == MOD_PD_STATE_ON)) - system_power_ctx.state = MOD_PD_STATE_ON; - else if ((sys0_state == MOD_PD_STATE_OFF) && - (sys1_state == MOD_PD_STATE_ON)) - system_power_ctx.state = MOD_SYSTEM_POWER_POWER_STATE_SLEEP0; - else - system_power_ctx.state = MOD_PD_STATE_OFF; + sys_ppu_transition_count++; - status = - system_power_ctx.mod_pd_driver_input_api->report_power_state_transition( - system_power_ctx.mod_pd_system_id, system_power_ctx.state); - assert(status == FWK_SUCCESS); - (void)status; + if (sys_ppu_transition_count < system_power_ctx.dev_count) + return FWK_SUCCESS; - return FWK_SUCCESS; + system_power_ctx.state = system_power_ctx.requested_state; + + sys_ppu_transition_count = 0; + + return system_power_ctx.mod_pd_driver_input_api-> + report_power_state_transition(system_power_ctx.mod_pd_system_id, + system_power_ctx.state); } static const struct mod_pd_driver_input_api @@ -222,13 +293,22 @@ static const struct mod_pd_driver_input_api */ static int system_power_mod_init(fwk_id_t module_id, - unsigned int unused, + unsigned int element_count, const void *data) { - assert(data != NULL); + const struct mod_system_power_config *config; + + fwk_assert(data != NULL); + fwk_expect(element_count > 0); - system_power_ctx.config = data; + system_power_ctx.config = config = data; system_power_ctx.mod_pd_system_id = FWK_ID_NONE; + system_power_ctx.dev_count = element_count; + + system_power_ctx.dev_ctx_table = + fwk_mm_calloc(element_count, sizeof(struct system_power_dev_ctx)); + if (system_power_ctx.dev_ctx_table == NULL) + return FWK_E_NOMEM; if (system_power_ctx.config->ext_ppus_count > 0) { system_power_ctx.ext_ppu_apis = fwk_mm_calloc( @@ -241,16 +321,42 @@ static int system_power_mod_init(fwk_id_t module_id, if (system_power_ctx.config->soc_wakeup_irq != FWK_INTERRUPT_NONE) { return fwk_interrupt_set_isr(system_power_ctx.config->soc_wakeup_irq, soc_wakeup_handler); - } else - return FWK_SUCCESS; + } + + return FWK_SUCCESS; +} + +static int system_power_mod_element_init(fwk_id_t element_id, + unsigned int unused, + const void *data) +{ + struct system_power_dev_ctx *dev_ctx; + + fwk_assert(data != NULL); + + dev_ctx = + system_power_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); + + dev_ctx->config = data; + + /* Ensure a system state table is provided */ + if (dev_ctx->config->sys_state_table == NULL) + return FWK_E_DATA; + + return FWK_SUCCESS; } static int system_power_bind(fwk_id_t id, unsigned int round) { int status; unsigned int i; + const struct mod_system_power_config *config; + struct system_power_dev_ctx *dev_ctx; if (round == 1) { + if (!fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) + return FWK_SUCCESS; + /* * During the first round of binding, the power domain module should * have bound to the power domain driver API provided by the present @@ -263,50 +369,49 @@ static int system_power_bind(fwk_id_t id, unsigned int round) &system_power_ctx.mod_pd_driver_input_api); } - status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), - FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &system_power_ctx.log_api); - if (status != FWK_SUCCESS) - return status; + if (fwk_id_is_type(id, FWK_ID_TYPE_MODULE)) { + status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG), + FWK_ID_API(FWK_MODULE_IDX_LOG, 0), &system_power_ctx.log_api); + if (status != FWK_SUCCESS) + return status; - status = fwk_module_bind(system_power_ctx.config->ppu_sys0_id, - system_power_ctx.config->ppu_sys_api_id, - &system_power_ctx.sys0_api); - if (status != FWK_SUCCESS) - return status; + config = system_power_ctx.config; - status = fwk_module_bind(system_power_ctx.config->ppu_sys1_id, - system_power_ctx.config->ppu_sys_api_id, - &system_power_ctx.sys1_api); - if (status != FWK_SUCCESS) - return status; + for (i = 0; i < config->ext_ppus_count; i++) { + status = fwk_module_bind( + config->ext_ppus[i].ppu_id, + config->ext_ppus[i].api_id, + &system_power_ctx.ext_ppu_apis[i]); + if (status != FWK_SUCCESS) + return status; + } - for (i = 0; i < system_power_ctx.config->ext_ppus_count; i++) { - status = fwk_module_bind( - system_power_ctx.config->ext_ppus[i].ppu_id, - system_power_ctx.config->ext_ppus[i].api_id, - &system_power_ctx.ext_ppu_apis[i]); + status = fwk_module_bind(config->driver_id, + config->driver_api_id, + &system_power_ctx.driver_api); if (status != FWK_SUCCESS) return status; - } - status = fwk_module_bind(system_power_ctx.config->driver_id, - system_power_ctx.config->driver_api_id, &system_power_ctx.driver_api); - if (status != FWK_SUCCESS) - return status; + return fwk_module_bind(fwk_module_id_power_domain, + mod_pd_api_id_restricted, + &system_power_ctx.mod_pd_restricted_api); + } - status = fwk_module_bind(fwk_module_id_power_domain, - mod_pd_api_id_restricted, - &system_power_ctx.mod_pd_restricted_api); - if (status != FWK_SUCCESS) - return status; + dev_ctx = system_power_ctx.dev_ctx_table + fwk_id_get_element_idx(id); - return FWK_SUCCESS; + return fwk_module_bind(dev_ctx->config->sys_ppu_id, + dev_ctx->config->api_id, + &dev_ctx->sys_ppu_api); } static int system_power_process_bind_request(fwk_id_t requester_id, - fwk_id_t pd_id, fwk_id_t api_id, - const void **api) + fwk_id_t pd_id, + fwk_id_t api_id, + const void **api) { + unsigned int dev_idx; + struct system_power_dev_ctx *dev_ctx; + if (fwk_id_is_equal(api_id, mod_system_power_api_id_pd_driver)) { if (!fwk_id_is_equal(fwk_id_build_module_id(requester_id), @@ -316,11 +421,21 @@ static int system_power_process_bind_request(fwk_id_t requester_id, *api = &system_power_power_domain_driver_api; system_power_ctx.mod_pd_system_id = requester_id; } else { - if (!fwk_id_is_equal(requester_id, - system_power_ctx.config->ppu_sys0_id) && - !fwk_id_is_equal(requester_id, - system_power_ctx.config->ppu_sys1_id)) + for (dev_idx = 0; dev_idx < system_power_ctx.dev_count; dev_idx++) { + dev_ctx = &system_power_ctx.dev_ctx_table[dev_idx]; + + /* + * If requester_id refers to a system PPU configured by any one of + * our elements, break when dev_idx reaches that element. + */ + if (fwk_id_is_equal(requester_id, dev_ctx->config->sys_ppu_id)) + break; + } + if (dev_idx >= system_power_ctx.dev_count) { + /* Requester_id does not refer to any configured system PPU */ return FWK_E_ACCESS; + } + *api = &system_power_power_domain_driver_input_api; } @@ -330,26 +445,17 @@ static int system_power_process_bind_request(fwk_id_t requester_id, static int system_power_start(fwk_id_t id) { int status; - unsigned int state; - - status = system_power_ctx.sys1_api->get_state - (system_power_ctx.config->ppu_sys1_id, &state); - if (status != FWK_SUCCESS) - return status; - if (state == MOD_PD_STATE_OFF) { - system_power_ctx.state = MOD_PD_STATE_OFF; - return FWK_SUCCESS; + if (system_power_ctx.driver_api->platform_interrupts != NULL) { + status = system_power_ctx.driver_api->platform_interrupts( + MOD_SYSTEM_POWER_PLATFORM_INTERRUPT_CMD_INIT); + if (status != FWK_SUCCESS) + return status; } - status = system_power_ctx.sys0_api->get_state - (system_power_ctx.config->ppu_sys0_id, &state); - if (status != FWK_SUCCESS) - return status; - - system_power_ctx.state = (state == MOD_PD_STATE_ON) ? - MOD_PD_STATE_ON : - MOD_SYSTEM_POWER_POWER_STATE_SLEEP0; + /* Configure initial power state */ + system_power_ctx.state = + (unsigned int)system_power_ctx.config->initial_system_power_state; return FWK_SUCCESS; } @@ -359,6 +465,7 @@ const struct fwk_module module_system_power = { .type = FWK_MODULE_TYPE_DRIVER, .api_count = MOD_SYSTEM_POWER_API_COUNT, .init = system_power_mod_init, + .element_init = system_power_mod_element_init, .bind = system_power_bind, .start = system_power_start, .process_bind_request = system_power_process_bind_request, diff --git a/product/n1sdp/scp_ramfw/config_system_power.c b/product/n1sdp/scp_ramfw/config_system_power.c index 7b9360f52213c54181dc011f733462772496453e..c87ca1e5aac204bc9ae035833ad5528fad4ee5e2 100644 --- a/product/n1sdp/scp_ramfw/config_system_power.c +++ b/product/n1sdp/scp_ramfw/config_system_power.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,41 +16,70 @@ #include #include -/* Table with only a terminator */ -static const struct fwk_element n1sdp_system_element_table = { 0 }; +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, - /* PPU settings */ - .ppu_sys_api_id = FWK_ID_API_INIT( - FWK_MODULE_IDX_PPU_V1, - MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), - /* System driver */ .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_N1SDP_SYSTEM), .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_N1SDP_SYSTEM, MOD_N1SDP_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + + /* Initial system state */ + .initial_system_power_state = MOD_PD_STATE_OFF, }; static const struct fwk_element *n1sdp_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 = n1sdp_core_get_core_count() + n1sdp_core_get_cluster_count(); - /* Set the system PPU elements */ - system_power_config.ppu_sys0_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base); - system_power_config.ppu_sys1_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base + 1); - - /* - * Return table with only a terminator as this function is only used to - * setup the dynamic module data. - */ - return &n1sdp_system_element_table; + 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 = { diff --git a/product/rdn1e1/scp_ramfw/config_system_power.c b/product/rdn1e1/scp_ramfw/config_system_power.c index c92d6549b06112b82e5a5674171b658dac7d28d6..af1a896f7a7a883750c5527ab95589675cccbcfc 100644 --- a/product/rdn1e1/scp_ramfw/config_system_power.c +++ b/product/rdn1e1/scp_ramfw/config_system_power.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,41 +16,70 @@ #include #include -/* Table with only a terminator */ -static const struct fwk_element rdn1e1_system_element_table = { 0 }; +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 = SOC_WAKEUP0_IRQ, - /* PPU settings */ - .ppu_sys_api_id = FWK_ID_API_INIT( - FWK_MODULE_IDX_PPU_V1, - MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), - /* System driver */ .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_RDN1E1_SYSTEM), .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_RDN1E1_SYSTEM, MOD_RDN1E1_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + + /* Initial system state */ + .initial_system_power_state = MOD_PD_STATE_OFF, }; static const struct fwk_element *rdn1e1_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 = rdn1e1_core_get_core_count() + rdn1e1_core_get_cluster_count(); - /* Set the system PPU elements */ - system_power_config.ppu_sys0_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base); - system_power_config.ppu_sys1_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base + 1); - - /* - * Return table with only a terminator as this function is only used to - * setup the dynamic module data. - */ - return &rdn1e1_system_element_table; + 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 = { diff --git a/product/sgi575/scp_ramfw/config_system_power.c b/product/sgi575/scp_ramfw/config_system_power.c index 95a2bb2776466e2766c263474a8dfd5a59765dd0..cf24b08bb4e33663696e06624badc76aeda5b0b9 100644 --- a/product/sgi575/scp_ramfw/config_system_power.c +++ b/product/sgi575/scp_ramfw/config_system_power.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -15,44 +16,73 @@ #include #include -/* Table with only a terminator */ -static const struct fwk_element sgi575_system_element_table = { 0 }; +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 = SOC_WAKEUP0_IRQ, - /* PPU settings */ - .ppu_sys_api_id = FWK_ID_API_INIT( - FWK_MODULE_IDX_PPU_V1, - MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), - /* System driver */ .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SGI575_SYSTEM), .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SGI575_SYSTEM, MOD_SGI575_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + + /* Initial system state */ + .initial_system_power_state = MOD_PD_STATE_OFF, }; static const struct fwk_element *sgi575_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 = sgi575_core_get_core_count() + sgi575_core_get_cluster_count(); - /* Set the system PPU elements */ - system_power_config.ppu_sys0_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base); - system_power_config.ppu_sys1_id = fwk_id_build_element_id( - fwk_module_id_ppu_v1, ppu_idx_base + 1); - - /* - * Return table with only a terminator as this function is only used to - * setup the dynamic module data. - */ - return &sgi575_system_element_table; + 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 = { - .get_element_table = sgi575_system_get_element_table, .data = &system_power_config, + .get_element_table = sgi575_system_get_element_table, }; diff --git a/product/sgm775/scp_ramfw/config_system_power.c b/product/sgm775/scp_ramfw/config_system_power.c index 0823ffd188e909c36bf4a8fe5262dff34ae039dc..d80595a61b21a659bdc400f88e299511f7448889 100644 --- a/product/sgm775/scp_ramfw/config_system_power.c +++ b/product/sgm775/scp_ramfw/config_system_power.c @@ -45,18 +45,57 @@ static const struct mod_system_power_ext_ppu_config ext_ppus[] = { }, }; +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 const struct fwk_element system_power_element_table[] = { + [0] = { + .name = "SYS-PPU-0", + .data = &((struct mod_system_power_dev_config) { + .sys_ppu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V0, + PPU_V0_ELEMENT_IDX_SYS0), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), + .sys_state_table = system_power_to_sys_ppu0_state, + }), + }, + + [1] = { + .name = "SYS-PPU-1", + .data = &((struct mod_system_power_dev_config) { + .sys_ppu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V0, + PPU_V0_ELEMENT_IDX_SYS1), + .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), + .sys_state_table = system_power_to_sys_ppu1_state, + }), + }, + + [2] = { 0 }, /* Termination description */ +}; + +static const struct fwk_element *system_power_get_element_table( + fwk_id_t module_id) +{ + return system_power_element_table; +} + const struct fwk_module_config config_system_power = { .data = &((struct mod_system_power_config) { .soc_wakeup_irq = SOC_WAKEUP0_IRQ, - .ppu_sys0_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V0, - PPU_V0_ELEMENT_IDX_SYS0), - .ppu_sys1_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PPU_V0, - PPU_V0_ELEMENT_IDX_SYS1), - .ppu_sys_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), .ext_ppus = ext_ppus, .ext_ppus_count = FWK_ARRAY_SIZE(ext_ppus), .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SGM775_SYSTEM), .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_SGM775_SYSTEM, - MOD_SGM775_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER) - }) + MOD_SGM775_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER), + .initial_system_power_state = MOD_PD_STATE_ON, + }), + .get_element_table = system_power_get_element_table, };