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