1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "morello_core.h"
9 
10 #include <mod_morello_system.h>
11 #include <mod_power_domain.h>
12 #include <mod_ppu_v1.h>
13 #include <mod_system_power.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 system_power_to_sys_ppu0_state[] = {
26     [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON,
27     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_OFF,
28     [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF,
29 };
30 
31 static const uint8_t system_power_to_sys_ppu1_state[] = {
32     [MOD_PD_STATE_ON] = (uint8_t)MOD_PD_STATE_ON,
33     [MOD_SYSTEM_POWER_POWER_STATE_SLEEP0] = (uint8_t)MOD_PD_STATE_ON,
34     [MOD_PD_STATE_OFF] = (uint8_t)MOD_PD_STATE_OFF,
35 };
36 
37 static struct fwk_element system_power_element_table[] = {
38     [0] =
39         {
40             .name = "SYS-PPU-0",
41             .data = &((struct mod_system_power_dev_config){
42                 .api_id = FWK_ID_API_INIT(
43                     FWK_MODULE_IDX_PPU_V1,
44                     MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
45                 .sys_state_table = system_power_to_sys_ppu0_state,
46             }),
47         },
48 
49     [1] =
50         {
51             .name = "SYS-PPU-1",
52             .data = &((struct mod_system_power_dev_config){
53                 .api_id = FWK_ID_API_INIT(
54                     FWK_MODULE_IDX_PPU_V1,
55                     MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER),
56                 .sys_state_table = system_power_to_sys_ppu1_state,
57             }),
58         },
59 
60     [2] = { 0 }, /* Termination description */
61 };
62 
63 static struct mod_system_power_config system_power_config = {
64     .soc_wakeup_irq = SCP_EXT_IRQ,
65 
66     /* System driver */
67     .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MORELLO_SYSTEM),
68     .driver_api_id = FWK_ID_API_INIT(
69         FWK_MODULE_IDX_MORELLO_SYSTEM,
70         MOD_MORELLO_SYSTEM_API_IDX_SYSTEM_POWER_DRIVER),
71 
72     /* Initial system state */
73     .initial_system_power_state = MOD_PD_STATE_OFF,
74 };
75 
morello_system_get_element_table(fwk_id_t unused)76 static const struct fwk_element *morello_system_get_element_table(
77     fwk_id_t unused)
78 {
79     struct mod_system_power_dev_config *dev_config_table;
80     unsigned int i;
81 
82     /* The system PPUs are placed after the core and cluster PPUs */
83     unsigned int ppu_idx_base =
84         morello_core_get_core_count() + morello_core_get_cluster_count();
85 
86     for (i = 0; i < (FWK_ARRAY_SIZE(system_power_element_table) - 1); i++) {
87         dev_config_table =
88             (struct mod_system_power_dev_config *)system_power_element_table[i]
89                 .data;
90         dev_config_table->sys_ppu_id =
91             fwk_id_build_element_id(fwk_module_id_ppu_v1, ppu_idx_base + i);
92     }
93 
94     return system_power_element_table;
95 }
96 
97 const struct fwk_module_config config_system_power = {
98     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(morello_system_get_element_table),
99     .data = &system_power_config,
100 };
101