1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "tc0_dvfs.h"
9 #include "tc0_scmi.h"
10 #include "tc0_timer.h"
11 
12 #include <scp_mmap.h>
13 #include <scp_software_mmap.h>
14 
15 #include <mod_scmi_perf.h>
16 
17 #include <fwk_module.h>
18 
19 #include <stdint.h>
20 
21 #define FC_LEVEL_SET(PERF_IDX) \
22     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LEVEL_SET + \
23      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX))
24 
25 #define FC_LIMIT_SET(PERF_IDX) \
26     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LIMIT_SET + \
27      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX))
28 
29 #define FC_LEVEL_GET(PERF_IDX) \
30     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LEVEL_GET + \
31      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX))
32 
33 #define FC_LIMIT_GET(PERF_IDX) \
34     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LIMIT_GET + \
35      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX))
36 
37 #define FC_LEVEL_SET_AP(PERF_IDX) \
38     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LEVEL_SET + \
39      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX) - \
40      SCP_SYSTEM_ACCESS_PORT1_BASE)
41 
42 #define FC_LIMIT_SET_AP(PERF_IDX) \
43     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LIMIT_SET + \
44      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX) - \
45      SCP_SYSTEM_ACCESS_PORT1_BASE)
46 
47 #define FC_LEVEL_GET_AP(PERF_IDX) \
48     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LEVEL_GET + \
49      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX) - \
50      SCP_SYSTEM_ACCESS_PORT1_BASE)
51 
52 #define FC_LIMIT_GET_AP(PERF_IDX) \
53     (SCMI_FAST_CHANNEL_BASE + MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_LIMIT_GET + \
54      (MOD_SCMI_PERF_FAST_CHANNEL_OFFSET_TOTAL * PERF_IDX) - \
55      SCP_SYSTEM_ACCESS_PORT1_BASE)
56 
57 static const struct mod_scmi_perf_domain_config domains[] = {
58     [DVFS_ELEMENT_IDX_KLEIN] = {
59 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
60          .fast_channels_addr_scp = (uint64_t[]) {
61             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
62                 FC_LEVEL_SET(DVFS_ELEMENT_IDX_KLEIN),
63             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
64                 FC_LIMIT_SET(DVFS_ELEMENT_IDX_KLEIN),
65             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
66                 FC_LEVEL_GET(DVFS_ELEMENT_IDX_KLEIN),
67             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
68                 FC_LIMIT_GET(DVFS_ELEMENT_IDX_KLEIN),
69         },
70          .fast_channels_addr_ap = (uint64_t[]) {
71             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
72                 FC_LEVEL_SET_AP(DVFS_ELEMENT_IDX_KLEIN),
73             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
74                 FC_LIMIT_SET_AP(DVFS_ELEMENT_IDX_KLEIN),
75             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
76                 FC_LEVEL_GET_AP(DVFS_ELEMENT_IDX_KLEIN),
77             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
78                 FC_LIMIT_GET_AP(DVFS_ELEMENT_IDX_KLEIN),
79         },
80 #endif
81     },
82     [DVFS_ELEMENT_IDX_MATTERHORN] = {
83 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
84          .fast_channels_addr_scp = (uint64_t[]) {
85             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
86                 FC_LEVEL_SET(DVFS_ELEMENT_IDX_MATTERHORN),
87             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
88                 FC_LIMIT_SET(DVFS_ELEMENT_IDX_MATTERHORN),
89             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
90                 FC_LEVEL_GET(DVFS_ELEMENT_IDX_MATTERHORN),
91             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
92                 FC_LIMIT_GET(DVFS_ELEMENT_IDX_MATTERHORN),
93         },
94          .fast_channels_addr_ap = (uint64_t[]) {
95             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
96                 FC_LEVEL_SET_AP(DVFS_ELEMENT_IDX_MATTERHORN),
97             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
98                 FC_LIMIT_SET_AP(DVFS_ELEMENT_IDX_MATTERHORN),
99             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
100                 FC_LEVEL_GET_AP(DVFS_ELEMENT_IDX_MATTERHORN),
101             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
102                 FC_LIMIT_GET_AP(DVFS_ELEMENT_IDX_MATTERHORN),
103         },
104 #endif
105     },
106     [DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM] = {
107 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
108          .fast_channels_addr_scp = (uint64_t[]) {
109             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
110                 FC_LEVEL_SET(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
111             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
112                 FC_LIMIT_SET(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
113             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
114                 FC_LEVEL_GET(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
115             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
116                 FC_LIMIT_GET(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
117         },
118          .fast_channels_addr_ap = (uint64_t[]) {
119             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_SET] =
120                 FC_LEVEL_SET_AP(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
121             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_SET] =
122                 FC_LIMIT_SET_AP(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
123             [MOD_SCMI_PERF_FAST_CHANNEL_LEVEL_GET] =
124                 FC_LEVEL_GET_AP(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
125             [MOD_SCMI_PERF_FAST_CHANNEL_LIMIT_GET] =
126                 FC_LIMIT_GET_AP(DVFS_ELEMENT_IDX_MATTERHORN_ELP_ARM),
127         },
128 #endif
129     },
130 };
131 
132 #if defined(PLATFORM_VARIANT) && (PLATFORM_VARIANT == TC0_VAR_EXPERIMENT_POWER)
133 static const struct mod_scmi_plugin_config plugins_table[] = {
134     [0] = {
135         .id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_TRAFFIC_COP),
136         .dom_type = PERF_PLUGIN_DOM_TYPE_PHYSICAL,
137     },
138     [1] = {
139         .id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_MPMM),
140         .dom_type = PERF_PLUGIN_DOM_TYPE_PHYSICAL,
141     },
142     [2] = {
143         .id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_THERMAL_MGMT),
144         .dom_type = PERF_PLUGIN_DOM_TYPE_FULL,
145     },
146 };
147 #endif
148 
149 const struct fwk_module_config config_scmi_perf = {
150     .data = &((struct mod_scmi_perf_config) {
151         .domains = &domains, .perf_doms_count = FWK_ARRAY_SIZE(domains),
152 #ifdef BUILD_HAS_SCMI_PERF_FAST_CHANNELS
153         .fast_channels_alarm_id = FWK_ID_SUB_ELEMENT_INIT(
154             FWK_MODULE_IDX_TIMER, 0, CONFIG_TIMER_FAST_CHANNEL_TIMER_IDX),
155         .fast_channels_rate_limit = (2 * 1000),
156 #else
157         .fast_channels_alarm_id = FWK_ID_NONE_INIT,
158 #endif
159 #if defined(PLATFORM_VARIANT) && (PLATFORM_VARIANT == TC0_VAR_EXPERIMENT_POWER)
160         .plugins = plugins_table,
161         .plugins_count = FWK_ARRAY_SIZE(plugins_table),
162 #endif
163     })
164 };
165