xref: /rk3399_ARM-atf/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c (revision 44418fce30938ee483fbfc79cc32fde33753d1aa)
1*04150feeSXiaoDong Huang /*
2*04150feeSXiaoDong Huang  * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
3*04150feeSXiaoDong Huang  *
4*04150feeSXiaoDong Huang  * SPDX-License-Identifier: BSD-3-Clause
5*04150feeSXiaoDong Huang  */
6*04150feeSXiaoDong Huang 
7*04150feeSXiaoDong Huang #include <assert.h>
8*04150feeSXiaoDong Huang #include <errno.h>
9*04150feeSXiaoDong Huang 
10*04150feeSXiaoDong Huang #include <drivers/delay_timer.h>
11*04150feeSXiaoDong Huang #include <drivers/scmi.h>
12*04150feeSXiaoDong Huang #include <lib/mmio.h>
13*04150feeSXiaoDong Huang #include <platform_def.h>
14*04150feeSXiaoDong Huang 
15*04150feeSXiaoDong Huang #include <plat_private.h>
16*04150feeSXiaoDong Huang #include "rk3588_clk.h"
17*04150feeSXiaoDong Huang #include <rockchip_sip_svc.h>
18*04150feeSXiaoDong Huang #include <scmi_clock.h>
19*04150feeSXiaoDong Huang #include <soc.h>
20*04150feeSXiaoDong Huang 
21*04150feeSXiaoDong Huang enum pll_type_sel {
22*04150feeSXiaoDong Huang 	PLL_SEL_AUTO, /* all plls (normal pll or pvtpll) */
23*04150feeSXiaoDong Huang 	PLL_SEL_PVT,
24*04150feeSXiaoDong Huang 	PLL_SEL_NOR,
25*04150feeSXiaoDong Huang 	PLL_SEL_AUTO_NOR /* all normal plls (apll/gpll/npll) */
26*04150feeSXiaoDong Huang };
27*04150feeSXiaoDong Huang 
28*04150feeSXiaoDong Huang #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
29*04150feeSXiaoDong Huang 
30*04150feeSXiaoDong Huang #define RK3588_CPUL_PVTPLL_CON0_L	0x40
31*04150feeSXiaoDong Huang #define RK3588_CPUL_PVTPLL_CON0_H	0x44
32*04150feeSXiaoDong Huang #define RK3588_CPUL_PVTPLL_CON1		0x48
33*04150feeSXiaoDong Huang #define RK3588_CPUL_PVTPLL_CON2		0x4c
34*04150feeSXiaoDong Huang #define RK3588_CPUB_PVTPLL_CON0_L	0x00
35*04150feeSXiaoDong Huang #define RK3588_CPUB_PVTPLL_CON0_H	0x04
36*04150feeSXiaoDong Huang #define RK3588_CPUB_PVTPLL_CON1		0x08
37*04150feeSXiaoDong Huang #define RK3588_CPUB_PVTPLL_CON2		0x0c
38*04150feeSXiaoDong Huang #define RK3588_DSU_PVTPLL_CON0_L	0x60
39*04150feeSXiaoDong Huang #define RK3588_DSU_PVTPLL_CON0_H	0x64
40*04150feeSXiaoDong Huang #define RK3588_DSU_PVTPLL_CON1		0x70
41*04150feeSXiaoDong Huang #define RK3588_DSU_PVTPLL_CON2		0x74
42*04150feeSXiaoDong Huang #define RK3588_GPU_PVTPLL_CON0_L	0x00
43*04150feeSXiaoDong Huang #define RK3588_GPU_PVTPLL_CON0_H	0x04
44*04150feeSXiaoDong Huang #define RK3588_GPU_PVTPLL_CON1		0x08
45*04150feeSXiaoDong Huang #define RK3588_GPU_PVTPLL_CON2		0x0c
46*04150feeSXiaoDong Huang #define RK3588_NPU_PVTPLL_CON0_L	0x0c
47*04150feeSXiaoDong Huang #define RK3588_NPU_PVTPLL_CON0_H	0x10
48*04150feeSXiaoDong Huang #define RK3588_NPU_PVTPLL_CON1		0x14
49*04150feeSXiaoDong Huang #define RK3588_NPU_PVTPLL_CON2		0x18
50*04150feeSXiaoDong Huang #define RK3588_PVTPLL_MAX_LENGTH	0x3f
51*04150feeSXiaoDong Huang 
52*04150feeSXiaoDong Huang #define GPLL_RATE			1188000000
53*04150feeSXiaoDong Huang #define CPLL_RATE			1500000000
54*04150feeSXiaoDong Huang #define SPLL_RATE			702000000
55*04150feeSXiaoDong Huang #define AUPLL_RATE			786431952
56*04150feeSXiaoDong Huang #define NPLL_RATE			850000000
57*04150feeSXiaoDong Huang 
58*04150feeSXiaoDong Huang #define MAX_RATE_TABLE			16
59*04150feeSXiaoDong Huang 
60*04150feeSXiaoDong Huang #define CLKDIV_6BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3fU, shift)
61*04150feeSXiaoDong Huang #define CLKDIV_5BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1fU, shift)
62*04150feeSXiaoDong Huang #define CLKDIV_4BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0xfU, shift)
63*04150feeSXiaoDong Huang #define CLKDIV_3BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x7U, shift)
64*04150feeSXiaoDong Huang #define CLKDIV_2BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x3U, shift)
65*04150feeSXiaoDong Huang #define CLKDIV_1BITS_SHF(div, shift)	BITS_WITH_WMASK(div, 0x1U, shift)
66*04150feeSXiaoDong Huang 
67*04150feeSXiaoDong Huang #define CPU_PLL_PATH_SLOWMODE		BITS_WITH_WMASK(0U, 0x3U, 0)
68*04150feeSXiaoDong Huang #define CPU_PLL_PATH_NORMAL		BITS_WITH_WMASK(1U, 0x3U, 0)
69*04150feeSXiaoDong Huang #define CPU_PLL_PATH_DEEP_SLOW		BITS_WITH_WMASK(2U, 0x3U, 0)
70*04150feeSXiaoDong Huang 
71*04150feeSXiaoDong Huang #define CRU_PLL_POWER_DOWN		BIT_WITH_WMSK(13)
72*04150feeSXiaoDong Huang #define CRU_PLL_POWER_UP		WMSK_BIT(13)
73*04150feeSXiaoDong Huang 
74*04150feeSXiaoDong Huang /* core_i: from gpll or apll */
75*04150feeSXiaoDong Huang #define CLK_CORE_I_SEL_APLL		WMSK_BIT(6)
76*04150feeSXiaoDong Huang #define CLK_CORE_I_SEL_GPLL		BIT_WITH_WMSK(6)
77*04150feeSXiaoDong Huang 
78*04150feeSXiaoDong Huang /* clk_core:
79*04150feeSXiaoDong Huang  * from normal pll(core_i: gpll or apll) path or direct pass from apll
80*04150feeSXiaoDong Huang  */
81*04150feeSXiaoDong Huang 
82*04150feeSXiaoDong Huang /* cpul clk path */
83*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 14)
84*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(1U, 0x3U, 14)
85*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 14)
86*04150feeSXiaoDong Huang 
87*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_LPLL		(BITS_WITH_WMASK(0U, 0x3U, 5) | \
88*04150feeSXiaoDong Huang 					BITS_WITH_WMASK(0U, 0x3U, 12))
89*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_DIR_LPLL		(BITS_WITH_WMASK(0x1, 0x3U, 5) | \
90*04150feeSXiaoDong Huang 					BITS_WITH_WMASK(1U, 0x3U, 12))
91*04150feeSXiaoDong Huang #define CPUL_CLK_PATH_PVTPLL		(BITS_WITH_WMASK(0x2, 0x3U, 5) | \
92*04150feeSXiaoDong Huang 					BITS_WITH_WMASK(2U, 0x3U, 12))
93*04150feeSXiaoDong Huang 
94*04150feeSXiaoDong Huang #define CPUL_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 14)
95*04150feeSXiaoDong Huang #define CPUL_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 14)
96*04150feeSXiaoDong Huang 
97*04150feeSXiaoDong Huang /* cpub01 clk path */
98*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_NOR_XIN		BITS_WITH_WMASK(0U, 0x3U, 6)
99*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_NOR_GPLL	BITS_WITH_WMASK(1U, 0x3U, 6)
100*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_NOR_B0PLL	BITS_WITH_WMASK(2U, 0x3U, 6)
101*04150feeSXiaoDong Huang 
102*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 13)
103*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_DIR_B0PLL	BITS_WITH_WMASK(1U, 0x3U, 13)
104*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_B0_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 13)
105*04150feeSXiaoDong Huang 
106*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_B1PLL		BITS_WITH_WMASK(0U, 0x3U, 5)
107*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_DIR_B1PLL	BITS_WITH_WMASK(1U, 0x3U, 5)
108*04150feeSXiaoDong Huang #define CPUB01_CLK_PATH_B1_PVTPLL	BITS_WITH_WMASK(2U, 0x3U, 5)
109*04150feeSXiaoDong Huang 
110*04150feeSXiaoDong Huang #define CPUB01_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 2)
111*04150feeSXiaoDong Huang #define CPUB01_PVTPLL_PATH_PVTPLL	BITS_WITH_WMASK(1U, 0x1U, 2)
112*04150feeSXiaoDong Huang 
113*04150feeSXiaoDong Huang #define CPUB_PCLK_PATH_100M		BITS_WITH_WMASK(0U, 0x3U, 0)
114*04150feeSXiaoDong Huang #define CPUB_PCLK_PATH_50M		BITS_WITH_WMASK(1U, 0x3U, 0)
115*04150feeSXiaoDong Huang #define CPUB_PCLK_PATH_24M		BITS_WITH_WMASK(2U, 0x3U, 0)
116*04150feeSXiaoDong Huang 
117*04150feeSXiaoDong Huang /* dsu clk path */
118*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_NOR_B0PLL		BITS_WITH_WMASK(0U, 0x3U, 12)
119*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_NOR_B1PLL		BITS_WITH_WMASK(1U, 0x3U, 12)
120*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_NOR_LPLL		BITS_WITH_WMASK(2U, 0x3U, 12)
121*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_NOR_GPLL		BITS_WITH_WMASK(3U, 0x3U, 12)
122*04150feeSXiaoDong Huang 
123*04150feeSXiaoDong Huang #define DSU_PVTPLL_PATH_DEEP_SLOW	BITS_WITH_WMASK(0U, 0x1U, 15)
124*04150feeSXiaoDong Huang #define DSU_PVTPLL_PATH_PVTPLL		BITS_WITH_WMASK(1U, 0x1U, 15)
125*04150feeSXiaoDong Huang 
126*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_NOR_PLL		WMSK_BIT(0)
127*04150feeSXiaoDong Huang #define SCLK_DSU_PATH_PVTPLL		BIT_WITH_WMSK(0)
128*04150feeSXiaoDong Huang 
129*04150feeSXiaoDong Huang /* npu clk path */
130*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 7)
131*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 7)
132*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 7)
133*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_NPLL		BITS_WITH_WMASK(3U, 0x7U, 7)
134*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 7)
135*04150feeSXiaoDong Huang 
136*04150feeSXiaoDong Huang #define NPU_CLK_PATH_NOR_PLL		WMSK_BIT(0)
137*04150feeSXiaoDong Huang #define NPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(0)
138*04150feeSXiaoDong Huang 
139*04150feeSXiaoDong Huang /* gpu clk path */
140*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_GPLL		BITS_WITH_WMASK(0U, 0x7U, 5)
141*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_CPLL		BITS_WITH_WMASK(1U, 0x7U, 5)
142*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_AUPLL		BITS_WITH_WMASK(2U, 0x7U, 5)
143*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_NPLL		BITS_WITH_WMASK(3U, 0x7U, 5)
144*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_SPLL		BITS_WITH_WMASK(4U, 0x7U, 5)
145*04150feeSXiaoDong Huang #define GPU_CLK_PATH_NOR_PLL		WMSK_BIT(14)
146*04150feeSXiaoDong Huang #define GPU_CLK_PATH_PVTPLL		BIT_WITH_WMSK(14)
147*04150feeSXiaoDong Huang 
148*04150feeSXiaoDong Huang #define PVTPLL_NEED(type, length)	(((type) == PLL_SEL_PVT || \
149*04150feeSXiaoDong Huang 					  (type) == PLL_SEL_AUTO) && \
150*04150feeSXiaoDong Huang 					 (length))
151*04150feeSXiaoDong Huang 
152*04150feeSXiaoDong Huang struct pvtpll_table {
153*04150feeSXiaoDong Huang 	unsigned int rate;
154*04150feeSXiaoDong Huang 	uint32_t length;
155*04150feeSXiaoDong Huang 	uint32_t ring_sel;
156*04150feeSXiaoDong Huang };
157*04150feeSXiaoDong Huang 
158*04150feeSXiaoDong Huang struct sys_clk_info_t {
159*04150feeSXiaoDong Huang 	struct pvtpll_table *cpul_table;
160*04150feeSXiaoDong Huang 	struct pvtpll_table *cpub01_table;
161*04150feeSXiaoDong Huang 	struct pvtpll_table *cpub23_table;
162*04150feeSXiaoDong Huang 	struct pvtpll_table *gpu_table;
163*04150feeSXiaoDong Huang 	struct pvtpll_table *npu_table;
164*04150feeSXiaoDong Huang 	unsigned int cpul_rate_count;
165*04150feeSXiaoDong Huang 	unsigned int cpub01_rate_count;
166*04150feeSXiaoDong Huang 	unsigned int cpub23_rate_count;
167*04150feeSXiaoDong Huang 	unsigned int gpu_rate_count;
168*04150feeSXiaoDong Huang 	unsigned int npu_rate_count;
169*04150feeSXiaoDong Huang 	unsigned long cpul_rate;
170*04150feeSXiaoDong Huang 	unsigned long dsu_rate;
171*04150feeSXiaoDong Huang 	unsigned long cpub01_rate;
172*04150feeSXiaoDong Huang 	unsigned long cpub23_rate;
173*04150feeSXiaoDong Huang 	unsigned long gpu_rate;
174*04150feeSXiaoDong Huang 	unsigned long npu_rate;
175*04150feeSXiaoDong Huang };
176*04150feeSXiaoDong Huang 
177*04150feeSXiaoDong Huang #define RK3588_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s)	\
178*04150feeSXiaoDong Huang {									\
179*04150feeSXiaoDong Huang 	.id	= _id,							\
180*04150feeSXiaoDong Huang 	.name = _name,							\
181*04150feeSXiaoDong Huang 	.clk_ops = _data,						\
182*04150feeSXiaoDong Huang 	.rate_table = _table,						\
183*04150feeSXiaoDong Huang 	.rate_cnt = _cnt,						\
184*04150feeSXiaoDong Huang 	.is_security = _is_s,						\
185*04150feeSXiaoDong Huang }
186*04150feeSXiaoDong Huang 
187*04150feeSXiaoDong Huang #define ROCKCHIP_PVTPLL(_rate, _sel, _len)				\
188*04150feeSXiaoDong Huang {									\
189*04150feeSXiaoDong Huang 	.rate = _rate##U,						\
190*04150feeSXiaoDong Huang 	.ring_sel = _sel,						\
191*04150feeSXiaoDong Huang 	.length = _len,							\
192*04150feeSXiaoDong Huang }
193*04150feeSXiaoDong Huang 
194*04150feeSXiaoDong Huang static struct pvtpll_table rk3588_cpul_pvtpll_table[] = {
195*04150feeSXiaoDong Huang 	/* rate_hz, ring_sel, length */
196*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1800000000, 1, 15),
197*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1704000000, 1, 15),
198*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1608000000, 1, 15),
199*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1416000000, 1, 15),
200*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1200000000, 1, 17),
201*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1008000000, 1, 22),
202*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(816000000, 1, 32),
203*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(600000000, 0, 0),
204*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(408000000, 0, 0),
205*04150feeSXiaoDong Huang 	{ /* sentinel */ },
206*04150feeSXiaoDong Huang };
207*04150feeSXiaoDong Huang 
208*04150feeSXiaoDong Huang static struct pvtpll_table rk3588_cpub0_pvtpll_table[] = {
209*04150feeSXiaoDong Huang 	/* rate_hz, ring_sel, length */
210*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2400000000, 1, 11),
211*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2352000000, 1, 11),
212*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2304000000, 1, 11),
213*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2256000000, 1, 11),
214*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2208000000, 1, 11),
215*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2112000000, 1, 11),
216*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(2016000000, 1, 11),
217*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1800000000, 1, 11),
218*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1608000000, 1, 11),
219*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1416000000, 1, 13),
220*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1200000000, 1, 17),
221*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1008000000, 1, 23),
222*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(816000000, 1, 33),
223*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(600000000, 0, 0),
224*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(408000000, 0, 0),
225*04150feeSXiaoDong Huang 	{ /* sentinel */ },
226*04150feeSXiaoDong Huang };
227*04150feeSXiaoDong Huang 
228*04150feeSXiaoDong Huang static struct
229*04150feeSXiaoDong Huang pvtpll_table rk3588_cpub1_pvtpll_table[ARRAY_SIZE(rk3588_cpub0_pvtpll_table)] = { 0 };
230*04150feeSXiaoDong Huang 
231*04150feeSXiaoDong Huang static struct pvtpll_table rk3588_gpu_pvtpll_table[] = {
232*04150feeSXiaoDong Huang 	/* rate_hz, ring_sel, length */
233*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1000000000, 1, 12),
234*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(900000000, 1, 12),
235*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(800000000, 1, 12),
236*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(700000000, 1, 13),
237*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(600000000, 1, 17),
238*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(500000000, 1, 25),
239*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(400000000, 1, 38),
240*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(300000000, 1, 55),
241*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(200000000, 0, 0),
242*04150feeSXiaoDong Huang 	{ /* sentinel */ },
243*04150feeSXiaoDong Huang };
244*04150feeSXiaoDong Huang 
245*04150feeSXiaoDong Huang static struct pvtpll_table rk3588_npu_pvtpll_table[] = {
246*04150feeSXiaoDong Huang 	/* rate_hz, ring_sel, length */
247*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(1000000000, 1, 12),
248*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(900000000, 1, 12),
249*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(800000000, 1, 12),
250*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(700000000, 1, 13),
251*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(600000000, 1, 17),
252*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(500000000, 1, 25),
253*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(400000000, 1, 38),
254*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(300000000, 1, 55),
255*04150feeSXiaoDong Huang 	ROCKCHIP_PVTPLL(200000000, 0, 0),
256*04150feeSXiaoDong Huang 	{ /* sentinel */ },
257*04150feeSXiaoDong Huang };
258*04150feeSXiaoDong Huang 
259*04150feeSXiaoDong Huang static unsigned long rk3588_cpul_rates[] = {
260*04150feeSXiaoDong Huang 	408000000, 600000000, 816000000, 1008000000,
261*04150feeSXiaoDong Huang 	1200000000, 1416000000, 1608000000, 1800000063,
262*04150feeSXiaoDong Huang };
263*04150feeSXiaoDong Huang 
264*04150feeSXiaoDong Huang static unsigned long rk3588_cpub_rates[] = {
265*04150feeSXiaoDong Huang 	408000000, 816000000, 1008000000, 1200000000,
266*04150feeSXiaoDong Huang 	1416000000, 1608000000, 1800000000, 2016000000,
267*04150feeSXiaoDong Huang 	2208000000, 2304000000, 2400000063
268*04150feeSXiaoDong Huang };
269*04150feeSXiaoDong Huang 
270*04150feeSXiaoDong Huang static unsigned long rk3588_gpu_rates[] = {
271*04150feeSXiaoDong Huang 	200000000, 300000000, 400000000, 500000000,
272*04150feeSXiaoDong Huang 	600000000, 700000000, 800000000, 900000000,
273*04150feeSXiaoDong Huang 	1000000063
274*04150feeSXiaoDong Huang };
275*04150feeSXiaoDong Huang 
276*04150feeSXiaoDong Huang static unsigned long rk3588_sbus_rates[] = {
277*04150feeSXiaoDong Huang 	24000000, 50000000, 100000000, 150000000, 200000000,
278*04150feeSXiaoDong Huang 	250000000, 350000000, 700000000
279*04150feeSXiaoDong Huang };
280*04150feeSXiaoDong Huang 
281*04150feeSXiaoDong Huang static unsigned long rk3588_sdmmc_rates[] = {
282*04150feeSXiaoDong Huang 	400000, 24000000, 50000000, 100000000, 150000000, 200000000,
283*04150feeSXiaoDong Huang 	300000000, 400000000, 600000000, 700000000
284*04150feeSXiaoDong Huang };
285*04150feeSXiaoDong Huang 
286*04150feeSXiaoDong Huang static struct sys_clk_info_t sys_clk_info;
287*04150feeSXiaoDong Huang static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
288*04150feeSXiaoDong Huang 
rkclk_get_pvtpll_config(struct pvtpll_table * table,unsigned int count,unsigned int freq_hz)289*04150feeSXiaoDong Huang static struct pvtpll_table *rkclk_get_pvtpll_config(struct pvtpll_table *table,
290*04150feeSXiaoDong Huang 						    unsigned int count,
291*04150feeSXiaoDong Huang 						    unsigned int freq_hz)
292*04150feeSXiaoDong Huang {
293*04150feeSXiaoDong Huang 	int i;
294*04150feeSXiaoDong Huang 
295*04150feeSXiaoDong Huang 	for (i = 0; i < count; i++) {
296*04150feeSXiaoDong Huang 		if (freq_hz == table[i].rate)
297*04150feeSXiaoDong Huang 			return &table[i];
298*04150feeSXiaoDong Huang 	}
299*04150feeSXiaoDong Huang 	return NULL;
300*04150feeSXiaoDong Huang }
301*04150feeSXiaoDong Huang 
clk_cpul_set_rate(unsigned long rate,enum pll_type_sel type)302*04150feeSXiaoDong Huang static int clk_cpul_set_rate(unsigned long rate, enum pll_type_sel type)
303*04150feeSXiaoDong Huang {
304*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
305*04150feeSXiaoDong Huang 	int div;
306*04150feeSXiaoDong Huang 
307*04150feeSXiaoDong Huang 	if (rate == 0)
308*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
309*04150feeSXiaoDong Huang 
310*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
311*04150feeSXiaoDong Huang 					 sys_clk_info.cpul_rate_count, rate);
312*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
313*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
314*04150feeSXiaoDong Huang 
315*04150feeSXiaoDong Huang 	/* set lpll */
316*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length) != 0) {
317*04150feeSXiaoDong Huang 		/* set clock gating interval */
318*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON2,
319*04150feeSXiaoDong Huang 			      0x00040000);
320*04150feeSXiaoDong Huang 		/* set ring sel */
321*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
322*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
323*04150feeSXiaoDong Huang 		/* set length */
324*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_H,
325*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
326*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
327*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON1,
328*04150feeSXiaoDong Huang 			      0x18);
329*04150feeSXiaoDong Huang 		/* enable pvtpll */
330*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
331*04150feeSXiaoDong Huang 			      0x00020002);
332*04150feeSXiaoDong Huang 		/* start monitor */
333*04150feeSXiaoDong Huang 		mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
334*04150feeSXiaoDong Huang 			      0x00010001);
335*04150feeSXiaoDong Huang 		/* set corel mux pvtpll */
336*04150feeSXiaoDong Huang 		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
337*04150feeSXiaoDong Huang 			      CPUL_PVTPLL_PATH_PVTPLL);
338*04150feeSXiaoDong Huang 		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
339*04150feeSXiaoDong Huang 			      CPUL_CLK_PATH_PVTPLL);
340*04150feeSXiaoDong Huang 		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
341*04150feeSXiaoDong Huang 			      CPUL_CLK_PATH_PVTPLL);
342*04150feeSXiaoDong Huang 		return 0;
343*04150feeSXiaoDong Huang 	}
344*04150feeSXiaoDong Huang 
345*04150feeSXiaoDong Huang 	/* set clk corel div */
346*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
347*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
348*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
349*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
350*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
351*04150feeSXiaoDong Huang 	/* set corel mux gpll */
352*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
353*04150feeSXiaoDong Huang 		      CPUL_CLK_PATH_NOR_GPLL);
354*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
355*04150feeSXiaoDong Huang 		      CPUL_CLK_PATH_LPLL);
356*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
357*04150feeSXiaoDong Huang 		      CPUL_CLK_PATH_LPLL);
358*04150feeSXiaoDong Huang 
359*04150feeSXiaoDong Huang 	return 0;
360*04150feeSXiaoDong Huang }
361*04150feeSXiaoDong Huang 
clk_scmi_cpul_set_rate(rk_scmi_clock_t * clock,unsigned long rate)362*04150feeSXiaoDong Huang static int clk_scmi_cpul_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
363*04150feeSXiaoDong Huang {
364*04150feeSXiaoDong Huang 	int ret;
365*04150feeSXiaoDong Huang 
366*04150feeSXiaoDong Huang 	if (rate == 0)
367*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
368*04150feeSXiaoDong Huang 
369*04150feeSXiaoDong Huang 	ret = clk_cpul_set_rate(rate, PLL_SEL_AUTO);
370*04150feeSXiaoDong Huang 	if (ret == 0) {
371*04150feeSXiaoDong Huang 		sys_clk_info.cpul_rate = rate;
372*04150feeSXiaoDong Huang 		ret = clk_scmi_dsu_set_rate(clock, rate);
373*04150feeSXiaoDong Huang 	}
374*04150feeSXiaoDong Huang 
375*04150feeSXiaoDong Huang 	return ret;
376*04150feeSXiaoDong Huang }
377*04150feeSXiaoDong Huang 
rk3588_lpll_get_rate(void)378*04150feeSXiaoDong Huang static unsigned long rk3588_lpll_get_rate(void)
379*04150feeSXiaoDong Huang {
380*04150feeSXiaoDong Huang 	unsigned int m, p, s, k;
381*04150feeSXiaoDong Huang 	uint64_t rate64 = 24000000, postdiv;
382*04150feeSXiaoDong Huang 	int mode;
383*04150feeSXiaoDong Huang 
384*04150feeSXiaoDong Huang 	mode = (mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) >> 14) &
385*04150feeSXiaoDong Huang 	       0x3;
386*04150feeSXiaoDong Huang 
387*04150feeSXiaoDong Huang 	if (mode == 0)
388*04150feeSXiaoDong Huang 		return rate64;
389*04150feeSXiaoDong Huang 
390*04150feeSXiaoDong Huang 	m = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(16)) >>
391*04150feeSXiaoDong Huang 		 CRU_PLLCON0_M_SHIFT) &
392*04150feeSXiaoDong Huang 		CRU_PLLCON0_M_MASK;
393*04150feeSXiaoDong Huang 	p = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
394*04150feeSXiaoDong Huang 		    CRU_PLLCON1_P_SHIFT) &
395*04150feeSXiaoDong Huang 		   CRU_PLLCON1_P_MASK;
396*04150feeSXiaoDong Huang 	s = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
397*04150feeSXiaoDong Huang 		  CRU_PLLCON1_S_SHIFT) &
398*04150feeSXiaoDong Huang 		 CRU_PLLCON1_S_MASK;
399*04150feeSXiaoDong Huang 	k = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(18)) >>
400*04150feeSXiaoDong Huang 		    CRU_PLLCON2_K_SHIFT) &
401*04150feeSXiaoDong Huang 		   CRU_PLLCON2_K_MASK;
402*04150feeSXiaoDong Huang 
403*04150feeSXiaoDong Huang 	rate64 *= m;
404*04150feeSXiaoDong Huang 	rate64 = rate64 / p;
405*04150feeSXiaoDong Huang 
406*04150feeSXiaoDong Huang 	if (k != 0) {
407*04150feeSXiaoDong Huang 		/* fractional mode */
408*04150feeSXiaoDong Huang 		uint64_t frac_rate64 = 24000000 * k;
409*04150feeSXiaoDong Huang 
410*04150feeSXiaoDong Huang 		postdiv = p * 65535;
411*04150feeSXiaoDong Huang 		frac_rate64 = frac_rate64 / postdiv;
412*04150feeSXiaoDong Huang 		rate64 += frac_rate64;
413*04150feeSXiaoDong Huang 	}
414*04150feeSXiaoDong Huang 	rate64 = rate64 >> s;
415*04150feeSXiaoDong Huang 
416*04150feeSXiaoDong Huang 	return (unsigned long)rate64;
417*04150feeSXiaoDong Huang }
418*04150feeSXiaoDong Huang 
clk_scmi_cpul_get_rate(rk_scmi_clock_t * clock)419*04150feeSXiaoDong Huang static unsigned long clk_scmi_cpul_get_rate(rk_scmi_clock_t *clock)
420*04150feeSXiaoDong Huang {
421*04150feeSXiaoDong Huang 	int src, div;
422*04150feeSXiaoDong Huang 
423*04150feeSXiaoDong Huang 	src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x0060;
424*04150feeSXiaoDong Huang 	src = src >> 5;
425*04150feeSXiaoDong Huang 	if (src == 2) {
426*04150feeSXiaoDong Huang 		return sys_clk_info.cpul_rate;
427*04150feeSXiaoDong Huang 	} else {
428*04150feeSXiaoDong Huang 		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) & 0xc000;
429*04150feeSXiaoDong Huang 		src = src >> 14;
430*04150feeSXiaoDong Huang 		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x1f;
431*04150feeSXiaoDong Huang 		switch (src) {
432*04150feeSXiaoDong Huang 		case 0:
433*04150feeSXiaoDong Huang 			return 24000000;
434*04150feeSXiaoDong Huang 		case 1:
435*04150feeSXiaoDong Huang 			/* Make the return rate is equal to the set rate */
436*04150feeSXiaoDong Huang 			if (sys_clk_info.cpul_rate)
437*04150feeSXiaoDong Huang 				return sys_clk_info.cpul_rate;
438*04150feeSXiaoDong Huang 			else
439*04150feeSXiaoDong Huang 				return GPLL_RATE / (div + 1);
440*04150feeSXiaoDong Huang 		case 2:
441*04150feeSXiaoDong Huang 			return rk3588_lpll_get_rate();
442*04150feeSXiaoDong Huang 		default:
443*04150feeSXiaoDong Huang 			return 0;
444*04150feeSXiaoDong Huang 		}
445*04150feeSXiaoDong Huang 	}
446*04150feeSXiaoDong Huang }
447*04150feeSXiaoDong Huang 
clk_scmi_cpul_set_status(rk_scmi_clock_t * clock,bool status)448*04150feeSXiaoDong Huang static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
449*04150feeSXiaoDong Huang {
450*04150feeSXiaoDong Huang 	return 0;
451*04150feeSXiaoDong Huang }
452*04150feeSXiaoDong Huang 
clk_scmi_b0pll_disable(void)453*04150feeSXiaoDong Huang static void clk_scmi_b0pll_disable(void)
454*04150feeSXiaoDong Huang {
455*04150feeSXiaoDong Huang 	static bool is_b0pll_disabled;
456*04150feeSXiaoDong Huang 
457*04150feeSXiaoDong Huang 	if (is_b0pll_disabled != 0)
458*04150feeSXiaoDong Huang 		return;
459*04150feeSXiaoDong Huang 
460*04150feeSXiaoDong Huang 	/* set coreb01 mux gpll */
461*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
462*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_NOR_GPLL);
463*04150feeSXiaoDong Huang 	 /* pll enter slow mode */
464*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
465*04150feeSXiaoDong Huang 	/* set pll power down */
466*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1), CRU_PLL_POWER_DOWN);
467*04150feeSXiaoDong Huang 
468*04150feeSXiaoDong Huang 	is_b0pll_disabled = true;
469*04150feeSXiaoDong Huang }
470*04150feeSXiaoDong Huang 
clk_cpub01_set_rate(unsigned long rate,enum pll_type_sel type)471*04150feeSXiaoDong Huang static int clk_cpub01_set_rate(unsigned long rate, enum pll_type_sel type)
472*04150feeSXiaoDong Huang {
473*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
474*04150feeSXiaoDong Huang 	int div;
475*04150feeSXiaoDong Huang 
476*04150feeSXiaoDong Huang 	if (rate == 0)
477*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
478*04150feeSXiaoDong Huang 
479*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub01_table,
480*04150feeSXiaoDong Huang 					 sys_clk_info.cpub01_rate_count, rate);
481*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
482*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
483*04150feeSXiaoDong Huang 
484*04150feeSXiaoDong Huang 	/* set b0pll */
485*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length)) {
486*04150feeSXiaoDong Huang 		/* set clock gating interval */
487*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
488*04150feeSXiaoDong Huang 			      0x00040000);
489*04150feeSXiaoDong Huang 		/* set ring sel */
490*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
491*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
492*04150feeSXiaoDong Huang 		/* set length */
493*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
494*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
495*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
496*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
497*04150feeSXiaoDong Huang 			      0x18);
498*04150feeSXiaoDong Huang 		/* enable pvtpll */
499*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
500*04150feeSXiaoDong Huang 			      0x00020002);
501*04150feeSXiaoDong Huang 		/* start monitor */
502*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
503*04150feeSXiaoDong Huang 			      0x00010001);
504*04150feeSXiaoDong Huang 		/* set core mux pvtpll */
505*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
506*04150feeSXiaoDong Huang 			      CPUB01_PVTPLL_PATH_PVTPLL);
507*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
508*04150feeSXiaoDong Huang 			      CPUB01_CLK_PATH_B0_PVTPLL);
509*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
510*04150feeSXiaoDong Huang 			      CPUB01_CLK_PATH_B1_PVTPLL);
511*04150feeSXiaoDong Huang 		goto out;
512*04150feeSXiaoDong Huang 	}
513*04150feeSXiaoDong Huang 
514*04150feeSXiaoDong Huang 	/* set clk coreb01 div */
515*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
516*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
517*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 8));
518*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
519*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 0));
520*04150feeSXiaoDong Huang 	/* set coreb01 mux gpll */
521*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
522*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_NOR_GPLL);
523*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
524*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_B0PLL);
525*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
526*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_B1PLL);
527*04150feeSXiaoDong Huang 
528*04150feeSXiaoDong Huang out:
529*04150feeSXiaoDong Huang 	clk_scmi_b0pll_disable();
530*04150feeSXiaoDong Huang 
531*04150feeSXiaoDong Huang 	return 0;
532*04150feeSXiaoDong Huang }
533*04150feeSXiaoDong Huang 
clk_scmi_cpub01_set_rate(rk_scmi_clock_t * clock,unsigned long rate)534*04150feeSXiaoDong Huang static int clk_scmi_cpub01_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
535*04150feeSXiaoDong Huang {
536*04150feeSXiaoDong Huang 	int ret;
537*04150feeSXiaoDong Huang 
538*04150feeSXiaoDong Huang 	if (rate == 0)
539*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
540*04150feeSXiaoDong Huang 
541*04150feeSXiaoDong Huang 	ret = clk_cpub01_set_rate(rate, PLL_SEL_AUTO);
542*04150feeSXiaoDong Huang 	if (ret == 0)
543*04150feeSXiaoDong Huang 		sys_clk_info.cpub01_rate = rate;
544*04150feeSXiaoDong Huang 
545*04150feeSXiaoDong Huang 	return ret;
546*04150feeSXiaoDong Huang }
547*04150feeSXiaoDong Huang 
rk3588_b0pll_get_rate(void)548*04150feeSXiaoDong Huang static unsigned long rk3588_b0pll_get_rate(void)
549*04150feeSXiaoDong Huang {
550*04150feeSXiaoDong Huang 	unsigned int m, p, s, k;
551*04150feeSXiaoDong Huang 	uint64_t rate64 = 24000000, postdiv;
552*04150feeSXiaoDong Huang 	int mode;
553*04150feeSXiaoDong Huang 
554*04150feeSXiaoDong Huang 	mode = (mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
555*04150feeSXiaoDong Huang 	       0x3;
556*04150feeSXiaoDong Huang 
557*04150feeSXiaoDong Huang 	if (mode == 0)
558*04150feeSXiaoDong Huang 		return rate64;
559*04150feeSXiaoDong Huang 
560*04150feeSXiaoDong Huang 	m = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(0)) >>
561*04150feeSXiaoDong Huang 		 CRU_PLLCON0_M_SHIFT) &
562*04150feeSXiaoDong Huang 		CRU_PLLCON0_M_MASK;
563*04150feeSXiaoDong Huang 	p = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
564*04150feeSXiaoDong Huang 		    CRU_PLLCON1_P_SHIFT) &
565*04150feeSXiaoDong Huang 		   CRU_PLLCON1_P_MASK;
566*04150feeSXiaoDong Huang 	s = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
567*04150feeSXiaoDong Huang 		  CRU_PLLCON1_S_SHIFT) &
568*04150feeSXiaoDong Huang 		 CRU_PLLCON1_S_MASK;
569*04150feeSXiaoDong Huang 	k = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(2)) >>
570*04150feeSXiaoDong Huang 		    CRU_PLLCON2_K_SHIFT) &
571*04150feeSXiaoDong Huang 		   CRU_PLLCON2_K_MASK;
572*04150feeSXiaoDong Huang 
573*04150feeSXiaoDong Huang 	rate64 *= m;
574*04150feeSXiaoDong Huang 	rate64 = rate64 / p;
575*04150feeSXiaoDong Huang 
576*04150feeSXiaoDong Huang 	if (k != 0) {
577*04150feeSXiaoDong Huang 		/* fractional mode */
578*04150feeSXiaoDong Huang 		uint64_t frac_rate64 = 24000000 * k;
579*04150feeSXiaoDong Huang 
580*04150feeSXiaoDong Huang 		postdiv = p * 65535;
581*04150feeSXiaoDong Huang 		frac_rate64 = frac_rate64 / postdiv;
582*04150feeSXiaoDong Huang 		rate64 += frac_rate64;
583*04150feeSXiaoDong Huang 	}
584*04150feeSXiaoDong Huang 	rate64 = rate64 >> s;
585*04150feeSXiaoDong Huang 
586*04150feeSXiaoDong Huang 	return (unsigned long)rate64;
587*04150feeSXiaoDong Huang }
588*04150feeSXiaoDong Huang 
clk_scmi_cpub01_get_rate(rk_scmi_clock_t * clock)589*04150feeSXiaoDong Huang static unsigned long clk_scmi_cpub01_get_rate(rk_scmi_clock_t *clock)
590*04150feeSXiaoDong Huang {
591*04150feeSXiaoDong Huang 	int value, src, div;
592*04150feeSXiaoDong Huang 
593*04150feeSXiaoDong Huang 	value = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0));
594*04150feeSXiaoDong Huang 	src = (value & 0x6000) >> 13;
595*04150feeSXiaoDong Huang 	if (src == 2) {
596*04150feeSXiaoDong Huang 		return sys_clk_info.cpub01_rate;
597*04150feeSXiaoDong Huang 	} else {
598*04150feeSXiaoDong Huang 		src = (value & 0x00c0) >> 6;
599*04150feeSXiaoDong Huang 		div = (value & 0x1f00) >> 8;
600*04150feeSXiaoDong Huang 		switch (src) {
601*04150feeSXiaoDong Huang 		case 0:
602*04150feeSXiaoDong Huang 			return 24000000;
603*04150feeSXiaoDong Huang 		case 1:
604*04150feeSXiaoDong Huang 			/* Make the return rate is equal to the set rate */
605*04150feeSXiaoDong Huang 			if (sys_clk_info.cpub01_rate)
606*04150feeSXiaoDong Huang 				return sys_clk_info.cpub01_rate;
607*04150feeSXiaoDong Huang 			else
608*04150feeSXiaoDong Huang 				return GPLL_RATE / (div + 1);
609*04150feeSXiaoDong Huang 		case 2:
610*04150feeSXiaoDong Huang 			return rk3588_b0pll_get_rate();
611*04150feeSXiaoDong Huang 		default:
612*04150feeSXiaoDong Huang 			return 0;
613*04150feeSXiaoDong Huang 		}
614*04150feeSXiaoDong Huang 	}
615*04150feeSXiaoDong Huang }
616*04150feeSXiaoDong Huang 
clk_scmi_cpub01_set_status(rk_scmi_clock_t * clock,bool status)617*04150feeSXiaoDong Huang static int clk_scmi_cpub01_set_status(rk_scmi_clock_t *clock, bool status)
618*04150feeSXiaoDong Huang {
619*04150feeSXiaoDong Huang 	return 0;
620*04150feeSXiaoDong Huang }
621*04150feeSXiaoDong Huang 
clk_scmi_b1pll_disable(void)622*04150feeSXiaoDong Huang static void clk_scmi_b1pll_disable(void)
623*04150feeSXiaoDong Huang {
624*04150feeSXiaoDong Huang 	static bool is_b1pll_disabled;
625*04150feeSXiaoDong Huang 
626*04150feeSXiaoDong Huang 	if (is_b1pll_disabled != 0)
627*04150feeSXiaoDong Huang 		return;
628*04150feeSXiaoDong Huang 
629*04150feeSXiaoDong Huang 	/* set coreb23 mux gpll */
630*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
631*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_NOR_GPLL);
632*04150feeSXiaoDong Huang 	 /* pll enter slow mode */
633*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
634*04150feeSXiaoDong Huang 	/* set pll power down */
635*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9), CRU_PLL_POWER_DOWN);
636*04150feeSXiaoDong Huang 
637*04150feeSXiaoDong Huang 	is_b1pll_disabled = true;
638*04150feeSXiaoDong Huang }
639*04150feeSXiaoDong Huang 
clk_cpub23_set_rate(unsigned long rate,enum pll_type_sel type)640*04150feeSXiaoDong Huang static int clk_cpub23_set_rate(unsigned long rate, enum pll_type_sel type)
641*04150feeSXiaoDong Huang {
642*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
643*04150feeSXiaoDong Huang 	int div;
644*04150feeSXiaoDong Huang 
645*04150feeSXiaoDong Huang 	if (rate == 0)
646*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
647*04150feeSXiaoDong Huang 
648*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub23_table,
649*04150feeSXiaoDong Huang 					 sys_clk_info.cpub23_rate_count, rate);
650*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
651*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
652*04150feeSXiaoDong Huang 
653*04150feeSXiaoDong Huang 	/* set b1pll */
654*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length)) {
655*04150feeSXiaoDong Huang 		/* set clock gating interval */
656*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
657*04150feeSXiaoDong Huang 			      0x00040000);
658*04150feeSXiaoDong Huang 		/* set ring sel */
659*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
660*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
661*04150feeSXiaoDong Huang 		/* set length */
662*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
663*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
664*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
665*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
666*04150feeSXiaoDong Huang 			      0x18);
667*04150feeSXiaoDong Huang 		/* enable pvtpll */
668*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
669*04150feeSXiaoDong Huang 			      0x00020002);
670*04150feeSXiaoDong Huang 		/* start monitor */
671*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
672*04150feeSXiaoDong Huang 			      0x00010001);
673*04150feeSXiaoDong Huang 		/* set core mux pvtpll */
674*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
675*04150feeSXiaoDong Huang 			      CPUB01_PVTPLL_PATH_PVTPLL);
676*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
677*04150feeSXiaoDong Huang 			      CPUB01_CLK_PATH_B0_PVTPLL);
678*04150feeSXiaoDong Huang 		mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
679*04150feeSXiaoDong Huang 			      CPUB01_CLK_PATH_B1_PVTPLL);
680*04150feeSXiaoDong Huang 		goto out;
681*04150feeSXiaoDong Huang 	}
682*04150feeSXiaoDong Huang 
683*04150feeSXiaoDong Huang 	/* set clk coreb23 div */
684*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
685*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
686*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 8));
687*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
688*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 0));
689*04150feeSXiaoDong Huang 	/* set coreb23 mux gpll */
690*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
691*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_NOR_GPLL);
692*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
693*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_B0PLL);
694*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
695*04150feeSXiaoDong Huang 		      CPUB01_CLK_PATH_B1PLL);
696*04150feeSXiaoDong Huang 
697*04150feeSXiaoDong Huang out:
698*04150feeSXiaoDong Huang 	clk_scmi_b1pll_disable();
699*04150feeSXiaoDong Huang 
700*04150feeSXiaoDong Huang 	return 0;
701*04150feeSXiaoDong Huang }
702*04150feeSXiaoDong Huang 
clk_scmi_cpub23_set_rate(rk_scmi_clock_t * clock,unsigned long rate)703*04150feeSXiaoDong Huang static int clk_scmi_cpub23_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
704*04150feeSXiaoDong Huang {
705*04150feeSXiaoDong Huang 	int ret;
706*04150feeSXiaoDong Huang 
707*04150feeSXiaoDong Huang 	if (rate == 0)
708*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
709*04150feeSXiaoDong Huang 
710*04150feeSXiaoDong Huang 	ret = clk_cpub23_set_rate(rate, PLL_SEL_AUTO);
711*04150feeSXiaoDong Huang 	if (ret == 0)
712*04150feeSXiaoDong Huang 		sys_clk_info.cpub23_rate = rate;
713*04150feeSXiaoDong Huang 
714*04150feeSXiaoDong Huang 	return ret;
715*04150feeSXiaoDong Huang }
716*04150feeSXiaoDong Huang 
rk3588_b1pll_get_rate(void)717*04150feeSXiaoDong Huang static unsigned long rk3588_b1pll_get_rate(void)
718*04150feeSXiaoDong Huang {
719*04150feeSXiaoDong Huang 	unsigned int m, p, s, k;
720*04150feeSXiaoDong Huang 	uint64_t rate64 = 24000000, postdiv;
721*04150feeSXiaoDong Huang 	int mode;
722*04150feeSXiaoDong Huang 
723*04150feeSXiaoDong Huang 	mode = (mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
724*04150feeSXiaoDong Huang 	       0x3;
725*04150feeSXiaoDong Huang 
726*04150feeSXiaoDong Huang 	if (mode == 0)
727*04150feeSXiaoDong Huang 		return rate64;
728*04150feeSXiaoDong Huang 
729*04150feeSXiaoDong Huang 	m = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(8)) >>
730*04150feeSXiaoDong Huang 		 CRU_PLLCON0_M_SHIFT) &
731*04150feeSXiaoDong Huang 		CRU_PLLCON0_M_MASK;
732*04150feeSXiaoDong Huang 	p = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
733*04150feeSXiaoDong Huang 		    CRU_PLLCON1_P_SHIFT) &
734*04150feeSXiaoDong Huang 		   CRU_PLLCON1_P_MASK;
735*04150feeSXiaoDong Huang 	s = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
736*04150feeSXiaoDong Huang 		  CRU_PLLCON1_S_SHIFT) &
737*04150feeSXiaoDong Huang 		 CRU_PLLCON1_S_MASK;
738*04150feeSXiaoDong Huang 	k = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(10)) >>
739*04150feeSXiaoDong Huang 		    CRU_PLLCON2_K_SHIFT) &
740*04150feeSXiaoDong Huang 		   CRU_PLLCON2_K_MASK;
741*04150feeSXiaoDong Huang 
742*04150feeSXiaoDong Huang 	rate64 *= m;
743*04150feeSXiaoDong Huang 	rate64 = rate64 / p;
744*04150feeSXiaoDong Huang 
745*04150feeSXiaoDong Huang 	if (k != 0) {
746*04150feeSXiaoDong Huang 		/* fractional mode */
747*04150feeSXiaoDong Huang 		uint64_t frac_rate64 = 24000000 * k;
748*04150feeSXiaoDong Huang 
749*04150feeSXiaoDong Huang 		postdiv = p * 65535;
750*04150feeSXiaoDong Huang 		frac_rate64 = frac_rate64 / postdiv;
751*04150feeSXiaoDong Huang 		rate64 += frac_rate64;
752*04150feeSXiaoDong Huang 	}
753*04150feeSXiaoDong Huang 	rate64 = rate64 >> s;
754*04150feeSXiaoDong Huang 
755*04150feeSXiaoDong Huang 	return (unsigned long)rate64;
756*04150feeSXiaoDong Huang }
757*04150feeSXiaoDong Huang 
clk_scmi_cpub23_get_rate(rk_scmi_clock_t * clock)758*04150feeSXiaoDong Huang static unsigned long clk_scmi_cpub23_get_rate(rk_scmi_clock_t *clock)
759*04150feeSXiaoDong Huang {
760*04150feeSXiaoDong Huang 	int value, src, div;
761*04150feeSXiaoDong Huang 
762*04150feeSXiaoDong Huang 	value = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0));
763*04150feeSXiaoDong Huang 	src = (value & 0x6000) >> 13;
764*04150feeSXiaoDong Huang 	if (src == 2) {
765*04150feeSXiaoDong Huang 		return sys_clk_info.cpub23_rate;
766*04150feeSXiaoDong Huang 	} else {
767*04150feeSXiaoDong Huang 		src = (value & 0x00c0) >> 6;
768*04150feeSXiaoDong Huang 		div = (value & 0x1f00) >> 8;
769*04150feeSXiaoDong Huang 		switch (src) {
770*04150feeSXiaoDong Huang 		case 0:
771*04150feeSXiaoDong Huang 			return 24000000;
772*04150feeSXiaoDong Huang 		case 1:
773*04150feeSXiaoDong Huang 			/* Make the return rate is equal to the set rate */
774*04150feeSXiaoDong Huang 			if (sys_clk_info.cpub23_rate)
775*04150feeSXiaoDong Huang 				return sys_clk_info.cpub23_rate;
776*04150feeSXiaoDong Huang 			else
777*04150feeSXiaoDong Huang 				return GPLL_RATE / (div + 1);
778*04150feeSXiaoDong Huang 		case 2:
779*04150feeSXiaoDong Huang 			return rk3588_b1pll_get_rate();
780*04150feeSXiaoDong Huang 		default:
781*04150feeSXiaoDong Huang 			return 0;
782*04150feeSXiaoDong Huang 		}
783*04150feeSXiaoDong Huang 	}
784*04150feeSXiaoDong Huang }
785*04150feeSXiaoDong Huang 
clk_scmi_cpub23_set_status(rk_scmi_clock_t * clock,bool status)786*04150feeSXiaoDong Huang static int clk_scmi_cpub23_set_status(rk_scmi_clock_t *clock, bool status)
787*04150feeSXiaoDong Huang {
788*04150feeSXiaoDong Huang 	return 0;
789*04150feeSXiaoDong Huang }
790*04150feeSXiaoDong Huang 
clk_scmi_dsu_get_rate(rk_scmi_clock_t * clock)791*04150feeSXiaoDong Huang static unsigned long clk_scmi_dsu_get_rate(rk_scmi_clock_t *clock)
792*04150feeSXiaoDong Huang {
793*04150feeSXiaoDong Huang 	int src, div;
794*04150feeSXiaoDong Huang 
795*04150feeSXiaoDong Huang 	src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(1)) & 0x1;
796*04150feeSXiaoDong Huang 	if (src != 0) {
797*04150feeSXiaoDong Huang 		return sys_clk_info.dsu_rate;
798*04150feeSXiaoDong Huang 	} else {
799*04150feeSXiaoDong Huang 		src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0x3000;
800*04150feeSXiaoDong Huang 		src = src >> 12;
801*04150feeSXiaoDong Huang 		div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0xf80;
802*04150feeSXiaoDong Huang 		div = div >> 7;
803*04150feeSXiaoDong Huang 		switch (src) {
804*04150feeSXiaoDong Huang 		case 0:
805*04150feeSXiaoDong Huang 			return rk3588_b0pll_get_rate() / (div + 1);
806*04150feeSXiaoDong Huang 		case 1:
807*04150feeSXiaoDong Huang 			return rk3588_b1pll_get_rate() / (div + 1);
808*04150feeSXiaoDong Huang 		case 2:
809*04150feeSXiaoDong Huang 			return rk3588_lpll_get_rate() / (div + 1);
810*04150feeSXiaoDong Huang 		case 3:
811*04150feeSXiaoDong Huang 			return GPLL_RATE / (div + 1);
812*04150feeSXiaoDong Huang 		default:
813*04150feeSXiaoDong Huang 			return 0;
814*04150feeSXiaoDong Huang 		}
815*04150feeSXiaoDong Huang 	}
816*04150feeSXiaoDong Huang }
817*04150feeSXiaoDong Huang 
clk_scmi_lpll_disable(void)818*04150feeSXiaoDong Huang static void clk_scmi_lpll_disable(void)
819*04150feeSXiaoDong Huang {
820*04150feeSXiaoDong Huang 	static bool is_lpll_disabled;
821*04150feeSXiaoDong Huang 
822*04150feeSXiaoDong Huang 	if (is_lpll_disabled)
823*04150feeSXiaoDong Huang 		return;
824*04150feeSXiaoDong Huang 
825*04150feeSXiaoDong Huang 	/* set corel mux gpll */
826*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
827*04150feeSXiaoDong Huang 		      CPUL_CLK_PATH_NOR_GPLL);
828*04150feeSXiaoDong Huang 	/* set dsu mux gpll */
829*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
830*04150feeSXiaoDong Huang 		      SCLK_DSU_PATH_NOR_GPLL);
831*04150feeSXiaoDong Huang 	/* pll enter slow mode */
832*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
833*04150feeSXiaoDong Huang 	/* set pll power down */
834*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_PLL_CON(17), CRU_PLL_POWER_DOWN);
835*04150feeSXiaoDong Huang 
836*04150feeSXiaoDong Huang 	is_lpll_disabled = true;
837*04150feeSXiaoDong Huang }
838*04150feeSXiaoDong Huang 
clk_dsu_set_rate(unsigned long rate,enum pll_type_sel type)839*04150feeSXiaoDong Huang static int clk_dsu_set_rate(unsigned long rate, enum pll_type_sel type)
840*04150feeSXiaoDong Huang {
841*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
842*04150feeSXiaoDong Huang 	int div;
843*04150feeSXiaoDong Huang 
844*04150feeSXiaoDong Huang 	if (rate == 0)
845*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
846*04150feeSXiaoDong Huang 
847*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
848*04150feeSXiaoDong Huang 					 sys_clk_info.cpul_rate_count, rate);
849*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
850*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
851*04150feeSXiaoDong Huang 
852*04150feeSXiaoDong Huang 	/* set pvtpll */
853*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length)) {
854*04150feeSXiaoDong Huang 		/* set clock gating interval */
855*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON2,
856*04150feeSXiaoDong Huang 			      0x00040000);
857*04150feeSXiaoDong Huang 		/* set ring sel */
858*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
859*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
860*04150feeSXiaoDong Huang 		/* set length */
861*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_H,
862*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
863*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
864*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON1,
865*04150feeSXiaoDong Huang 			      0x18);
866*04150feeSXiaoDong Huang 		/* enable pvtpll */
867*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
868*04150feeSXiaoDong Huang 			      0x00020002);
869*04150feeSXiaoDong Huang 		/* start monitor */
870*04150feeSXiaoDong Huang 		mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
871*04150feeSXiaoDong Huang 			      0x00010001);
872*04150feeSXiaoDong Huang 		/* set dsu mux pvtpll */
873*04150feeSXiaoDong Huang 		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
874*04150feeSXiaoDong Huang 			      DSU_PVTPLL_PATH_PVTPLL);
875*04150feeSXiaoDong Huang 		mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
876*04150feeSXiaoDong Huang 			      SCLK_DSU_PATH_PVTPLL);
877*04150feeSXiaoDong Huang 		goto out;
878*04150feeSXiaoDong Huang 	}
879*04150feeSXiaoDong Huang 	/* set dsu div */
880*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
881*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
882*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div, 7));
883*04150feeSXiaoDong Huang 	/* set dsu mux gpll */
884*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
885*04150feeSXiaoDong Huang 		      SCLK_DSU_PATH_NOR_GPLL);
886*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
887*04150feeSXiaoDong Huang 		      SCLK_DSU_PATH_NOR_PLL);
888*04150feeSXiaoDong Huang 
889*04150feeSXiaoDong Huang out:
890*04150feeSXiaoDong Huang 	clk_scmi_lpll_disable();
891*04150feeSXiaoDong Huang 
892*04150feeSXiaoDong Huang 	return 0;
893*04150feeSXiaoDong Huang }
894*04150feeSXiaoDong Huang 
clk_scmi_dsu_set_rate(rk_scmi_clock_t * clock,unsigned long rate)895*04150feeSXiaoDong Huang static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
896*04150feeSXiaoDong Huang {
897*04150feeSXiaoDong Huang 	int ret;
898*04150feeSXiaoDong Huang 
899*04150feeSXiaoDong Huang 	if (rate == 0)
900*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
901*04150feeSXiaoDong Huang 
902*04150feeSXiaoDong Huang 	ret = clk_dsu_set_rate(rate, PLL_SEL_AUTO);
903*04150feeSXiaoDong Huang 
904*04150feeSXiaoDong Huang 	if (ret == 0)
905*04150feeSXiaoDong Huang 		sys_clk_info.dsu_rate = rate;
906*04150feeSXiaoDong Huang 	return ret;
907*04150feeSXiaoDong Huang }
908*04150feeSXiaoDong Huang 
clk_scmi_dsu_set_status(rk_scmi_clock_t * clock,bool status)909*04150feeSXiaoDong Huang static int clk_scmi_dsu_set_status(rk_scmi_clock_t *clock, bool status)
910*04150feeSXiaoDong Huang {
911*04150feeSXiaoDong Huang 	return 0;
912*04150feeSXiaoDong Huang }
913*04150feeSXiaoDong Huang 
clk_scmi_gpu_get_rate(rk_scmi_clock_t * clock)914*04150feeSXiaoDong Huang static unsigned long clk_scmi_gpu_get_rate(rk_scmi_clock_t *clock)
915*04150feeSXiaoDong Huang {
916*04150feeSXiaoDong Huang 	int div, src;
917*04150feeSXiaoDong Huang 
918*04150feeSXiaoDong Huang 	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x4000) != 0) {
919*04150feeSXiaoDong Huang 		return sys_clk_info.gpu_rate;
920*04150feeSXiaoDong Huang 	} else {
921*04150feeSXiaoDong Huang 		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x1f;
922*04150feeSXiaoDong Huang 		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x00e0;
923*04150feeSXiaoDong Huang 		src = src >> 5;
924*04150feeSXiaoDong Huang 		switch (src) {
925*04150feeSXiaoDong Huang 		case 0:
926*04150feeSXiaoDong Huang 			/* Make the return rate is equal to the set rate */
927*04150feeSXiaoDong Huang 			if (sys_clk_info.gpu_rate)
928*04150feeSXiaoDong Huang 				return sys_clk_info.gpu_rate;
929*04150feeSXiaoDong Huang 			else
930*04150feeSXiaoDong Huang 				return GPLL_RATE / (div + 1);
931*04150feeSXiaoDong Huang 		case 1:
932*04150feeSXiaoDong Huang 			return CPLL_RATE / (div + 1);
933*04150feeSXiaoDong Huang 		case 2:
934*04150feeSXiaoDong Huang 			return AUPLL_RATE / (div + 1);
935*04150feeSXiaoDong Huang 		case 3:
936*04150feeSXiaoDong Huang 			return NPLL_RATE / (div + 1);
937*04150feeSXiaoDong Huang 		case 4:
938*04150feeSXiaoDong Huang 			return SPLL_RATE / (div + 1);
939*04150feeSXiaoDong Huang 		default:
940*04150feeSXiaoDong Huang 			return 0;
941*04150feeSXiaoDong Huang 		}
942*04150feeSXiaoDong Huang 	}
943*04150feeSXiaoDong Huang }
944*04150feeSXiaoDong Huang 
clk_gpu_set_rate(unsigned long rate,enum pll_type_sel type)945*04150feeSXiaoDong Huang static int clk_gpu_set_rate(unsigned long rate, enum pll_type_sel type)
946*04150feeSXiaoDong Huang {
947*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
948*04150feeSXiaoDong Huang 	int div;
949*04150feeSXiaoDong Huang 
950*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.gpu_table,
951*04150feeSXiaoDong Huang 					 sys_clk_info.gpu_rate_count, rate);
952*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
953*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
954*04150feeSXiaoDong Huang 
955*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length)) {
956*04150feeSXiaoDong Huang 		/* set clock gating interval */
957*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON2,
958*04150feeSXiaoDong Huang 			      0x00040000);
959*04150feeSXiaoDong Huang 		/* set ring sel */
960*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
961*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
962*04150feeSXiaoDong Huang 		/* set length */
963*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_H,
964*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
965*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
966*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON1,
967*04150feeSXiaoDong Huang 			      0x18);
968*04150feeSXiaoDong Huang 		/* enable pvtpll */
969*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
970*04150feeSXiaoDong Huang 			      0x00020002);
971*04150feeSXiaoDong Huang 		/* start monitor */
972*04150feeSXiaoDong Huang 		mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
973*04150feeSXiaoDong Huang 			      0x00010001);
974*04150feeSXiaoDong Huang 		/* set gpu mux pvtpll */
975*04150feeSXiaoDong Huang 		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
976*04150feeSXiaoDong Huang 			      GPU_CLK_PATH_PVTPLL);
977*04150feeSXiaoDong Huang 		return 0;
978*04150feeSXiaoDong Huang 	}
979*04150feeSXiaoDong Huang 
980*04150feeSXiaoDong Huang 	/* set gpu div */
981*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate);
982*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
983*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div - 1, 0));
984*04150feeSXiaoDong Huang 	/* set gpu mux gpll */
985*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
986*04150feeSXiaoDong Huang 		      GPU_CLK_PATH_NOR_GPLL);
987*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
988*04150feeSXiaoDong Huang 		      GPU_CLK_PATH_NOR_PLL);
989*04150feeSXiaoDong Huang 
990*04150feeSXiaoDong Huang 	return 0;
991*04150feeSXiaoDong Huang }
992*04150feeSXiaoDong Huang 
clk_scmi_gpu_set_rate(rk_scmi_clock_t * clock,unsigned long rate)993*04150feeSXiaoDong Huang static int clk_scmi_gpu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
994*04150feeSXiaoDong Huang {
995*04150feeSXiaoDong Huang 	int ret;
996*04150feeSXiaoDong Huang 
997*04150feeSXiaoDong Huang 	if (rate == 0)
998*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
999*04150feeSXiaoDong Huang 
1000*04150feeSXiaoDong Huang 	ret = clk_gpu_set_rate(rate, PLL_SEL_AUTO);
1001*04150feeSXiaoDong Huang 	if (ret == 0)
1002*04150feeSXiaoDong Huang 		sys_clk_info.gpu_rate = rate;
1003*04150feeSXiaoDong Huang 
1004*04150feeSXiaoDong Huang 	return ret;
1005*04150feeSXiaoDong Huang }
1006*04150feeSXiaoDong Huang 
clk_scmi_gpu_set_status(rk_scmi_clock_t * clock,bool status)1007*04150feeSXiaoDong Huang static int clk_scmi_gpu_set_status(rk_scmi_clock_t *clock, bool status)
1008*04150feeSXiaoDong Huang {
1009*04150feeSXiaoDong Huang 	return 0;
1010*04150feeSXiaoDong Huang }
1011*04150feeSXiaoDong Huang 
clk_scmi_npu_get_rate(rk_scmi_clock_t * clock)1012*04150feeSXiaoDong Huang static unsigned long clk_scmi_npu_get_rate(rk_scmi_clock_t *clock)
1013*04150feeSXiaoDong Huang {
1014*04150feeSXiaoDong Huang 	int div, src;
1015*04150feeSXiaoDong Huang 
1016*04150feeSXiaoDong Huang 	if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(74)) & 0x1) != 0) {
1017*04150feeSXiaoDong Huang 		return sys_clk_info.npu_rate;
1018*04150feeSXiaoDong Huang 	} else {
1019*04150feeSXiaoDong Huang 		div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x007c;
1020*04150feeSXiaoDong Huang 		div = div >> 2;
1021*04150feeSXiaoDong Huang 		src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x0380;
1022*04150feeSXiaoDong Huang 		src = src >> 7;
1023*04150feeSXiaoDong Huang 		switch (src) {
1024*04150feeSXiaoDong Huang 		case 0:
1025*04150feeSXiaoDong Huang 			/* Make the return rate is equal to the set rate */
1026*04150feeSXiaoDong Huang 			if (sys_clk_info.npu_rate != 0)
1027*04150feeSXiaoDong Huang 				return sys_clk_info.npu_rate;
1028*04150feeSXiaoDong Huang 			else
1029*04150feeSXiaoDong Huang 				return GPLL_RATE / (div + 1);
1030*04150feeSXiaoDong Huang 		case 1:
1031*04150feeSXiaoDong Huang 			return CPLL_RATE / (div + 1);
1032*04150feeSXiaoDong Huang 		case 2:
1033*04150feeSXiaoDong Huang 			return AUPLL_RATE / (div + 1);
1034*04150feeSXiaoDong Huang 		case 3:
1035*04150feeSXiaoDong Huang 			return NPLL_RATE / (div + 1);
1036*04150feeSXiaoDong Huang 		case 4:
1037*04150feeSXiaoDong Huang 			return SPLL_RATE / (div + 1);
1038*04150feeSXiaoDong Huang 		default:
1039*04150feeSXiaoDong Huang 			return 0;
1040*04150feeSXiaoDong Huang 		}
1041*04150feeSXiaoDong Huang 	}
1042*04150feeSXiaoDong Huang }
1043*04150feeSXiaoDong Huang 
clk_npu_set_rate(unsigned long rate,enum pll_type_sel type)1044*04150feeSXiaoDong Huang static int clk_npu_set_rate(unsigned long rate, enum pll_type_sel type)
1045*04150feeSXiaoDong Huang {
1046*04150feeSXiaoDong Huang 	struct pvtpll_table *pvtpll;
1047*04150feeSXiaoDong Huang 	int div;
1048*04150feeSXiaoDong Huang 
1049*04150feeSXiaoDong Huang 	pvtpll = rkclk_get_pvtpll_config(sys_clk_info.npu_table,
1050*04150feeSXiaoDong Huang 					 sys_clk_info.npu_rate_count, rate);
1051*04150feeSXiaoDong Huang 	if (pvtpll == NULL)
1052*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
1053*04150feeSXiaoDong Huang 
1054*04150feeSXiaoDong Huang 	if (PVTPLL_NEED(type, pvtpll->length)) {
1055*04150feeSXiaoDong Huang 		/* set clock gating interval */
1056*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON2,
1057*04150feeSXiaoDong Huang 			      0x00040000);
1058*04150feeSXiaoDong Huang 		/* set ring sel */
1059*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
1060*04150feeSXiaoDong Huang 			      0x07000000 | (pvtpll->ring_sel << 8));
1061*04150feeSXiaoDong Huang 		/* set length */
1062*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_H,
1063*04150feeSXiaoDong Huang 			      0x003f0000 | pvtpll->length);
1064*04150feeSXiaoDong Huang 		/* set cal cnt = 24, T = 1us */
1065*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON1,
1066*04150feeSXiaoDong Huang 			      0x18);
1067*04150feeSXiaoDong Huang 		/* enable pvtpll */
1068*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
1069*04150feeSXiaoDong Huang 			      0x00020002);
1070*04150feeSXiaoDong Huang 		/* start monitor */
1071*04150feeSXiaoDong Huang 		mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
1072*04150feeSXiaoDong Huang 			      0x00010001);
1073*04150feeSXiaoDong Huang 		/* set npu mux pvtpll */
1074*04150feeSXiaoDong Huang 		mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
1075*04150feeSXiaoDong Huang 			      NPU_CLK_PATH_PVTPLL);
1076*04150feeSXiaoDong Huang 		return 0;
1077*04150feeSXiaoDong Huang 	}
1078*04150feeSXiaoDong Huang 
1079*04150feeSXiaoDong Huang 	/* set npu div */
1080*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(GPLL_RATE, rate);
1081*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
1082*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div - 1, 2));
1083*04150feeSXiaoDong Huang 	/* set npu mux gpll */
1084*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
1085*04150feeSXiaoDong Huang 		      NPU_CLK_PATH_NOR_GPLL);
1086*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
1087*04150feeSXiaoDong Huang 		      NPU_CLK_PATH_NOR_PLL);
1088*04150feeSXiaoDong Huang 
1089*04150feeSXiaoDong Huang 	return 0;
1090*04150feeSXiaoDong Huang }
1091*04150feeSXiaoDong Huang 
clk_scmi_npu_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1092*04150feeSXiaoDong Huang static int clk_scmi_npu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1093*04150feeSXiaoDong Huang {
1094*04150feeSXiaoDong Huang 	int ret;
1095*04150feeSXiaoDong Huang 
1096*04150feeSXiaoDong Huang 	if (rate == 0)
1097*04150feeSXiaoDong Huang 		return SCMI_INVALID_PARAMETERS;
1098*04150feeSXiaoDong Huang 
1099*04150feeSXiaoDong Huang 	ret = clk_npu_set_rate(rate, PLL_SEL_AUTO);
1100*04150feeSXiaoDong Huang 	if (ret == 0)
1101*04150feeSXiaoDong Huang 		sys_clk_info.npu_rate = rate;
1102*04150feeSXiaoDong Huang 
1103*04150feeSXiaoDong Huang 	return ret;
1104*04150feeSXiaoDong Huang }
1105*04150feeSXiaoDong Huang 
clk_scmi_npu_set_status(rk_scmi_clock_t * clock,bool status)1106*04150feeSXiaoDong Huang static int clk_scmi_npu_set_status(rk_scmi_clock_t *clock, bool status)
1107*04150feeSXiaoDong Huang {
1108*04150feeSXiaoDong Huang 	return 0;
1109*04150feeSXiaoDong Huang }
1110*04150feeSXiaoDong Huang 
clk_scmi_sbus_get_rate(rk_scmi_clock_t * clock)1111*04150feeSXiaoDong Huang static unsigned long clk_scmi_sbus_get_rate(rk_scmi_clock_t *clock)
1112*04150feeSXiaoDong Huang {
1113*04150feeSXiaoDong Huang 	int div;
1114*04150feeSXiaoDong Huang 
1115*04150feeSXiaoDong Huang 	if ((mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0)) & 0x0800) != 0) {
1116*04150feeSXiaoDong Huang 		div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
1117*04150feeSXiaoDong Huang 		div = (div & 0x03e0) >> 5;
1118*04150feeSXiaoDong Huang 		return SPLL_RATE / (div + 1);
1119*04150feeSXiaoDong Huang 	} else {
1120*04150feeSXiaoDong Huang 		return OSC_HZ;
1121*04150feeSXiaoDong Huang 	}
1122*04150feeSXiaoDong Huang }
1123*04150feeSXiaoDong Huang 
clk_scmi_sbus_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1124*04150feeSXiaoDong Huang static int clk_scmi_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1125*04150feeSXiaoDong Huang {
1126*04150feeSXiaoDong Huang 	int div;
1127*04150feeSXiaoDong Huang 
1128*04150feeSXiaoDong Huang 	if (rate == OSC_HZ) {
1129*04150feeSXiaoDong Huang 		mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
1130*04150feeSXiaoDong Huang 			      WMSK_BIT(11));
1131*04150feeSXiaoDong Huang 		return 0;
1132*04150feeSXiaoDong Huang 	}
1133*04150feeSXiaoDong Huang 
1134*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(SPLL_RATE, rate);
1135*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
1136*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div - 1, 5));
1137*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
1138*04150feeSXiaoDong Huang 		      BIT_WITH_WMSK(11) | WMSK_BIT(10));
1139*04150feeSXiaoDong Huang 	return 0;
1140*04150feeSXiaoDong Huang }
1141*04150feeSXiaoDong Huang 
clk_scmi_sbus_set_status(rk_scmi_clock_t * clock,bool status)1142*04150feeSXiaoDong Huang static int clk_scmi_sbus_set_status(rk_scmi_clock_t *clock, bool status)
1143*04150feeSXiaoDong Huang {
1144*04150feeSXiaoDong Huang 	return 0;
1145*04150feeSXiaoDong Huang }
1146*04150feeSXiaoDong Huang 
clk_scmi_pclk_sbus_get_rate(rk_scmi_clock_t * clock)1147*04150feeSXiaoDong Huang static unsigned long clk_scmi_pclk_sbus_get_rate(rk_scmi_clock_t *clock)
1148*04150feeSXiaoDong Huang {
1149*04150feeSXiaoDong Huang 	int div;
1150*04150feeSXiaoDong Huang 
1151*04150feeSXiaoDong Huang 	div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
1152*04150feeSXiaoDong Huang 	div = div & 0x001f;
1153*04150feeSXiaoDong Huang 	return SPLL_RATE / (div + 1);
1154*04150feeSXiaoDong Huang 
1155*04150feeSXiaoDong Huang }
1156*04150feeSXiaoDong Huang 
clk_scmi_pclk_sbus_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1157*04150feeSXiaoDong Huang static int clk_scmi_pclk_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1158*04150feeSXiaoDong Huang {
1159*04150feeSXiaoDong Huang 	int div;
1160*04150feeSXiaoDong Huang 
1161*04150feeSXiaoDong Huang 	div = DIV_ROUND_UP(SPLL_RATE, rate);
1162*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
1163*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(div - 1, 0));
1164*04150feeSXiaoDong Huang 	return 0;
1165*04150feeSXiaoDong Huang }
1166*04150feeSXiaoDong Huang 
clk_scmi_pclk_sbus_set_status(rk_scmi_clock_t * clock,bool status)1167*04150feeSXiaoDong Huang static int clk_scmi_pclk_sbus_set_status(rk_scmi_clock_t *clock, bool status)
1168*04150feeSXiaoDong Huang {
1169*04150feeSXiaoDong Huang 	return 0;
1170*04150feeSXiaoDong Huang }
1171*04150feeSXiaoDong Huang 
clk_scmi_cclk_sdmmc_get_rate(rk_scmi_clock_t * clock)1172*04150feeSXiaoDong Huang static unsigned long clk_scmi_cclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
1173*04150feeSXiaoDong Huang {
1174*04150feeSXiaoDong Huang 	int div;
1175*04150feeSXiaoDong Huang 	uint32_t src;
1176*04150feeSXiaoDong Huang 
1177*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x3000;
1178*04150feeSXiaoDong Huang 	src = src >> 12;
1179*04150feeSXiaoDong Huang 	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0fc0;
1180*04150feeSXiaoDong Huang 	div = div >> 6;
1181*04150feeSXiaoDong Huang 	if (src == 1) {
1182*04150feeSXiaoDong Huang 		return SPLL_RATE / (div + 1);
1183*04150feeSXiaoDong Huang 	} else if (src == 2) {
1184*04150feeSXiaoDong Huang 		return OSC_HZ / (div + 1);
1185*04150feeSXiaoDong Huang 	} else {
1186*04150feeSXiaoDong Huang 		return GPLL_RATE / (div + 1);
1187*04150feeSXiaoDong Huang 	}
1188*04150feeSXiaoDong Huang }
1189*04150feeSXiaoDong Huang 
clk_scmi_cclk_sdmmc_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1190*04150feeSXiaoDong Huang static int clk_scmi_cclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1191*04150feeSXiaoDong Huang {
1192*04150feeSXiaoDong Huang 	int div;
1193*04150feeSXiaoDong Huang 
1194*04150feeSXiaoDong Huang 	if ((OSC_HZ % rate) == 0) {
1195*04150feeSXiaoDong Huang 		div = DIV_ROUND_UP(OSC_HZ, rate);
1196*04150feeSXiaoDong Huang 		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
1197*04150feeSXiaoDong Huang 			      CLKDIV_6BITS_SHF(div - 1, 6) |
1198*04150feeSXiaoDong Huang 			      BITS_WITH_WMASK(2U, 0x3U, 12));
1199*04150feeSXiaoDong Huang 	} else if ((SPLL_RATE % rate) == 0) {
1200*04150feeSXiaoDong Huang 		div = DIV_ROUND_UP(SPLL_RATE, rate);
1201*04150feeSXiaoDong Huang 		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
1202*04150feeSXiaoDong Huang 			      CLKDIV_6BITS_SHF(div - 1, 6) |
1203*04150feeSXiaoDong Huang 			      BITS_WITH_WMASK(1U, 0x3U, 12));
1204*04150feeSXiaoDong Huang 	} else {
1205*04150feeSXiaoDong Huang 		div = DIV_ROUND_UP(GPLL_RATE, rate);
1206*04150feeSXiaoDong Huang 		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
1207*04150feeSXiaoDong Huang 			      CLKDIV_6BITS_SHF(div - 1, 6) |
1208*04150feeSXiaoDong Huang 			      BITS_WITH_WMASK(0U, 0x3U, 12));
1209*04150feeSXiaoDong Huang 	}
1210*04150feeSXiaoDong Huang 
1211*04150feeSXiaoDong Huang 	return 0;
1212*04150feeSXiaoDong Huang }
1213*04150feeSXiaoDong Huang 
clk_scmi_cclk_sdmmc_set_status(rk_scmi_clock_t * clock,bool status)1214*04150feeSXiaoDong Huang static int clk_scmi_cclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
1215*04150feeSXiaoDong Huang {
1216*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
1217*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 4));
1218*04150feeSXiaoDong Huang 	return 0;
1219*04150feeSXiaoDong Huang }
1220*04150feeSXiaoDong Huang 
clk_scmi_dclk_sdmmc_get_rate(rk_scmi_clock_t * clock)1221*04150feeSXiaoDong Huang static unsigned long clk_scmi_dclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
1222*04150feeSXiaoDong Huang {
1223*04150feeSXiaoDong Huang 	int div;
1224*04150feeSXiaoDong Huang 	uint32_t src;
1225*04150feeSXiaoDong Huang 
1226*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0020;
1227*04150feeSXiaoDong Huang 	div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x001f;
1228*04150feeSXiaoDong Huang 	if (src != 0) {
1229*04150feeSXiaoDong Huang 		return SPLL_RATE / (div + 1);
1230*04150feeSXiaoDong Huang 	} else {
1231*04150feeSXiaoDong Huang 		return GPLL_RATE / (div + 1);
1232*04150feeSXiaoDong Huang 	}
1233*04150feeSXiaoDong Huang }
1234*04150feeSXiaoDong Huang 
clk_scmi_dclk_sdmmc_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1235*04150feeSXiaoDong Huang static int clk_scmi_dclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1236*04150feeSXiaoDong Huang {
1237*04150feeSXiaoDong Huang 	int div;
1238*04150feeSXiaoDong Huang 
1239*04150feeSXiaoDong Huang 	if ((SPLL_RATE % rate) == 0) {
1240*04150feeSXiaoDong Huang 		div = DIV_ROUND_UP(SPLL_RATE, rate);
1241*04150feeSXiaoDong Huang 		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
1242*04150feeSXiaoDong Huang 			      CLKDIV_5BITS_SHF(div - 1, 0) |
1243*04150feeSXiaoDong Huang 			      BITS_WITH_WMASK(1U, 0x1U, 5));
1244*04150feeSXiaoDong Huang 	} else {
1245*04150feeSXiaoDong Huang 		div = DIV_ROUND_UP(GPLL_RATE, rate);
1246*04150feeSXiaoDong Huang 		mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
1247*04150feeSXiaoDong Huang 			      CLKDIV_5BITS_SHF(div - 1, 0) |
1248*04150feeSXiaoDong Huang 			      BITS_WITH_WMASK(0U, 0x1U, 5));
1249*04150feeSXiaoDong Huang 	}
1250*04150feeSXiaoDong Huang 	return 0;
1251*04150feeSXiaoDong Huang }
1252*04150feeSXiaoDong Huang 
clk_scmi_dclk_sdmmc_set_status(rk_scmi_clock_t * clock,bool status)1253*04150feeSXiaoDong Huang static int clk_scmi_dclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
1254*04150feeSXiaoDong Huang {
1255*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
1256*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 1));
1257*04150feeSXiaoDong Huang 	return 0;
1258*04150feeSXiaoDong Huang }
1259*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_ns_get_rate(rk_scmi_clock_t * clock)1260*04150feeSXiaoDong Huang static unsigned long clk_scmi_aclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
1261*04150feeSXiaoDong Huang {
1262*04150feeSXiaoDong Huang 	uint32_t src;
1263*04150feeSXiaoDong Huang 
1264*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0003;
1265*04150feeSXiaoDong Huang 	switch (src) {
1266*04150feeSXiaoDong Huang 	case 0:
1267*04150feeSXiaoDong Huang 		return 350 * MHz;
1268*04150feeSXiaoDong Huang 	case 1:
1269*04150feeSXiaoDong Huang 		return 200 * MHz;
1270*04150feeSXiaoDong Huang 	case 2:
1271*04150feeSXiaoDong Huang 		return 100 * MHz;
1272*04150feeSXiaoDong Huang 	case 3:
1273*04150feeSXiaoDong Huang 		return OSC_HZ;
1274*04150feeSXiaoDong Huang 	default:
1275*04150feeSXiaoDong Huang 		return 0;
1276*04150feeSXiaoDong Huang 	}
1277*04150feeSXiaoDong Huang }
1278*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_ns_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1279*04150feeSXiaoDong Huang static int clk_scmi_aclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1280*04150feeSXiaoDong Huang {
1281*04150feeSXiaoDong Huang 	uint32_t src;
1282*04150feeSXiaoDong Huang 
1283*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1284*04150feeSXiaoDong Huang 		src = 0;
1285*04150feeSXiaoDong Huang 	else if (rate >= 200 * MHz)
1286*04150feeSXiaoDong Huang 		src = 1;
1287*04150feeSXiaoDong Huang 	else if (rate >= 100 * MHz)
1288*04150feeSXiaoDong Huang 		src = 2;
1289*04150feeSXiaoDong Huang 	else
1290*04150feeSXiaoDong Huang 		src = 3;
1291*04150feeSXiaoDong Huang 
1292*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1293*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 0));
1294*04150feeSXiaoDong Huang 
1295*04150feeSXiaoDong Huang 	return 0;
1296*04150feeSXiaoDong Huang }
1297*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_ns_set_status(rk_scmi_clock_t * clock,bool status)1298*04150feeSXiaoDong Huang static int clk_scmi_aclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
1299*04150feeSXiaoDong Huang {
1300*04150feeSXiaoDong Huang 	return 0;
1301*04150feeSXiaoDong Huang }
1302*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_ns_get_rate(rk_scmi_clock_t * clock)1303*04150feeSXiaoDong Huang static unsigned long clk_scmi_hclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
1304*04150feeSXiaoDong Huang {
1305*04150feeSXiaoDong Huang 	uint32_t src;
1306*04150feeSXiaoDong Huang 
1307*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x000c;
1308*04150feeSXiaoDong Huang 	src = src >> 2;
1309*04150feeSXiaoDong Huang 	switch (src) {
1310*04150feeSXiaoDong Huang 	case 0:
1311*04150feeSXiaoDong Huang 		return 150 * MHz;
1312*04150feeSXiaoDong Huang 	case 1:
1313*04150feeSXiaoDong Huang 		return 100 * MHz;
1314*04150feeSXiaoDong Huang 	case 2:
1315*04150feeSXiaoDong Huang 		return 50 * MHz;
1316*04150feeSXiaoDong Huang 	case 3:
1317*04150feeSXiaoDong Huang 		return OSC_HZ;
1318*04150feeSXiaoDong Huang 	default:
1319*04150feeSXiaoDong Huang 		return 0;
1320*04150feeSXiaoDong Huang 	}
1321*04150feeSXiaoDong Huang }
1322*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_ns_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1323*04150feeSXiaoDong Huang static int clk_scmi_hclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1324*04150feeSXiaoDong Huang {
1325*04150feeSXiaoDong Huang 	uint32_t src;
1326*04150feeSXiaoDong Huang 
1327*04150feeSXiaoDong Huang 	if (rate >= 150 * MHz)
1328*04150feeSXiaoDong Huang 		src = 0;
1329*04150feeSXiaoDong Huang 	else if (rate >= 100 * MHz)
1330*04150feeSXiaoDong Huang 		src = 1;
1331*04150feeSXiaoDong Huang 	else if (rate >= 50 * MHz)
1332*04150feeSXiaoDong Huang 		src = 2;
1333*04150feeSXiaoDong Huang 	else
1334*04150feeSXiaoDong Huang 		src = 3;
1335*04150feeSXiaoDong Huang 
1336*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1337*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 2));
1338*04150feeSXiaoDong Huang 	return 0;
1339*04150feeSXiaoDong Huang }
1340*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_ns_set_status(rk_scmi_clock_t * clock,bool status)1341*04150feeSXiaoDong Huang static int clk_scmi_hclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
1342*04150feeSXiaoDong Huang {
1343*04150feeSXiaoDong Huang 	return 0;
1344*04150feeSXiaoDong Huang }
1345*04150feeSXiaoDong Huang 
clk_scmi_tclk_wdt_get_rate(rk_scmi_clock_t * clock)1346*04150feeSXiaoDong Huang static unsigned long clk_scmi_tclk_wdt_get_rate(rk_scmi_clock_t *clock)
1347*04150feeSXiaoDong Huang {
1348*04150feeSXiaoDong Huang 	return OSC_HZ;
1349*04150feeSXiaoDong Huang }
1350*04150feeSXiaoDong Huang 
clk_scmi_tclk_wdt_set_status(rk_scmi_clock_t * clock,bool status)1351*04150feeSXiaoDong Huang static int clk_scmi_tclk_wdt_set_status(rk_scmi_clock_t *clock, bool status)
1352*04150feeSXiaoDong Huang {
1353*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
1354*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 0));
1355*04150feeSXiaoDong Huang 	return 0;
1356*04150feeSXiaoDong Huang }
1357*04150feeSXiaoDong Huang 
clk_scmi_keyladder_core_get_rate(rk_scmi_clock_t * clock)1358*04150feeSXiaoDong Huang static unsigned long clk_scmi_keyladder_core_get_rate(rk_scmi_clock_t *clock)
1359*04150feeSXiaoDong Huang {
1360*04150feeSXiaoDong Huang 	uint32_t src;
1361*04150feeSXiaoDong Huang 
1362*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x00c0;
1363*04150feeSXiaoDong Huang 	src = src >> 6;
1364*04150feeSXiaoDong Huang 	switch (src) {
1365*04150feeSXiaoDong Huang 	case 0:
1366*04150feeSXiaoDong Huang 		return 350 * MHz;
1367*04150feeSXiaoDong Huang 	case 1:
1368*04150feeSXiaoDong Huang 		return 233 * MHz;
1369*04150feeSXiaoDong Huang 	case 2:
1370*04150feeSXiaoDong Huang 		return 116 * MHz;
1371*04150feeSXiaoDong Huang 	case 3:
1372*04150feeSXiaoDong Huang 		return OSC_HZ;
1373*04150feeSXiaoDong Huang 	default:
1374*04150feeSXiaoDong Huang 		return 0;
1375*04150feeSXiaoDong Huang 	}
1376*04150feeSXiaoDong Huang }
1377*04150feeSXiaoDong Huang 
clk_scmi_keyladder_core_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1378*04150feeSXiaoDong Huang static int clk_scmi_keyladder_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1379*04150feeSXiaoDong Huang {
1380*04150feeSXiaoDong Huang 	uint32_t src;
1381*04150feeSXiaoDong Huang 
1382*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1383*04150feeSXiaoDong Huang 		src = 0;
1384*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1385*04150feeSXiaoDong Huang 		src = 1;
1386*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1387*04150feeSXiaoDong Huang 		src = 2;
1388*04150feeSXiaoDong Huang 	else
1389*04150feeSXiaoDong Huang 		src = 3;
1390*04150feeSXiaoDong Huang 
1391*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
1392*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 6));
1393*04150feeSXiaoDong Huang 	return 0;
1394*04150feeSXiaoDong Huang }
1395*04150feeSXiaoDong Huang 
clk_scmi_keyladder_core_set_status(rk_scmi_clock_t * clock,bool status)1396*04150feeSXiaoDong Huang static int clk_scmi_keyladder_core_set_status(rk_scmi_clock_t *clock, bool status)
1397*04150feeSXiaoDong Huang {
1398*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1399*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 9));
1400*04150feeSXiaoDong Huang 	return 0;
1401*04150feeSXiaoDong Huang }
1402*04150feeSXiaoDong Huang 
clk_scmi_keyladder_rng_get_rate(rk_scmi_clock_t * clock)1403*04150feeSXiaoDong Huang static unsigned long clk_scmi_keyladder_rng_get_rate(rk_scmi_clock_t *clock)
1404*04150feeSXiaoDong Huang {
1405*04150feeSXiaoDong Huang 	uint32_t src;
1406*04150feeSXiaoDong Huang 
1407*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0300;
1408*04150feeSXiaoDong Huang 	src = src >> 8;
1409*04150feeSXiaoDong Huang 	switch (src) {
1410*04150feeSXiaoDong Huang 	case 0:
1411*04150feeSXiaoDong Huang 		return 175 * MHz;
1412*04150feeSXiaoDong Huang 	case 1:
1413*04150feeSXiaoDong Huang 		return 116 * MHz;
1414*04150feeSXiaoDong Huang 	case 2:
1415*04150feeSXiaoDong Huang 		return 58 * MHz;
1416*04150feeSXiaoDong Huang 	case 3:
1417*04150feeSXiaoDong Huang 		return OSC_HZ;
1418*04150feeSXiaoDong Huang 	default:
1419*04150feeSXiaoDong Huang 		return 0;
1420*04150feeSXiaoDong Huang 	}
1421*04150feeSXiaoDong Huang }
1422*04150feeSXiaoDong Huang 
clk_scmi_keyladder_rng_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1423*04150feeSXiaoDong Huang static int clk_scmi_keyladder_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1424*04150feeSXiaoDong Huang {
1425*04150feeSXiaoDong Huang 	uint32_t src;
1426*04150feeSXiaoDong Huang 
1427*04150feeSXiaoDong Huang 	if (rate >= 175 * MHz)
1428*04150feeSXiaoDong Huang 		src = 0;
1429*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1430*04150feeSXiaoDong Huang 		src = 1;
1431*04150feeSXiaoDong Huang 	else if (rate >= 58 * MHz)
1432*04150feeSXiaoDong Huang 		src = 2;
1433*04150feeSXiaoDong Huang 	else
1434*04150feeSXiaoDong Huang 		src = 3;
1435*04150feeSXiaoDong Huang 
1436*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
1437*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 8));
1438*04150feeSXiaoDong Huang 	return 0;
1439*04150feeSXiaoDong Huang }
1440*04150feeSXiaoDong Huang 
clk_scmi_keyladder_rng_set_status(rk_scmi_clock_t * clock,bool status)1441*04150feeSXiaoDong Huang static int clk_scmi_keyladder_rng_set_status(rk_scmi_clock_t *clock, bool status)
1442*04150feeSXiaoDong Huang {
1443*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1444*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 10));
1445*04150feeSXiaoDong Huang 	return 0;
1446*04150feeSXiaoDong Huang }
1447*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_s_get_rate(rk_scmi_clock_t * clock)1448*04150feeSXiaoDong Huang static unsigned long clk_scmi_aclk_secure_s_get_rate(rk_scmi_clock_t *clock)
1449*04150feeSXiaoDong Huang {
1450*04150feeSXiaoDong Huang 	uint32_t src;
1451*04150feeSXiaoDong Huang 
1452*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0030;
1453*04150feeSXiaoDong Huang 	src = src >> 4;
1454*04150feeSXiaoDong Huang 	switch (src) {
1455*04150feeSXiaoDong Huang 	case 0:
1456*04150feeSXiaoDong Huang 		return 350 * MHz;
1457*04150feeSXiaoDong Huang 	case 1:
1458*04150feeSXiaoDong Huang 		return 233 * MHz;
1459*04150feeSXiaoDong Huang 	case 2:
1460*04150feeSXiaoDong Huang 		return 116 * MHz;
1461*04150feeSXiaoDong Huang 	case 3:
1462*04150feeSXiaoDong Huang 		return OSC_HZ;
1463*04150feeSXiaoDong Huang 	default:
1464*04150feeSXiaoDong Huang 		return 0;
1465*04150feeSXiaoDong Huang 	}
1466*04150feeSXiaoDong Huang }
1467*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1468*04150feeSXiaoDong Huang static int clk_scmi_aclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1469*04150feeSXiaoDong Huang {
1470*04150feeSXiaoDong Huang 	uint32_t src;
1471*04150feeSXiaoDong Huang 
1472*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1473*04150feeSXiaoDong Huang 		src = 0;
1474*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1475*04150feeSXiaoDong Huang 		src = 1;
1476*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1477*04150feeSXiaoDong Huang 		src = 2;
1478*04150feeSXiaoDong Huang 	else
1479*04150feeSXiaoDong Huang 		src = 3;
1480*04150feeSXiaoDong Huang 
1481*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1482*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 4));
1483*04150feeSXiaoDong Huang 	return 0;
1484*04150feeSXiaoDong Huang }
1485*04150feeSXiaoDong Huang 
clk_scmi_aclk_secure_s_set_status(rk_scmi_clock_t * clock,bool status)1486*04150feeSXiaoDong Huang static int clk_scmi_aclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
1487*04150feeSXiaoDong Huang {
1488*04150feeSXiaoDong Huang 	return 0;
1489*04150feeSXiaoDong Huang }
1490*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_s_get_rate(rk_scmi_clock_t * clock)1491*04150feeSXiaoDong Huang static unsigned long clk_scmi_hclk_secure_s_get_rate(rk_scmi_clock_t *clock)
1492*04150feeSXiaoDong Huang {
1493*04150feeSXiaoDong Huang 	uint32_t src;
1494*04150feeSXiaoDong Huang 
1495*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x00c0;
1496*04150feeSXiaoDong Huang 	src = src >> 6;
1497*04150feeSXiaoDong Huang 	switch (src) {
1498*04150feeSXiaoDong Huang 	case 0:
1499*04150feeSXiaoDong Huang 		return 175 * MHz;
1500*04150feeSXiaoDong Huang 	case 1:
1501*04150feeSXiaoDong Huang 		return 116 * MHz;
1502*04150feeSXiaoDong Huang 	case 2:
1503*04150feeSXiaoDong Huang 		return 58 * MHz;
1504*04150feeSXiaoDong Huang 	case 3:
1505*04150feeSXiaoDong Huang 		return OSC_HZ;
1506*04150feeSXiaoDong Huang 	default:
1507*04150feeSXiaoDong Huang 		return 0;
1508*04150feeSXiaoDong Huang 	}
1509*04150feeSXiaoDong Huang }
1510*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1511*04150feeSXiaoDong Huang static int clk_scmi_hclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1512*04150feeSXiaoDong Huang {
1513*04150feeSXiaoDong Huang 	uint32_t src;
1514*04150feeSXiaoDong Huang 
1515*04150feeSXiaoDong Huang 	if (rate >= 175 * MHz)
1516*04150feeSXiaoDong Huang 		src = 0;
1517*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1518*04150feeSXiaoDong Huang 		src = 1;
1519*04150feeSXiaoDong Huang 	else if (rate >= 58 * MHz)
1520*04150feeSXiaoDong Huang 		src = 2;
1521*04150feeSXiaoDong Huang 	else
1522*04150feeSXiaoDong Huang 		src = 3;
1523*04150feeSXiaoDong Huang 
1524*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1525*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 6));
1526*04150feeSXiaoDong Huang 	return 0;
1527*04150feeSXiaoDong Huang }
1528*04150feeSXiaoDong Huang 
clk_scmi_hclk_secure_s_set_status(rk_scmi_clock_t * clock,bool status)1529*04150feeSXiaoDong Huang static int clk_scmi_hclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
1530*04150feeSXiaoDong Huang {
1531*04150feeSXiaoDong Huang 	return 0;
1532*04150feeSXiaoDong Huang }
1533*04150feeSXiaoDong Huang 
clk_scmi_pclk_secure_s_get_rate(rk_scmi_clock_t * clock)1534*04150feeSXiaoDong Huang static unsigned long clk_scmi_pclk_secure_s_get_rate(rk_scmi_clock_t *clock)
1535*04150feeSXiaoDong Huang {
1536*04150feeSXiaoDong Huang 	uint32_t src;
1537*04150feeSXiaoDong Huang 
1538*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0300;
1539*04150feeSXiaoDong Huang 	src = src >> 8;
1540*04150feeSXiaoDong Huang 	switch (src) {
1541*04150feeSXiaoDong Huang 	case 0:
1542*04150feeSXiaoDong Huang 		return 116 * MHz;
1543*04150feeSXiaoDong Huang 	case 1:
1544*04150feeSXiaoDong Huang 		return 58 * MHz;
1545*04150feeSXiaoDong Huang 	case 2:
1546*04150feeSXiaoDong Huang 		return OSC_HZ;
1547*04150feeSXiaoDong Huang 	default:
1548*04150feeSXiaoDong Huang 		return 0;
1549*04150feeSXiaoDong Huang 	}
1550*04150feeSXiaoDong Huang }
1551*04150feeSXiaoDong Huang 
clk_scmi_pclk_secure_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1552*04150feeSXiaoDong Huang static int clk_scmi_pclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1553*04150feeSXiaoDong Huang {
1554*04150feeSXiaoDong Huang 	uint32_t src;
1555*04150feeSXiaoDong Huang 
1556*04150feeSXiaoDong Huang 	if (rate >= 116 * MHz)
1557*04150feeSXiaoDong Huang 		src = 0;
1558*04150feeSXiaoDong Huang 	else if (rate >= 58 * MHz)
1559*04150feeSXiaoDong Huang 		src = 1;
1560*04150feeSXiaoDong Huang 	else
1561*04150feeSXiaoDong Huang 		src = 2;
1562*04150feeSXiaoDong Huang 
1563*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1564*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 8));
1565*04150feeSXiaoDong Huang 	return 0;
1566*04150feeSXiaoDong Huang }
1567*04150feeSXiaoDong Huang 
clk_scmi_pclk_secure_s_set_status(rk_scmi_clock_t * clock,bool status)1568*04150feeSXiaoDong Huang static int clk_scmi_pclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
1569*04150feeSXiaoDong Huang {
1570*04150feeSXiaoDong Huang 	return 0;
1571*04150feeSXiaoDong Huang }
1572*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_get_rate(rk_scmi_clock_t * clock)1573*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_rng_get_rate(rk_scmi_clock_t *clock)
1574*04150feeSXiaoDong Huang {
1575*04150feeSXiaoDong Huang 	uint32_t src;
1576*04150feeSXiaoDong Huang 
1577*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0xc000;
1578*04150feeSXiaoDong Huang 	src = src >> 14;
1579*04150feeSXiaoDong Huang 	switch (src) {
1580*04150feeSXiaoDong Huang 	case 0:
1581*04150feeSXiaoDong Huang 		return 175 * MHz;
1582*04150feeSXiaoDong Huang 	case 1:
1583*04150feeSXiaoDong Huang 		return 116 * MHz;
1584*04150feeSXiaoDong Huang 	case 2:
1585*04150feeSXiaoDong Huang 		return 58 * MHz;
1586*04150feeSXiaoDong Huang 	case 3:
1587*04150feeSXiaoDong Huang 		return OSC_HZ;
1588*04150feeSXiaoDong Huang 	default:
1589*04150feeSXiaoDong Huang 		return 0;
1590*04150feeSXiaoDong Huang 	}
1591*04150feeSXiaoDong Huang }
1592*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1593*04150feeSXiaoDong Huang static int clk_scmi_crypto_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1594*04150feeSXiaoDong Huang {
1595*04150feeSXiaoDong Huang 	uint32_t src;
1596*04150feeSXiaoDong Huang 
1597*04150feeSXiaoDong Huang 	if (rate >= 175 * MHz)
1598*04150feeSXiaoDong Huang 		src = 0;
1599*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1600*04150feeSXiaoDong Huang 		src = 1;
1601*04150feeSXiaoDong Huang 	else if (rate >= 58 * MHz)
1602*04150feeSXiaoDong Huang 		src = 2;
1603*04150feeSXiaoDong Huang 	else
1604*04150feeSXiaoDong Huang 		src = 3;
1605*04150feeSXiaoDong Huang 
1606*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1607*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 14));
1608*04150feeSXiaoDong Huang 	return 0;
1609*04150feeSXiaoDong Huang }
1610*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_set_status(rk_scmi_clock_t * clock,bool status)1611*04150feeSXiaoDong Huang static int clk_scmi_crypto_rng_set_status(rk_scmi_clock_t *clock, bool status)
1612*04150feeSXiaoDong Huang {
1613*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1614*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 1));
1615*04150feeSXiaoDong Huang 
1616*04150feeSXiaoDong Huang 	return 0;
1617*04150feeSXiaoDong Huang }
1618*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_get_rate(rk_scmi_clock_t * clock)1619*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_core_get_rate(rk_scmi_clock_t *clock)
1620*04150feeSXiaoDong Huang {
1621*04150feeSXiaoDong Huang 	uint32_t src;
1622*04150feeSXiaoDong Huang 
1623*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0c00;
1624*04150feeSXiaoDong Huang 	src = src >> 10;
1625*04150feeSXiaoDong Huang 	switch (src) {
1626*04150feeSXiaoDong Huang 	case 0:
1627*04150feeSXiaoDong Huang 		return 350 * MHz;
1628*04150feeSXiaoDong Huang 	case 1:
1629*04150feeSXiaoDong Huang 		return 233 * MHz;
1630*04150feeSXiaoDong Huang 	case 2:
1631*04150feeSXiaoDong Huang 		return 116 * MHz;
1632*04150feeSXiaoDong Huang 	case 3:
1633*04150feeSXiaoDong Huang 		return OSC_HZ;
1634*04150feeSXiaoDong Huang 	default:
1635*04150feeSXiaoDong Huang 		return 0;
1636*04150feeSXiaoDong Huang 	}
1637*04150feeSXiaoDong Huang }
1638*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1639*04150feeSXiaoDong Huang static int clk_scmi_crypto_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1640*04150feeSXiaoDong Huang {
1641*04150feeSXiaoDong Huang 	uint32_t src;
1642*04150feeSXiaoDong Huang 
1643*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1644*04150feeSXiaoDong Huang 		src = 0;
1645*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1646*04150feeSXiaoDong Huang 		src = 1;
1647*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1648*04150feeSXiaoDong Huang 		src = 2;
1649*04150feeSXiaoDong Huang 	else
1650*04150feeSXiaoDong Huang 		src = 3;
1651*04150feeSXiaoDong Huang 
1652*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1653*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 10));
1654*04150feeSXiaoDong Huang 	return 0;
1655*04150feeSXiaoDong Huang }
1656*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_set_status(rk_scmi_clock_t * clock,bool status)1657*04150feeSXiaoDong Huang static int clk_scmi_crypto_core_set_status(rk_scmi_clock_t *clock, bool status)
1658*04150feeSXiaoDong Huang {
1659*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(0),
1660*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 15));
1661*04150feeSXiaoDong Huang 
1662*04150feeSXiaoDong Huang 	return 0;
1663*04150feeSXiaoDong Huang }
1664*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_get_rate(rk_scmi_clock_t * clock)1665*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_pka_get_rate(rk_scmi_clock_t *clock)
1666*04150feeSXiaoDong Huang {
1667*04150feeSXiaoDong Huang 	uint32_t src;
1668*04150feeSXiaoDong Huang 
1669*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x3000;
1670*04150feeSXiaoDong Huang 	src = src >> 12;
1671*04150feeSXiaoDong Huang 	switch (src) {
1672*04150feeSXiaoDong Huang 	case 0:
1673*04150feeSXiaoDong Huang 		return 350 * MHz;
1674*04150feeSXiaoDong Huang 	case 1:
1675*04150feeSXiaoDong Huang 		return 233 * MHz;
1676*04150feeSXiaoDong Huang 	case 2:
1677*04150feeSXiaoDong Huang 		return 116 * MHz;
1678*04150feeSXiaoDong Huang 	case 3:
1679*04150feeSXiaoDong Huang 		return OSC_HZ;
1680*04150feeSXiaoDong Huang 	default:
1681*04150feeSXiaoDong Huang 		return 0;
1682*04150feeSXiaoDong Huang 	}
1683*04150feeSXiaoDong Huang }
1684*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1685*04150feeSXiaoDong Huang static int clk_scmi_crypto_pka_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1686*04150feeSXiaoDong Huang {
1687*04150feeSXiaoDong Huang 	uint32_t src;
1688*04150feeSXiaoDong Huang 
1689*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1690*04150feeSXiaoDong Huang 		src = 0;
1691*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1692*04150feeSXiaoDong Huang 		src = 1;
1693*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1694*04150feeSXiaoDong Huang 		src = 2;
1695*04150feeSXiaoDong Huang 	else
1696*04150feeSXiaoDong Huang 		src = 3;
1697*04150feeSXiaoDong Huang 
1698*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
1699*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 12));
1700*04150feeSXiaoDong Huang 	return 0;
1701*04150feeSXiaoDong Huang }
1702*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_set_status(rk_scmi_clock_t * clock,bool status)1703*04150feeSXiaoDong Huang static int clk_scmi_crypto_pka_set_status(rk_scmi_clock_t *clock, bool status)
1704*04150feeSXiaoDong Huang {
1705*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1706*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 0));
1707*04150feeSXiaoDong Huang 
1708*04150feeSXiaoDong Huang 	return 0;
1709*04150feeSXiaoDong Huang }
1710*04150feeSXiaoDong Huang 
clk_scmi_spll_get_rate(rk_scmi_clock_t * clock)1711*04150feeSXiaoDong Huang static unsigned long clk_scmi_spll_get_rate(rk_scmi_clock_t *clock)
1712*04150feeSXiaoDong Huang {
1713*04150feeSXiaoDong Huang 	uint32_t src;
1714*04150feeSXiaoDong Huang 
1715*04150feeSXiaoDong Huang 	src = mmio_read_32(BUSSCRU_BASE + CRU_MODE_CON0) & 0x3;
1716*04150feeSXiaoDong Huang 	switch (src) {
1717*04150feeSXiaoDong Huang 	case 0:
1718*04150feeSXiaoDong Huang 		return OSC_HZ;
1719*04150feeSXiaoDong Huang 	case 1:
1720*04150feeSXiaoDong Huang 		return 702 * MHz;
1721*04150feeSXiaoDong Huang 	case 2:
1722*04150feeSXiaoDong Huang 		return 32768;
1723*04150feeSXiaoDong Huang 	default:
1724*04150feeSXiaoDong Huang 		return 0;
1725*04150feeSXiaoDong Huang 	}
1726*04150feeSXiaoDong Huang }
1727*04150feeSXiaoDong Huang 
clk_scmi_spll_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1728*04150feeSXiaoDong Huang static int clk_scmi_spll_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1729*04150feeSXiaoDong Huang {
1730*04150feeSXiaoDong Huang 	uint32_t src;
1731*04150feeSXiaoDong Huang 
1732*04150feeSXiaoDong Huang 	if (rate >= 700 * MHz)
1733*04150feeSXiaoDong Huang 		src = 1;
1734*04150feeSXiaoDong Huang 	else
1735*04150feeSXiaoDong Huang 		src = 0;
1736*04150feeSXiaoDong Huang 
1737*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
1738*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(0, 0x3U, 0));
1739*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_PLL_CON(137),
1740*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(2, 0x7U, 6));
1741*04150feeSXiaoDong Huang 
1742*04150feeSXiaoDong Huang 	mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
1743*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 0));
1744*04150feeSXiaoDong Huang 	return 0;
1745*04150feeSXiaoDong Huang }
1746*04150feeSXiaoDong Huang 
clk_scmi_spll_set_status(rk_scmi_clock_t * clock,bool status)1747*04150feeSXiaoDong Huang static int clk_scmi_spll_set_status(rk_scmi_clock_t *clock, bool status)
1748*04150feeSXiaoDong Huang {
1749*04150feeSXiaoDong Huang 	return 0;
1750*04150feeSXiaoDong Huang }
1751*04150feeSXiaoDong Huang 
clk_scmi_hclk_sd_get_rate(rk_scmi_clock_t * clock)1752*04150feeSXiaoDong Huang static unsigned long clk_scmi_hclk_sd_get_rate(rk_scmi_clock_t *clock)
1753*04150feeSXiaoDong Huang {
1754*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_ns_get_rate(clock);
1755*04150feeSXiaoDong Huang }
1756*04150feeSXiaoDong Huang 
clk_scmi_hclk_sd_set_status(rk_scmi_clock_t * clock,bool status)1757*04150feeSXiaoDong Huang static int clk_scmi_hclk_sd_set_status(rk_scmi_clock_t *clock, bool status)
1758*04150feeSXiaoDong Huang {
1759*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
1760*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 2));
1761*04150feeSXiaoDong Huang 	return 0;
1762*04150feeSXiaoDong Huang }
1763*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_s_get_rate(rk_scmi_clock_t * clock)1764*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_rng_s_get_rate(rk_scmi_clock_t *clock)
1765*04150feeSXiaoDong Huang {
1766*04150feeSXiaoDong Huang 	uint32_t src;
1767*04150feeSXiaoDong Huang 
1768*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0030;
1769*04150feeSXiaoDong Huang 	src = src >> 4;
1770*04150feeSXiaoDong Huang 	switch (src) {
1771*04150feeSXiaoDong Huang 	case 0:
1772*04150feeSXiaoDong Huang 		return 175 * MHz;
1773*04150feeSXiaoDong Huang 	case 1:
1774*04150feeSXiaoDong Huang 		return 116 * MHz;
1775*04150feeSXiaoDong Huang 	case 2:
1776*04150feeSXiaoDong Huang 		return 58 * MHz;
1777*04150feeSXiaoDong Huang 	case 3:
1778*04150feeSXiaoDong Huang 		return OSC_HZ;
1779*04150feeSXiaoDong Huang 	default:
1780*04150feeSXiaoDong Huang 		return 0;
1781*04150feeSXiaoDong Huang 	}
1782*04150feeSXiaoDong Huang }
1783*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1784*04150feeSXiaoDong Huang static int clk_scmi_crypto_rng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1785*04150feeSXiaoDong Huang {
1786*04150feeSXiaoDong Huang 	uint32_t src;
1787*04150feeSXiaoDong Huang 
1788*04150feeSXiaoDong Huang 	if (rate >= 175 * MHz)
1789*04150feeSXiaoDong Huang 		src = 0;
1790*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1791*04150feeSXiaoDong Huang 		src = 1;
1792*04150feeSXiaoDong Huang 	else if (rate >= 58 * MHz)
1793*04150feeSXiaoDong Huang 		src = 2;
1794*04150feeSXiaoDong Huang 	else
1795*04150feeSXiaoDong Huang 		src = 3;
1796*04150feeSXiaoDong Huang 
1797*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
1798*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 4));
1799*04150feeSXiaoDong Huang 	return 0;
1800*04150feeSXiaoDong Huang }
1801*04150feeSXiaoDong Huang 
clk_scmi_crypto_rng_s_set_status(rk_scmi_clock_t * clock,bool status)1802*04150feeSXiaoDong Huang static int clk_scmi_crypto_rng_s_set_status(rk_scmi_clock_t *clock, bool status)
1803*04150feeSXiaoDong Huang {
1804*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1805*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 6));
1806*04150feeSXiaoDong Huang 
1807*04150feeSXiaoDong Huang 	return 0;
1808*04150feeSXiaoDong Huang }
1809*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_s_get_rate(rk_scmi_clock_t * clock)1810*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_core_s_get_rate(rk_scmi_clock_t *clock)
1811*04150feeSXiaoDong Huang {
1812*04150feeSXiaoDong Huang 	uint32_t src;
1813*04150feeSXiaoDong Huang 
1814*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x3;
1815*04150feeSXiaoDong Huang 	src = src >> 0;
1816*04150feeSXiaoDong Huang 	switch (src) {
1817*04150feeSXiaoDong Huang 	case 0:
1818*04150feeSXiaoDong Huang 		return 350 * MHz;
1819*04150feeSXiaoDong Huang 	case 1:
1820*04150feeSXiaoDong Huang 		return 233 * MHz;
1821*04150feeSXiaoDong Huang 	case 2:
1822*04150feeSXiaoDong Huang 		return 116 * MHz;
1823*04150feeSXiaoDong Huang 	case 3:
1824*04150feeSXiaoDong Huang 		return OSC_HZ;
1825*04150feeSXiaoDong Huang 	default:
1826*04150feeSXiaoDong Huang 		return 0;
1827*04150feeSXiaoDong Huang 	}
1828*04150feeSXiaoDong Huang }
1829*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1830*04150feeSXiaoDong Huang static int clk_scmi_crypto_core_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1831*04150feeSXiaoDong Huang {
1832*04150feeSXiaoDong Huang 	uint32_t src;
1833*04150feeSXiaoDong Huang 
1834*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1835*04150feeSXiaoDong Huang 		src = 0;
1836*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1837*04150feeSXiaoDong Huang 		src = 1;
1838*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1839*04150feeSXiaoDong Huang 		src = 2;
1840*04150feeSXiaoDong Huang 	else
1841*04150feeSXiaoDong Huang 		src = 3;
1842*04150feeSXiaoDong Huang 
1843*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
1844*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 0));
1845*04150feeSXiaoDong Huang 	return 0;
1846*04150feeSXiaoDong Huang }
1847*04150feeSXiaoDong Huang 
clk_scmi_crypto_core_s_set_status(rk_scmi_clock_t * clock,bool status)1848*04150feeSXiaoDong Huang static int clk_scmi_crypto_core_s_set_status(rk_scmi_clock_t *clock, bool status)
1849*04150feeSXiaoDong Huang {
1850*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1851*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 4));
1852*04150feeSXiaoDong Huang 
1853*04150feeSXiaoDong Huang 	return 0;
1854*04150feeSXiaoDong Huang }
1855*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_s_get_rate(rk_scmi_clock_t * clock)1856*04150feeSXiaoDong Huang static unsigned long clk_scmi_crypto_pka_s_get_rate(rk_scmi_clock_t *clock)
1857*04150feeSXiaoDong Huang {
1858*04150feeSXiaoDong Huang 	uint32_t src;
1859*04150feeSXiaoDong Huang 
1860*04150feeSXiaoDong Huang 	src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x000c;
1861*04150feeSXiaoDong Huang 	src = src >> 2;
1862*04150feeSXiaoDong Huang 	switch (src) {
1863*04150feeSXiaoDong Huang 	case 0:
1864*04150feeSXiaoDong Huang 		return 350 * MHz;
1865*04150feeSXiaoDong Huang 	case 1:
1866*04150feeSXiaoDong Huang 		return 233 * MHz;
1867*04150feeSXiaoDong Huang 	case 2:
1868*04150feeSXiaoDong Huang 		return 116 * MHz;
1869*04150feeSXiaoDong Huang 	case 3:
1870*04150feeSXiaoDong Huang 		return OSC_HZ;
1871*04150feeSXiaoDong Huang 	default:
1872*04150feeSXiaoDong Huang 		return 0;
1873*04150feeSXiaoDong Huang 	}
1874*04150feeSXiaoDong Huang }
1875*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1876*04150feeSXiaoDong Huang static int clk_scmi_crypto_pka_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1877*04150feeSXiaoDong Huang {
1878*04150feeSXiaoDong Huang 	uint32_t src;
1879*04150feeSXiaoDong Huang 
1880*04150feeSXiaoDong Huang 	if (rate >= 350 * MHz)
1881*04150feeSXiaoDong Huang 		src = 0;
1882*04150feeSXiaoDong Huang 	else if (rate >= 233 * MHz)
1883*04150feeSXiaoDong Huang 		src = 1;
1884*04150feeSXiaoDong Huang 	else if (rate >= 116 * MHz)
1885*04150feeSXiaoDong Huang 		src = 2;
1886*04150feeSXiaoDong Huang 	else
1887*04150feeSXiaoDong Huang 		src = 3;
1888*04150feeSXiaoDong Huang 
1889*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
1890*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(src, 0x3U, 2));
1891*04150feeSXiaoDong Huang 	return 0;
1892*04150feeSXiaoDong Huang }
1893*04150feeSXiaoDong Huang 
clk_scmi_crypto_pka_s_set_status(rk_scmi_clock_t * clock,bool status)1894*04150feeSXiaoDong Huang static int clk_scmi_crypto_pka_s_set_status(rk_scmi_clock_t *clock, bool status)
1895*04150feeSXiaoDong Huang {
1896*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1897*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 5));
1898*04150feeSXiaoDong Huang 
1899*04150feeSXiaoDong Huang 	return 0;
1900*04150feeSXiaoDong Huang }
1901*04150feeSXiaoDong Huang 
clk_scmi_a_crypto_s_get_rate(rk_scmi_clock_t * clock)1902*04150feeSXiaoDong Huang static unsigned long clk_scmi_a_crypto_s_get_rate(rk_scmi_clock_t *clock)
1903*04150feeSXiaoDong Huang {
1904*04150feeSXiaoDong Huang 	return clk_scmi_aclk_secure_s_get_rate(clock);
1905*04150feeSXiaoDong Huang }
1906*04150feeSXiaoDong Huang 
clk_scmi_a_crypto_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1907*04150feeSXiaoDong Huang static int clk_scmi_a_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1908*04150feeSXiaoDong Huang {
1909*04150feeSXiaoDong Huang 	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
1910*04150feeSXiaoDong Huang }
1911*04150feeSXiaoDong Huang 
clk_scmi_a_crypto_s_set_status(rk_scmi_clock_t * clock,bool status)1912*04150feeSXiaoDong Huang static int clk_scmi_a_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
1913*04150feeSXiaoDong Huang {
1914*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1915*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 7));
1916*04150feeSXiaoDong Huang 
1917*04150feeSXiaoDong Huang 	return 0;
1918*04150feeSXiaoDong Huang }
1919*04150feeSXiaoDong Huang 
clk_scmi_h_crypto_s_get_rate(rk_scmi_clock_t * clock)1920*04150feeSXiaoDong Huang static unsigned long clk_scmi_h_crypto_s_get_rate(rk_scmi_clock_t *clock)
1921*04150feeSXiaoDong Huang {
1922*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_get_rate(clock);
1923*04150feeSXiaoDong Huang }
1924*04150feeSXiaoDong Huang 
clk_scmi_h_crypto_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1925*04150feeSXiaoDong Huang static int clk_scmi_h_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1926*04150feeSXiaoDong Huang {
1927*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
1928*04150feeSXiaoDong Huang }
1929*04150feeSXiaoDong Huang 
clk_scmi_h_crypto_s_set_status(rk_scmi_clock_t * clock,bool status)1930*04150feeSXiaoDong Huang static int clk_scmi_h_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
1931*04150feeSXiaoDong Huang {
1932*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1933*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 8));
1934*04150feeSXiaoDong Huang 
1935*04150feeSXiaoDong Huang 	return 0;
1936*04150feeSXiaoDong Huang }
1937*04150feeSXiaoDong Huang 
clk_scmi_p_crypto_s_get_rate(rk_scmi_clock_t * clock)1938*04150feeSXiaoDong Huang static unsigned long clk_scmi_p_crypto_s_get_rate(rk_scmi_clock_t *clock)
1939*04150feeSXiaoDong Huang {
1940*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_get_rate(clock);
1941*04150feeSXiaoDong Huang }
1942*04150feeSXiaoDong Huang 
clk_scmi_p_crypto_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1943*04150feeSXiaoDong Huang static int clk_scmi_p_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1944*04150feeSXiaoDong Huang {
1945*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
1946*04150feeSXiaoDong Huang }
1947*04150feeSXiaoDong Huang 
clk_scmi_p_crypto_s_set_status(rk_scmi_clock_t * clock,bool status)1948*04150feeSXiaoDong Huang static int clk_scmi_p_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
1949*04150feeSXiaoDong Huang {
1950*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
1951*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 13));
1952*04150feeSXiaoDong Huang 
1953*04150feeSXiaoDong Huang 	return 0;
1954*04150feeSXiaoDong Huang }
1955*04150feeSXiaoDong Huang 
clk_scmi_a_keylad_s_get_rate(rk_scmi_clock_t * clock)1956*04150feeSXiaoDong Huang static unsigned long clk_scmi_a_keylad_s_get_rate(rk_scmi_clock_t *clock)
1957*04150feeSXiaoDong Huang {
1958*04150feeSXiaoDong Huang 	return clk_scmi_aclk_secure_s_get_rate(clock);
1959*04150feeSXiaoDong Huang }
1960*04150feeSXiaoDong Huang 
clk_scmi_a_keylad_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1961*04150feeSXiaoDong Huang static int clk_scmi_a_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1962*04150feeSXiaoDong Huang {
1963*04150feeSXiaoDong Huang 	return clk_scmi_aclk_secure_s_set_rate(clock, rate);
1964*04150feeSXiaoDong Huang }
1965*04150feeSXiaoDong Huang 
clk_scmi_a_keylad_s_set_status(rk_scmi_clock_t * clock,bool status)1966*04150feeSXiaoDong Huang static int clk_scmi_a_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
1967*04150feeSXiaoDong Huang {
1968*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1969*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 11));
1970*04150feeSXiaoDong Huang 
1971*04150feeSXiaoDong Huang 	return 0;
1972*04150feeSXiaoDong Huang }
1973*04150feeSXiaoDong Huang 
clk_scmi_h_keylad_s_get_rate(rk_scmi_clock_t * clock)1974*04150feeSXiaoDong Huang static unsigned long clk_scmi_h_keylad_s_get_rate(rk_scmi_clock_t *clock)
1975*04150feeSXiaoDong Huang {
1976*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_get_rate(clock);
1977*04150feeSXiaoDong Huang }
1978*04150feeSXiaoDong Huang 
clk_scmi_h_keylad_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1979*04150feeSXiaoDong Huang static int clk_scmi_h_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1980*04150feeSXiaoDong Huang {
1981*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
1982*04150feeSXiaoDong Huang }
1983*04150feeSXiaoDong Huang 
clk_scmi_h_keylad_s_set_status(rk_scmi_clock_t * clock,bool status)1984*04150feeSXiaoDong Huang static int clk_scmi_h_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
1985*04150feeSXiaoDong Huang {
1986*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
1987*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 12));
1988*04150feeSXiaoDong Huang 
1989*04150feeSXiaoDong Huang 	return 0;
1990*04150feeSXiaoDong Huang }
1991*04150feeSXiaoDong Huang 
clk_scmi_p_keylad_s_get_rate(rk_scmi_clock_t * clock)1992*04150feeSXiaoDong Huang static unsigned long clk_scmi_p_keylad_s_get_rate(rk_scmi_clock_t *clock)
1993*04150feeSXiaoDong Huang {
1994*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_get_rate(clock);
1995*04150feeSXiaoDong Huang }
1996*04150feeSXiaoDong Huang 
clk_scmi_p_keylad_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)1997*04150feeSXiaoDong Huang static int clk_scmi_p_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
1998*04150feeSXiaoDong Huang {
1999*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
2000*04150feeSXiaoDong Huang }
2001*04150feeSXiaoDong Huang 
clk_scmi_p_keylad_s_set_status(rk_scmi_clock_t * clock,bool status)2002*04150feeSXiaoDong Huang static int clk_scmi_p_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
2003*04150feeSXiaoDong Huang {
2004*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
2005*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 14));
2006*04150feeSXiaoDong Huang 
2007*04150feeSXiaoDong Huang 	return 0;
2008*04150feeSXiaoDong Huang }
2009*04150feeSXiaoDong Huang 
clk_scmi_trng_s_get_rate(rk_scmi_clock_t * clock)2010*04150feeSXiaoDong Huang static unsigned long clk_scmi_trng_s_get_rate(rk_scmi_clock_t *clock)
2011*04150feeSXiaoDong Huang {
2012*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_get_rate(clock);
2013*04150feeSXiaoDong Huang }
2014*04150feeSXiaoDong Huang 
clk_scmi_trng_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)2015*04150feeSXiaoDong Huang static int clk_scmi_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
2016*04150feeSXiaoDong Huang {
2017*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
2018*04150feeSXiaoDong Huang }
2019*04150feeSXiaoDong Huang 
clk_scmi_trng_s_set_status(rk_scmi_clock_t * clock,bool status)2020*04150feeSXiaoDong Huang static int clk_scmi_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
2021*04150feeSXiaoDong Huang {
2022*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
2023*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 6));
2024*04150feeSXiaoDong Huang 
2025*04150feeSXiaoDong Huang 	return 0;
2026*04150feeSXiaoDong Huang }
2027*04150feeSXiaoDong Huang 
clk_scmi_h_trng_s_get_rate(rk_scmi_clock_t * clock)2028*04150feeSXiaoDong Huang static unsigned long clk_scmi_h_trng_s_get_rate(rk_scmi_clock_t *clock)
2029*04150feeSXiaoDong Huang {
2030*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_get_rate(clock);
2031*04150feeSXiaoDong Huang }
2032*04150feeSXiaoDong Huang 
clk_scmi_h_trng_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)2033*04150feeSXiaoDong Huang static int clk_scmi_h_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
2034*04150feeSXiaoDong Huang {
2035*04150feeSXiaoDong Huang 	return clk_scmi_hclk_secure_s_set_rate(clock, rate);
2036*04150feeSXiaoDong Huang }
2037*04150feeSXiaoDong Huang 
clk_scmi_h_trng_s_set_status(rk_scmi_clock_t * clock,bool status)2038*04150feeSXiaoDong Huang static int clk_scmi_h_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
2039*04150feeSXiaoDong Huang {
2040*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
2041*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 15));
2042*04150feeSXiaoDong Huang 
2043*04150feeSXiaoDong Huang 	return 0;
2044*04150feeSXiaoDong Huang }
2045*04150feeSXiaoDong Huang 
clk_scmi_p_otpc_s_get_rate(rk_scmi_clock_t * clock)2046*04150feeSXiaoDong Huang static unsigned long clk_scmi_p_otpc_s_get_rate(rk_scmi_clock_t *clock)
2047*04150feeSXiaoDong Huang {
2048*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_get_rate(clock);
2049*04150feeSXiaoDong Huang }
2050*04150feeSXiaoDong Huang 
clk_scmi_p_otpc_s_set_rate(rk_scmi_clock_t * clock,unsigned long rate)2051*04150feeSXiaoDong Huang static int clk_scmi_p_otpc_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
2052*04150feeSXiaoDong Huang {
2053*04150feeSXiaoDong Huang 	return clk_scmi_pclk_secure_s_set_rate(clock, rate);
2054*04150feeSXiaoDong Huang }
2055*04150feeSXiaoDong Huang 
clk_scmi_p_otpc_s_set_status(rk_scmi_clock_t * clock,bool status)2056*04150feeSXiaoDong Huang static int clk_scmi_p_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
2057*04150feeSXiaoDong Huang {
2058*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
2059*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 13));
2060*04150feeSXiaoDong Huang 
2061*04150feeSXiaoDong Huang 	return 0;
2062*04150feeSXiaoDong Huang }
2063*04150feeSXiaoDong Huang 
clk_scmi_otpc_s_get_rate(rk_scmi_clock_t * clock)2064*04150feeSXiaoDong Huang static unsigned long clk_scmi_otpc_s_get_rate(rk_scmi_clock_t *clock)
2065*04150feeSXiaoDong Huang {
2066*04150feeSXiaoDong Huang 	return OSC_HZ;
2067*04150feeSXiaoDong Huang }
2068*04150feeSXiaoDong Huang 
clk_scmi_otpc_s_set_status(rk_scmi_clock_t * clock,bool status)2069*04150feeSXiaoDong Huang static int clk_scmi_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
2070*04150feeSXiaoDong Huang {
2071*04150feeSXiaoDong Huang 	mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
2072*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 14));
2073*04150feeSXiaoDong Huang 	return 0;
2074*04150feeSXiaoDong Huang }
2075*04150feeSXiaoDong Huang 
clk_scmi_otp_phy_get_rate(rk_scmi_clock_t * clock)2076*04150feeSXiaoDong Huang static unsigned long clk_scmi_otp_phy_get_rate(rk_scmi_clock_t *clock)
2077*04150feeSXiaoDong Huang {
2078*04150feeSXiaoDong Huang 	return OSC_HZ;
2079*04150feeSXiaoDong Huang }
2080*04150feeSXiaoDong Huang 
clk_scmi_otp_phy_set_status(rk_scmi_clock_t * clock,bool status)2081*04150feeSXiaoDong Huang static int clk_scmi_otp_phy_set_status(rk_scmi_clock_t *clock, bool status)
2082*04150feeSXiaoDong Huang {
2083*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
2084*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 13));
2085*04150feeSXiaoDong Huang 	return 0;
2086*04150feeSXiaoDong Huang }
2087*04150feeSXiaoDong Huang 
clk_scmi_otpc_rd_get_rate(rk_scmi_clock_t * clock)2088*04150feeSXiaoDong Huang static unsigned long clk_scmi_otpc_rd_get_rate(rk_scmi_clock_t *clock)
2089*04150feeSXiaoDong Huang {
2090*04150feeSXiaoDong Huang 	return OSC_HZ;
2091*04150feeSXiaoDong Huang }
2092*04150feeSXiaoDong Huang 
clk_scmi_otpc_rd_set_status(rk_scmi_clock_t * clock,bool status)2093*04150feeSXiaoDong Huang static int clk_scmi_otpc_rd_set_status(rk_scmi_clock_t *clock, bool status)
2094*04150feeSXiaoDong Huang {
2095*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
2096*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 12));
2097*04150feeSXiaoDong Huang 	return 0;
2098*04150feeSXiaoDong Huang }
2099*04150feeSXiaoDong Huang 
clk_scmi_otpc_arb_get_rate(rk_scmi_clock_t * clock)2100*04150feeSXiaoDong Huang static unsigned long clk_scmi_otpc_arb_get_rate(rk_scmi_clock_t *clock)
2101*04150feeSXiaoDong Huang {
2102*04150feeSXiaoDong Huang 	return OSC_HZ;
2103*04150feeSXiaoDong Huang }
2104*04150feeSXiaoDong Huang 
clk_scmi_otpc_arb_set_status(rk_scmi_clock_t * clock,bool status)2105*04150feeSXiaoDong Huang static int clk_scmi_otpc_arb_set_status(rk_scmi_clock_t *clock, bool status)
2106*04150feeSXiaoDong Huang {
2107*04150feeSXiaoDong Huang 	mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
2108*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(!status, 0x1U, 11));
2109*04150feeSXiaoDong Huang 	return 0;
2110*04150feeSXiaoDong Huang }
2111*04150feeSXiaoDong Huang 
2112*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_cpul_ops = {
2113*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_cpul_get_rate,
2114*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_cpul_set_rate,
2115*04150feeSXiaoDong Huang 	.set_status = clk_scmi_cpul_set_status,
2116*04150feeSXiaoDong Huang };
2117*04150feeSXiaoDong Huang 
2118*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_dsu_ops = {
2119*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_dsu_get_rate,
2120*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_dsu_set_rate,
2121*04150feeSXiaoDong Huang 	.set_status = clk_scmi_dsu_set_status,
2122*04150feeSXiaoDong Huang };
2123*04150feeSXiaoDong Huang 
2124*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_cpub01_ops = {
2125*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_cpub01_get_rate,
2126*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_cpub01_set_rate,
2127*04150feeSXiaoDong Huang 	.set_status = clk_scmi_cpub01_set_status,
2128*04150feeSXiaoDong Huang };
2129*04150feeSXiaoDong Huang 
2130*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_cpub23_ops = {
2131*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_cpub23_get_rate,
2132*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_cpub23_set_rate,
2133*04150feeSXiaoDong Huang 	.set_status = clk_scmi_cpub23_set_status,
2134*04150feeSXiaoDong Huang };
2135*04150feeSXiaoDong Huang 
2136*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_gpu_ops = {
2137*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_gpu_get_rate,
2138*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_gpu_set_rate,
2139*04150feeSXiaoDong Huang 	.set_status = clk_scmi_gpu_set_status,
2140*04150feeSXiaoDong Huang };
2141*04150feeSXiaoDong Huang 
2142*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_npu_ops = {
2143*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_npu_get_rate,
2144*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_npu_set_rate,
2145*04150feeSXiaoDong Huang 	.set_status = clk_scmi_npu_set_status,
2146*04150feeSXiaoDong Huang };
2147*04150feeSXiaoDong Huang 
2148*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_sbus_ops = {
2149*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_sbus_get_rate,
2150*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_sbus_set_rate,
2151*04150feeSXiaoDong Huang 	.set_status = clk_scmi_sbus_set_status,
2152*04150feeSXiaoDong Huang };
2153*04150feeSXiaoDong Huang 
2154*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_pclk_sbus_ops = {
2155*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_pclk_sbus_get_rate,
2156*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_pclk_sbus_set_rate,
2157*04150feeSXiaoDong Huang 	.set_status = clk_scmi_pclk_sbus_set_status,
2158*04150feeSXiaoDong Huang };
2159*04150feeSXiaoDong Huang 
2160*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_cclk_sdmmc_ops = {
2161*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_cclk_sdmmc_get_rate,
2162*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_cclk_sdmmc_set_rate,
2163*04150feeSXiaoDong Huang 	.set_status = clk_scmi_cclk_sdmmc_set_status,
2164*04150feeSXiaoDong Huang };
2165*04150feeSXiaoDong Huang 
2166*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_dclk_sdmmc_ops = {
2167*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_dclk_sdmmc_get_rate,
2168*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_dclk_sdmmc_set_rate,
2169*04150feeSXiaoDong Huang 	.set_status = clk_scmi_dclk_sdmmc_set_status,
2170*04150feeSXiaoDong Huang };
2171*04150feeSXiaoDong Huang 
2172*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_aclk_secure_ns_ops = {
2173*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_aclk_secure_ns_get_rate,
2174*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_aclk_secure_ns_set_rate,
2175*04150feeSXiaoDong Huang 	.set_status = clk_scmi_aclk_secure_ns_set_status,
2176*04150feeSXiaoDong Huang };
2177*04150feeSXiaoDong Huang 
2178*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_hclk_secure_ns_ops = {
2179*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_hclk_secure_ns_get_rate,
2180*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_hclk_secure_ns_set_rate,
2181*04150feeSXiaoDong Huang 	.set_status = clk_scmi_hclk_secure_ns_set_status,
2182*04150feeSXiaoDong Huang };
2183*04150feeSXiaoDong Huang 
2184*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_tclk_wdt_ops = {
2185*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_tclk_wdt_get_rate,
2186*04150feeSXiaoDong Huang 	.set_status = clk_scmi_tclk_wdt_set_status,
2187*04150feeSXiaoDong Huang };
2188*04150feeSXiaoDong Huang 
2189*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_keyladder_core_ops = {
2190*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_keyladder_core_get_rate,
2191*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_keyladder_core_set_rate,
2192*04150feeSXiaoDong Huang 	.set_status = clk_scmi_keyladder_core_set_status,
2193*04150feeSXiaoDong Huang };
2194*04150feeSXiaoDong Huang 
2195*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_keyladder_rng_ops = {
2196*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_keyladder_rng_get_rate,
2197*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_keyladder_rng_set_rate,
2198*04150feeSXiaoDong Huang 	.set_status = clk_scmi_keyladder_rng_set_status,
2199*04150feeSXiaoDong Huang };
2200*04150feeSXiaoDong Huang 
2201*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_aclk_secure_s_ops = {
2202*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_aclk_secure_s_get_rate,
2203*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_aclk_secure_s_set_rate,
2204*04150feeSXiaoDong Huang 	.set_status = clk_scmi_aclk_secure_s_set_status,
2205*04150feeSXiaoDong Huang };
2206*04150feeSXiaoDong Huang 
2207*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_hclk_secure_s_ops = {
2208*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_hclk_secure_s_get_rate,
2209*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_hclk_secure_s_set_rate,
2210*04150feeSXiaoDong Huang 	.set_status = clk_scmi_hclk_secure_s_set_status,
2211*04150feeSXiaoDong Huang };
2212*04150feeSXiaoDong Huang 
2213*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_pclk_secure_s_ops = {
2214*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_pclk_secure_s_get_rate,
2215*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_pclk_secure_s_set_rate,
2216*04150feeSXiaoDong Huang 	.set_status = clk_scmi_pclk_secure_s_set_status,
2217*04150feeSXiaoDong Huang };
2218*04150feeSXiaoDong Huang 
2219*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_rng_ops = {
2220*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_rng_get_rate,
2221*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_rng_set_rate,
2222*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_rng_set_status,
2223*04150feeSXiaoDong Huang };
2224*04150feeSXiaoDong Huang 
2225*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_core_ops = {
2226*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_core_get_rate,
2227*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_core_set_rate,
2228*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_core_set_status,
2229*04150feeSXiaoDong Huang };
2230*04150feeSXiaoDong Huang 
2231*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_pka_ops = {
2232*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_pka_get_rate,
2233*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_pka_set_rate,
2234*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_pka_set_status,
2235*04150feeSXiaoDong Huang };
2236*04150feeSXiaoDong Huang 
2237*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_spll_ops = {
2238*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_spll_get_rate,
2239*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_spll_set_rate,
2240*04150feeSXiaoDong Huang 	.set_status = clk_scmi_spll_set_status,
2241*04150feeSXiaoDong Huang };
2242*04150feeSXiaoDong Huang 
2243*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_hclk_sd_ops = {
2244*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_hclk_sd_get_rate,
2245*04150feeSXiaoDong Huang 	.set_status = clk_scmi_hclk_sd_set_status,
2246*04150feeSXiaoDong Huang };
2247*04150feeSXiaoDong Huang 
2248*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_rng_s_ops = {
2249*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_rng_s_get_rate,
2250*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_rng_s_set_rate,
2251*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_rng_s_set_status,
2252*04150feeSXiaoDong Huang };
2253*04150feeSXiaoDong Huang 
2254*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_core_s_ops = {
2255*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_core_s_get_rate,
2256*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_core_s_set_rate,
2257*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_core_s_set_status,
2258*04150feeSXiaoDong Huang };
2259*04150feeSXiaoDong Huang 
2260*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_crypto_pka_s_ops = {
2261*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_crypto_pka_s_get_rate,
2262*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_crypto_pka_s_set_rate,
2263*04150feeSXiaoDong Huang 	.set_status = clk_scmi_crypto_pka_s_set_status,
2264*04150feeSXiaoDong Huang };
2265*04150feeSXiaoDong Huang 
2266*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_a_crypto_s_ops = {
2267*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_a_crypto_s_get_rate,
2268*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_a_crypto_s_set_rate,
2269*04150feeSXiaoDong Huang 	.set_status = clk_scmi_a_crypto_s_set_status,
2270*04150feeSXiaoDong Huang };
2271*04150feeSXiaoDong Huang 
2272*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_h_crypto_s_ops = {
2273*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_h_crypto_s_get_rate,
2274*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_h_crypto_s_set_rate,
2275*04150feeSXiaoDong Huang 	.set_status = clk_scmi_h_crypto_s_set_status,
2276*04150feeSXiaoDong Huang };
2277*04150feeSXiaoDong Huang 
2278*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_p_crypto_s_ops = {
2279*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_p_crypto_s_get_rate,
2280*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_p_crypto_s_set_rate,
2281*04150feeSXiaoDong Huang 	.set_status = clk_scmi_p_crypto_s_set_status,
2282*04150feeSXiaoDong Huang };
2283*04150feeSXiaoDong Huang 
2284*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_a_keylad_s_ops = {
2285*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_a_keylad_s_get_rate,
2286*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_a_keylad_s_set_rate,
2287*04150feeSXiaoDong Huang 	.set_status = clk_scmi_a_keylad_s_set_status,
2288*04150feeSXiaoDong Huang };
2289*04150feeSXiaoDong Huang 
2290*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_h_keylad_s_ops = {
2291*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_h_keylad_s_get_rate,
2292*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_h_keylad_s_set_rate,
2293*04150feeSXiaoDong Huang 	.set_status = clk_scmi_h_keylad_s_set_status,
2294*04150feeSXiaoDong Huang };
2295*04150feeSXiaoDong Huang 
2296*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_p_keylad_s_ops = {
2297*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_p_keylad_s_get_rate,
2298*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_p_keylad_s_set_rate,
2299*04150feeSXiaoDong Huang 	.set_status = clk_scmi_p_keylad_s_set_status,
2300*04150feeSXiaoDong Huang };
2301*04150feeSXiaoDong Huang 
2302*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_trng_s_ops = {
2303*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_trng_s_get_rate,
2304*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_trng_s_set_rate,
2305*04150feeSXiaoDong Huang 	.set_status = clk_scmi_trng_s_set_status,
2306*04150feeSXiaoDong Huang };
2307*04150feeSXiaoDong Huang 
2308*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_h_trng_s_ops = {
2309*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_h_trng_s_get_rate,
2310*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_h_trng_s_set_rate,
2311*04150feeSXiaoDong Huang 	.set_status = clk_scmi_h_trng_s_set_status,
2312*04150feeSXiaoDong Huang };
2313*04150feeSXiaoDong Huang 
2314*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_p_otpc_s_ops = {
2315*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_p_otpc_s_get_rate,
2316*04150feeSXiaoDong Huang 	.set_rate = clk_scmi_p_otpc_s_set_rate,
2317*04150feeSXiaoDong Huang 	.set_status = clk_scmi_p_otpc_s_set_status,
2318*04150feeSXiaoDong Huang };
2319*04150feeSXiaoDong Huang 
2320*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_otpc_s_ops = {
2321*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_otpc_s_get_rate,
2322*04150feeSXiaoDong Huang 	.set_status = clk_scmi_otpc_s_set_status,
2323*04150feeSXiaoDong Huang };
2324*04150feeSXiaoDong Huang 
2325*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_otp_phy_ops = {
2326*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_otp_phy_get_rate,
2327*04150feeSXiaoDong Huang 	.set_status = clk_scmi_otp_phy_set_status,
2328*04150feeSXiaoDong Huang };
2329*04150feeSXiaoDong Huang 
2330*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_otpc_rd_ops = {
2331*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_otpc_rd_get_rate,
2332*04150feeSXiaoDong Huang 	.set_status = clk_scmi_otpc_rd_set_status,
2333*04150feeSXiaoDong Huang };
2334*04150feeSXiaoDong Huang 
2335*04150feeSXiaoDong Huang static const struct rk_clk_ops clk_scmi_otpc_arb_ops = {
2336*04150feeSXiaoDong Huang 	.get_rate = clk_scmi_otpc_arb_get_rate,
2337*04150feeSXiaoDong Huang 	.set_status = clk_scmi_otpc_arb_set_status,
2338*04150feeSXiaoDong Huang };
2339*04150feeSXiaoDong Huang 
2340*04150feeSXiaoDong Huang rk_scmi_clock_t clock_table[] = {
2341*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_CPUL, "scmi_clk_cpul", &clk_scmi_cpul_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
2342*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_DSU, "scmi_clk_dsu", &clk_scmi_dsu_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
2343*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB01, "scmi_clk_cpub01", &clk_scmi_cpub01_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
2344*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_CPUB23, "scmi_clk_cpub23", &clk_scmi_cpub23_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
2345*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_DDR, "scmi_clk_ddr", NULL, NULL, 0, false),
2346*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_GPU, "scmi_clk_gpu", &clk_scmi_gpu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
2347*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_NPU, "scmi_clk_npu", &clk_scmi_npu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
2348*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CLK_SBUS, "scmi_clk_sbus", &clk_scmi_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2349*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_PCLK_SBUS, "scmi_pclk_sbus", &clk_scmi_pclk_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2350*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CCLK_SD, "scmi_cclk_sd", &clk_scmi_cclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
2351*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_DCLK_SD, "scmi_dclk_sd", &clk_scmi_dclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
2352*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_NS, "scmi_aclk_se_ns", &clk_scmi_aclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2353*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_NS, "scmi_hclk_se_ns", &clk_scmi_hclk_secure_ns_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2354*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_TCLK_WDT, "scmi_tclk_wdt", &clk_scmi_tclk_wdt_ops, NULL, 0, false),
2355*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_CORE, "scmi_keylad_c", &clk_scmi_keyladder_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2356*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_KEYLADDER_RNG, "scmi_keylad_r", &clk_scmi_keyladder_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2357*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_ACLK_SECURE_S, "scmi_aclk_se_s", &clk_scmi_aclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2358*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_HCLK_SECURE_S, "scmi_hclk_se_s", &clk_scmi_hclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2359*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_PCLK_SECURE_S, "scmi_pclk_se_s", &clk_scmi_pclk_secure_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2360*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG, "scmi_crypto_r", &clk_scmi_crypto_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2361*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE, "scmi_crypto_c", &clk_scmi_crypto_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2362*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA, "scmi_crypto_p", &clk_scmi_crypto_pka_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2363*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_SPLL, "scmi_spll", &clk_scmi_spll_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
2364*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_HCLK_SD, "scmi_hclk_sd", &clk_scmi_hclk_sd_ops, NULL, 0, false),
2365*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG_S, "scmi_crypto_r_s", &clk_scmi_crypto_rng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2366*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE_S, "scmi_crypto_c_s", &clk_scmi_crypto_core_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2367*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA_S, "scmi_crypto_p_s", &clk_scmi_crypto_pka_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2368*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_A_CRYPTO_S, "scmi_a_crypto_s", &clk_scmi_a_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2369*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_H_CRYPTO_S, "scmi_h_crypto_s", &clk_scmi_h_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2370*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_P_CRYPTO_S, "scmi_p_crypto_s", &clk_scmi_p_crypto_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2371*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_A_KEYLADDER_S, "scmi_a_keylad_s", &clk_scmi_a_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2372*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_H_KEYLADDER_S, "scmi_h_keylad_s", &clk_scmi_h_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2373*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_P_KEYLADDER_S, "scmi_p_keylad_s", &clk_scmi_p_keylad_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2374*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_TRNG_S, "scmi_trng_s", &clk_scmi_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2375*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_H_TRNG_S, "scmi_h_trng_s", &clk_scmi_h_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2376*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_P_OTPC_S, "scmi_p_otpc_s", &clk_scmi_p_otpc_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
2377*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_OTPC_S, "scmi_otpc_s", &clk_scmi_otpc_s_ops, NULL, 0, true),
2378*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_OTP_PHY, "scmi_otp_phy", &clk_scmi_otp_phy_ops, NULL, 0, false),
2379*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_OTPC_AUTO_RD, "scmi_otpc_rd", &clk_scmi_otpc_rd_ops, NULL, 0, false),
2380*04150feeSXiaoDong Huang 	RK3588_SCMI_CLOCK(SCMI_OTPC_ARB, "scmi_otpc_arb", &clk_scmi_otpc_arb_ops, NULL, 0, false),
2381*04150feeSXiaoDong Huang };
2382*04150feeSXiaoDong Huang 
rockchip_scmi_clock_count(unsigned int agent_id __unused)2383*04150feeSXiaoDong Huang size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
2384*04150feeSXiaoDong Huang {
2385*04150feeSXiaoDong Huang 	return ARRAY_SIZE(clock_table);
2386*04150feeSXiaoDong Huang }
2387*04150feeSXiaoDong Huang 
rockchip_scmi_get_clock(uint32_t agent_id __unused,uint32_t clock_id)2388*04150feeSXiaoDong Huang rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
2389*04150feeSXiaoDong Huang 					 uint32_t clock_id)
2390*04150feeSXiaoDong Huang {
2391*04150feeSXiaoDong Huang 	rk_scmi_clock_t *table = NULL;
2392*04150feeSXiaoDong Huang 
2393*04150feeSXiaoDong Huang 	if (clock_id < ARRAY_SIZE(clock_table))
2394*04150feeSXiaoDong Huang 		table = &clock_table[clock_id];
2395*04150feeSXiaoDong Huang 
2396*04150feeSXiaoDong Huang 	if (table && !table->is_security)
2397*04150feeSXiaoDong Huang 		return table;
2398*04150feeSXiaoDong Huang 	else
2399*04150feeSXiaoDong Huang 		return NULL;
2400*04150feeSXiaoDong Huang }
2401*04150feeSXiaoDong Huang 
pvtplls_suspend(void)2402*04150feeSXiaoDong Huang void pvtplls_suspend(void)
2403*04150feeSXiaoDong Huang {
2404*04150feeSXiaoDong Huang 	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
2405*04150feeSXiaoDong Huang 	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
2406*04150feeSXiaoDong Huang 	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
2407*04150feeSXiaoDong Huang 	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
2408*04150feeSXiaoDong Huang }
2409*04150feeSXiaoDong Huang 
pvtplls_resume(void)2410*04150feeSXiaoDong Huang void pvtplls_resume(void)
2411*04150feeSXiaoDong Huang {
2412*04150feeSXiaoDong Huang 	clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
2413*04150feeSXiaoDong Huang 	clk_dsu_set_rate(sys_clk_info.dsu_rate, PLL_SEL_AUTO);
2414*04150feeSXiaoDong Huang 	clk_cpub01_set_rate(sys_clk_info.cpub01_rate, PLL_SEL_AUTO);
2415*04150feeSXiaoDong Huang 	clk_cpub23_set_rate(sys_clk_info.cpub23_rate, PLL_SEL_AUTO);
2416*04150feeSXiaoDong Huang }
2417*04150feeSXiaoDong Huang 
sys_reset_pvtplls_prepare(void)2418*04150feeSXiaoDong Huang void sys_reset_pvtplls_prepare(void)
2419*04150feeSXiaoDong Huang {
2420*04150feeSXiaoDong Huang 	clk_gpu_set_rate(100000000, PLL_SEL_NOR);
2421*04150feeSXiaoDong Huang 	clk_npu_set_rate(100000000, PLL_SEL_NOR);
2422*04150feeSXiaoDong Huang 	clk_cpul_set_rate(408000000, PLL_SEL_NOR);
2423*04150feeSXiaoDong Huang 	clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
2424*04150feeSXiaoDong Huang 	clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
2425*04150feeSXiaoDong Huang 	clk_dsu_set_rate(408000000, PLL_SEL_NOR);
2426*04150feeSXiaoDong Huang }
2427*04150feeSXiaoDong Huang 
rockchip_clock_init(void)2428*04150feeSXiaoDong Huang void rockchip_clock_init(void)
2429*04150feeSXiaoDong Huang {
2430*04150feeSXiaoDong Huang 	/* set gpll src div to 0 for cpul */
2431*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5), CLKDIV_5BITS_SHF(0U, 9));
2432*04150feeSXiaoDong Huang 	/* set gpll src div to 0 for cpub01 */
2433*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
2434*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(0U, 1));
2435*04150feeSXiaoDong Huang 	/* set gpll src div to 0 for cpu23 */
2436*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
2437*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(0U, 1));
2438*04150feeSXiaoDong Huang 
2439*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
2440*04150feeSXiaoDong Huang 		      CPUB_PCLK_PATH_50M);
2441*04150feeSXiaoDong Huang 	mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
2442*04150feeSXiaoDong Huang 		      CPUB_PCLK_PATH_50M);
2443*04150feeSXiaoDong Huang 
2444*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
2445*04150feeSXiaoDong Huang 		      CLKDIV_5BITS_SHF(5U, 0));
2446*04150feeSXiaoDong Huang 	mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
2447*04150feeSXiaoDong Huang 		      BITS_WITH_WMASK(PCLK_DSU_ROOT_SEL_GPLL,
2448*04150feeSXiaoDong Huang 				      PCLK_DSU_ROOT_SEL_MASK,
2449*04150feeSXiaoDong Huang 				      PCLK_DSU_ROOT_SEL_SHIFT));
2450*04150feeSXiaoDong Huang 
2451*04150feeSXiaoDong Huang 	sys_clk_info.cpul_table = rk3588_cpul_pvtpll_table;
2452*04150feeSXiaoDong Huang 	sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3588_cpul_pvtpll_table);
2453*04150feeSXiaoDong Huang 	sys_clk_info.cpub01_table = rk3588_cpub0_pvtpll_table;
2454*04150feeSXiaoDong Huang 	sys_clk_info.cpub01_rate_count = ARRAY_SIZE(rk3588_cpub0_pvtpll_table);
2455*04150feeSXiaoDong Huang 	sys_clk_info.cpub23_table = rk3588_cpub1_pvtpll_table;
2456*04150feeSXiaoDong Huang 	sys_clk_info.cpub23_rate_count = ARRAY_SIZE(rk3588_cpub1_pvtpll_table);
2457*04150feeSXiaoDong Huang 	memcpy(sys_clk_info.cpub23_table, sys_clk_info.cpub01_table,
2458*04150feeSXiaoDong Huang 	       sys_clk_info.cpub01_rate_count * sizeof(*sys_clk_info.cpub01_table));
2459*04150feeSXiaoDong Huang 	sys_clk_info.gpu_table = rk3588_gpu_pvtpll_table;
2460*04150feeSXiaoDong Huang 	sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3588_gpu_pvtpll_table);
2461*04150feeSXiaoDong Huang 	sys_clk_info.npu_table = rk3588_npu_pvtpll_table;
2462*04150feeSXiaoDong Huang 	sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3588_npu_pvtpll_table);
2463*04150feeSXiaoDong Huang }
2464