1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "clock_soc.h"
9 
10 #include <mod_css_clock.h>
11 #include <mod_pik_clock.h>
12 #include <mod_system_pll.h>
13 
14 #include <fwk_element.h>
15 #include <fwk_id.h>
16 #include <fwk_macros.h>
17 #include <fwk_module.h>
18 #include <fwk_module_idx.h>
19 
20 static const struct mod_css_clock_rate rate_table_cpu_group_hayes[5] = {
21     {
22         /* Super Underdrive */
23         .rate = 768 * FWK_MHZ,
24         .pll_rate = 768 * FWK_MHZ,
25         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
26         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
27         .clock_div = 1,
28         .clock_mod_numerator = 1,
29         .clock_mod_denominator = 1,
30     },
31     {
32         /* Underdrive */
33         .rate = 1153 * FWK_MHZ,
34         .pll_rate = 1153 * FWK_MHZ,
35         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
36         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
37         .clock_div = 1,
38         .clock_mod_numerator = 1,
39         .clock_mod_denominator = 1,
40     },
41     {
42         /* Nominal */
43         .rate = 1537 * FWK_MHZ,
44         .pll_rate = 1537 * FWK_MHZ,
45         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
46         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
47         .clock_div = 1,
48         .clock_mod_numerator = 1,
49         .clock_mod_denominator = 1,
50     },
51     {
52         /* Overdrive */
53         .rate = 1844 * FWK_MHZ,
54         .pll_rate = 1844 * FWK_MHZ,
55         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
56         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
57         .clock_div = 1,
58         .clock_mod_numerator = 1,
59         .clock_mod_denominator = 1,
60     },
61     {
62         /* Super Overdrive */
63         .rate = 2152 * FWK_MHZ,
64         .pll_rate = 2152 * FWK_MHZ,
65         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
66         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
67         .clock_div = 1,
68         .clock_mod_numerator = 1,
69         .clock_mod_denominator = 1,
70     },
71 };
72 
73 static const struct mod_css_clock_rate rate_table_cpu_group_hunter[5] = {
74     {
75         /* Super Underdrive */
76         .rate = 946 * FWK_MHZ,
77         .pll_rate = 946 * FWK_MHZ,
78         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
79         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
80         .clock_div = 1,
81         .clock_mod_numerator = 1,
82         .clock_mod_denominator = 1,
83     },
84     {
85         /* Underdrive */
86         .rate = 1419 * FWK_MHZ,
87         .pll_rate = 1419 * FWK_MHZ,
88         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
89         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
90         .clock_div = 1,
91         .clock_mod_numerator = 1,
92         .clock_mod_denominator = 1,
93     },
94     {
95         /* Nominal */
96         .rate = 1893 * FWK_MHZ,
97         .pll_rate = 1893 * FWK_MHZ,
98         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
99         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
100         .clock_div = 1,
101         .clock_mod_numerator = 1,
102         .clock_mod_denominator = 1,
103     },
104     {
105         /* Overdrive */
106         .rate = 2271 * FWK_MHZ,
107         .pll_rate = 2271 * FWK_MHZ,
108         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
109         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
110         .clock_div = 1,
111         .clock_mod_numerator = 1,
112         .clock_mod_denominator = 1,
113     },
114     {
115         /* Super Overdrive */
116         .rate = 2650 * FWK_MHZ,
117         .pll_rate = 2650 * FWK_MHZ,
118         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
119         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
120         .clock_div = 1,
121         .clock_mod_numerator = 1,
122         .clock_mod_denominator = 1,
123     },
124 };
125 
126 static const struct mod_css_clock_rate rate_table_cpu_group_hunter_elp[5] = {
127     {
128         /* Super Underdrive */
129         .rate = 1088 * FWK_MHZ,
130         .pll_rate = 1088 * FWK_MHZ,
131         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
132         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
133         .clock_div = 1,
134         .clock_mod_numerator = 1,
135         .clock_mod_denominator = 1,
136     },
137     {
138         /* Underdrive */
139         .rate = 1632 * FWK_MHZ,
140         .pll_rate = 1632 * FWK_MHZ,
141         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
142         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
143         .clock_div = 1,
144         .clock_mod_numerator = 1,
145         .clock_mod_denominator = 1,
146     },
147     {
148         /* Nominal */
149         .rate = 2176 * FWK_MHZ,
150         .pll_rate = 2176 * FWK_MHZ,
151         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
152         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
153         .clock_div = 1,
154         .clock_mod_numerator = 1,
155         .clock_mod_denominator = 1,
156     },
157     {
158         /* Overdrive */
159         .rate = 2612 * FWK_MHZ,
160         .pll_rate = 2612 * FWK_MHZ,
161         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
162         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
163         .clock_div = 1,
164         .clock_mod_numerator = 1,
165         .clock_mod_denominator = 1,
166     },
167     {
168         /* Super Overdrive */
169         .rate = 3047 * FWK_MHZ,
170         .pll_rate = 3047 * FWK_MHZ,
171         .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
172         .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
173         .clock_div = 1,
174         .clock_mod_numerator = 1,
175         .clock_mod_denominator = 1,
176     },
177 };
178 
179 static const fwk_id_t member_table_cpu_group_hayes[4] = {
180     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0),
181     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU1),
182     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU2),
183     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU3),
184 };
185 
186 static const fwk_id_t member_table_cpu_group_hunter[3] = {
187     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU4),
188     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU5),
189     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU6),
190 };
191 
192 static const fwk_id_t member_table_cpu_group_hunter_elp[1] = {
193     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU7),
194 };
195 
196 static const fwk_id_t member_table_dpu[1] = {
197     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_DPU),
198 };
199 
200 static const struct fwk_element css_clock_element_table[
201     CLOCK_CSS_IDX_COUNT + 1] = {
202     [CLOCK_CSS_IDX_CPU_GROUP_HAYES] =
203         {
204             .name = "CPU_GROUP_HAYES",
205             .data = &((struct mod_css_clock_dev_config){
206                 .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
207                 .rate_table = rate_table_cpu_group_hayes,
208                 .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_hayes),
209                 .clock_switching_source =
210                     MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
211                 .pll_id = FWK_ID_ELEMENT_INIT(
212                     FWK_MODULE_IDX_SYSTEM_PLL,
213                     CLOCK_PLL_IDX_CPU_HAYES),
214                 .pll_api_id = FWK_ID_API_INIT(
215                     FWK_MODULE_IDX_SYSTEM_PLL,
216                     MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
217                 .member_table = member_table_cpu_group_hayes,
218                 .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_hayes),
219                 .member_api_id = FWK_ID_API_INIT(
220                     FWK_MODULE_IDX_PIK_CLOCK,
221                     MOD_PIK_CLOCK_API_TYPE_CSS),
222                 .initial_rate = 1537 * FWK_MHZ,
223                 .modulation_supported = true,
224             }),
225         },
226     [CLOCK_CSS_IDX_CPU_GROUP_HUNTER] =
227         {
228             .name = "CPU_GROUP_HUNTER",
229             .data = &((struct mod_css_clock_dev_config){
230                 .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
231                 .rate_table = rate_table_cpu_group_hunter,
232                 .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_hunter),
233                 .clock_switching_source =
234                     MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL1,
235                 .pll_id = FWK_ID_ELEMENT_INIT(
236                     FWK_MODULE_IDX_SYSTEM_PLL,
237                     CLOCK_PLL_IDX_CPU_HUNTER),
238                 .pll_api_id = FWK_ID_API_INIT(
239                     FWK_MODULE_IDX_SYSTEM_PLL,
240                     MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
241                 .member_table = member_table_cpu_group_hunter,
242                 .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_hunter),
243                 .member_api_id = FWK_ID_API_INIT(
244                     FWK_MODULE_IDX_PIK_CLOCK,
245                     MOD_PIK_CLOCK_API_TYPE_CSS),
246                 .initial_rate = 1893 * FWK_MHZ,
247                 .modulation_supported = true,
248             }),
249         },
250     [CLOCK_CSS_IDX_CPU_GROUP_HUNTER_ELP] =
251         {
252             .name = "CPU_GROUP_HUNTER_ELP",
253             .data = &((struct mod_css_clock_dev_config){
254                 .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
255                 .rate_table = rate_table_cpu_group_hunter_elp,
256                 .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_hunter_elp),
257                 .clock_switching_source =
258                     MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL2,
259                 .pll_id = FWK_ID_ELEMENT_INIT(
260                     FWK_MODULE_IDX_SYSTEM_PLL,
261                     CLOCK_PLL_IDX_CPU_HUNTER_ELP),
262                 .pll_api_id = FWK_ID_API_INIT(
263                     FWK_MODULE_IDX_SYSTEM_PLL,
264                     MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
265                 .member_table = member_table_cpu_group_hunter_elp,
266                 .member_count =
267                     FWK_ARRAY_SIZE(member_table_cpu_group_hunter_elp),
268                 .member_api_id = FWK_ID_API_INIT(
269                     FWK_MODULE_IDX_PIK_CLOCK,
270                     MOD_PIK_CLOCK_API_TYPE_CSS),
271                 .initial_rate = 2176 * FWK_MHZ,
272                 .modulation_supported = true,
273             }),
274         },
275     [CLOCK_CSS_IDX_DPU] =
276         {
277             .name = "DPU",
278             .data = &((struct mod_css_clock_dev_config){
279                 .clock_type = MOD_CSS_CLOCK_TYPE_NON_INDEXED,
280                 .clock_default_source =
281                     MOD_PIK_CLOCK_ACLKDPU_SOURCE_DISPLAYPLLCLK,
282                 .clock_switching_source =
283                     MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSREFCLK,
284                 .pll_id = FWK_ID_ELEMENT_INIT(
285                     FWK_MODULE_IDX_SYSTEM_PLL,
286                     CLOCK_PLL_IDX_DPU),
287                 .pll_api_id = FWK_ID_API_INIT(
288                     FWK_MODULE_IDX_SYSTEM_PLL,
289                     MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
290                 .member_table = member_table_dpu,
291                 .member_count = FWK_ARRAY_SIZE(member_table_dpu),
292                 .member_api_id = FWK_ID_API_INIT(
293                     FWK_MODULE_IDX_PIK_CLOCK,
294                     MOD_PIK_CLOCK_API_TYPE_CSS),
295                 .initial_rate = 600 * FWK_MHZ,
296                 .modulation_supported = false,
297             }),
298         },
299     [CLOCK_CSS_IDX_COUNT] = { 0 }, /* Termination description. */
300 };
301 
css_clock_get_element_table(fwk_id_t module_id)302 static const struct fwk_element *css_clock_get_element_table(fwk_id_t module_id)
303 {
304     return css_clock_element_table;
305 }
306 
307 const struct fwk_module_config config_css_clock = {
308     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(css_clock_get_element_table),
309 };
310