1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
4 */
5
6 #include <assert.h>
7 #include <errno.h>
8
9 #include <drivers/delay_timer.h>
10 #include <drivers/scmi.h>
11 #include <lib/mmio.h>
12 #include <lib/spinlock.h>
13 #include <platform_def.h>
14
15 #include <plat_private.h>
16 #include <rk3576_clk.h>
17 #include <rockchip_sip_svc.h>
18 #include <scmi_clock.h>
19 #include <soc.h>
20
21 enum pll_type_sel {
22 PLL_SEL_AUTO, /* all plls (normal pll or pvtpll) */
23 PLL_SEL_PVT,
24 PLL_SEL_NOR,
25 PLL_SEL_AUTO_NOR /* all normal plls (apll/gpll/npll) */
26 };
27
28 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
29
30 #define RK3576_PVTPLL_RING_EN 0x00
31 #define RK3576_PVTPLL_RING0_LENGTH 0x04
32 #define RK3576_PVTPLL_RING1_LENGTH 0x08
33 #define RK3576_PVTPLL_RING2_LENGTH 0x0c
34 #define RK3576_PVTPLL_RING3_LENGTH 0x10
35 #define RK3576_PVTPLL_GCK_CFG 0x20
36 #define RK3576_PVTPLL_GCK_LEN 0x24
37 #define RK3576_PVTPLL_GCK_DIV 0x28
38 #define RK3576_PVTPLL_GCK_CAL_CNT 0x2c
39 #define RK3576_PVTPLL_GCK_REF_VAL 0x30
40 #define RK3576_PVTPLL_GCK_CFG_VAL 0x34
41 #define RK3576_PVTPLL_GCK_THR 0x38
42 #define RK3576_PVTPLL_GFREE_CON 0x3c
43 #define RK3576_PVTPLL_ADC_CFG 0x40
44 #define RK3576_PVTPLL_ADC_CAL_CNT 0x48
45 #define RK3576_PVTPLL_GCK_CNT 0x50
46 #define RK3576_PVTPLL_GCK_CNT_AVG 0x54
47 #define RK3576_PVTPLL_GCK_STATE 0x5c
48 #define RK3576_PVTPLL_ADC_CNT 0x60
49 #define RK3576_PVTPLL_ADC_CNT_AVG 0x68
50 #define RK3576_PVTPLL_VERSION 0x70
51 #define RK3576_PVTPLL_MAX_LENGTH 0x3f
52
53 #define GPLL_RATE 1188000000
54 #define CPLL_RATE 1000000000
55 #define SPLL_RATE 702000000
56 #define AUPLL_RATE 786431952
57
58 #define MAX_RATE_TABLE 16
59
60 #define CLKDIV_6BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3fU, shift)
61 #define CLKDIV_5BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1fU, shift)
62 #define CLKDIV_4BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0xfU, shift)
63 #define CLKDIV_3BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x7U, shift)
64 #define CLKDIV_2BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3U, shift)
65 #define CLKDIV_1BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1U, shift)
66
67 #define CPU_PLL_PATH_SLOWMODE BITS_WITH_WMASK(0U, 0x3U, 0)
68 #define CPU_PLL_PATH_NORMAL BITS_WITH_WMASK(1U, 0x3U, 0)
69 #define CPU_PLL_PATH_DEEP_SLOW BITS_WITH_WMASK(2U, 0x3U, 0)
70
71 #define CRU_PLL_POWER_DOWN BIT_WITH_WMSK(13)
72 #define CRU_PLL_POWER_UP WMSK_BIT(13)
73
74 /* clk_core:
75 * from normal pll(core_i: gpll or apll) path or direct pass from apll
76 */
77
78 /* cpul clk path */
79 #define CPUL_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 12)
80 #define CPUL_CLK_PATH_NOR_LPLL BITS_WITH_WMASK(0U, 0x3U, 12)
81 #define CPUL_CLK_PATH_NOR_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 12)
82
83 #define CPUL_CLK_PATH_LPLL BITS_WITH_WMASK(0U, 0x3U, 6)
84 #define CPUL_CLK_PATH_DIR_LPLL BITS_WITH_WMASK(2U, 0x3U, 6)
85 #define CPUL_CLK_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 6)
86
87 #define CPUL_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 13)
88 #define CPUL_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(0x1, 0x1U, 13)
89
90 /* cpub clk path */
91 #define CPUB_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 12)
92 #define CPUB_CLK_PATH_NOR_BPLL BITS_WITH_WMASK(0U, 0x3U, 12)
93 #define CPUB_CLK_PATH_NOR_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 12)
94
95 #define CPUB_CLK_PATH_BPLL BITS_WITH_WMASK(0U, 0x3U, 14)
96 #define CPUB_CLK_PATH_DIR_BPLL BITS_WITH_WMASK(2U, 0x3U, 14)
97 #define CPUB_CLK_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 14)
98
99 #define CPUB_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 5)
100 #define CPUB_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(0x1, 0x1U, 5)
101
102 #define CPUB_PCLK_PATH_100M BITS_WITH_WMASK(0U, 0x3U, 0)
103 #define CPUB_PCLK_PATH_50M BITS_WITH_WMASK(1U, 0x3U, 0)
104 #define CPUB_PCLK_PATH_24M BITS_WITH_WMASK(2U, 0x3U, 0)
105
106 /* cci clk path */
107 #define SCLK_CCI_PATH_XIN BITS_WITH_WMASK(0U, 0x3U, 12)
108 #define SCLK_CCI_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 12)
109 #define SCLK_CCI_PATH_NOR_LPLL BITS_WITH_WMASK(3U, 0x3U, 12)
110 #define SCLK_CCI_PATH_NOR_GPLL BITS_WITH_WMASK(2U, 0x3U, 12)
111
112 #define CCI_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 14)
113 #define CCI_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 14)
114
115 /* npu clk path */
116 #define NPU_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(0U, 0x7U, 7)
117 #define NPU_CLK_PATH_NOR_CPLL BITS_WITH_WMASK(1U, 0x7U, 7)
118 #define NPU_CLK_PATH_NOR_AUPLL BITS_WITH_WMASK(2U, 0x7U, 7)
119 #define NPU_CLK_PATH_NOR_SPLL BITS_WITH_WMASK(3U, 0x7U, 7)
120
121 #define NPU_CLK_PATH_NOR_PLL WMSK_BIT(15)
122 #define NPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(15)
123 #define NPU_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 9)
124 #define NPU_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 9)
125
126 /* gpu clk path */
127 #define GPU_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(0U, 0x7U, 5)
128 #define GPU_CLK_PATH_NOR_CPLL BITS_WITH_WMASK(1U, 0x7U, 5)
129 #define GPU_CLK_PATH_NOR_AUPLL BITS_WITH_WMASK(2U, 0x7U, 5)
130 #define GPU_CLK_PATH_NOR_SPLL BITS_WITH_WMASK(3U, 0x7U, 5)
131 #define GPU_CLK_PATH_NOR_LPLL BITS_WITH_WMASK(4U, 0x7U, 5)
132 #define GPU_CLK_PATH_NOR_PLL WMSK_BIT(8)
133 #define GPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(8)
134 #define GPU_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 9)
135 #define GPU_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 9)
136
137 #define PVTPLL_NEED(type, length) (((type) == PLL_SEL_PVT || \
138 (type) == PLL_SEL_AUTO) && \
139 (length))
140 /*
141 * [0]: set intermediate rate
142 * [1]: scaling up rate or scaling down rate
143 * [1]: add length for pvtpll
144 * [2:5]: length
145 * [2]: use low length for pvtpll
146 * [3:5]: reserved
147 */
148 #define OPP_RATE_MASK 0x3f
149 #define OPP_INTERMEDIATE_RATE BIT(0)
150 #define OPP_SCALING_UP_RATE BIT(1)
151 #define OPP_ADD_LENGTH BIT(1)
152 #define OPP_LENGTH_MASK GENMASK_32(5, 2)
153 #define OPP_LENGTH_SHIFT 2
154 #define OPP_LENGTH_LOW BIT(2)
155
156 #define PRATE(x) static const unsigned long const x[]
157 #define PINFO(x) static const uint32_t const x[]
158
159 PRATE(p_24m) = { OSC_HZ };
160 PRATE(p_100m_24m) = { 100 * MHz, OSC_HZ };
161 PRATE(p_350m_175m_116m_24m) = { 350 * MHz, 175 * MHz, 116 * MHz, OSC_HZ };
162 PRATE(p_175m_116m_58m_24m) = { 175 * MHz, 116 * MHz, 58 * MHz, OSC_HZ };
163 PRATE(p_116m_58m_24m) = { 116 * MHz, 58 * MHz, OSC_HZ };
164 PRATE(p_pclk_secure_s) = { PCLK_SECURE_S };
165 PRATE(p_hclk_secure_s) = { HCLK_SECURE_S };
166 PRATE(p_aclk_secure_s) = { ACLK_SECURE_S };
167 PRATE(p_hclk_vo0_s) = { HCLK_VO0_S };
168 PRATE(p_pclk_vo0_s) = { PCLK_VO0_S };
169 PRATE(p_hclk_vo1_s) = { HCLK_VO1_S };
170 PRATE(p_pclk_vo1_s) = { PCLK_VO1_S };
171
172 PINFO(clk_stimer0_root_info) = { 0x27214004, 6, 1, 0, 0, 0, 0x27214028, 9 };
173 PINFO(clk_stimer1_root_info) = { 0x27214004, 7, 1, 0, 0, 0, 0x2721402c, 1 };
174 PINFO(pclk_secure_s_info) = { 0x27214004, 4, 2, 0, 0, 0, 0x27214028, 2 };
175 PINFO(hclk_secure_s_info) = { 0x27214004, 2, 2, 0, 0, 0, 0x27214028, 1 };
176 PINFO(aclk_secure_s_info) = { 0x27214004, 0, 2, 0, 0, 0, 0x27214028, 0 };
177 PINFO(clk_pka_crypto_s_info) = { 0x27214004, 11, 2, 0, 0, 0, 0x27214030, 11 };
178 PINFO(hclk_vo1_s_info) = { 0x27214010, 0, 2, 0, 0, 0, 0x27214038, 1 };
179 PINFO(pclk_vo1_s_info) = { 0x27214010, 2, 2, 0, 0, 0, 0x27214038, 4 };
180 PINFO(hclk_vo0_s_info) = { 0x27214018, 0, 2, 0, 0, 0, 0x2721403c, 1 };
181 PINFO(pclk_vo0_s_info) = { 0x27214018, 2, 2, 0, 0, 0, 0x2721403c, 4 };
182 PINFO(pclk_klad_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 7 };
183 PINFO(hclk_crypto_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 8 };
184 PINFO(hclk_klad_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 9 };
185 PINFO(aclk_crypto_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 12 };
186 PINFO(hclk_trng_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 0 };
187 PINFO(pclk_otpc_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 3 };
188 PINFO(clk_otpc_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 4 };
189 PINFO(pclk_wdt_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 9 };
190 PINFO(tclk_wdt_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 10 };
191 PINFO(pclk_hdcp1_trng_info) = { 0, 0, 0, 0, 0, 0, 0x27214038, 0 };
192 PINFO(hclk_hdcp_key1_info) = { 0, 0, 0, 0, 0, 0, 0x27214038, 3 };
193 PINFO(pclk_hdcp0_trng_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 0 };
194 PINFO(hclk_hdcp_key0_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 3 };
195 PINFO(pclk_edp_s_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 5 };
196
197 struct pvtpll_table {
198 unsigned int rate;
199 uint32_t length;
200 uint32_t length_frac;
201 uint32_t length_low;
202 uint32_t length_low_frac;
203 uint32_t ring_sel;
204 uint32_t volt_sel_thr;
205 };
206
207 struct sys_clk_info_t {
208 struct pvtpll_table *cpul_table;
209 struct pvtpll_table *cci_table;
210 struct pvtpll_table *cpub_table;
211 struct pvtpll_table *gpu_table;
212 struct pvtpll_table *npu_table;
213 unsigned int cpul_rate_count;
214 unsigned int cci_rate_count;
215 unsigned int cpub_rate_count;
216 unsigned int gpu_rate_count;
217 unsigned int npu_rate_count;
218 unsigned long cpul_rate;
219 unsigned long cci_rate;
220 unsigned long cpub_rate;
221 unsigned long gpu_rate;
222 unsigned long npu_rate;
223 };
224
225 struct otp_opp_info {
226 uint16_t min_freq;
227 uint16_t max_freq;
228 uint8_t volt;
229 uint8_t length;
230 } __packed;
231
232 #define RK3576_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s) \
233 rk_scmi_clock_t _name = { \
234 .id = _id, \
235 .name = #_name, \
236 .clk_ops = _data, \
237 .rate_table = _table, \
238 .rate_cnt = _cnt, \
239 .is_security = _is_s, \
240 }
241
242 #define RK3576_SCMI_CLOCK_COM(_id, _name, _parent_table, _info, _data, \
243 _table, is_d, _is_s) \
244 rk_scmi_clock_t _name = { \
245 .id = _id, \
246 .name = #_name, \
247 .parent_table = _parent_table, \
248 .info = _info, \
249 .clk_ops = _data, \
250 .rate_table = _table, \
251 .rate_cnt = ARRAY_SIZE(_table), \
252 .is_dynamic_prate = is_d, \
253 .is_security = _is_s, \
254 }
255
256 #define ROCKCHIP_PVTPLL(_rate, _sel, _len, _len_frac) \
257 { \
258 .rate = _rate##U, \
259 .ring_sel = _sel, \
260 .length = _len, \
261 .length_frac = _len_frac, \
262 }
263
264 static struct pvtpll_table rk3576_cpul_pvtpll_table[] = {
265 /* rate_hz, ring_sel, length, length_frac */
266 ROCKCHIP_PVTPLL(2016000000, 0, 6, 0),
267 ROCKCHIP_PVTPLL(1920000000, 0, 6, 1),
268 ROCKCHIP_PVTPLL(1800000000, 0, 6, 1),
269 ROCKCHIP_PVTPLL(1608000000, 0, 6, 1),
270 ROCKCHIP_PVTPLL(1416000000, 0, 8, 0),
271 ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
272 ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
273 ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
274 ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
275 ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
276 { /* sentinel */ },
277 };
278
279 static struct pvtpll_table rk3576_cci_pvtpll_table[] = {
280 /* cpul_rate_hz, ring_sel, length, length_frac */
281 ROCKCHIP_PVTPLL(2016000000 / 2, 0, 27, 0),
282 ROCKCHIP_PVTPLL(1920000000 / 2, 0, 28, 0),
283 ROCKCHIP_PVTPLL(1800000000 / 2, 0, 28, 0),
284 ROCKCHIP_PVTPLL(1608000000 / 2, 0, 30, 0),
285 ROCKCHIP_PVTPLL(1416000000 / 2, 0, 34, 0),
286 ROCKCHIP_PVTPLL(1200000000 / 2, 0, 34, 0),
287 { /* sentinel */ },
288 };
289
290 static struct pvtpll_table rk3576_cpub_pvtpll_table[] = {
291 /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
292 ROCKCHIP_PVTPLL(2208000000, 0, 4, 3),
293 ROCKCHIP_PVTPLL(2112000000, 0, 5, 0),
294 ROCKCHIP_PVTPLL(2016000000, 0, 5, 0),
295 ROCKCHIP_PVTPLL(1800000000, 0, 5, 0),
296 ROCKCHIP_PVTPLL(1608000000, 0, 5, 0),
297 ROCKCHIP_PVTPLL(1416000000, 0, 7, 0),
298 ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
299 ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
300 ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
301 ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
302 ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
303 { /* sentinel */ },
304 };
305
306 static struct pvtpll_table rk3576_gpu_pvtpll_table[] = {
307 /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
308 ROCKCHIP_PVTPLL(900000000, 0, 20, 0),
309 ROCKCHIP_PVTPLL(800000000, 0, 21, 0),
310 ROCKCHIP_PVTPLL(700000000, 0, 21, 0),
311 ROCKCHIP_PVTPLL(600000000, 0, 23, 0),
312 ROCKCHIP_PVTPLL(500000000, 0, 32, 0),
313 ROCKCHIP_PVTPLL(400000000, 0, 48, 0),
314 ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
315 ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
316 { /* sentinel */ },
317 };
318
319 static struct pvtpll_table rk3576_npu_pvtpll_table[] = {
320 /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
321 ROCKCHIP_PVTPLL(950000000, 0, 16, 0),
322 ROCKCHIP_PVTPLL(900000000, 0, 17, 0),
323 ROCKCHIP_PVTPLL(800000000, 0, 18, 0),
324 ROCKCHIP_PVTPLL(700000000, 0, 22, 0),
325 ROCKCHIP_PVTPLL(600000000, 0, 25, 0),
326 ROCKCHIP_PVTPLL(500000000, 0, 35, 0),
327 ROCKCHIP_PVTPLL(400000000, 0, 46, 0),
328 ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
329 ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
330 { /* sentinel */ },
331 };
332
333 static unsigned long rk3576_cpul_rates[] = {
334 408000000, 600000000, 816000000, 1008000000,
335 1200000000, 1416000000, 1608000000, 1800000000,
336 2016000000, 2208000000, 2304000063
337 };
338
339 static unsigned long rk3576_cpub_rates[] = {
340 408000000, 600000000, 816000000, 1008000000,
341 1200000000, 1416000000, 1608000000, 1800000000,
342 2016000000, 2208000000, 2304000000, 2400000063
343 };
344
345 static unsigned long rk3576_gpu_rates[] = {
346 200000000, 300000000, 400000000, 500000000,
347 600000000, 700000000, 800000000, 900000000,
348 1000000063
349 };
350
351 static unsigned long rk3576_npu_rates[] = {
352 200000000, 300000000, 400000000, 500000000,
353 600000000, 700000000, 800000000, 900000000,
354 1000000063
355 };
356
357 static unsigned long rk3576_common_rates[] = {
358 400000, 24000000, 58000000, 100000000, 116000000, 175000000, 350000000,
359 };
360
361 static unsigned long rk3576_aclk_secure_s_rates[] = {
362 116000000, 175000000, 350000000,
363 };
364
365 static int aclk_crypto_s_enable;
366 static int aclk_klad_enable;
367 static spinlock_t crypto_lock;
368 static bool cpub_suspended;
369
370 static struct sys_clk_info_t sys_clk_info;
371 static int clk_scmi_cci_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
372
rkclk_get_pvtpll_config(struct pvtpll_table * table,unsigned int count,unsigned int freq_hz)373 static struct pvtpll_table *rkclk_get_pvtpll_config(struct pvtpll_table *table,
374 unsigned int count,
375 unsigned int freq_hz)
376 {
377 int i;
378
379 for (i = 0; i < count; i++) {
380 if (freq_hz == table[i].rate)
381 return &table[i];
382 }
383 return NULL;
384 }
385
clk_scmi_set_low_length(struct pvtpll_table * pvtpll,unsigned int count)386 static int clk_scmi_set_low_length(struct pvtpll_table *pvtpll, unsigned int count)
387 {
388 int i;
389
390 for (i = 0; i < count; i++) {
391 if (pvtpll[i].length_low) {
392 pvtpll[i].length = pvtpll[i].length_low;
393 pvtpll[i].length_frac = pvtpll[i].length_low_frac;
394 }
395 }
396
397 return 0;
398 }
399
clk_cpul_set_rate(unsigned long rate,enum pll_type_sel type)400 static int clk_cpul_set_rate(unsigned long rate, enum pll_type_sel type)
401 {
402 struct pvtpll_table *pvtpll;
403 int div;
404
405 if (rate == 0)
406 return SCMI_INVALID_PARAMETERS;
407
408 pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
409 sys_clk_info.cpul_rate_count, rate);
410 if (pvtpll == NULL)
411 return SCMI_INVALID_PARAMETERS;
412
413 /*
414 * |-\
415 * -----lpll-----| \
416 * | \ |-\
417 * -----gpll-----|mux|--litcore unclean src--[div]--[autocs]--| \
418 * | / | \
419 * --pvtpll src--| / --pvtpll src--|mux|--litcore--
420 * |-/ | /
421 * --litcore clean src--| /
422 * |-/
423 */
424 if (PVTPLL_NEED(type, pvtpll->length)) {
425 /* set ring sel and length */
426 mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_LEN,
427 0x1dff0000 |
428 (pvtpll->ring_sel << 10) |
429 (pvtpll->length << 2) |
430 (pvtpll->length_frac));
431 /* set cal cnt = 24, T = 1us */
432 mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
433 /* enable pvtpll */
434 mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
435 /* start pvtpll */
436 mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
437
438 /* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
439 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
440 CPUL_PVTPLL_PATH_PVTPLL);
441
442 /* set litcore unclean_src parent to pvtpll_src */
443 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
444 CPUL_CLK_PATH_NOR_PVTPLL);
445 /*
446 * set litcore parent from pvtpll_src to unclean_src,
447 * because autocs is on litcore unclean_src.
448 */
449 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
450 CPUL_CLK_PATH_LPLL);
451 /* set litcore unclean_src div to 0 */
452 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
453 CLKDIV_5BITS_SHF(0, 7));
454
455 return 0;
456 }
457 /* set litcore unclean_src div */
458 div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
459 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
460 CLKDIV_5BITS_SHF(div, 7));
461 /* set litcore unclean_src parent to gpll */
462 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
463 CPUL_CLK_PATH_NOR_GPLL);
464 /* set litcore parent to unclean_src */
465 mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
466 CPUL_CLK_PATH_LPLL);
467
468 return 0;
469 }
470
clk_scmi_cpul_set_rate(rk_scmi_clock_t * clock,unsigned long rate)471 static int clk_scmi_cpul_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
472 {
473 int ret;
474
475 if (rate == 0)
476 return SCMI_INVALID_PARAMETERS;
477
478 ret = clk_cpul_set_rate(rate, PLL_SEL_AUTO);
479 if (ret == 0) {
480 sys_clk_info.cpul_rate = rate;
481 ret = clk_scmi_cci_set_rate(clock, rate / 2);
482 }
483
484 return ret;
485 }
486
rk3576_lpll_get_rate(void)487 static unsigned long rk3576_lpll_get_rate(void)
488 {
489 unsigned int m, p, s, k;
490 uint64_t rate64 = 24000000, postdiv;
491 int mode;
492
493 mode = mmio_read_32(LITTLE_CRU_BASE + CRU_MODE_CON) &
494 0x3;
495
496 if (mode == 0)
497 return rate64;
498
499 m = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(16)) >>
500 CRU_PLLCON0_M_SHIFT) &
501 CRU_PLLCON0_M_MASK;
502 p = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
503 CRU_PLLCON1_P_SHIFT) &
504 CRU_PLLCON1_P_MASK;
505 s = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
506 CRU_PLLCON1_S_SHIFT) &
507 CRU_PLLCON1_S_MASK;
508 k = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(18)) >>
509 CRU_PLLCON2_K_SHIFT) &
510 CRU_PLLCON2_K_MASK;
511
512 rate64 *= m;
513 rate64 = rate64 / p;
514
515 if (k != 0) {
516 /* fractional mode */
517 uint64_t frac_rate64 = 24000000 * k;
518
519 postdiv = p * 65536;
520 frac_rate64 = frac_rate64 / postdiv;
521 rate64 += frac_rate64;
522 }
523 rate64 = rate64 >> s;
524
525 return (unsigned long)rate64;
526 }
527
clk_scmi_cpul_get_rate(rk_scmi_clock_t * clock)528 static unsigned long clk_scmi_cpul_get_rate(rk_scmi_clock_t *clock)
529 {
530 int src, div;
531
532 src = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1)) & 0x00c0;
533 src = src >> 6;
534 if (src == 1)
535 return sys_clk_info.cpul_rate;
536
537 src = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0)) & 0x3000;
538 src = src >> 12;
539 div = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(6)) & 0x0f80;
540 div = div >> 7;
541 switch (src) {
542 case 0:
543 return rk3576_lpll_get_rate();
544 case 1:
545 /* Make the return rate is equal to the set rate */
546 if (sys_clk_info.cpul_rate != 0)
547 return sys_clk_info.cpul_rate;
548 else
549 return GPLL_RATE / (div + 1);
550 case 2:
551 return sys_clk_info.cpul_rate;
552 default:
553 return 0;
554 }
555 }
556
clk_scmi_cpul_set_status(rk_scmi_clock_t * clock,bool status)557 static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
558 {
559 return 0;
560 }
561
clk_cpub_set_rate(unsigned long rate,enum pll_type_sel type)562 static int clk_cpub_set_rate(unsigned long rate, enum pll_type_sel type)
563 {
564 struct pvtpll_table *pvtpll;
565 int div;
566
567 if (rate == 0)
568 return SCMI_INVALID_PARAMETERS;
569
570 pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub_table,
571 sys_clk_info.cpub_rate_count, rate);
572 if (pvtpll == NULL)
573 return SCMI_INVALID_PARAMETERS;
574
575 /*
576 * |-\
577 * -----bpll-----| \
578 * | \ |-\
579 * -----gpll-----|mux|--bigcore unclean src--[div]--[autocs]--| \
580 * | / | \
581 * --pvtpll src--| / --pvtpll src--|mux|--bigcore--
582 * |-/ | /
583 * --bigcore clean src--| /
584 * |-/
585 */
586 if (PVTPLL_NEED(type, pvtpll->length) != 0) {
587 /* set ring sel and length */
588 mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_LEN,
589 0x1dff0000 |
590 (pvtpll->ring_sel << 10) |
591 (pvtpll->length << 2) |
592 (pvtpll->length_frac));
593 /* set cal cnt = 24, T = 1us */
594 mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
595 /* enable pvtpll */
596 mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
597 /* start pvtpll */
598 mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
599
600 /* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
601 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(2),
602 CPUB_PVTPLL_PATH_PVTPLL);
603
604 /* set bigcore unclean_src parent to pvtpll_src */
605 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
606 CPUB_CLK_PATH_NOR_PVTPLL);
607 /*
608 * set bigcore parent from pvtpll_src to unclean_src,
609 * because autocs is on bigcore unclean_src.
610 */
611 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
612 CPUB_CLK_PATH_BPLL);
613
614 /* set bigcore unclean_src div to 0 */
615 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
616 CLKDIV_5BITS_SHF(0, 7));
617
618 return 0;
619 }
620
621 /* set bigcore unclean_src div */
622 div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
623 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
624 CLKDIV_5BITS_SHF(div, 7));
625 /* set bigcore unclean_src parent to gpll */
626 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
627 CPUB_CLK_PATH_NOR_GPLL);
628 /* set bigcore parent to unclean_src */
629 mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
630 CPUB_CLK_PATH_BPLL);
631
632 return 0;
633 }
634
clk_scmi_cpub_set_rate(rk_scmi_clock_t * clock,unsigned long rate)635 static int clk_scmi_cpub_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
636 {
637 int ret;
638
639 if (rate == 0)
640 return SCMI_INVALID_PARAMETERS;
641
642 if ((rate & OPP_LENGTH_LOW) != 0) {
643 clk_scmi_set_low_length(sys_clk_info.cpub_table,
644 sys_clk_info.cpub_rate_count);
645 return 0;
646 }
647
648 ret = clk_cpub_set_rate(rate, PLL_SEL_AUTO);
649 if (ret == 0)
650 sys_clk_info.cpub_rate = rate;
651
652 return ret;
653 }
654
rk3576_bpll_get_rate(void)655 static unsigned long rk3576_bpll_get_rate(void)
656 {
657 unsigned int m, p, s, k;
658 uint64_t rate64 = 24000000, postdiv;
659 int mode;
660
661 mode = mmio_read_32(CRU_BASE + CRU_MODE_CON) &
662 0x3;
663
664 if (mode == 0)
665 return rate64;
666
667 m = (mmio_read_32(CRU_BASE + CRU_PLL_CON(0)) >>
668 CRU_PLLCON0_M_SHIFT) &
669 CRU_PLLCON0_M_MASK;
670 p = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
671 CRU_PLLCON1_P_SHIFT) &
672 CRU_PLLCON1_P_MASK;
673 s = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
674 CRU_PLLCON1_S_SHIFT) &
675 CRU_PLLCON1_S_MASK;
676 k = (mmio_read_32(CRU_BASE + CRU_PLL_CON(2)) >>
677 CRU_PLLCON2_K_SHIFT) &
678 CRU_PLLCON2_K_MASK;
679
680 rate64 *= m;
681 rate64 = rate64 / p;
682
683 if (k != 0) {
684 /* fractional mode */
685 uint64_t frac_rate64 = 24000000 * k;
686
687 postdiv = p * 65536;
688 frac_rate64 = frac_rate64 / postdiv;
689 rate64 += frac_rate64;
690 }
691 rate64 = rate64 >> s;
692
693 return (unsigned long)rate64;
694 }
695
clk_scmi_cpub_get_rate(rk_scmi_clock_t * clock)696 static unsigned long clk_scmi_cpub_get_rate(rk_scmi_clock_t *clock)
697 {
698 int value, src, div;
699
700 if (cpub_suspended != 0)
701 return sys_clk_info.cpub_rate;
702
703 value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
704 src = (value & 0xc000) >> 14;
705 if (src == 1)
706 return sys_clk_info.cpub_rate;
707
708 value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
709 src = (value & 0x3000) >> 12;
710 div = (value & 0x0f80) >> 7;
711 switch (src) {
712 case 0:
713 return rk3576_bpll_get_rate();
714 case 1:
715 /* Make the return rate is equal to the set rate */
716 if (sys_clk_info.cpub_rate != 0)
717 return sys_clk_info.cpub_rate;
718 else
719 return GPLL_RATE / (div + 1);
720 case 2:
721 return sys_clk_info.cpub_rate;
722 default:
723 return 0;
724 }
725 }
726
clk_scmi_cpub_set_status(rk_scmi_clock_t * clock,bool status)727 static int clk_scmi_cpub_set_status(rk_scmi_clock_t *clock, bool status)
728 {
729 return 0;
730 }
731
clk_scmi_cci_get_rate(rk_scmi_clock_t * clock)732 static unsigned long clk_scmi_cci_get_rate(rk_scmi_clock_t *clock)
733 {
734 int src, div;
735
736 src = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0x3000;
737 src = src >> 12;
738 if (src == 1)
739 return sys_clk_info.cci_rate;
740
741 div = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0xf80;
742 div = div >> 7;
743 switch (src) {
744 case 0:
745 return OSC_HZ;
746 case 1:
747 return sys_clk_info.cci_rate;
748 case 2:
749 return GPLL_RATE / (div + 1);
750 case 3:
751 return rk3576_lpll_get_rate() / (div + 1);
752 default:
753 return 0;
754 }
755 }
756
clk_cci_set_rate(unsigned long rate,enum pll_type_sel type)757 static int clk_cci_set_rate(unsigned long rate, enum pll_type_sel type)
758 {
759 struct pvtpll_table *pvtpll;
760 uint32_t pvtpll_en = 0;
761
762 if (rate == 0)
763 return SCMI_INVALID_PARAMETERS;
764
765 pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cci_table,
766 sys_clk_info.cci_rate_count, rate);
767
768 /* set pvtpll */
769 if ((pvtpll != 0) && (PVTPLL_NEED(type, pvtpll->length) != 0)) {
770 /* set ring sel and length */
771 mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_LEN,
772 0x1dff0000 |
773 (pvtpll->ring_sel << 10) |
774 (pvtpll->length << 2) |
775 (pvtpll->length_frac));
776 /* set cal cnt = 24, T = 1us */
777 mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
778 /* enable pvtpll */
779 pvtpll_en = mmio_read_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG);
780 if (pvtpll_en && 0x22 != 0x22)
781 mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
782 /* start pvtpll */
783 mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
784
785 /* set cci mux pvtpll */
786 mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
787 CCI_PVTPLL_PATH_PVTPLL);
788 mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
789 SCLK_CCI_PATH_PVTPLL);
790 mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
791 CLKDIV_5BITS_SHF(0, 7));
792 sys_clk_info.cci_rate = rate;
793 return 0;
794 }
795 sys_clk_info.cci_rate = 594000000;
796 /* set cci div */
797 mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
798 CLKDIV_5BITS_SHF(1, 7));
799 /* set cci mux gpll */
800 mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
801 SCLK_CCI_PATH_NOR_GPLL);
802
803 return 0;
804 }
805
clk_scmi_cci_set_rate(rk_scmi_clock_t * clock,unsigned long rate)806 static int clk_scmi_cci_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
807 {
808 if (rate == 0)
809 return SCMI_INVALID_PARAMETERS;
810
811 return clk_cci_set_rate(rate, PLL_SEL_AUTO);
812 }
813
clk_scmi_cci_set_status(rk_scmi_clock_t * clock,bool status)814 static int clk_scmi_cci_set_status(rk_scmi_clock_t *clock, bool status)
815 {
816 return 0;
817 }
818
clk_scmi_gpu_get_rate(rk_scmi_clock_t * clock)819 static unsigned long clk_scmi_gpu_get_rate(rk_scmi_clock_t *clock)
820 {
821 int div, src;
822
823 if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x100) != 0)
824 return sys_clk_info.gpu_rate;
825
826 div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x1f;
827 src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x00e0;
828 src = src >> 5;
829 switch (src) {
830 case 0:
831 /* Make the return rate is equal to the set rate */
832 if (sys_clk_info.gpu_rate != 0)
833 return sys_clk_info.gpu_rate;
834 else
835 return GPLL_RATE / (div + 1);
836 case 1:
837 return CPLL_RATE / (div + 1);
838 case 2:
839 return AUPLL_RATE / (div + 1);
840 case 3:
841 return SPLL_RATE / (div + 1);
842 case 4:
843 return rk3576_lpll_get_rate() / (div + 1);
844 default:
845 return 0;
846 }
847 }
848
clk_gpu_set_rate(unsigned long rate,enum pll_type_sel type)849 static int clk_gpu_set_rate(unsigned long rate, enum pll_type_sel type)
850 {
851 struct pvtpll_table *pvtpll;
852 int div;
853
854 pvtpll = rkclk_get_pvtpll_config(sys_clk_info.gpu_table,
855 sys_clk_info.gpu_rate_count, rate);
856 if (pvtpll == NULL)
857 return SCMI_INVALID_PARAMETERS;
858
859 if (PVTPLL_NEED(type, pvtpll->length) != 0) {
860 /* set ring sel and length */
861 mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_LEN,
862 0x1dff0000 |
863 (pvtpll->ring_sel << 10) |
864 (pvtpll->length << 2) |
865 (pvtpll->length_frac));
866 /* set cal cnt = 24, T = 1us */
867 mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
868 /* enable pvtpll */
869 mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
870 /* start pvtpll */
871 mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
872 /* set gpu mux pvtpll */
873 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
874 GPU_PVTPLL_PATH_PVTPLL);
875 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
876 GPU_CLK_PATH_PVTPLL);
877 return 0;
878 }
879
880 /* set gpu div */
881 div = DIV_ROUND_UP(GPLL_RATE, rate);
882 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
883 CLKDIV_5BITS_SHF(div - 1, 0));
884 /* set gpu mux gpll */
885 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
886 GPU_CLK_PATH_NOR_GPLL);
887 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
888 GPU_CLK_PATH_NOR_PLL);
889
890 return 0;
891 }
892
clk_scmi_gpu_set_rate(rk_scmi_clock_t * clock,unsigned long rate)893 static int clk_scmi_gpu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
894 {
895 int ret;
896
897 if (rate == 0)
898 return SCMI_INVALID_PARAMETERS;
899
900 if ((rate & OPP_LENGTH_LOW) != 0) {
901 clk_scmi_set_low_length(sys_clk_info.gpu_table,
902 sys_clk_info.gpu_rate_count);
903 return 0;
904 }
905
906 ret = clk_gpu_set_rate(rate, PLL_SEL_AUTO);
907 if (ret == 0)
908 sys_clk_info.gpu_rate = rate;
909
910 return ret;
911 }
912
clk_scmi_gpu_set_status(rk_scmi_clock_t * clock,bool status)913 static int clk_scmi_gpu_set_status(rk_scmi_clock_t *clock, bool status)
914 {
915 return 0;
916 }
917
clk_scmi_npu_get_rate(rk_scmi_clock_t * clock)918 static unsigned long clk_scmi_npu_get_rate(rk_scmi_clock_t *clock)
919 {
920 int div, src, div_src;
921
922 if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x8000) != 0)
923 return sys_clk_info.npu_rate;
924
925 div_src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x07c;
926 div_src = div_src >> 2;
927 src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x0180;
928 src = src >> 7;
929 div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x7c00;
930 div = div >> 10;
931 switch (src) {
932 case 0:
933 /* Make the return rate is equal to the set rate */
934 if (sys_clk_info.npu_rate != 0)
935 return sys_clk_info.npu_rate;
936 else
937 return GPLL_RATE / (div_src + 1) / (div + 1);
938 case 1:
939 return CPLL_RATE / (div_src + 1) / (div + 1);
940 case 2:
941 return AUPLL_RATE / (div_src + 1) / (div + 1);
942 case 3:
943 return SPLL_RATE / (div_src + 1) / (div + 1);
944 default:
945 return 0;
946 }
947 }
948
clk_npu_set_rate(unsigned long rate,enum pll_type_sel type)949 static int clk_npu_set_rate(unsigned long rate, enum pll_type_sel type)
950 {
951 struct pvtpll_table *pvtpll;
952 int div;
953
954 pvtpll = rkclk_get_pvtpll_config(sys_clk_info.npu_table,
955 sys_clk_info.npu_rate_count, rate);
956 if (pvtpll == NULL)
957 return SCMI_INVALID_PARAMETERS;
958
959 if (PVTPLL_NEED(type, pvtpll->length) != 0) {
960 /* set ring sel and length */
961 mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_LEN,
962 0x1dff0000 |
963 (pvtpll->ring_sel << 10) |
964 (pvtpll->length << 2) |
965 (pvtpll->length_frac));
966 /* set cal cnt = 24, T = 1us */
967 mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
968 /* enable pvtpll */
969 mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
970 /* start pvtpll */
971 mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
972 /* set npu mux pvtpll */
973 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
974 NPU_PVTPLL_PATH_PVTPLL);
975 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
976 NPU_CLK_PATH_PVTPLL);
977 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
978 CLKDIV_5BITS_SHF(0, 10));
979 return 0;
980 }
981
982 /* set npu div */
983 div = DIV_ROUND_UP(GPLL_RATE, rate);
984 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
985 CLKDIV_5BITS_SHF(div - 1, 2));
986 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
987 CLKDIV_5BITS_SHF(0, 10));
988 /* set npu mux gpll */
989 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
990 NPU_CLK_PATH_NOR_GPLL);
991 mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
992 NPU_CLK_PATH_NOR_PLL);
993
994 return 0;
995 }
996
clk_scmi_npu_set_rate(rk_scmi_clock_t * clock,unsigned long rate)997 static int clk_scmi_npu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
998 {
999 int ret;
1000
1001 if (rate == 0)
1002 return SCMI_INVALID_PARAMETERS;
1003
1004 if ((rate & OPP_LENGTH_LOW) != 0) {
1005 clk_scmi_set_low_length(sys_clk_info.npu_table,
1006 sys_clk_info.npu_rate_count);
1007 return 0;
1008 }
1009
1010 ret = clk_npu_set_rate(rate, PLL_SEL_AUTO);
1011 if (ret == 0)
1012 sys_clk_info.npu_rate = rate;
1013
1014 return ret;
1015 }
1016
clk_scmi_npu_set_status(rk_scmi_clock_t * clock,bool status)1017 static int clk_scmi_npu_set_status(rk_scmi_clock_t *clock, bool status)
1018 {
1019 return 0;
1020 }
1021
clk_scmi_crypto_set_status(rk_scmi_clock_t * clock,bool status)1022 int clk_scmi_crypto_set_status(rk_scmi_clock_t *clock, bool status)
1023 {
1024 spin_lock(&crypto_lock);
1025
1026 if (clock->id == ACLK_CRYPTO_S)
1027 aclk_crypto_s_enable = status;
1028 else
1029 aclk_klad_enable = status;
1030
1031 if ((aclk_crypto_s_enable != 0) || (aclk_klad_enable != 0))
1032 clk_scmi_common_set_status(clock, 1);
1033 else
1034 clk_scmi_common_set_status(clock, 0);
1035
1036 spin_unlock(&crypto_lock);
1037 return 0;
1038 }
1039
clk_scmi_common_set_status_critical(rk_scmi_clock_t * clock,bool status)1040 static int clk_scmi_common_set_status_critical(rk_scmi_clock_t *clock, bool status)
1041 {
1042 return 0;
1043 }
1044
1045 static const struct rk_clk_ops clk_scmi_cpul_ops = {
1046 .get_rate = clk_scmi_cpul_get_rate,
1047 .set_rate = clk_scmi_cpul_set_rate,
1048 .set_status = clk_scmi_cpul_set_status,
1049 };
1050
1051 static const struct rk_clk_ops clk_scmi_cci_ops = {
1052 .get_rate = clk_scmi_cci_get_rate,
1053 .set_rate = clk_scmi_cci_set_rate,
1054 .set_status = clk_scmi_cci_set_status,
1055 };
1056
1057 static const struct rk_clk_ops clk_scmi_cpub_ops = {
1058 .get_rate = clk_scmi_cpub_get_rate,
1059 .set_rate = clk_scmi_cpub_set_rate,
1060 .set_status = clk_scmi_cpub_set_status,
1061 };
1062
1063 static const struct rk_clk_ops clk_scmi_gpu_ops = {
1064 .get_rate = clk_scmi_gpu_get_rate,
1065 .set_rate = clk_scmi_gpu_set_rate,
1066 .set_status = clk_scmi_gpu_set_status,
1067 };
1068
1069 static const struct rk_clk_ops clk_scmi_npu_ops = {
1070 .get_rate = clk_scmi_npu_get_rate,
1071 .set_rate = clk_scmi_npu_set_rate,
1072 .set_status = clk_scmi_npu_set_status,
1073 };
1074
1075 static const struct rk_clk_ops clk_scmi_ops_com_critical = {
1076 .get_rate = clk_scmi_common_get_rate,
1077 .set_rate = clk_scmi_common_set_rate,
1078 .set_status = clk_scmi_common_set_status_critical,
1079 };
1080
1081 static const struct rk_clk_ops clk_scmi_ops_com = {
1082 .get_rate = clk_scmi_common_get_rate,
1083 .set_rate = clk_scmi_common_set_rate,
1084 .set_status = clk_scmi_common_set_status,
1085 };
1086
1087 static const struct rk_clk_ops clk_scmi_ops_gate = {
1088 .get_rate = clk_scmi_common_get_rate,
1089 .set_status = clk_scmi_common_set_status,
1090 };
1091
1092 static const struct rk_clk_ops clk_scmi_ops_crypto = {
1093 .get_rate = clk_scmi_common_get_rate,
1094 .set_status = clk_scmi_crypto_set_status,
1095 };
1096
1097 RK3576_SCMI_CLOCK(ARMCLK_L, scmi_armclkl, &clk_scmi_cpul_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
1098 RK3576_SCMI_CLOCK(ACLK_CCI_ROOT, scmi_aclk_cci, &clk_scmi_cci_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
1099 RK3576_SCMI_CLOCK(ARMCLK_B, scmi_armclkb, &clk_scmi_cpub_ops, rk3576_cpub_rates, ARRAY_SIZE(rk3576_cpub_rates), false);
1100 RK3576_SCMI_CLOCK(CLK_GPU, scmi_clk_gpu, &clk_scmi_gpu_ops, rk3576_gpu_rates, ARRAY_SIZE(rk3576_gpu_rates), false);
1101 RK3576_SCMI_CLOCK(CLK_RKNN_DSU0, scmi_clk_npu, &clk_scmi_npu_ops, rk3576_npu_rates, ARRAY_SIZE(rk3576_npu_rates), false);
1102 RK3576_SCMI_CLOCK_COM(CLK_STIMER0_ROOT, clk_stimer0_root, p_100m_24m, clk_stimer0_root_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1103 RK3576_SCMI_CLOCK_COM(CLK_STIMER1_ROOT, clk_stimer1_root, p_100m_24m, clk_stimer1_root_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1104 RK3576_SCMI_CLOCK_COM(PCLK_SECURE_S, pclk_secure_s, p_116m_58m_24m, pclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1105 RK3576_SCMI_CLOCK_COM(HCLK_SECURE_S, hclk_secure_s, p_175m_116m_58m_24m, hclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1106 RK3576_SCMI_CLOCK_COM(ACLK_SECURE_S, aclk_secure_s, p_350m_175m_116m_24m, aclk_secure_s_info, &clk_scmi_ops_com_critical, rk3576_aclk_secure_s_rates, false, false);
1107 RK3576_SCMI_CLOCK_COM(CLK_PKA_CRYPTO_S, clk_pka_crypto_s, p_350m_175m_116m_24m, clk_pka_crypto_s_info, &clk_scmi_ops_com, rk3576_common_rates, false, true);
1108 RK3576_SCMI_CLOCK_COM(HCLK_VO1_S, hclk_vo1_s, p_175m_116m_58m_24m, hclk_vo1_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1109 RK3576_SCMI_CLOCK_COM(PCLK_VO1_S, pclk_vo1_s, p_116m_58m_24m, pclk_vo1_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1110 RK3576_SCMI_CLOCK_COM(HCLK_VO0_S, hclk_vo0_s, p_175m_116m_58m_24m, hclk_vo0_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1111 RK3576_SCMI_CLOCK_COM(PCLK_VO0_S, pclk_vo0_s, p_116m_58m_24m, pclk_vo0_s_info, &clk_scmi_ops_com_critical, rk3576_common_rates, false, true);
1112 RK3576_SCMI_CLOCK_COM(PCLK_KLAD, pclk_klad, p_pclk_secure_s, pclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1113 RK3576_SCMI_CLOCK_COM(HCLK_CRYPTO_S, hclk_crypto_s, p_hclk_secure_s, hclk_crypto_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1114 RK3576_SCMI_CLOCK_COM(HCLK_KLAD, hclk_klad, p_hclk_secure_s, hclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1115 RK3576_SCMI_CLOCK_COM(ACLK_CRYPTO_S, aclk_crypto_s, p_aclk_secure_s, aclk_crypto_s_info, &clk_scmi_ops_crypto, rk3576_common_rates, true, true);
1116 RK3576_SCMI_CLOCK_COM(HCLK_TRNG_S, hclk_trng_s, p_hclk_secure_s, hclk_trng_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1117 RK3576_SCMI_CLOCK_COM(PCLK_OTPC_S, plk_otpc_s, p_pclk_secure_s, pclk_otpc_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1118 RK3576_SCMI_CLOCK_COM(CLK_OTPC_S, clk_otpc_s, p_24m, clk_otpc_s_info, &clk_scmi_ops_gate, rk3576_common_rates, false, true);
1119 RK3576_SCMI_CLOCK_COM(PCLK_WDT_S, pclk_wdt_s, p_pclk_secure_s, pclk_wdt_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1120 RK3576_SCMI_CLOCK_COM(TCLK_WDT_S, tclk_wdt_s, p_24m, tclk_wdt_s_info, &clk_scmi_ops_gate, rk3576_common_rates, false, true);
1121 RK3576_SCMI_CLOCK_COM(PCLK_HDCP0_TRNG, pclk_hdcp0_trng, p_pclk_vo0_s, pclk_hdcp0_trng_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1122 RK3576_SCMI_CLOCK_COM(PCLK_HDCP1_TRNG, pclk_hdcp1_trng, p_pclk_vo1_s, pclk_hdcp1_trng_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1123 RK3576_SCMI_CLOCK_COM(HCLK_HDCP_KEY0, hclk_hdcp_key0, p_hclk_vo0_s, hclk_hdcp_key0_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1124 RK3576_SCMI_CLOCK_COM(HCLK_HDCP_KEY1, hclk_hdcp_key1, p_hclk_vo1_s, hclk_hdcp_key1_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1125 RK3576_SCMI_CLOCK_COM(PCLK_EDP_S, pclk_edp_s, p_pclk_vo0_s, pclk_edp_s_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
1126 RK3576_SCMI_CLOCK_COM(ACLK_KLAD, aclk_klad, p_aclk_secure_s, aclk_crypto_s_info, &clk_scmi_ops_crypto, rk3576_common_rates, true, true);
1127
1128 rk_scmi_clock_t *clock_table[] = {
1129 [ARMCLK_L] = &scmi_armclkl,
1130 [ACLK_CCI_ROOT] = &scmi_aclk_cci,
1131 [ARMCLK_B] = &scmi_armclkb,
1132 [CLK_GPU] = &scmi_clk_gpu,
1133 [CLK_RKNN_DSU0] = &scmi_clk_npu,
1134 [CLK_STIMER0_ROOT] = &clk_stimer0_root,
1135 [CLK_STIMER1_ROOT] = &clk_stimer1_root,
1136 [PCLK_SECURE_S] = &pclk_secure_s,
1137 [HCLK_SECURE_S] = &hclk_secure_s,
1138 [ACLK_SECURE_S] = &aclk_secure_s,
1139 [CLK_PKA_CRYPTO_S] = &clk_pka_crypto_s,
1140 [HCLK_VO1_S] = &hclk_vo1_s,
1141 [PCLK_VO1_S] = &pclk_vo1_s,
1142 [HCLK_VO0_S] = &hclk_vo0_s,
1143 [PCLK_VO0_S] = &pclk_vo0_s,
1144 [PCLK_KLAD] = &pclk_klad,
1145 [HCLK_CRYPTO_S] = &hclk_crypto_s,
1146 [HCLK_KLAD] = &hclk_klad,
1147 [ACLK_CRYPTO_S] = &aclk_crypto_s,
1148 [HCLK_TRNG_S] = &hclk_trng_s,
1149 [PCLK_OTPC_S] = &plk_otpc_s,
1150 [CLK_OTPC_S] = &clk_otpc_s,
1151 [PCLK_WDT_S] = &pclk_wdt_s,
1152 [TCLK_WDT_S] = &tclk_wdt_s,
1153 [PCLK_HDCP0_TRNG] = &pclk_hdcp0_trng,
1154 [PCLK_HDCP1_TRNG] = &pclk_hdcp1_trng,
1155 [HCLK_HDCP_KEY0] = &hclk_hdcp_key0,
1156 [HCLK_HDCP_KEY1] = &hclk_hdcp_key1,
1157 [PCLK_EDP_S] = &pclk_edp_s,
1158 [ACLK_KLAD] = &aclk_klad,
1159 };
1160
rockchip_scmi_clock_count(unsigned int agent_id __unused)1161 size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
1162 {
1163 return CLK_NR_CLKS;
1164 }
1165
rockchip_scmi_get_clock(uint32_t agent_id __unused,uint32_t clock_id)1166 rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
1167 uint32_t clock_id)
1168 {
1169 rk_scmi_clock_t *table = NULL;
1170
1171 if (clock_id < ARRAY_SIZE(clock_table)) {
1172 table = clock_table[clock_id];
1173 if (table == NULL)
1174 return NULL;
1175 }
1176
1177 if ((table != NULL) && (table->is_security == 0))
1178 return table;
1179 else
1180 return NULL;
1181
1182 return NULL;
1183 }
1184
pvtplls_cpub_suspend(void)1185 void pvtplls_cpub_suspend(void)
1186 {
1187 clk_cpub_set_rate(408000000, PLL_SEL_NOR);
1188 cpub_suspended = true;
1189 }
1190
pvtplls_cpub_resume(void)1191 void pvtplls_cpub_resume(void)
1192 {
1193 cpub_suspended = false;
1194 clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
1195 }
1196
pvtplls_suspend(void)1197 void pvtplls_suspend(void)
1198 {
1199 clk_cpul_set_rate(408000000, PLL_SEL_NOR);
1200 clk_cci_set_rate(408000000, PLL_SEL_NOR);
1201 clk_cpub_set_rate(408000000, PLL_SEL_NOR);
1202 }
1203
pvtplls_resume(void)1204 void pvtplls_resume(void)
1205 {
1206 clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
1207 clk_cci_set_rate(sys_clk_info.cci_rate, PLL_SEL_AUTO);
1208 clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
1209 }
1210
sys_reset_pvtplls_prepare(void)1211 void sys_reset_pvtplls_prepare(void)
1212 {
1213 clk_gpu_set_rate(200000000, PLL_SEL_NOR);
1214 clk_npu_set_rate(200000000, PLL_SEL_NOR);
1215 clk_cpul_set_rate(408000000, PLL_SEL_NOR);
1216 clk_cci_set_rate(408000000, PLL_SEL_NOR);
1217 clk_cpub_set_rate(408000000, PLL_SEL_NOR);
1218 }
1219
rockchip_opteed_clk_set_rate(uint64_t clk_idx,uint64_t rate)1220 int rockchip_opteed_clk_set_rate(uint64_t clk_idx, uint64_t rate)
1221 {
1222 rk_scmi_clock_t *table;
1223
1224 if (clk_idx > CLK_NR_CLKS) {
1225 INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, rate);
1226 return SCMI_INVALID_PARAMETERS;
1227 }
1228
1229 table = rockchip_scmi_get_clock(0, clk_idx);
1230 if (table != NULL)
1231 table->clk_ops->set_rate(table, rate);
1232
1233 return 0;
1234 }
1235
rockchip_opteed_clk_get_rate(uint64_t clk_idx,uint64_t * rate)1236 int rockchip_opteed_clk_get_rate(uint64_t clk_idx, uint64_t *rate)
1237 {
1238 rk_scmi_clock_t *table;
1239
1240 if (clk_idx > CLK_NR_CLKS) {
1241 INFO("%s: clk-%ld not supported\n", __func__, clk_idx);
1242 return SCMI_INVALID_PARAMETERS;
1243 }
1244
1245 table = rockchip_scmi_get_clock(0, clk_idx);
1246 if (table != NULL)
1247 *rate = (uint64_t)table->clk_ops->get_rate(table);
1248 return 0;
1249 }
1250
rockchip_opteed_clk_enable(uint64_t clk_idx,uint64_t enable)1251 int rockchip_opteed_clk_enable(uint64_t clk_idx, uint64_t enable)
1252 {
1253 rk_scmi_clock_t *table;
1254
1255 if (clk_idx > CLK_NR_CLKS) {
1256 INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, enable);
1257 return SCMI_INVALID_PARAMETERS;
1258 }
1259
1260 table = rockchip_scmi_get_clock(0, clk_idx);
1261 if (table != NULL) {
1262 if (enable != 0) {
1263 table->clk_ops->set_status(table, enable);
1264 table->enable_count++;
1265 } else {
1266 if (table->enable_count == 0)
1267 return 0;
1268 if (--table->enable_count > 0)
1269 return 0;
1270 table->clk_ops->set_status(table, enable);
1271 }
1272 }
1273 return 0;
1274 }
1275
1276 #define RK3576_CPUB_OPP_INFO_OFFSET 48
1277 #define RK3576_CPUL_OPP_INFO_OFFSET 54
1278 #define RK3576_CCI_OPP_INFO_OFFSET 60
1279 #define RK3576_NPU_OPP_INFO_OFFSET 66
1280 #define RK3576_GPU_OPP_INFO_OFFSET 72
1281
rockchip_init_pvtpll_table(void)1282 static void rockchip_init_pvtpll_table(void)
1283 {
1284 sys_clk_info.cpul_table = rk3576_cpul_pvtpll_table;
1285 sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3576_cpul_pvtpll_table);
1286 sys_clk_info.cci_table = rk3576_cci_pvtpll_table;
1287 sys_clk_info.cci_rate_count = ARRAY_SIZE(rk3576_cci_pvtpll_table);
1288 sys_clk_info.cpub_table = rk3576_cpub_pvtpll_table;
1289 sys_clk_info.cpub_rate_count = ARRAY_SIZE(rk3576_cpub_pvtpll_table);
1290 sys_clk_info.gpu_table = rk3576_gpu_pvtpll_table;
1291 sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3576_gpu_pvtpll_table);
1292 sys_clk_info.npu_table = rk3576_npu_pvtpll_table;
1293 sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3576_npu_pvtpll_table);
1294 }
1295
rockchip_clock_init(void)1296 void rockchip_clock_init(void)
1297 {
1298 rockchip_init_pvtpll_table();
1299 }
1300
pvtpll_get_clk(uint64_t clock_id,struct pvtpll_table ** table,unsigned int * count)1301 static int pvtpll_get_clk(uint64_t clock_id, struct pvtpll_table **table,
1302 unsigned int *count)
1303 {
1304 switch (clock_id) {
1305 case ARMCLK_L:
1306 *table = sys_clk_info.cpul_table;
1307 *count = sys_clk_info.cpul_rate_count;
1308 break;
1309 case ARMCLK_B:
1310 *table = sys_clk_info.cpub_table;
1311 *count = sys_clk_info.cpub_rate_count;
1312 break;
1313 case CLK_GPU:
1314 *table = sys_clk_info.gpu_table;
1315 *count = sys_clk_info.gpu_rate_count;
1316 break;
1317 case CLK_RKNN_DSU0:
1318 *table = sys_clk_info.npu_table;
1319 *count = sys_clk_info.npu_rate_count;
1320 break;
1321 default:
1322 return -1;
1323 }
1324
1325 if ((*table == NULL) || (*count == 0))
1326 return -1;
1327
1328 return 0;
1329 }
1330
pvtpll_volt_sel_adjust(uint64_t clock_id,uint64_t volt_sel)1331 int pvtpll_volt_sel_adjust(uint64_t clock_id, uint64_t volt_sel)
1332 {
1333 struct pvtpll_table *table = NULL;
1334 uint32_t delta_len = 0;
1335 unsigned int count = 0;
1336 int i;
1337
1338 if (pvtpll_get_clk(clock_id, &table, &count) != 0)
1339 return -1;
1340
1341 for (i = 0; i < count; i++) {
1342 if (table[i].volt_sel_thr == 0)
1343 continue;
1344 if (volt_sel >= table[i].volt_sel_thr) {
1345 delta_len = volt_sel - table[i].volt_sel_thr + 1;
1346 table[i].length += delta_len;
1347 if (table[i].length > RK3576_PVTPLL_MAX_LENGTH)
1348 table[i].length = RK3576_PVTPLL_MAX_LENGTH;
1349 }
1350 }
1351
1352 return 0;
1353 }
1354