1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <fwk_element.h>
9 #include <fwk_id.h>
10 #include <fwk_module.h>
11 #include <fwk_module_idx.h>
12 
13 #include <mod_clock.h>
14 #include <mod_optee_clock.h>
15 #include <mod_scmi_clock.h>
16 #include <scmi_agents.h>
17 
18 #include <assert.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 #include <dt-bindings/clock/stm32mp1-clks.h>
23 #include <stm32_util.h>
24 #include <util.h>
25 
26 /*
27  * Indices of clock elements exposed through a SCMI agent.
28  * As all exposed SCMI clocks relate to a single backend dirver
29  * these indices are used as indices for fwk elements for modules
30  * CLOCK and STM32_CLOCK. Note these are not the clock ID values
31  * exposed through SCMI.
32  */
33 enum clock_elt_idx {
34     /* Clocks exposed to agent SCMI */
35     CLK_IDX_SCMI_HSE,
36     CLK_IDX_SCMI_HSI,
37     CLK_IDX_SCMI_CSI,
38     CLK_IDX_SCMI_LSE,
39     CLK_IDX_SCMI_LSI,
40     CLK_IDX_SCMI_PLL2_Q,
41     CLK_IDX_SCMI_PLL2_R,
42     CLK_IDX_SCMI_MPU,
43     CLK_IDX_SCMI_AXI,
44     CLK_IDX_SCMI_BSEC,
45     CLK_IDX_SCMI_CRYP1,
46     CLK_IDX_SCMI_GPIOZ,
47     CLK_IDX_SCMI_HASH1,
48     CLK_IDX_SCMI_I2C4,
49     CLK_IDX_SCMI_I2C6,
50     CLK_IDX_SCMI_IWDG1,
51     CLK_IDX_SCMI_RNG1,
52     CLK_IDX_SCMI_RTC,
53     CLK_IDX_SCMI_RTCAPB,
54     CLK_IDX_SCMI_SPI6,
55     CLK_IDX_SCMI_USART1,
56     /* Count indices */
57     CLK_IDX_COUNT
58 };
59 
60 struct mod_stm32_clock_dev_config {
61     const char *name;
62     unsigned long rcc_clk_id;
63     bool default_enabled;
64 };
65 
66 /*
67  * stm32_clock_cfg - Common configuration for exposed SCMI clocks
68  *
69  * Clock name defined here is used for all CLOCK and STM32_CLOCK
70  * fwk elements names.
71  */
72 #define STM32_CLOCK_CFG(_idx, _rcc_clk_id, _name, _default_enabled) \
73     [(_idx)] = { \
74         .rcc_clk_id = (_rcc_clk_id), \
75         .name = (_name), \
76         .default_enabled = (_default_enabled), \
77     }
78 
79 static const struct mod_stm32_clock_dev_config stm32_clock_cfg[] = {
80     STM32_CLOCK_CFG(CLK_IDX_SCMI_HSE, CK_HSE, "ck_hse", true),
81     STM32_CLOCK_CFG(CLK_IDX_SCMI_HSI, CK_HSI, "ck_hsi", true),
82     STM32_CLOCK_CFG(CLK_IDX_SCMI_CSI, CK_CSI, "ck_csi", true),
83     STM32_CLOCK_CFG(CLK_IDX_SCMI_LSE, CK_LSE, "ck_lse", true),
84     STM32_CLOCK_CFG(CLK_IDX_SCMI_LSI, CK_LSI, "ck_lsi", true),
85     STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_Q, PLL2_Q, "pll2_q", true),
86     STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_R, PLL2_R, "pll2_r", true),
87     STM32_CLOCK_CFG(CLK_IDX_SCMI_MPU, CK_MCU, "ck_mpu", true),
88     STM32_CLOCK_CFG(CLK_IDX_SCMI_AXI, CK_AXI, "ck_axi", true),
89     STM32_CLOCK_CFG(CLK_IDX_SCMI_BSEC, BSEC, "bsec", false),
90     STM32_CLOCK_CFG(CLK_IDX_SCMI_CRYP1, CRYP1, "cryp1", false),
91     STM32_CLOCK_CFG(CLK_IDX_SCMI_GPIOZ, GPIOZ, "gpioz", false),
92     STM32_CLOCK_CFG(CLK_IDX_SCMI_HASH1, HASH1, "hash1", false),
93     STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C4, I2C4_K, "i2c4_k", false),
94     STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C6, I2C6_K, "i2c6_k", false),
95     STM32_CLOCK_CFG(CLK_IDX_SCMI_IWDG1, IWDG1, "iwdg1", false),
96     STM32_CLOCK_CFG(CLK_IDX_SCMI_RNG1, RNG1_K, "rng1_k", true),
97     STM32_CLOCK_CFG(CLK_IDX_SCMI_RTC, RTC, "ck_rtc", true),
98     STM32_CLOCK_CFG(CLK_IDX_SCMI_RTCAPB, RTCAPB, "rtcapb", true),
99     STM32_CLOCK_CFG(CLK_IDX_SCMI_SPI6, SPI6_K, "spi6_k", false),
100     STM32_CLOCK_CFG(CLK_IDX_SCMI_USART1, USART1_K, "usart1_k", false),
101 };
102 
103 /*
104  * Bindgins between SCMI clock_id value and clock module element in fwk
105  */
106 #define SCMI_CLOCK_ELT_ID(_idx) \
107     { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, (_idx)) }
108 
109 static struct mod_scmi_clock_device scmi_clock_device[] = {
110     [CK_SCMI_HSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSE),
111     [CK_SCMI_HSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSI),
112     [CK_SCMI_CSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CSI),
113     [CK_SCMI_LSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSE),
114     [CK_SCMI_LSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSI),
115     [CK_SCMI_PLL2_Q] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_Q),
116     [CK_SCMI_PLL2_R] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_R),
117     [CK_SCMI_MPU]    = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_MPU),
118     [CK_SCMI_AXI]    = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_AXI),
119     [CK_SCMI_BSEC]   = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_BSEC),
120     [CK_SCMI_CRYP1]  = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CRYP1),
121     [CK_SCMI_GPIOZ]  = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_GPIOZ),
122     [CK_SCMI_HASH1]  = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HASH1),
123     [CK_SCMI_I2C4]   = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C4),
124     [CK_SCMI_I2C6]   = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C6),
125     [CK_SCMI_IWDG1]  = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_IWDG1),
126     [CK_SCMI_RNG1]   = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RNG1),
127     [CK_SCMI_RTC]    = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTC),
128     [CK_SCMI_RTCAPB] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTCAPB),
129     [CK_SCMI_SPI6]   = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_SPI6),
130     [CK_SCMI_USART1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_USART1),
131 };
132 
133 /* Agents and clocks references */
134 static const struct mod_scmi_clock_agent clk_agent_tbl[SCMI_AGENT_ID_COUNT] = {
135     [SCMI_AGENT_ID_NSEC0] = {
136         .device_table = (void *)scmi_clock_device,
137         .device_count = FWK_ARRAY_SIZE(scmi_clock_device),
138     },
139 };
140 
141 /* Exported configuration data for module SCMI_CLOCK */
142 struct fwk_module_config config_scmi_clock = {
143     .data = &((struct mod_scmi_clock_config){
144         .agent_table = clk_agent_tbl,
145         .agent_count = FWK_ARRAY_SIZE(clk_agent_tbl),
146     }),
147 };
148 
149 /*
150  * Clock backend driver configuration
151  * STM32_CLOCK element index is the related CLOCK element index.
152  */
153 #define CLOCK_DATA(_idx) ((struct mod_clock_dev_config){ \
154         .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, \
155                          (_idx)), \
156         .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, 0), \
157     })
158 
159 #define CLOCK_ELT(_idx) [(_idx)] = { \
160         .name = stm32_clock_cfg[(_idx)].name, \
161         .data = &CLOCK_DATA((_idx)), \
162     }
163 
164 /* Element names are the clock names exposed by the SCMI service */
165 static struct fwk_element clock_elt[] = {
166     /* Clocks exposed to agent SCMI */
167     CLOCK_ELT(CLK_IDX_SCMI_HSE),
168     CLOCK_ELT(CLK_IDX_SCMI_HSI),
169     CLOCK_ELT(CLK_IDX_SCMI_CSI),
170     CLOCK_ELT(CLK_IDX_SCMI_LSE),
171     CLOCK_ELT(CLK_IDX_SCMI_LSI),
172     CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q),
173     CLOCK_ELT(CLK_IDX_SCMI_PLL2_R),
174     CLOCK_ELT(CLK_IDX_SCMI_MPU),
175     CLOCK_ELT(CLK_IDX_SCMI_AXI),
176     CLOCK_ELT(CLK_IDX_SCMI_BSEC),
177     CLOCK_ELT(CLK_IDX_SCMI_CRYP1),
178     CLOCK_ELT(CLK_IDX_SCMI_GPIOZ),
179     CLOCK_ELT(CLK_IDX_SCMI_HASH1),
180     CLOCK_ELT(CLK_IDX_SCMI_I2C4),
181     CLOCK_ELT(CLK_IDX_SCMI_I2C6),
182     CLOCK_ELT(CLK_IDX_SCMI_IWDG1),
183     CLOCK_ELT(CLK_IDX_SCMI_RNG1),
184     CLOCK_ELT(CLK_IDX_SCMI_RTC),
185     CLOCK_ELT(CLK_IDX_SCMI_RTCAPB),
186     CLOCK_ELT(CLK_IDX_SCMI_SPI6),
187     CLOCK_ELT(CLK_IDX_SCMI_USART1),
188     /* Termination entry */
189     [CLK_IDX_COUNT] = { 0 }
190 };
191 
192 static_assert(FWK_ARRAY_SIZE(clock_elt) == CLK_IDX_COUNT + 1,
193               "Invalid range for CLOCK and STM32_CLOCK indices");
194 
195 /* Exported configuration data for module VOLTAGE_DOMAIN */
196 const struct fwk_module_config config_clock = {
197     .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(clock_elt),
198 };
199 
200 #define CLOCK_COUNT    FWK_ARRAY_SIZE(stm32_clock_cfg)
201 static struct mod_optee_clock_config optee_clock_cfg[CLOCK_COUNT];
202 
203 #define OPTEE_CLOCK_ELT(_idx) \
204     [(_idx)] = { \
205         .name = stm32_clock_cfg[(_idx)].name, \
206         .data = &optee_clock_cfg[(_idx)], \
207     }
208 
209 static const struct fwk_element optee_clock_elt[] = {
210     /* Clocks exposed to agent SCMI */
211     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSE),
212     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSI),
213     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CSI),
214     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSE),
215     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSI),
216     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q),
217     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_R),
218     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_MPU),
219     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_AXI),
220     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_BSEC),
221     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CRYP1),
222     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_GPIOZ),
223     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HASH1),
224     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C4),
225     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C6),
226     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_IWDG1),
227     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RNG1),
228     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTC),
229     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTCAPB),
230     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_SPI6),
231     OPTEE_CLOCK_ELT(CLK_IDX_SCMI_USART1),
232     /* Termination entry */
233     [CLK_IDX_COUNT] = { 0 }
234 };
235 
236 static_assert(FWK_ARRAY_SIZE(optee_clock_elt) == CLK_IDX_COUNT + 1,
237               "Invalid range for CLOCK and STM32_CLOCK indices");
238 
optee_clock_get_elt_table(fwk_id_t module_id)239 static const struct fwk_element *optee_clock_get_elt_table(fwk_id_t module_id)
240 {
241     size_t n;
242 
243     for (n = 0; n < FWK_ARRAY_SIZE(optee_clock_cfg); n++) {
244         optee_clock_cfg[n].clk =
245             stm32mp_rcc_clock_id_to_clk(stm32_clock_cfg[n].rcc_clk_id);
246         optee_clock_cfg[n].default_enabled = stm32_clock_cfg[n].default_enabled;
247     }
248 
249     return optee_clock_elt;
250 }
251 
252 struct fwk_module_config config_optee_clock = {
253     .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_elt_table),
254 };
255