1 /*
2 * Arm SCP/MCP Software
3 * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "config_power_domain.h"
9 #include "sgm775_core.h"
10 #include "sgm775_mmap.h"
11
12 #include <mod_power_domain.h>
13 #include <mod_ppu_v1.h>
14
15 #include <fwk_element.h>
16 #include <fwk_id.h>
17 #include <fwk_mm.h>
18 #include <fwk_module.h>
19 #include <fwk_module_idx.h>
20
21 #include <fmw_cmsis.h>
22
23 #include <stddef.h>
24 #include <stdint.h>
25
26 static const char *core_pd_name_table[SGM775_CORE_PER_CLUSTER_MAX] = {
27 "CLUS0CORE0", "CLUS0CORE1", "CLUS0CORE2", "CLUS0CORE3",
28 "CLUS0CORE4", "CLUS0CORE5", "CLUS0CORE6", "CLUS0CORE7",
29 };
30
31 static uintptr_t core_pd_ppu_base_table[] = {
32 PPU_CLUS0CORE0_BASE, PPU_CLUS0CORE1_BASE, PPU_CLUS0CORE2_BASE,
33 PPU_CLUS0CORE3_BASE, PPU_CLUS0CORE4_BASE, PPU_CLUS0CORE5_BASE,
34 PPU_CLUS0CORE6_BASE, PPU_CLUS0CORE7_BASE
35 };
36
37 static unsigned int core_pd_ppu_irq_table[] = {
38 PPU_CLUS0CORE0_IRQ, PPU_CLUS0CORE1_IRQ, PPU_CLUS0CORE2_IRQ,
39 PPU_CLUS0CORE3_IRQ, PPU_CLUS0CORE4_IRQ, PPU_CLUS0CORE5_IRQ,
40 PPU_CLUS0CORE6_IRQ, PPU_CLUS0CORE7_IRQ
41 };
42
43 struct mod_ppu_v1_config sgm775_ppu_v1_notification_config = {
44 .pd_notification_id = FWK_ID_NOTIFICATION_INIT(
45 FWK_MODULE_IDX_POWER_DOMAIN,
46 MOD_PD_NOTIFICATION_IDX_POWER_STATE_TRANSITION),
47 };
48
sgm775_ppu_v1_get_element_table(fwk_id_t module_id)49 static const struct fwk_element *sgm775_ppu_v1_get_element_table
50 (fwk_id_t module_id)
51 {
52 struct fwk_element *element_table, *element;
53 struct mod_ppu_v1_pd_config *pd_config_table, *pd_config;
54 unsigned int core_idx;
55
56 /*
57 * Allocate element descriptors based on:
58 * Number of cores
59 * +1 cluster descriptor
60 * +1 terminator descriptor
61 */
62 element_table = fwk_mm_calloc(sgm775_core_get_count() + 2,
63 sizeof(struct fwk_element));
64
65 pd_config_table = fwk_mm_calloc(sgm775_core_get_count() + 1,
66 sizeof(struct mod_ppu_v1_pd_config));
67
68 for (core_idx = 0; core_idx < sgm775_core_get_count(); core_idx++) {
69 element = &element_table[core_idx];
70 pd_config = &pd_config_table[core_idx];
71
72 element->name = core_pd_name_table[core_idx];
73 element->data = pd_config;
74
75 pd_config->pd_type = MOD_PD_TYPE_CORE;
76 pd_config->ppu.reg_base = core_pd_ppu_base_table[core_idx];
77 pd_config->ppu.irq = core_pd_ppu_irq_table[core_idx];
78 pd_config->cluster_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1,
79 sgm775_core_get_count());
80 pd_config->observer_id = FWK_ID_NONE;
81 }
82
83 element = &element_table[sgm775_core_get_count()];
84 pd_config = &pd_config_table[sgm775_core_get_count()];
85
86 element->name = "CLUS0";
87 element->data = pd_config;
88
89 pd_config->pd_type = MOD_PD_TYPE_CLUSTER;
90 pd_config->ppu.reg_base = PPU_CLUS0_BASE;
91 pd_config->ppu.irq = PPU_CLUS0_IRQ;
92 pd_config->observer_id = FWK_ID_NONE;
93
94 sgm775_ppu_v1_notification_config.pd_source_id = FWK_ID_ELEMENT(
95 FWK_MODULE_IDX_POWER_DOMAIN,
96 CONFIG_POWER_DOMAIN_SYSTOP_SYSTEM + sgm775_core_get_count() +
97 sgm775_cluster_get_count());
98
99 return element_table;
100 }
101
102 /*
103 * Power module configuration data
104 */
105 struct fwk_module_config config_ppu_v1 = {
106 .data = &sgm775_ppu_v1_notification_config,
107 .elements = FWK_MODULE_DYNAMIC_ELEMENTS(sgm775_ppu_v1_get_element_table),
108 };
109