feat(rk3588): support SCMI for clock/reset domain
rockchip scmi clock controls clocks which only available in secure mode.
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
Change-Id: I5b983877a5b4e8acababbf7e0a3e2725e6479e08
diff --git a/plat/rockchip/rk3588/drivers/pmu/pmu.c b/plat/rockchip/rk3588/drivers/pmu/pmu.c
index 445cf8d..83d6cad 100644
--- a/plat/rockchip/rk3588/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3588/drivers/pmu/pmu.c
@@ -23,6 +23,7 @@
#include <plat_pm_helpers.h>
#include <plat_private.h>
#include <pm_pd_regs.h>
+#include <rk3588_clk.h>
#include <rockchip_sip_svc.h>
#include <secure.h>
#include <soc.h>
@@ -164,12 +165,14 @@
pmusram_data.dsu_ddr_fw_con_reg[i] =
mmio_read_32(FIREWALL_DSU_BASE + FIREWALL_DSU_CON(i));
+ pvtplls_suspend();
pd_dsu_core_save();
}
static void dsu_core_restore(void)
{
pd_dsu_core_restore();
+ pvtplls_resume();
}
static uint32_t clk_save[CRU_CLKGATE_CON_CNT + PHPCRU_CLKGATE_CON_CNT +
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
new file mode 100644
index 0000000..ab3af5f
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.c
@@ -0,0 +1,2463 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_clk.h"
+#include <rockchip_sip_svc.h>
+#include <scmi_clock.h>
+#include <soc.h>
+
+enum pll_type_sel {
+ PLL_SEL_AUTO, /* all plls (normal pll or pvtpll) */
+ PLL_SEL_PVT,
+ PLL_SEL_NOR,
+ PLL_SEL_AUTO_NOR /* all normal plls (apll/gpll/npll) */
+};
+
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#define RK3588_CPUL_PVTPLL_CON0_L 0x40
+#define RK3588_CPUL_PVTPLL_CON0_H 0x44
+#define RK3588_CPUL_PVTPLL_CON1 0x48
+#define RK3588_CPUL_PVTPLL_CON2 0x4c
+#define RK3588_CPUB_PVTPLL_CON0_L 0x00
+#define RK3588_CPUB_PVTPLL_CON0_H 0x04
+#define RK3588_CPUB_PVTPLL_CON1 0x08
+#define RK3588_CPUB_PVTPLL_CON2 0x0c
+#define RK3588_DSU_PVTPLL_CON0_L 0x60
+#define RK3588_DSU_PVTPLL_CON0_H 0x64
+#define RK3588_DSU_PVTPLL_CON1 0x70
+#define RK3588_DSU_PVTPLL_CON2 0x74
+#define RK3588_GPU_PVTPLL_CON0_L 0x00
+#define RK3588_GPU_PVTPLL_CON0_H 0x04
+#define RK3588_GPU_PVTPLL_CON1 0x08
+#define RK3588_GPU_PVTPLL_CON2 0x0c
+#define RK3588_NPU_PVTPLL_CON0_L 0x0c
+#define RK3588_NPU_PVTPLL_CON0_H 0x10
+#define RK3588_NPU_PVTPLL_CON1 0x14
+#define RK3588_NPU_PVTPLL_CON2 0x18
+#define RK3588_PVTPLL_MAX_LENGTH 0x3f
+
+#define GPLL_RATE 1188000000
+#define CPLL_RATE 1500000000
+#define SPLL_RATE 702000000
+#define AUPLL_RATE 786431952
+#define NPLL_RATE 850000000
+
+#define MAX_RATE_TABLE 16
+
+#define CLKDIV_6BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3fU, shift)
+#define CLKDIV_5BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1fU, shift)
+#define CLKDIV_4BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0xfU, shift)
+#define CLKDIV_3BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x7U, shift)
+#define CLKDIV_2BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x3U, shift)
+#define CLKDIV_1BITS_SHF(div, shift) BITS_WITH_WMASK(div, 0x1U, shift)
+
+#define CPU_PLL_PATH_SLOWMODE BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPU_PLL_PATH_NORMAL BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPU_PLL_PATH_DEEP_SLOW BITS_WITH_WMASK(2U, 0x3U, 0)
+
+#define CRU_PLL_POWER_DOWN BIT_WITH_WMSK(13)
+#define CRU_PLL_POWER_UP WMSK_BIT(13)
+
+/* core_i: from gpll or apll */
+#define CLK_CORE_I_SEL_APLL WMSK_BIT(6)
+#define CLK_CORE_I_SEL_GPLL BIT_WITH_WMSK(6)
+
+/* clk_core:
+ * from normal pll(core_i: gpll or apll) path or direct pass from apll
+ */
+
+/* cpul clk path */
+#define CPUL_CLK_PATH_NOR_XIN BITS_WITH_WMASK(0U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 14)
+#define CPUL_CLK_PATH_NOR_LPLL BITS_WITH_WMASK(2U, 0x3U, 14)
+
+#define CPUL_CLK_PATH_LPLL (BITS_WITH_WMASK(0U, 0x3U, 5) | \
+ BITS_WITH_WMASK(0U, 0x3U, 12))
+#define CPUL_CLK_PATH_DIR_LPLL (BITS_WITH_WMASK(0x1, 0x3U, 5) | \
+ BITS_WITH_WMASK(1U, 0x3U, 12))
+#define CPUL_CLK_PATH_PVTPLL (BITS_WITH_WMASK(0x2, 0x3U, 5) | \
+ BITS_WITH_WMASK(2U, 0x3U, 12))
+
+#define CPUL_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 14)
+#define CPUL_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 14)
+
+/* cpub01 clk path */
+#define CPUB01_CLK_PATH_NOR_XIN BITS_WITH_WMASK(0U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 6)
+#define CPUB01_CLK_PATH_NOR_B0PLL BITS_WITH_WMASK(2U, 0x3U, 6)
+
+#define CPUB01_CLK_PATH_B0PLL BITS_WITH_WMASK(0U, 0x3U, 13)
+#define CPUB01_CLK_PATH_DIR_B0PLL BITS_WITH_WMASK(1U, 0x3U, 13)
+#define CPUB01_CLK_PATH_B0_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 13)
+
+#define CPUB01_CLK_PATH_B1PLL BITS_WITH_WMASK(0U, 0x3U, 5)
+#define CPUB01_CLK_PATH_DIR_B1PLL BITS_WITH_WMASK(1U, 0x3U, 5)
+#define CPUB01_CLK_PATH_B1_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 5)
+
+#define CPUB01_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 2)
+#define CPUB01_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 2)
+
+#define CPUB_PCLK_PATH_100M BITS_WITH_WMASK(0U, 0x3U, 0)
+#define CPUB_PCLK_PATH_50M BITS_WITH_WMASK(1U, 0x3U, 0)
+#define CPUB_PCLK_PATH_24M BITS_WITH_WMASK(2U, 0x3U, 0)
+
+/* dsu clk path */
+#define SCLK_DSU_PATH_NOR_B0PLL BITS_WITH_WMASK(0U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_B1PLL BITS_WITH_WMASK(1U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_LPLL BITS_WITH_WMASK(2U, 0x3U, 12)
+#define SCLK_DSU_PATH_NOR_GPLL BITS_WITH_WMASK(3U, 0x3U, 12)
+
+#define DSU_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 15)
+#define DSU_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 15)
+
+#define SCLK_DSU_PATH_NOR_PLL WMSK_BIT(0)
+#define SCLK_DSU_PATH_PVTPLL BIT_WITH_WMSK(0)
+
+/* npu clk path */
+#define NPU_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(0U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_CPLL BITS_WITH_WMASK(1U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_AUPLL BITS_WITH_WMASK(2U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_NPLL BITS_WITH_WMASK(3U, 0x7U, 7)
+#define NPU_CLK_PATH_NOR_SPLL BITS_WITH_WMASK(4U, 0x7U, 7)
+
+#define NPU_CLK_PATH_NOR_PLL WMSK_BIT(0)
+#define NPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(0)
+
+/* gpu clk path */
+#define GPU_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(0U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_CPLL BITS_WITH_WMASK(1U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_AUPLL BITS_WITH_WMASK(2U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_NPLL BITS_WITH_WMASK(3U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_SPLL BITS_WITH_WMASK(4U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_PLL WMSK_BIT(14)
+#define GPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(14)
+
+#define PVTPLL_NEED(type, length) (((type) == PLL_SEL_PVT || \
+ (type) == PLL_SEL_AUTO) && \
+ (length))
+
+struct pvtpll_table {
+ unsigned int rate;
+ uint32_t length;
+ uint32_t ring_sel;
+};
+
+struct sys_clk_info_t {
+ struct pvtpll_table *cpul_table;
+ struct pvtpll_table *cpub01_table;
+ struct pvtpll_table *cpub23_table;
+ struct pvtpll_table *gpu_table;
+ struct pvtpll_table *npu_table;
+ unsigned int cpul_rate_count;
+ unsigned int cpub01_rate_count;
+ unsigned int cpub23_rate_count;
+ unsigned int gpu_rate_count;
+ unsigned int npu_rate_count;
+ unsigned long cpul_rate;
+ unsigned long dsu_rate;
+ unsigned long cpub01_rate;
+ unsigned long cpub23_rate;
+ unsigned long gpu_rate;
+ unsigned long npu_rate;
+};
+
+#define RK3588_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s) \
+{ \
+ .id = _id, \
+ .name = _name, \
+ .clk_ops = _data, \
+ .rate_table = _table, \
+ .rate_cnt = _cnt, \
+ .is_security = _is_s, \
+}
+
+#define ROCKCHIP_PVTPLL(_rate, _sel, _len) \
+{ \
+ .rate = _rate##U, \
+ .ring_sel = _sel, \
+ .length = _len, \
+}
+
+static struct pvtpll_table rk3588_cpul_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length */
+ ROCKCHIP_PVTPLL(1800000000, 1, 15),
+ ROCKCHIP_PVTPLL(1704000000, 1, 15),
+ ROCKCHIP_PVTPLL(1608000000, 1, 15),
+ ROCKCHIP_PVTPLL(1416000000, 1, 15),
+ ROCKCHIP_PVTPLL(1200000000, 1, 17),
+ ROCKCHIP_PVTPLL(1008000000, 1, 22),
+ ROCKCHIP_PVTPLL(816000000, 1, 32),
+ ROCKCHIP_PVTPLL(600000000, 0, 0),
+ ROCKCHIP_PVTPLL(408000000, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_cpub0_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length */
+ ROCKCHIP_PVTPLL(2400000000, 1, 11),
+ ROCKCHIP_PVTPLL(2352000000, 1, 11),
+ ROCKCHIP_PVTPLL(2304000000, 1, 11),
+ ROCKCHIP_PVTPLL(2256000000, 1, 11),
+ ROCKCHIP_PVTPLL(2208000000, 1, 11),
+ ROCKCHIP_PVTPLL(2112000000, 1, 11),
+ ROCKCHIP_PVTPLL(2016000000, 1, 11),
+ ROCKCHIP_PVTPLL(1800000000, 1, 11),
+ ROCKCHIP_PVTPLL(1608000000, 1, 11),
+ ROCKCHIP_PVTPLL(1416000000, 1, 13),
+ ROCKCHIP_PVTPLL(1200000000, 1, 17),
+ ROCKCHIP_PVTPLL(1008000000, 1, 23),
+ ROCKCHIP_PVTPLL(816000000, 1, 33),
+ ROCKCHIP_PVTPLL(600000000, 0, 0),
+ ROCKCHIP_PVTPLL(408000000, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct
+pvtpll_table rk3588_cpub1_pvtpll_table[ARRAY_SIZE(rk3588_cpub0_pvtpll_table)] = { 0 };
+
+static struct pvtpll_table rk3588_gpu_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length */
+ ROCKCHIP_PVTPLL(1000000000, 1, 12),
+ ROCKCHIP_PVTPLL(900000000, 1, 12),
+ ROCKCHIP_PVTPLL(800000000, 1, 12),
+ ROCKCHIP_PVTPLL(700000000, 1, 13),
+ ROCKCHIP_PVTPLL(600000000, 1, 17),
+ ROCKCHIP_PVTPLL(500000000, 1, 25),
+ ROCKCHIP_PVTPLL(400000000, 1, 38),
+ ROCKCHIP_PVTPLL(300000000, 1, 55),
+ ROCKCHIP_PVTPLL(200000000, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3588_npu_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length */
+ ROCKCHIP_PVTPLL(1000000000, 1, 12),
+ ROCKCHIP_PVTPLL(900000000, 1, 12),
+ ROCKCHIP_PVTPLL(800000000, 1, 12),
+ ROCKCHIP_PVTPLL(700000000, 1, 13),
+ ROCKCHIP_PVTPLL(600000000, 1, 17),
+ ROCKCHIP_PVTPLL(500000000, 1, 25),
+ ROCKCHIP_PVTPLL(400000000, 1, 38),
+ ROCKCHIP_PVTPLL(300000000, 1, 55),
+ ROCKCHIP_PVTPLL(200000000, 0, 0),
+ { /* sentinel */ },
+};
+
+static unsigned long rk3588_cpul_rates[] = {
+ 408000000, 600000000, 816000000, 1008000000,
+ 1200000000, 1416000000, 1608000000, 1800000063,
+};
+
+static unsigned long rk3588_cpub_rates[] = {
+ 408000000, 816000000, 1008000000, 1200000000,
+ 1416000000, 1608000000, 1800000000, 2016000000,
+ 2208000000, 2304000000, 2400000063
+};
+
+static unsigned long rk3588_gpu_rates[] = {
+ 200000000, 300000000, 400000000, 500000000,
+ 600000000, 700000000, 800000000, 900000000,
+ 1000000063
+};
+
+static unsigned long rk3588_sbus_rates[] = {
+ 24000000, 50000000, 100000000, 150000000, 200000000,
+ 250000000, 350000000, 700000000
+};
+
+static unsigned long rk3588_sdmmc_rates[] = {
+ 400000, 24000000, 50000000, 100000000, 150000000, 200000000,
+ 300000000, 400000000, 600000000, 700000000
+};
+
+static struct sys_clk_info_t sys_clk_info;
+static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
+
+static struct pvtpll_table *rkclk_get_pvtpll_config(struct pvtpll_table *table,
+ unsigned int count,
+ unsigned int freq_hz)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (freq_hz == table[i].rate)
+ return &table[i];
+ }
+ return NULL;
+}
+
+static int clk_cpul_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
+ sys_clk_info.cpul_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ /* set lpll */
+ if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+ /* set clock gating interval */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(LITCOREGRF_BASE + RK3588_CPUL_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set corel mux pvtpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+ CPUL_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+ CPUL_CLK_PATH_PVTPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+ CPUL_CLK_PATH_PVTPLL);
+ return 0;
+ }
+
+ /* set clk corel div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+ CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+ CLKDIV_5BITS_SHF(div, 0) | CLKDIV_5BITS_SHF(div, 7));
+ /* set corel mux gpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+ CPUL_CLK_PATH_NOR_GPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(6),
+ CPUL_CLK_PATH_LPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+ CPUL_CLK_PATH_LPLL);
+
+ return 0;
+}
+
+static int clk_scmi_cpul_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_cpul_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0) {
+ sys_clk_info.cpul_rate = rate;
+ ret = clk_scmi_dsu_set_rate(clock, rate);
+ }
+
+ return ret;
+}
+
+static unsigned long rk3588_lpll_get_rate(void)
+{
+ unsigned int m, p, s, k;
+ uint64_t rate64 = 24000000, postdiv;
+ int mode;
+
+ mode = (mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) >> 14) &
+ 0x3;
+
+ if (mode == 0)
+ return rate64;
+
+ m = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(16)) >>
+ CRU_PLLCON0_M_SHIFT) &
+ CRU_PLLCON0_M_MASK;
+ p = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+ CRU_PLLCON1_P_SHIFT) &
+ CRU_PLLCON1_P_MASK;
+ s = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(17)) >>
+ CRU_PLLCON1_S_SHIFT) &
+ CRU_PLLCON1_S_MASK;
+ k = (mmio_read_32(DSUCRU_BASE + CRU_PLL_CON(18)) >>
+ CRU_PLLCON2_K_SHIFT) &
+ CRU_PLLCON2_K_MASK;
+
+ rate64 *= m;
+ rate64 = rate64 / p;
+
+ if (k != 0) {
+ /* fractional mode */
+ uint64_t frac_rate64 = 24000000 * k;
+
+ postdiv = p * 65535;
+ frac_rate64 = frac_rate64 / postdiv;
+ rate64 += frac_rate64;
+ }
+ rate64 = rate64 >> s;
+
+ return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpul_get_rate(rk_scmi_clock_t *clock)
+{
+ int src, div;
+
+ src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x0060;
+ src = src >> 5;
+ if (src == 2) {
+ return sys_clk_info.cpul_rate;
+ } else {
+ src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(5)) & 0xc000;
+ src = src >> 14;
+ div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(6)) & 0x1f;
+ switch (src) {
+ case 0:
+ return 24000000;
+ case 1:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.cpul_rate)
+ return sys_clk_info.cpul_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 2:
+ return rk3588_lpll_get_rate();
+ default:
+ return 0;
+ }
+ }
+}
+
+static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static void clk_scmi_b0pll_disable(void)
+{
+ static bool is_b0pll_disabled;
+
+ if (is_b0pll_disabled != 0)
+ return;
+
+ /* set coreb01 mux gpll */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_NOR_GPLL);
+ /* pll enter slow mode */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+ /* set pll power down */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1), CRU_PLL_POWER_DOWN);
+
+ is_b0pll_disabled = true;
+}
+
+static int clk_cpub01_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub01_table,
+ sys_clk_info.cpub01_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ /* set b0pll */
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set clock gating interval */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(BIGCORE0GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set core mux pvtpll */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+ CPUB01_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_B0_PVTPLL);
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+ CPUB01_CLK_PATH_B1_PVTPLL);
+ goto out;
+ }
+
+ /* set clk coreb01 div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div, 8));
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+ CLKDIV_5BITS_SHF(div, 0));
+ /* set coreb01 mux gpll */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_NOR_GPLL);
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_B0PLL);
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(1),
+ CPUB01_CLK_PATH_B1PLL);
+
+out:
+ clk_scmi_b0pll_disable();
+
+ return 0;
+}
+
+static int clk_scmi_cpub01_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_cpub01_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0)
+ sys_clk_info.cpub01_rate = rate;
+
+ return ret;
+}
+
+static unsigned long rk3588_b0pll_get_rate(void)
+{
+ unsigned int m, p, s, k;
+ uint64_t rate64 = 24000000, postdiv;
+ int mode;
+
+ mode = (mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+ 0x3;
+
+ if (mode == 0)
+ return rate64;
+
+ m = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(0)) >>
+ CRU_PLLCON0_M_SHIFT) &
+ CRU_PLLCON0_M_MASK;
+ p = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+ CRU_PLLCON1_P_SHIFT) &
+ CRU_PLLCON1_P_MASK;
+ s = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(1)) >>
+ CRU_PLLCON1_S_SHIFT) &
+ CRU_PLLCON1_S_MASK;
+ k = (mmio_read_32(BIGCORE0CRU_BASE + CRU_PLL_CON(2)) >>
+ CRU_PLLCON2_K_SHIFT) &
+ CRU_PLLCON2_K_MASK;
+
+ rate64 *= m;
+ rate64 = rate64 / p;
+
+ if (k != 0) {
+ /* fractional mode */
+ uint64_t frac_rate64 = 24000000 * k;
+
+ postdiv = p * 65535;
+ frac_rate64 = frac_rate64 / postdiv;
+ rate64 += frac_rate64;
+ }
+ rate64 = rate64 >> s;
+
+ return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub01_get_rate(rk_scmi_clock_t *clock)
+{
+ int value, src, div;
+
+ value = mmio_read_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0));
+ src = (value & 0x6000) >> 13;
+ if (src == 2) {
+ return sys_clk_info.cpub01_rate;
+ } else {
+ src = (value & 0x00c0) >> 6;
+ div = (value & 0x1f00) >> 8;
+ switch (src) {
+ case 0:
+ return 24000000;
+ case 1:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.cpub01_rate)
+ return sys_clk_info.cpub01_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 2:
+ return rk3588_b0pll_get_rate();
+ default:
+ return 0;
+ }
+ }
+}
+
+static int clk_scmi_cpub01_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static void clk_scmi_b1pll_disable(void)
+{
+ static bool is_b1pll_disabled;
+
+ if (is_b1pll_disabled != 0)
+ return;
+
+ /* set coreb23 mux gpll */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_NOR_GPLL);
+ /* pll enter slow mode */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+ /* set pll power down */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9), CRU_PLL_POWER_DOWN);
+
+ is_b1pll_disabled = true;
+}
+
+static int clk_cpub23_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpub23_table,
+ sys_clk_info.cpub23_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ /* set b1pll */
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set clock gating interval */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(BIGCORE1GRF_BASE + RK3588_CPUB_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set core mux pvtpll */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+ CPUB01_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_B0_PVTPLL);
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+ CPUB01_CLK_PATH_B1_PVTPLL);
+ goto out;
+ }
+
+ /* set clk coreb23 div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div, 8));
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+ CLKDIV_5BITS_SHF(div, 0));
+ /* set coreb23 mux gpll */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_NOR_GPLL);
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CPUB01_CLK_PATH_B0PLL);
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(1),
+ CPUB01_CLK_PATH_B1PLL);
+
+out:
+ clk_scmi_b1pll_disable();
+
+ return 0;
+}
+
+static int clk_scmi_cpub23_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_cpub23_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0)
+ sys_clk_info.cpub23_rate = rate;
+
+ return ret;
+}
+
+static unsigned long rk3588_b1pll_get_rate(void)
+{
+ unsigned int m, p, s, k;
+ uint64_t rate64 = 24000000, postdiv;
+ int mode;
+
+ mode = (mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0)) >> 6) &
+ 0x3;
+
+ if (mode == 0)
+ return rate64;
+
+ m = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(8)) >>
+ CRU_PLLCON0_M_SHIFT) &
+ CRU_PLLCON0_M_MASK;
+ p = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+ CRU_PLLCON1_P_SHIFT) &
+ CRU_PLLCON1_P_MASK;
+ s = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(9)) >>
+ CRU_PLLCON1_S_SHIFT) &
+ CRU_PLLCON1_S_MASK;
+ k = (mmio_read_32(BIGCORE1CRU_BASE + CRU_PLL_CON(10)) >>
+ CRU_PLLCON2_K_SHIFT) &
+ CRU_PLLCON2_K_MASK;
+
+ rate64 *= m;
+ rate64 = rate64 / p;
+
+ if (k != 0) {
+ /* fractional mode */
+ uint64_t frac_rate64 = 24000000 * k;
+
+ postdiv = p * 65535;
+ frac_rate64 = frac_rate64 / postdiv;
+ rate64 += frac_rate64;
+ }
+ rate64 = rate64 >> s;
+
+ return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub23_get_rate(rk_scmi_clock_t *clock)
+{
+ int value, src, div;
+
+ value = mmio_read_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0));
+ src = (value & 0x6000) >> 13;
+ if (src == 2) {
+ return sys_clk_info.cpub23_rate;
+ } else {
+ src = (value & 0x00c0) >> 6;
+ div = (value & 0x1f00) >> 8;
+ switch (src) {
+ case 0:
+ return 24000000;
+ case 1:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.cpub23_rate)
+ return sys_clk_info.cpub23_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 2:
+ return rk3588_b1pll_get_rate();
+ default:
+ return 0;
+ }
+ }
+}
+
+static int clk_scmi_cpub23_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_dsu_get_rate(rk_scmi_clock_t *clock)
+{
+ int src, div;
+
+ src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(1)) & 0x1;
+ if (src != 0) {
+ return sys_clk_info.dsu_rate;
+ } else {
+ src = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0x3000;
+ src = src >> 12;
+ div = mmio_read_32(DSUCRU_BASE + CRU_CLKSEL_CON(0)) & 0xf80;
+ div = div >> 7;
+ switch (src) {
+ case 0:
+ return rk3588_b0pll_get_rate() / (div + 1);
+ case 1:
+ return rk3588_b1pll_get_rate() / (div + 1);
+ case 2:
+ return rk3588_lpll_get_rate() / (div + 1);
+ case 3:
+ return GPLL_RATE / (div + 1);
+ default:
+ return 0;
+ }
+ }
+}
+
+static void clk_scmi_lpll_disable(void)
+{
+ static bool is_lpll_disabled;
+
+ if (is_lpll_disabled)
+ return;
+
+ /* set corel mux gpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5),
+ CPUL_CLK_PATH_NOR_GPLL);
+ /* set dsu mux gpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+ SCLK_DSU_PATH_NOR_GPLL);
+ /* pll enter slow mode */
+ mmio_write_32(DSUCRU_BASE + CRU_MODE_CON0, CPU_PLL_PATH_SLOWMODE);
+ /* set pll power down */
+ mmio_write_32(DSUCRU_BASE + CRU_PLL_CON(17), CRU_PLL_POWER_DOWN);
+
+ is_lpll_disabled = true;
+}
+
+static int clk_dsu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cpul_table,
+ sys_clk_info.cpul_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ /* set pvtpll */
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set clock gating interval */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(DSUGRF_BASE + RK3588_DSU_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set dsu mux pvtpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(7),
+ DSU_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+ SCLK_DSU_PATH_PVTPLL);
+ goto out;
+ }
+ /* set dsu div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div, 7));
+ /* set dsu mux gpll */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(0),
+ SCLK_DSU_PATH_NOR_GPLL);
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(1),
+ SCLK_DSU_PATH_NOR_PLL);
+
+out:
+ clk_scmi_lpll_disable();
+
+ return 0;
+}
+
+static int clk_scmi_dsu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_dsu_set_rate(rate, PLL_SEL_AUTO);
+
+ if (ret == 0)
+ sys_clk_info.dsu_rate = rate;
+ return ret;
+}
+
+static int clk_scmi_dsu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_gpu_get_rate(rk_scmi_clock_t *clock)
+{
+ int div, src;
+
+ if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x4000) != 0) {
+ return sys_clk_info.gpu_rate;
+ } else {
+ div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x1f;
+ src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(158)) & 0x00e0;
+ src = src >> 5;
+ switch (src) {
+ case 0:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.gpu_rate)
+ return sys_clk_info.gpu_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 1:
+ return CPLL_RATE / (div + 1);
+ case 2:
+ return AUPLL_RATE / (div + 1);
+ case 3:
+ return NPLL_RATE / (div + 1);
+ case 4:
+ return SPLL_RATE / (div + 1);
+ default:
+ return 0;
+ }
+ }
+}
+
+static int clk_gpu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.gpu_table,
+ sys_clk_info.gpu_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set clock gating interval */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(GPUGRF_BASE + RK3588_GPU_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set gpu mux pvtpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+ GPU_CLK_PATH_PVTPLL);
+ return 0;
+ }
+
+ /* set gpu div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+ CLKDIV_5BITS_SHF(div - 1, 0));
+ /* set gpu mux gpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+ GPU_CLK_PATH_NOR_GPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(158),
+ GPU_CLK_PATH_NOR_PLL);
+
+ return 0;
+}
+
+static int clk_scmi_gpu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_gpu_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0)
+ sys_clk_info.gpu_rate = rate;
+
+ return ret;
+}
+
+static int clk_scmi_gpu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_npu_get_rate(rk_scmi_clock_t *clock)
+{
+ int div, src;
+
+ if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(74)) & 0x1) != 0) {
+ return sys_clk_info.npu_rate;
+ } else {
+ div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x007c;
+ div = div >> 2;
+ src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(73)) & 0x0380;
+ src = src >> 7;
+ switch (src) {
+ case 0:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.npu_rate != 0)
+ return sys_clk_info.npu_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 1:
+ return CPLL_RATE / (div + 1);
+ case 2:
+ return AUPLL_RATE / (div + 1);
+ case 3:
+ return NPLL_RATE / (div + 1);
+ case 4:
+ return SPLL_RATE / (div + 1);
+ default:
+ return 0;
+ }
+ }
+}
+
+static int clk_npu_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ int div;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.npu_table,
+ sys_clk_info.npu_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set clock gating interval */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON2,
+ 0x00040000);
+ /* set ring sel */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+ 0x07000000 | (pvtpll->ring_sel << 8));
+ /* set length */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_H,
+ 0x003f0000 | pvtpll->length);
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON1,
+ 0x18);
+ /* enable pvtpll */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+ 0x00020002);
+ /* start monitor */
+ mmio_write_32(NPUGRF_BASE + RK3588_NPU_PVTPLL_CON0_L,
+ 0x00010001);
+ /* set npu mux pvtpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+ NPU_CLK_PATH_PVTPLL);
+ return 0;
+ }
+
+ /* set npu div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+ CLKDIV_5BITS_SHF(div - 1, 2));
+ /* set npu mux gpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(73),
+ NPU_CLK_PATH_NOR_GPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(74),
+ NPU_CLK_PATH_NOR_PLL);
+
+ return 0;
+}
+
+static int clk_scmi_npu_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ ret = clk_npu_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0)
+ sys_clk_info.npu_rate = rate;
+
+ return ret;
+}
+
+static int clk_scmi_npu_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+ int div;
+
+ if ((mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0)) & 0x0800) != 0) {
+ div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+ div = (div & 0x03e0) >> 5;
+ return SPLL_RATE / (div + 1);
+ } else {
+ return OSC_HZ;
+ }
+}
+
+static int clk_scmi_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int div;
+
+ if (rate == OSC_HZ) {
+ mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+ WMSK_BIT(11));
+ return 0;
+ }
+
+ div = DIV_ROUND_UP(SPLL_RATE, rate);
+ mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div - 1, 5));
+ mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+ BIT_WITH_WMSK(11) | WMSK_BIT(10));
+ return 0;
+}
+
+static int clk_scmi_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_pclk_sbus_get_rate(rk_scmi_clock_t *clock)
+{
+ int div;
+
+ div = mmio_read_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0));
+ div = div & 0x001f;
+ return SPLL_RATE / (div + 1);
+
+}
+
+static int clk_scmi_pclk_sbus_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int div;
+
+ div = DIV_ROUND_UP(SPLL_RATE, rate);
+ mmio_write_32(BUSSCRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div - 1, 0));
+ return 0;
+}
+
+static int clk_scmi_pclk_sbus_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_cclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+ int div;
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x3000;
+ src = src >> 12;
+ div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0fc0;
+ div = div >> 6;
+ if (src == 1) {
+ return SPLL_RATE / (div + 1);
+ } else if (src == 2) {
+ return OSC_HZ / (div + 1);
+ } else {
+ return GPLL_RATE / (div + 1);
+ }
+}
+
+static int clk_scmi_cclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int div;
+
+ if ((OSC_HZ % rate) == 0) {
+ div = DIV_ROUND_UP(OSC_HZ, rate);
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+ CLKDIV_6BITS_SHF(div - 1, 6) |
+ BITS_WITH_WMASK(2U, 0x3U, 12));
+ } else if ((SPLL_RATE % rate) == 0) {
+ div = DIV_ROUND_UP(SPLL_RATE, rate);
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+ CLKDIV_6BITS_SHF(div - 1, 6) |
+ BITS_WITH_WMASK(1U, 0x3U, 12));
+ } else {
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+ CLKDIV_6BITS_SHF(div - 1, 6) |
+ BITS_WITH_WMASK(0U, 0x3U, 12));
+ }
+
+ return 0;
+}
+
+static int clk_scmi_cclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+ BITS_WITH_WMASK(!status, 0x1U, 4));
+ return 0;
+}
+
+static unsigned long clk_scmi_dclk_sdmmc_get_rate(rk_scmi_clock_t *clock)
+{
+ int div;
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x0020;
+ div = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(3)) & 0x001f;
+ if (src != 0) {
+ return SPLL_RATE / (div + 1);
+ } else {
+ return GPLL_RATE / (div + 1);
+ }
+}
+
+static int clk_scmi_dclk_sdmmc_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int div;
+
+ if ((SPLL_RATE % rate) == 0) {
+ div = DIV_ROUND_UP(SPLL_RATE, rate);
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+ CLKDIV_5BITS_SHF(div - 1, 0) |
+ BITS_WITH_WMASK(1U, 0x1U, 5));
+ } else {
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(3),
+ CLKDIV_5BITS_SHF(div - 1, 0) |
+ BITS_WITH_WMASK(0U, 0x1U, 5));
+ }
+ return 0;
+}
+
+static int clk_scmi_dclk_sdmmc_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+ BITS_WITH_WMASK(!status, 0x1U, 1));
+ return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0003;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 200 * MHz;
+ case 2:
+ return 100 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_aclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 200 * MHz)
+ src = 1;
+ else if (rate >= 100 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 0));
+
+ return 0;
+}
+
+static int clk_scmi_aclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_ns_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x000c;
+ src = src >> 2;
+ switch (src) {
+ case 0:
+ return 150 * MHz;
+ case 1:
+ return 100 * MHz;
+ case 2:
+ return 50 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_hclk_secure_ns_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 150 * MHz)
+ src = 0;
+ else if (rate >= 100 * MHz)
+ src = 1;
+ else if (rate >= 50 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 2));
+ return 0;
+}
+
+static int clk_scmi_hclk_secure_ns_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_tclk_wdt_get_rate(rk_scmi_clock_t *clock)
+{
+ return OSC_HZ;
+}
+
+static int clk_scmi_tclk_wdt_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+ BITS_WITH_WMASK(!status, 0x1U, 0));
+ return 0;
+}
+
+static unsigned long clk_scmi_keyladder_core_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x00c0;
+ src = src >> 6;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_keyladder_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+ BITS_WITH_WMASK(src, 0x3U, 6));
+ return 0;
+}
+
+static int clk_scmi_keyladder_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 9));
+ return 0;
+}
+
+static unsigned long clk_scmi_keyladder_rng_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0300;
+ src = src >> 8;
+ switch (src) {
+ case 0:
+ return 175 * MHz;
+ case 1:
+ return 116 * MHz;
+ case 2:
+ return 58 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_keyladder_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 175 * MHz)
+ src = 0;
+ else if (rate >= 116 * MHz)
+ src = 1;
+ else if (rate >= 58 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+ BITS_WITH_WMASK(src, 0x3U, 8));
+ return 0;
+}
+
+static int clk_scmi_keyladder_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 10));
+ return 0;
+}
+
+static unsigned long clk_scmi_aclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0030;
+ src = src >> 4;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_aclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 4));
+ return 0;
+}
+
+static int clk_scmi_aclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_hclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x00c0;
+ src = src >> 6;
+ switch (src) {
+ case 0:
+ return 175 * MHz;
+ case 1:
+ return 116 * MHz;
+ case 2:
+ return 58 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_hclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 175 * MHz)
+ src = 0;
+ else if (rate >= 116 * MHz)
+ src = 1;
+ else if (rate >= 58 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 6));
+ return 0;
+}
+
+static int clk_scmi_hclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_pclk_secure_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0300;
+ src = src >> 8;
+ switch (src) {
+ case 0:
+ return 116 * MHz;
+ case 1:
+ return 58 * MHz;
+ case 2:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_pclk_secure_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 116 * MHz)
+ src = 0;
+ else if (rate >= 58 * MHz)
+ src = 1;
+ else
+ src = 2;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 8));
+ return 0;
+}
+
+static int clk_scmi_pclk_secure_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0xc000;
+ src = src >> 14;
+ switch (src) {
+ case 0:
+ return 175 * MHz;
+ case 1:
+ return 116 * MHz;
+ case 2:
+ return 58 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_rng_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 175 * MHz)
+ src = 0;
+ else if (rate >= 116 * MHz)
+ src = 1;
+ else if (rate >= 58 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 14));
+ return 0;
+}
+
+static int clk_scmi_crypto_rng_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 1));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x0c00;
+ src = src >> 10;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_core_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 10));
+ return 0;
+}
+
+static int clk_scmi_crypto_core_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(0),
+ BITS_WITH_WMASK(!status, 0x1U, 15));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(1)) & 0x3000;
+ src = src >> 12;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_pka_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(1),
+ BITS_WITH_WMASK(src, 0x3U, 12));
+ return 0;
+}
+
+static int clk_scmi_crypto_pka_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 0));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_spll_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(BUSSCRU_BASE + CRU_MODE_CON0) & 0x3;
+ switch (src) {
+ case 0:
+ return OSC_HZ;
+ case 1:
+ return 702 * MHz;
+ case 2:
+ return 32768;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_spll_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 700 * MHz)
+ src = 1;
+ else
+ src = 0;
+
+ mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+ BITS_WITH_WMASK(0, 0x3U, 0));
+ mmio_write_32(BUSSCRU_BASE + CRU_PLL_CON(137),
+ BITS_WITH_WMASK(2, 0x7U, 6));
+
+ mmio_write_32(BUSSCRU_BASE + CRU_MODE_CON0,
+ BITS_WITH_WMASK(src, 0x3U, 0));
+ return 0;
+}
+
+static int clk_scmi_spll_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_hclk_sd_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_hclk_secure_ns_get_rate(clock);
+}
+
+static int clk_scmi_hclk_sd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+ BITS_WITH_WMASK(!status, 0x1U, 2));
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_rng_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x0030;
+ src = src >> 4;
+ switch (src) {
+ case 0:
+ return 175 * MHz;
+ case 1:
+ return 116 * MHz;
+ case 2:
+ return 58 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_rng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 175 * MHz)
+ src = 0;
+ else if (rate >= 116 * MHz)
+ src = 1;
+ else if (rate >= 58 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+ BITS_WITH_WMASK(src, 0x3U, 4));
+ return 0;
+}
+
+static int clk_scmi_crypto_rng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 6));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_core_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x3;
+ src = src >> 0;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_core_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+ BITS_WITH_WMASK(src, 0x3U, 0));
+ return 0;
+}
+
+static int clk_scmi_crypto_core_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 4));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_crypto_pka_s_get_rate(rk_scmi_clock_t *clock)
+{
+ uint32_t src;
+
+ src = mmio_read_32(SCRU_BASE + CRU_CLKSEL_CON(2)) & 0x000c;
+ src = src >> 2;
+ switch (src) {
+ case 0:
+ return 350 * MHz;
+ case 1:
+ return 233 * MHz;
+ case 2:
+ return 116 * MHz;
+ case 3:
+ return OSC_HZ;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_crypto_pka_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ uint32_t src;
+
+ if (rate >= 350 * MHz)
+ src = 0;
+ else if (rate >= 233 * MHz)
+ src = 1;
+ else if (rate >= 116 * MHz)
+ src = 2;
+ else
+ src = 3;
+
+ mmio_write_32(SCRU_BASE + CRU_CLKSEL_CON(2),
+ BITS_WITH_WMASK(src, 0x3U, 2));
+ return 0;
+}
+
+static int clk_scmi_crypto_pka_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 5));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_a_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 7));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_h_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 8));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_p_crypto_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_crypto_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_crypto_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+ BITS_WITH_WMASK(!status, 0x1U, 13));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_a_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_aclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_a_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_aclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_a_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 11));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_h_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 12));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_p_keylad_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_keylad_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_keylad_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+ BITS_WITH_WMASK(!status, 0x1U, 14));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(3),
+ BITS_WITH_WMASK(!status, 0x1U, 6));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_h_trng_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_hclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_h_trng_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_hclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_h_trng_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(2),
+ BITS_WITH_WMASK(!status, 0x1U, 15));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_p_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return clk_scmi_pclk_secure_s_get_rate(clock);
+}
+
+static int clk_scmi_p_otpc_s_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ return clk_scmi_pclk_secure_s_set_rate(clock, rate);
+}
+
+static int clk_scmi_p_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 13));
+
+ return 0;
+}
+
+static unsigned long clk_scmi_otpc_s_get_rate(rk_scmi_clock_t *clock)
+{
+ return OSC_HZ;
+}
+
+static int clk_scmi_otpc_s_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(SCRU_BASE + CRU_CLKGATE_CON(1),
+ BITS_WITH_WMASK(!status, 0x1U, 14));
+ return 0;
+}
+
+static unsigned long clk_scmi_otp_phy_get_rate(rk_scmi_clock_t *clock)
+{
+ return OSC_HZ;
+}
+
+static int clk_scmi_otp_phy_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+ BITS_WITH_WMASK(!status, 0x1U, 13));
+ return 0;
+}
+
+static unsigned long clk_scmi_otpc_rd_get_rate(rk_scmi_clock_t *clock)
+{
+ return OSC_HZ;
+}
+
+static int clk_scmi_otpc_rd_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+ BITS_WITH_WMASK(!status, 0x1U, 12));
+ return 0;
+}
+
+static unsigned long clk_scmi_otpc_arb_get_rate(rk_scmi_clock_t *clock)
+{
+ return OSC_HZ;
+}
+
+static int clk_scmi_otpc_arb_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(18),
+ BITS_WITH_WMASK(!status, 0x1U, 11));
+ return 0;
+}
+
+static const struct rk_clk_ops clk_scmi_cpul_ops = {
+ .get_rate = clk_scmi_cpul_get_rate,
+ .set_rate = clk_scmi_cpul_set_rate,
+ .set_status = clk_scmi_cpul_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_dsu_ops = {
+ .get_rate = clk_scmi_dsu_get_rate,
+ .set_rate = clk_scmi_dsu_set_rate,
+ .set_status = clk_scmi_dsu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub01_ops = {
+ .get_rate = clk_scmi_cpub01_get_rate,
+ .set_rate = clk_scmi_cpub01_set_rate,
+ .set_status = clk_scmi_cpub01_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub23_ops = {
+ .get_rate = clk_scmi_cpub23_get_rate,
+ .set_rate = clk_scmi_cpub23_set_rate,
+ .set_status = clk_scmi_cpub23_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_gpu_ops = {
+ .get_rate = clk_scmi_gpu_get_rate,
+ .set_rate = clk_scmi_gpu_set_rate,
+ .set_status = clk_scmi_gpu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_npu_ops = {
+ .get_rate = clk_scmi_npu_get_rate,
+ .set_rate = clk_scmi_npu_set_rate,
+ .set_status = clk_scmi_npu_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_sbus_ops = {
+ .get_rate = clk_scmi_sbus_get_rate,
+ .set_rate = clk_scmi_sbus_set_rate,
+ .set_status = clk_scmi_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_sbus_ops = {
+ .get_rate = clk_scmi_pclk_sbus_get_rate,
+ .set_rate = clk_scmi_pclk_sbus_set_rate,
+ .set_status = clk_scmi_pclk_sbus_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cclk_sdmmc_ops = {
+ .get_rate = clk_scmi_cclk_sdmmc_get_rate,
+ .set_rate = clk_scmi_cclk_sdmmc_set_rate,
+ .set_status = clk_scmi_cclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_dclk_sdmmc_ops = {
+ .get_rate = clk_scmi_dclk_sdmmc_get_rate,
+ .set_rate = clk_scmi_dclk_sdmmc_set_rate,
+ .set_status = clk_scmi_dclk_sdmmc_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_ns_ops = {
+ .get_rate = clk_scmi_aclk_secure_ns_get_rate,
+ .set_rate = clk_scmi_aclk_secure_ns_set_rate,
+ .set_status = clk_scmi_aclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_ns_ops = {
+ .get_rate = clk_scmi_hclk_secure_ns_get_rate,
+ .set_rate = clk_scmi_hclk_secure_ns_set_rate,
+ .set_status = clk_scmi_hclk_secure_ns_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_tclk_wdt_ops = {
+ .get_rate = clk_scmi_tclk_wdt_get_rate,
+ .set_status = clk_scmi_tclk_wdt_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_core_ops = {
+ .get_rate = clk_scmi_keyladder_core_get_rate,
+ .set_rate = clk_scmi_keyladder_core_set_rate,
+ .set_status = clk_scmi_keyladder_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_keyladder_rng_ops = {
+ .get_rate = clk_scmi_keyladder_rng_get_rate,
+ .set_rate = clk_scmi_keyladder_rng_set_rate,
+ .set_status = clk_scmi_keyladder_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_aclk_secure_s_ops = {
+ .get_rate = clk_scmi_aclk_secure_s_get_rate,
+ .set_rate = clk_scmi_aclk_secure_s_set_rate,
+ .set_status = clk_scmi_aclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_secure_s_ops = {
+ .get_rate = clk_scmi_hclk_secure_s_get_rate,
+ .set_rate = clk_scmi_hclk_secure_s_set_rate,
+ .set_status = clk_scmi_hclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_pclk_secure_s_ops = {
+ .get_rate = clk_scmi_pclk_secure_s_get_rate,
+ .set_rate = clk_scmi_pclk_secure_s_set_rate,
+ .set_status = clk_scmi_pclk_secure_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_ops = {
+ .get_rate = clk_scmi_crypto_rng_get_rate,
+ .set_rate = clk_scmi_crypto_rng_set_rate,
+ .set_status = clk_scmi_crypto_rng_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_ops = {
+ .get_rate = clk_scmi_crypto_core_get_rate,
+ .set_rate = clk_scmi_crypto_core_set_rate,
+ .set_status = clk_scmi_crypto_core_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_ops = {
+ .get_rate = clk_scmi_crypto_pka_get_rate,
+ .set_rate = clk_scmi_crypto_pka_set_rate,
+ .set_status = clk_scmi_crypto_pka_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_spll_ops = {
+ .get_rate = clk_scmi_spll_get_rate,
+ .set_rate = clk_scmi_spll_set_rate,
+ .set_status = clk_scmi_spll_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_hclk_sd_ops = {
+ .get_rate = clk_scmi_hclk_sd_get_rate,
+ .set_status = clk_scmi_hclk_sd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_rng_s_ops = {
+ .get_rate = clk_scmi_crypto_rng_s_get_rate,
+ .set_rate = clk_scmi_crypto_rng_s_set_rate,
+ .set_status = clk_scmi_crypto_rng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_core_s_ops = {
+ .get_rate = clk_scmi_crypto_core_s_get_rate,
+ .set_rate = clk_scmi_crypto_core_s_set_rate,
+ .set_status = clk_scmi_crypto_core_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_crypto_pka_s_ops = {
+ .get_rate = clk_scmi_crypto_pka_s_get_rate,
+ .set_rate = clk_scmi_crypto_pka_s_set_rate,
+ .set_status = clk_scmi_crypto_pka_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_crypto_s_ops = {
+ .get_rate = clk_scmi_a_crypto_s_get_rate,
+ .set_rate = clk_scmi_a_crypto_s_set_rate,
+ .set_status = clk_scmi_a_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_crypto_s_ops = {
+ .get_rate = clk_scmi_h_crypto_s_get_rate,
+ .set_rate = clk_scmi_h_crypto_s_set_rate,
+ .set_status = clk_scmi_h_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_crypto_s_ops = {
+ .get_rate = clk_scmi_p_crypto_s_get_rate,
+ .set_rate = clk_scmi_p_crypto_s_set_rate,
+ .set_status = clk_scmi_p_crypto_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_a_keylad_s_ops = {
+ .get_rate = clk_scmi_a_keylad_s_get_rate,
+ .set_rate = clk_scmi_a_keylad_s_set_rate,
+ .set_status = clk_scmi_a_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_keylad_s_ops = {
+ .get_rate = clk_scmi_h_keylad_s_get_rate,
+ .set_rate = clk_scmi_h_keylad_s_set_rate,
+ .set_status = clk_scmi_h_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_keylad_s_ops = {
+ .get_rate = clk_scmi_p_keylad_s_get_rate,
+ .set_rate = clk_scmi_p_keylad_s_set_rate,
+ .set_status = clk_scmi_p_keylad_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_trng_s_ops = {
+ .get_rate = clk_scmi_trng_s_get_rate,
+ .set_rate = clk_scmi_trng_s_set_rate,
+ .set_status = clk_scmi_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_h_trng_s_ops = {
+ .get_rate = clk_scmi_h_trng_s_get_rate,
+ .set_rate = clk_scmi_h_trng_s_set_rate,
+ .set_status = clk_scmi_h_trng_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_p_otpc_s_ops = {
+ .get_rate = clk_scmi_p_otpc_s_get_rate,
+ .set_rate = clk_scmi_p_otpc_s_set_rate,
+ .set_status = clk_scmi_p_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_s_ops = {
+ .get_rate = clk_scmi_otpc_s_get_rate,
+ .set_status = clk_scmi_otpc_s_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otp_phy_ops = {
+ .get_rate = clk_scmi_otp_phy_get_rate,
+ .set_status = clk_scmi_otp_phy_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_rd_ops = {
+ .get_rate = clk_scmi_otpc_rd_get_rate,
+ .set_status = clk_scmi_otpc_rd_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_otpc_arb_ops = {
+ .get_rate = clk_scmi_otpc_arb_get_rate,
+ .set_status = clk_scmi_otpc_arb_set_status,
+};
+
+rk_scmi_clock_t clock_table[] = {
+ RK3588_SCMI_CLOCK(SCMI_CLK_CPUL, "scmi_clk_cpul", &clk_scmi_cpul_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_DSU, "scmi_clk_dsu", &clk_scmi_dsu_ops, rk3588_cpul_rates, ARRAY_SIZE(rk3588_cpul_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_CPUB01, "scmi_clk_cpub01", &clk_scmi_cpub01_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_CPUB23, "scmi_clk_cpub23", &clk_scmi_cpub23_ops, rk3588_cpub_rates, ARRAY_SIZE(rk3588_cpub_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_DDR, "scmi_clk_ddr", NULL, NULL, 0, false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_GPU, "scmi_clk_gpu", &clk_scmi_gpu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_NPU, "scmi_clk_npu", &clk_scmi_npu_ops, rk3588_gpu_rates, ARRAY_SIZE(rk3588_gpu_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CLK_SBUS, "scmi_clk_sbus", &clk_scmi_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+ RK3588_SCMI_CLOCK(SCMI_PCLK_SBUS, "scmi_pclk_sbus", &clk_scmi_pclk_sbus_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+ RK3588_SCMI_CLOCK(SCMI_CCLK_SD, "scmi_cclk_sd", &clk_scmi_cclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_DCLK_SD, "scmi_dclk_sd", &clk_scmi_dclk_sdmmc_ops, rk3588_sdmmc_rates, ARRAY_SIZE(rk3588_sdmmc_rates), false),
+ 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),
+ 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),
+ RK3588_SCMI_CLOCK(SCMI_TCLK_WDT, "scmi_tclk_wdt", &clk_scmi_tclk_wdt_ops, NULL, 0, false),
+ RK3588_SCMI_CLOCK(SCMI_KEYLADDER_CORE, "scmi_keylad_c", &clk_scmi_keyladder_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+ RK3588_SCMI_CLOCK(SCMI_KEYLADDER_RNG, "scmi_keylad_r", &clk_scmi_keyladder_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+ 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),
+ 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),
+ 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),
+ RK3588_SCMI_CLOCK(SCMI_CRYPTO_RNG, "scmi_crypto_r", &clk_scmi_crypto_rng_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CRYPTO_CORE, "scmi_crypto_c", &clk_scmi_crypto_core_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_CRYPTO_PKA, "scmi_crypto_p", &clk_scmi_crypto_pka_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_SPLL, "scmi_spll", &clk_scmi_spll_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), false),
+ RK3588_SCMI_CLOCK(SCMI_HCLK_SD, "scmi_hclk_sd", &clk_scmi_hclk_sd_ops, NULL, 0, false),
+ 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),
+ 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),
+ 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),
+ 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),
+ 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),
+ 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),
+ 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),
+ 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),
+ 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),
+ RK3588_SCMI_CLOCK(SCMI_TRNG_S, "scmi_trng_s", &clk_scmi_trng_s_ops, rk3588_sbus_rates, ARRAY_SIZE(rk3588_sbus_rates), true),
+ 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),
+ 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),
+ RK3588_SCMI_CLOCK(SCMI_OTPC_S, "scmi_otpc_s", &clk_scmi_otpc_s_ops, NULL, 0, true),
+ RK3588_SCMI_CLOCK(SCMI_OTP_PHY, "scmi_otp_phy", &clk_scmi_otp_phy_ops, NULL, 0, false),
+ RK3588_SCMI_CLOCK(SCMI_OTPC_AUTO_RD, "scmi_otpc_rd", &clk_scmi_otpc_rd_ops, NULL, 0, false),
+ RK3588_SCMI_CLOCK(SCMI_OTPC_ARB, "scmi_otpc_arb", &clk_scmi_otpc_arb_ops, NULL, 0, false),
+};
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+ return ARRAY_SIZE(clock_table);
+}
+
+rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id __unused,
+ uint32_t clock_id)
+{
+ rk_scmi_clock_t *table = NULL;
+
+ if (clock_id < ARRAY_SIZE(clock_table))
+ table = &clock_table[clock_id];
+
+ if (table && !table->is_security)
+ return table;
+ else
+ return NULL;
+}
+
+void pvtplls_suspend(void)
+{
+ clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+ clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void pvtplls_resume(void)
+{
+ clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
+ clk_dsu_set_rate(sys_clk_info.dsu_rate, PLL_SEL_AUTO);
+ clk_cpub01_set_rate(sys_clk_info.cpub01_rate, PLL_SEL_AUTO);
+ clk_cpub23_set_rate(sys_clk_info.cpub23_rate, PLL_SEL_AUTO);
+}
+
+void sys_reset_pvtplls_prepare(void)
+{
+ clk_gpu_set_rate(100000000, PLL_SEL_NOR);
+ clk_npu_set_rate(100000000, PLL_SEL_NOR);
+ clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub01_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub23_set_rate(408000000, PLL_SEL_NOR);
+ clk_dsu_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void rockchip_clock_init(void)
+{
+ /* set gpll src div to 0 for cpul */
+ mmio_write_32(DSUCRU_BASE + CRU_CLKSEL_CON(5), CLKDIV_5BITS_SHF(0U, 9));
+ /* set gpll src div to 0 for cpub01 */
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(0U, 1));
+ /* set gpll src div to 0 for cpu23 */
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(0U, 1));
+
+ mmio_write_32(BIGCORE0CRU_BASE + CRU_CLKSEL_CON(2),
+ CPUB_PCLK_PATH_50M);
+ mmio_write_32(BIGCORE1CRU_BASE + CRU_CLKSEL_CON(2),
+ CPUB_PCLK_PATH_50M);
+
+ mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+ CLKDIV_5BITS_SHF(5U, 0));
+ mmio_write_32(DSUCRU_BASE + DSUCRU_CLKSEL_CON(4),
+ BITS_WITH_WMASK(PCLK_DSU_ROOT_SEL_GPLL,
+ PCLK_DSU_ROOT_SEL_MASK,
+ PCLK_DSU_ROOT_SEL_SHIFT));
+
+ sys_clk_info.cpul_table = rk3588_cpul_pvtpll_table;
+ sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3588_cpul_pvtpll_table);
+ sys_clk_info.cpub01_table = rk3588_cpub0_pvtpll_table;
+ sys_clk_info.cpub01_rate_count = ARRAY_SIZE(rk3588_cpub0_pvtpll_table);
+ sys_clk_info.cpub23_table = rk3588_cpub1_pvtpll_table;
+ sys_clk_info.cpub23_rate_count = ARRAY_SIZE(rk3588_cpub1_pvtpll_table);
+ memcpy(sys_clk_info.cpub23_table, sys_clk_info.cpub01_table,
+ sys_clk_info.cpub01_rate_count * sizeof(*sys_clk_info.cpub01_table));
+ sys_clk_info.gpu_table = rk3588_gpu_pvtpll_table;
+ sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3588_gpu_pvtpll_table);
+ sys_clk_info.npu_table = rk3588_npu_pvtpll_table;
+ sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3588_npu_pvtpll_table);
+}
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
new file mode 100644
index 0000000..66fddaa
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_clk.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPUL 0
+#define SCMI_CLK_DSU 1
+#define SCMI_CLK_CPUB01 2
+#define SCMI_CLK_CPUB23 3
+#define SCMI_CLK_DDR 4
+#define SCMI_CLK_GPU 5
+#define SCMI_CLK_NPU 6
+#define SCMI_CLK_SBUS 7
+#define SCMI_PCLK_SBUS 8
+#define SCMI_CCLK_SD 9
+#define SCMI_DCLK_SD 10
+#define SCMI_ACLK_SECURE_NS 11
+#define SCMI_HCLK_SECURE_NS 12
+#define SCMI_TCLK_WDT 13
+#define SCMI_KEYLADDER_CORE 14
+#define SCMI_KEYLADDER_RNG 15
+#define SCMI_ACLK_SECURE_S 16
+#define SCMI_HCLK_SECURE_S 17
+#define SCMI_PCLK_SECURE_S 18
+#define SCMI_CRYPTO_RNG 19
+#define SCMI_CRYPTO_CORE 20
+#define SCMI_CRYPTO_PKA 21
+#define SCMI_SPLL 22
+#define SCMI_HCLK_SD 23
+#define SCMI_CRYPTO_RNG_S 24
+#define SCMI_CRYPTO_CORE_S 25
+#define SCMI_CRYPTO_PKA_S 26
+#define SCMI_A_CRYPTO_S 27
+#define SCMI_H_CRYPTO_S 28
+#define SCMI_P_CRYPTO_S 29
+#define SCMI_A_KEYLADDER_S 30
+#define SCMI_H_KEYLADDER_S 31
+#define SCMI_P_KEYLADDER_S 32
+#define SCMI_TRNG_S 33
+#define SCMI_H_TRNG_S 34
+#define SCMI_P_OTPC_S 35
+#define SCMI_OTPC_S 36
+#define SCMI_OTP_PHY 37
+#define SCMI_OTPC_AUTO_RD 38
+#define SCMI_OTPC_ARB 39
+
+/******** DSUCRU **************************************/
+#define DSUCRU_CLKSEL_CON(n) (0x0300 + (n) * 4)
+
+/********Name=DSUCRU_CLKSEL_CON04,Offset=0x310********/
+#define PCLK_DSU_ROOT_SEL_SHIFT 5
+#define PCLK_DSU_ROOT_SEL_MASK 0x3
+#define PCLK_DSU_ROOT_SEL_GPLL 0x3
+
+/********Name=SECURE_SOFTRST_CON00,Offset=0xA00********/
+#define SRST_A_SECURE_NS_BIU 10
+#define SRST_H_SECURE_NS_BIU 11
+#define SRST_A_SECURE_S_BIU 12
+#define SRST_H_SECURE_S_BIU 13
+#define SRST_P_SECURE_S_BIU 14
+#define SRST_CRYPTO_CORE 15
+/********Name=SECURE_SOFTRST_CON01,Offset=0xA04********/
+#define SRST_CRYPTO_PKA 16
+#define SRST_CRYPTO_RNG 17
+#define SRST_A_CRYPTO 18
+#define SRST_H_CRYPTO 19
+#define SRST_KEYLADDER_CORE 25
+#define SRST_KEYLADDER_RNG 26
+#define SRST_A_KEYLADDER 27
+#define SRST_H_KEYLADDER 28
+#define SRST_P_OTPC_S 29
+#define SRST_OTPC_S 30
+#define SRST_WDT_S 31
+/********Name=SECURE_SOFTRST_CON02,Offset=0xA08********/
+#define SRST_T_WDT_S 32
+#define SRST_H_BOOTROM 33
+#define SRST_A_DCF 34
+#define SRST_P_DCF 35
+#define SRST_H_BOOTROM_NS 37
+#define SRST_P_KEYLADDER 46
+#define SRST_H_TRNG_S 47
+/********Name=SECURE_SOFTRST_CON03,Offset=0xA0C********/
+#define SRST_H_TRNG_NS 48
+#define SRST_D_SDMMC_BUFFER 49
+#define SRST_H_SDMMC 50
+#define SRST_H_SDMMC_BUFFER 51
+#define SRST_SDMMC 52
+#define SRST_P_TRNG_CHK 53
+#define SRST_TRNG_S 54
+
+#define SRST_INVALID 55
+
+void pvtplls_suspend(void);
+void pvtplls_resume(void);
+
+void rockchip_clock_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
new file mode 100644
index 0000000..50b99e7
--- /dev/null
+++ b/plat/rockchip/rk3588/drivers/scmi/rk3588_rstd.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include "rk3588_clk.h"
+#include <scmi_rstd.h>
+#include <soc.h>
+
+#define DEFAULT_RESET_DOM_ATTRIBUTE 0
+
+#define RK3588_SCMI_RESET(_id, _name, _attribute, _ops) \
+{ \
+ .id = _id, \
+ .name = _name, \
+ .attribute = _attribute, \
+ .rstd_ops = _ops, \
+}
+
+static int rk3588_reset_explicit(rk_scmi_rstd_t *reset_domain,
+ bool assert_not_deassert)
+{
+ int bank = reset_domain->id / 16;
+ int offset = reset_domain->id % 16;
+
+ mmio_write_32(SCRU_BASE + CRU_SOFTRST_CON(bank),
+ BITS_WITH_WMASK(assert_not_deassert, 0x1U, offset));
+ return SCMI_SUCCESS;
+}
+
+static struct rk_scmi_rstd_ops rk3588_reset_domain_ops = {
+ .reset_explicit = rk3588_reset_explicit,
+};
+
+static rk_scmi_rstd_t rk3588_reset_domain_table[] = {
+ RK3588_SCMI_RESET(SRST_CRYPTO_CORE, "scmi_sr_cy_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_CRYPTO_PKA, "scmi_sr_cy_pka", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_CRYPTO_RNG, "scmi_sr_cy_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_A_CRYPTO, "scmi_sr_a_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_CRYPTO, "scmi_sr_h_cy", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_KEYLADDER_CORE, "scmi_sr_k_core", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_KEYLADDER_RNG, "scmi_sr_k_rng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_P_OTPC_S, "scmi_sr_p_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_OTPC_S, "scmi_sr_otp", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_WDT_S, "scmi_sr_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_T_WDT_S, "scmi_sr_t_wdt", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_BOOTROM, "scmi_sr_h_boot", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_P_KEYLADDER, "scmi_sr_p_ky", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_TRNG_S, "scmi_sr_h_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_TRNG_NS, "scmi_sr_t_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_D_SDMMC_BUFFER, "scmi_sr_d_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_SDMMC, "scmi_sr_h_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_H_SDMMC_BUFFER, "scmi_sr_h_sd_b", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_SDMMC, "scmi_sr_sd", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_P_TRNG_CHK, "scmi_sr_p_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_TRNG_S, "scmi_sr_trng", DEFAULT_RESET_DOM_ATTRIBUTE, &rk3588_reset_domain_ops),
+ RK3588_SCMI_RESET(SRST_INVALID, "scmi_sr_invalid", DEFAULT_RESET_DOM_ATTRIBUTE, NULL),
+};
+
+static rk_scmi_rstd_t *
+rockchip_get_reset_domain_table(int id)
+{
+ rk_scmi_rstd_t *reset = rk3588_reset_domain_table;
+ int i = 0, cnt = ARRAY_SIZE(rk3588_reset_domain_table);
+
+ for (i = 0; i < cnt; i++) {
+ if (reset->id == id)
+ return &rk3588_reset_domain_table[i];
+ reset++;
+ }
+
+ return &rk3588_reset_domain_table[cnt - 1];
+}
+
+rk_scmi_rstd_t *rockchip_scmi_get_rstd(unsigned int agent_id,
+ unsigned int scmi_id)
+
+{
+ return rockchip_get_reset_domain_table(scmi_id);
+}
+
+size_t rockchip_scmi_rstd_count(unsigned int agent_id)
+{
+ return SRST_TRNG_S;
+}
+
diff --git a/plat/rockchip/rk3588/drivers/soc/soc.c b/plat/rockchip/rk3588/drivers/soc/soc.c
index a276859..6db81ee 100644
--- a/plat/rockchip/rk3588/drivers/soc/soc.c
+++ b/plat/rockchip/rk3588/drivers/soc/soc.c
@@ -19,6 +19,7 @@
#include <pmu.h>
#include <plat_private.h>
+#include <rk3588_clk.h>
#include <secure.h>
#include <soc.h>
@@ -89,8 +90,10 @@
void plat_rockchip_soc_init(void)
{
+ rockchip_clock_init();
secure_timer_init();
timer_hp_init();
system_reset_init();
sgrf_init();
+ rockchip_init_scmi_server();
}
diff --git a/plat/rockchip/rk3588/plat_sip_calls.c b/plat/rockchip/rk3588/plat_sip_calls.c
index 57f5de5..496e8d7 100644
--- a/plat/rockchip/rk3588/plat_sip_calls.c
+++ b/plat/rockchip/rk3588/plat_sip_calls.c
@@ -6,6 +6,7 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
#include <plat_sip_calls.h>
#include <rockchip_sip_svc.h>
@@ -20,6 +21,10 @@
u_register_t flags)
{
switch (smc_fid) {
+ case RK_SIP_SCMI_AGENT0:
+ scmi_smt_fastcall_smc_entry(0);
+ SMC_RET1(handle, 0);
+
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/rockchip/rk3588/platform.mk b/plat/rockchip/rk3588/platform.mk
index f987815..07eda40 100644
--- a/plat/rockchip/rk3588/platform.mk
+++ b/plat/rockchip/rk3588/platform.mk
@@ -21,13 +21,16 @@
PLAT_INCLUDES := -Iinclude/plat/common \
-Idrivers/arm/gic/v3/ \
+ -Idrivers/scmi-msg/ \
-I${RK_PLAT_COMMON}/ \
-I${RK_PLAT_COMMON}/drivers/pmu/ \
-I${RK_PLAT_COMMON}/drivers/parameter/ \
-I${RK_PLAT_COMMON}/include/ \
-I${RK_PLAT_COMMON}/pmusram/ \
+ -I${RK_PLAT_COMMON}/scmi/ \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/scmi/ \
-I${RK_PLAT_SOC}/drivers/secure/ \
-I${RK_PLAT_SOC}/drivers/soc/ \
-I${RK_PLAT_SOC}/include/
@@ -50,6 +53,11 @@
drivers/ti/uart/aarch64/16550_console.S \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
+ drivers/scmi-msg/base.c \
+ drivers/scmi-msg/clock.c \
+ drivers/scmi-msg/entry.c \
+ drivers/scmi-msg/reset_domain.c \
+ drivers/scmi-msg/smt.c \
lib/cpus/aarch64/cortex_a55.S \
lib/cpus/aarch64/cortex_a76.S \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
@@ -61,11 +69,16 @@
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S \
${RK_PLAT_COMMON}/rockchip_sip_svc.c \
+ ${RK_PLAT_COMMON}/scmi/scmi.c \
+ ${RK_PLAT_COMMON}/scmi/scmi_clock.c \
+ ${RK_PLAT_COMMON}/scmi/scmi_rstd.c \
${RK_PLAT_SOC}/plat_sip_calls.c \
${RK_PLAT_SOC}/drivers/secure/secure.c \
${RK_PLAT_SOC}/drivers/soc/soc.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
- ${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c
+ ${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c \
+ ${RK_PLAT_SOC}/drivers/scmi/rk3588_clk.c \
+ ${RK_PLAT_SOC}/drivers/scmi/rk3588_rstd.c
CTX_INCLUDE_AARCH32_REGS := 0
ENABLE_PLAT_COMPAT := 0
diff --git a/plat/rockchip/rk3588/rk3588_def.h b/plat/rockchip/rk3588/rk3588_def.h
index 75b685a..412495a 100644
--- a/plat/rockchip/rk3588/rk3588_def.h
+++ b/plat/rockchip/rk3588/rk3588_def.h
@@ -162,6 +162,9 @@
#define SCMI_SHARE_MEM_BASE (SHARE_MEM_BASE + SHARE_MEM_SIZE)
#define SCMI_SHARE_MEM_SIZE SIZE_K(4)
+#define SMT_BUFFER_BASE SCMI_SHARE_MEM_BASE
+#define SMT_BUFFER0_BASE SMT_BUFFER_BASE
+
/**************************************************************************
* UART related constants
**************************************************************************/