xref: /rk3399_ARM-atf/plat/rockchip/rk3576/scmi/rk3576_clk.c (revision 04b2fb42b171e3fbf2ef823558ac5b0119663dc7)
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