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