1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "tc2_core.h"
9 
10 #include <mod_power_domain.h>
11 #include <mod_ppu_v1.h>
12 #include <mod_system_power.h>
13 #include <mod_tc2_system.h>
14 
15 #include <fwk_element.h>
16 #include <fwk_id.h>
17 #include <fwk_macros.h>
18 #include <fwk_module.h>
19 #include <fwk_module_idx.h>
20 
21 #include <fmw_cmsis.h>
22 
23 #include <stdint.h>
24 
25 static const uint8_t
26     system_power_to_sys_ppu0_state[MOD_SYSTEM_POWER_POWER_STATE_COUNT] = {
27         [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON,
28         [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_OFF,
29         [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF,
30     };
31 
32 static struct fwk_element system_power_element_table[2] = {
33     [0] =
34         {
35             .name = "SYS-PPU-0",
36             .data = &((struct mod_system_power_dev_config){
37                 .api_id = FWK_ID_API_INIT(
38                     FWK_MODULE_IDX_PPU_V1,
39                     MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
40                 .sys_state_table = system_power_to_sys_ppu0_state,
41             }),
42         },
43     [1] = { 0 }, /* Termination description */
44 };
45 
46 static struct mod_system_power_config system_power_config = {
47     .soc_wakeup_irq = SOC_WAKEUP0_IRQ,
48 
49     /* System driver */
50     .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_TC2_SYSTEM),
51     .driver_api_id = FWK_ID_API_INIT(
52         FWK_MODULE_IDX_TC2_SYSTEM,
53         MOD_TC2_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER),
54 
55     /* Initial system state */
56     .initial_system_power_state = MOD_PD_STATE_OFF,
57 };
58 
tc2_system_get_element_table(fwk_id_t unused)59 static const struct fwk_element *tc2_system_get_element_table(fwk_id_t unused)
60 {
61     struct mod_system_power_dev_config *dev_config_table;
62     unsigned int i;
63 
64     /* The system PPUs are placed after the core and cluster PPUs */
65     unsigned int ppu_idx_base =
66         tc2_core_get_core_count() + tc2_core_get_cluster_count();
67 
68     for (i = 0; i < (FWK_ARRAY_SIZE(system_power_element_table) - 1); i++) {
69         dev_config_table =
70             (struct mod_system_power_dev_config *)system_power_element_table[i]
71                 .data;
72         dev_config_table->sys_ppu_id =
73             fwk_id_build_element_id(fwk_module_id_ppu_v1, ppu_idx_base + i);
74     }
75 
76     return system_power_element_table;
77 }
78 
79 const struct fwk_module_config config_system_power = {
80     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(tc2_system_get_element_table),
81     .data = &system_power_config,
82 };
83