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