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