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 "clock_soc.h"
9 #include "platform_core.h"
10
11 #include <mod_css_clock.h>
12 #include <mod_pik_clock.h>
13 #include <mod_system_pll.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 <stdbool.h>
22
23 #define MEMBER_TABLE_CPU_GROUP(n) \
24 static const fwk_id_t member_table_cpu_group_##n[] = { \
25 FWK_ID_ELEMENT_INIT( \
26 FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS##n##_CPU0), \
27 }
28
29 #define CLOCK_CSS_CPU_GROUP(n) \
30 [CLOCK_CSS_IDX_CPU_GROUP##n] = { \
31 .name = "CPU_GROUP_" #n, \
32 .data = &((struct mod_css_clock_dev_config){ \
33 .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED, \
34 .rate_table = rate_table_cpu_group, \
35 .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group), \
36 .clock_switching_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK, \
37 .pll_id = FWK_ID_ELEMENT_INIT( \
38 FWK_MODULE_IDX_SYSTEM_PLL, CLOCK_PLL_IDX_CPU##n), \
39 .pll_api_id = FWK_ID_API_INIT( \
40 FWK_MODULE_IDX_SYSTEM_PLL, MOD_SYSTEM_PLL_API_TYPE_DEFAULT), \
41 .member_table = member_table_cpu_group_##n, \
42 .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_##n), \
43 .member_api_id = FWK_ID_API_INIT( \
44 FWK_MODULE_IDX_PIK_CLOCK, MOD_PIK_CLOCK_API_TYPE_CSS), \
45 .initial_rate = 2600 * FWK_MHZ, \
46 .modulation_supported = true, \
47 }), \
48 }
49
50 static const struct mod_css_clock_rate rate_table_cpu_group[] = {
51 {
52 .rate = 2300 * FWK_MHZ,
53 .pll_rate = 2300 * FWK_MHZ,
54 .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
55 .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
56 .clock_div = 1,
57 .clock_mod_numerator = 1,
58 .clock_mod_denominator = 1,
59 },
60 {
61 .rate = 2600 * FWK_MHZ,
62 .pll_rate = 2600 * FWK_MHZ,
63 .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
64 .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
65 .clock_div = 1,
66 .clock_mod_numerator = 1,
67 .clock_mod_denominator = 1,
68 },
69 {
70 .rate = 3200 * FWK_MHZ,
71 .pll_rate = 3200 * FWK_MHZ,
72 .clock_source = MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0,
73 .clock_div_type = MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
74 .clock_div = 1,
75 .clock_mod_numerator = 1,
76 .clock_mod_denominator = 1,
77 },
78 };
79
80 MEMBER_TABLE_CPU_GROUP(0);
81 MEMBER_TABLE_CPU_GROUP(1);
82 MEMBER_TABLE_CPU_GROUP(2);
83 MEMBER_TABLE_CPU_GROUP(3);
84 #if (NUMBER_OF_CLUSTERS > 4)
85 MEMBER_TABLE_CPU_GROUP(4);
86 MEMBER_TABLE_CPU_GROUP(5);
87 MEMBER_TABLE_CPU_GROUP(6);
88 MEMBER_TABLE_CPU_GROUP(7);
89 # if (NUMBER_OF_CLUSTERS > 8)
90 MEMBER_TABLE_CPU_GROUP(8);
91 MEMBER_TABLE_CPU_GROUP(9);
92 MEMBER_TABLE_CPU_GROUP(10);
93 MEMBER_TABLE_CPU_GROUP(11);
94 MEMBER_TABLE_CPU_GROUP(12);
95 MEMBER_TABLE_CPU_GROUP(13);
96 MEMBER_TABLE_CPU_GROUP(14);
97 MEMBER_TABLE_CPU_GROUP(15);
98 # endif
99 #endif
100
101 static const struct fwk_element css_clock_element_table[] = {
102 CLOCK_CSS_CPU_GROUP(0), CLOCK_CSS_CPU_GROUP(1),
103 CLOCK_CSS_CPU_GROUP(2), CLOCK_CSS_CPU_GROUP(3),
104 #if (NUMBER_OF_CLUSTERS > 4)
105 CLOCK_CSS_CPU_GROUP(4), CLOCK_CSS_CPU_GROUP(5),
106 CLOCK_CSS_CPU_GROUP(6), CLOCK_CSS_CPU_GROUP(7),
107 # if (NUMBER_OF_CLUSTERS > 8)
108 CLOCK_CSS_CPU_GROUP(8), CLOCK_CSS_CPU_GROUP(9),
109 CLOCK_CSS_CPU_GROUP(10), CLOCK_CSS_CPU_GROUP(11),
110 CLOCK_CSS_CPU_GROUP(12), CLOCK_CSS_CPU_GROUP(13),
111 CLOCK_CSS_CPU_GROUP(14), CLOCK_CSS_CPU_GROUP(15),
112 # endif
113 #endif
114 [CLOCK_CSS_IDX_COUNT] = { 0 }, /* Termination description. */
115 };
116
css_clock_get_element_table(fwk_id_t module_id)117 static const struct fwk_element *css_clock_get_element_table(fwk_id_t module_id)
118 {
119 return css_clock_element_table;
120 }
121
122 const struct fwk_module_config config_css_clock = {
123 .elements = FWK_MODULE_DYNAMIC_ELEMENTS(css_clock_get_element_table),
124 };
125