1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, 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 fwk_id_t member_table_cpu_group_hayes[4] = {
74     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU0),
75     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU1),
76     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU2),
77     FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PIK_CLOCK, CLOCK_PIK_IDX_CLUS0_CPU3),
78 };
79 
80 static const struct fwk_element css_clock_element_table[2] = {
81     [CLOCK_CSS_IDX_CPU_GROUP_HAYES] =
82         {
83             .name = "CPU_GROUP_HAYES",
84             .data = &((struct mod_css_clock_dev_config){
85                 .clock_type = MOD_CSS_CLOCK_TYPE_INDEXED,
86                 .rate_table = rate_table_cpu_group_hayes,
87                 .rate_count = FWK_ARRAY_SIZE(rate_table_cpu_group_hayes),
88                 .clock_switching_source =
89                     MOD_PIK_CLOCK_CLUSCLK_SOURCE_TC2_PLL0,
90                 .pll_id = FWK_ID_ELEMENT_INIT(
91                     FWK_MODULE_IDX_SYSTEM_PLL,
92                     CLOCK_PLL_IDX_CPU_HAYES),
93                 .pll_api_id = FWK_ID_API_INIT(
94                     FWK_MODULE_IDX_SYSTEM_PLL,
95                     MOD_SYSTEM_PLL_API_TYPE_DEFAULT),
96                 .member_table = member_table_cpu_group_hayes,
97                 .member_count = FWK_ARRAY_SIZE(member_table_cpu_group_hayes),
98                 .member_api_id = FWK_ID_API_INIT(
99                     FWK_MODULE_IDX_PIK_CLOCK,
100                     MOD_PIK_CLOCK_API_TYPE_CSS),
101                 .initial_rate = 1537 * FWK_MHZ,
102                 .modulation_supported = true,
103             }),
104         },
105     { 0 }, /* Termination description. */
106 };
107 
css_clock_get_element_table(fwk_id_t module_id)108 static const struct fwk_element *css_clock_get_element_table(fwk_id_t module_id)
109 {
110     return css_clock_element_table;
111 }
112 
113 const struct fwk_module_config config_css_clock = {
114     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(css_clock_get_element_table),
115 };
116