feat(rk3576): support rk3576
rk3576 is an Octa-core soc with Cortex-a53/a72 inside.
This patch supports the following functions:
1. basic platform setup
2. power up/off cpus
3. suspend/resume cpus
4. suspend/resume system
5. reset system
6. power off system
Change-Id: I67a019822bd4af13e4a3cdd09cf06202f4922cc4
Signed-off-by: XiaoDong Huang <derrick.huang@rock-chips.com>
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 384cd73..016bed7 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -11,6 +11,7 @@
- rk3368: Octa-Core Cortex-A53
- rk3399: Hexa-Core Cortex-A53/A72
- rk3566/rk3568: Quad-Core Cortex-A55
+- rk3576: Octa-Core Cortex-A53/A72
- rk3588: Octa-Core Cortex-A55/A76
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index df51d89..e88855a 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,9 +1,10 @@
/*
- * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <string.h>
#include <platform_def.h>
@@ -58,7 +59,18 @@
unsigned int plat_get_syscnt_freq2(void)
{
+#ifdef SYS_COUNTER_FREQ_IN_TICKS
return SYS_COUNTER_FREQ_IN_TICKS;
+#else
+ static int sys_counter_freq_in_hz;
+
+ if (sys_counter_freq_in_hz == 0)
+ sys_counter_freq_in_hz = read_cntfrq_el0();
+
+ assert(sys_counter_freq_in_hz != 0);
+
+ return sys_counter_freq_in_hz;
+#endif
}
void plat_cci_init(void)
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 1e13a9e..6388c47 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2025, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,6 +28,9 @@
extern uint32_t __bl31_sram_data_start, __bl31_sram_data_end;
extern uint32_t __bl31_sram_stack_start, __bl31_sram_stack_end;
extern uint32_t __bl31_sram_text_real_end, __bl31_sram_data_real_end;
+extern uint32_t __bl31_pmusram_text_start, __bl31_pmusram_text_end;
+extern uint32_t __bl31_pmusram_data_start, __bl31_pmusram_data_end;
+extern uint32_t __bl31_pmusram_text_real_end, __bl31_pmusram_data_real_end;
extern uint32_t __sram_incbin_start, __sram_incbin_end;
extern uint32_t __sram_incbin_real_end;
diff --git a/plat/rockchip/common/scmi/rockchip_common_clock.c b/plat/rockchip/common/scmi/rockchip_common_clock.c
new file mode 100644
index 0000000..d77bde3
--- /dev/null
+++ b/plat/rockchip/common/scmi/rockchip_common_clock.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include <scmi_clock.h>
+
+#define MUX_ADDR_INFO 0
+#define MUX_SHIFT_INFO 1
+#define MUX_WIDTH_INFO 2
+#define DIV_ADDR_INFO 3
+#define DIV_SHIFT_INFO 4
+#define DIV_WIDTH_INFO 5
+#define GATE_ADDR_INFO 6
+#define GATE_SHIFT_INFO 7
+
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
+#define abs(x) ({ \
+ long ret; \
+ if (sizeof(x) == sizeof(long)) { \
+ long __x = (x); \
+ ret = (__x < 0) ? -__x : __x; \
+ } else { \
+ int __x = (x); \
+ ret = (__x < 0) ? -__x : __x; \
+ } \
+ ret; \
+ })
+
+static unsigned long clk_scmi_common_get_parent_rate(rk_scmi_clock_t *clock,
+ int id)
+{
+ rk_scmi_clock_t *p_clock;
+
+ if (clock->is_dynamic_prate != 0) {
+ p_clock = rockchip_scmi_get_clock(0, clock->parent_table[id]);
+ if (p_clock == NULL)
+ return 0;
+ if ((p_clock->clk_ops != NULL) && (p_clock->clk_ops->get_rate != NULL))
+ return p_clock->clk_ops->get_rate(p_clock);
+ else
+ return 0;
+ } else {
+ return clock->parent_table[id];
+ }
+}
+
+unsigned long clk_scmi_common_get_rate(rk_scmi_clock_t *clock)
+{
+ unsigned long parent_rate, sel, div;
+
+ sel = mmio_read_32(clock->info[MUX_ADDR_INFO]) >>
+ clock->info[MUX_SHIFT_INFO];
+ sel = sel & (BIT(clock->info[MUX_WIDTH_INFO]) - 1);
+ div = mmio_read_32(clock->info[DIV_ADDR_INFO]) >>
+ clock->info[DIV_SHIFT_INFO];
+ div = div & (BIT(clock->info[DIV_WIDTH_INFO]) - 1);
+ parent_rate = clk_scmi_common_get_parent_rate(clock, sel);
+
+ return parent_rate / (div + 1);
+}
+
+int clk_scmi_common_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ unsigned long parent_rate, now, best_rate = 0;
+ int i = 0, sel_mask, div_mask, best_sel = 0, best_div = 0, div;
+
+ if ((rate == 0) ||
+ (clock->info[MUX_WIDTH_INFO] == 0 && clock->info[DIV_WIDTH_INFO] == 0))
+ return SCMI_INVALID_PARAMETERS;
+
+ sel_mask = BIT(clock->info[MUX_WIDTH_INFO]) - 1;
+ div_mask = BIT(clock->info[DIV_WIDTH_INFO]) - 1;
+ if (clock->info[MUX_WIDTH_INFO] == 0) {
+ parent_rate = clk_scmi_common_get_parent_rate(clock, 0);
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div > div_mask + 1)
+ div = div_mask + 1;
+ mmio_write_32(clock->info[DIV_ADDR_INFO],
+ BITS_WITH_WMASK(div - 1, div_mask,
+ clock->info[DIV_SHIFT_INFO]));
+ } else if (clock->info[DIV_WIDTH_INFO] == 0) {
+ for (i = 0; i <= sel_mask; i++) {
+ parent_rate = clk_scmi_common_get_parent_rate(clock, i);
+ now = parent_rate;
+ if (abs(rate - now) < abs(rate - best_rate)) {
+ best_rate = now;
+ best_sel = i;
+ }
+ }
+ if (best_rate == 0)
+ best_sel = 0;
+ mmio_write_32(clock->info[MUX_ADDR_INFO],
+ BITS_WITH_WMASK(best_sel, sel_mask,
+ clock->info[MUX_SHIFT_INFO]));
+ } else {
+ for (i = 0; i <= sel_mask; i++) {
+ parent_rate = clk_scmi_common_get_parent_rate(clock, i);
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div > div_mask + 1)
+ div = div_mask + 1;
+ now = parent_rate / div;
+ if (abs(rate - now) < abs(rate - best_rate)) {
+ best_rate = now;
+ best_div = div;
+ best_sel = i;
+ }
+ }
+ if (best_rate == 0) {
+ best_div = div_mask + 1;
+ best_sel = 0;
+ }
+
+ mmio_write_32(clock->info[DIV_ADDR_INFO],
+ BITS_WITH_WMASK(div_mask, div_mask,
+ clock->info[DIV_SHIFT_INFO]));
+ mmio_write_32(clock->info[MUX_ADDR_INFO],
+ BITS_WITH_WMASK(best_sel, sel_mask,
+ clock->info[MUX_SHIFT_INFO]));
+ mmio_write_32(clock->info[DIV_ADDR_INFO],
+ BITS_WITH_WMASK(best_div - 1, div_mask,
+ clock->info[DIV_SHIFT_INFO]));
+ }
+ return 0;
+}
+
+int clk_scmi_common_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ mmio_write_32(clock->info[GATE_ADDR_INFO],
+ BITS_WITH_WMASK(!status, 0x1U,
+ clock->info[GATE_SHIFT_INFO]));
+
+ return 0;
+}
diff --git a/plat/rockchip/common/scmi/scmi_clock.h b/plat/rockchip/common/scmi/scmi_clock.h
index e640fe1..4b94adf 100644
--- a/plat/rockchip/common/scmi/scmi_clock.h
+++ b/plat/rockchip/common/scmi/scmi_clock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
+ * Copyright (c) 2025, Rockchip, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,11 +23,14 @@
char name[SCMI_CLOCK_NAME_LENGTH_MAX];
uint8_t enable;
int8_t is_security;
+ int8_t is_dynamic_prate;
uint32_t id;
uint32_t rate_cnt;
uint64_t cur_rate;
uint32_t enable_count;
const struct rk_clk_ops *clk_ops;
+ const unsigned long *parent_table;
+ const uint32_t *info;
unsigned long *rate_table;
} rk_scmi_clock_t;
@@ -47,4 +50,7 @@
rk_scmi_clock_t *rockchip_scmi_get_clock(uint32_t agent_id,
uint32_t scmi_id);
+unsigned long clk_scmi_common_get_rate(rk_scmi_clock_t *clock);
+int clk_scmi_common_set_rate(rk_scmi_clock_t *clock, unsigned long rate);
+int clk_scmi_common_set_status(rk_scmi_clock_t *clock, bool status);
#endif /* RK_SCMI_CLOCK_H */
diff --git a/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h b/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h
new file mode 100644
index 0000000..d8c231c
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_ROCKCHIP_DMC_RK3576_H__
+#define __PLAT_ROCKCHIP_DMC_RK3576_H__
+
+#define MAX_CH_NUM (2)
+#define CTL_PORT_NUM (5)
+
+/* DDR_GRF Register */
+#define GRF_CH_CON(ch, n) ((((ch) % 2) * 0x100) + ((n) * 4))
+#define DDR_GRF_CH_STATUS16(ch) (0x220 + ((ch) * 0x100))
+#define GRF_DDRPHY_CON(n) (0x530 + ((n) * 4))
+#define GRF_DDRPHY_CON0(ch) (0x530 + (((ch) % 2) * 0x4))
+#define DDR_GRF_COMMON_CON(n) (0x540 + ((n) * 4))
+
+/* PMUGRF Register */
+#define PMUGRF_OS_REG(n) (0x200 + ((n) * 4))
+
+struct low_power_st {
+ uint32_t pwrctl;
+ uint32_t clkgatectl;
+ uint32_t dfi_lp_mode_apb;
+ uint32_t grf_ddr_con0;
+ uint32_t grf_ddr_con1;
+ uint32_t grf_ddr_con6;
+ uint32_t grf_ddr_con7;
+ uint32_t grf_ddr_con9;
+ uint32_t grf_ddrphy_con0;
+ uint32_t hwlp_0;
+ uint32_t hwlp_c;
+ uint32_t pcl_pd;
+};
+
+struct rk3576_dmc_config {
+ struct low_power_st low_power[MAX_CH_NUM];
+};
+
+void dmc_save(void);
+void dmc_restore(void);
+
+#endif /* __PLAT_ROCKCHIP_DMC_RK3576_H__ */
diff --git a/plat/rockchip/rk3576/drivers/dmc/suspend.c b/plat/rockchip/rk3576/drivers/dmc/suspend.c
new file mode 100644
index 0000000..389cc1b
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/dmc/suspend.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+
+#include <dmc_rk3576.h>
+#include <rk3576_def.h>
+#include <soc.h>
+
+struct rk3576_dmc_config dmc_config;
+
+/* DDR_PHY */
+#define LP_CON0 0x0018
+#define DFI_LP_CON0 0x0e04
+/* DDR_CTL */
+#define DDRCTL_STAT 0x10014
+#define DDRCTL_PWRCTL 0x10180
+#define DDRCTL_CLKGATECTL 0x1018c
+
+/* LP_CON0 */
+#define DS_IO_PD BIT(14)
+#define SCHD_HW_CLOCK_GATING_DISABLE BIT(13)
+#define PCL_PD BIT(12)
+#define DQS_ENABLE BIT(10)
+#define WCK_ENABLE BIT(9)
+#define CTRL_DQS_DRV_OFF BIT(8)
+#define CTRL_SCHEDULER_EN BIT(6)
+
+/* DFI_LP_CON0 0x0e04 */
+#define DFI_LP_MODE_APB BIT(31)
+
+/* DDRCTL_STAT 0x10014 */
+#define CTL_SELFREF_STATE_SHIFT (12)
+#define CTL_SELFREF_STATE_MASK (0x7 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_NOT_IN_SELF_REFRESH (0x0 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_1 (0x1 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_POWER_DOWN (0x2 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_2 (0x3 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELF_REFRESH_DEEP_SLEEP (0x4 << CTL_SELFREF_STATE_SHIFT)
+#define CTL_SELFREF_TYPE_SHIFT (4)
+#define CTL_SELFREF_TYPE_MASK (0x3 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_NOT_BY_PHY (0x1 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_NOT_BY_AUTO (0x2 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_SELFREF_BY_AUTO (0x3 << CTL_SELFREF_TYPE_SHIFT)
+#define CTL_OPERATING_MODE_MASK (0x7)
+#define CTL_OPERATING_MODE_INIT (0x0)
+#define CTL_OPERATING_MODE_NORMAL (0x1)
+#define CTL_OPERATING_MODE_PD (0x2)
+#define CTL_OPERATING_MODE_SR_SRPD (0x3)
+
+/* DDRCTL_PWRCTL 0x10180 */
+#define CTL_DSM_EN BIT(18)
+#define CTL_STAY_IN_SELFREF BIT(15)
+#define CTL_SELFREF_SW BIT(11)
+#define CTL_EN_DFI_DRAM_CLK_DISABLE BIT(9)
+#define CTL_POWERDOWN_EN_MASK (0xf)
+#define CTL_POWERDOWN_EN_SHIFT (4)
+#define CTL_SELFREF_EN_MASK (0xf)
+#define CTL_SELFREF_EN_SHIFT (0)
+
+#define SYS_REG_DEC_CHINFO(n, ch) (((n) >> (28 + (ch))) & 0x1)
+#define SYS_REG_DEC_CHINFO_V3(reg2, ch) SYS_REG_DEC_CHINFO(reg2, ch)
+
+#define SYS_REG_DEC_NUM_CH(n) (1 + (((n) >> 12) & 0x1))
+#define SYS_REG_DEC_NUM_CH_V3(reg2) SYS_REG_DEC_NUM_CH(reg2)
+
+static void exit_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
+{
+ /* LP_CON0: [12]pcl_pd */
+ configs->low_power[ch].pcl_pd = mmio_read_32(DDRPHY_BASE_CH(0) + LP_CON0) & PCL_PD;
+ mmio_clrbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
+
+ /* Disable low power activities */
+ configs->low_power[ch].pwrctl = mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL);
+ mmio_clrbits_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL,
+ CTL_DSM_EN | (CTL_POWERDOWN_EN_MASK << CTL_POWERDOWN_EN_SHIFT) |
+ (CTL_SELFREF_EN_MASK << CTL_SELFREF_EN_SHIFT));
+ while ((mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_STAT) & CTL_OPERATING_MODE_MASK) !=
+ CTL_OPERATING_MODE_NORMAL)
+ continue;
+
+ /* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
+ configs->low_power[ch].grf_ddr_con6 =
+ mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6)) & 0xff7f;
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6), (0x1ul << (15 + 16)));
+
+ /* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
+ configs->low_power[ch].grf_ddr_con0 =
+ mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0)) & 0x1f00;
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0), 0x1f000000);
+
+ /*
+ * DDR_GRF_CHA_CON1:
+ * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
+ * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
+ */
+ configs->low_power[ch].grf_ddr_con1 =
+ mmio_read_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1)) & 0x90e6;
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1), 0x90e60000);
+
+ configs->low_power[ch].hwlp_0 = mmio_read_32(HWLP_BASE_CH(ch) + 0x0);
+ mmio_write_32(HWLP_BASE_CH(ch) + 0x0, 0x0);
+ configs->low_power[ch].hwlp_c = mmio_read_32(HWLP_BASE_CH(ch) + 0xc);
+ mmio_write_32(HWLP_BASE_CH(ch) + 0xc, 0x0);
+
+ /* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
+ configs->low_power[ch].grf_ddrphy_con0 =
+ mmio_read_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch)) & BIT(14);
+ mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch), BIT(14 + 16));
+
+ /* CLKGATECTL: [5:0]bsm_clk_on */
+ configs->low_power[ch].clkgatectl =
+ mmio_read_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL) & 0x3f;
+ /* DFI_LP_CON0: [31]dfi_lp_mode_apb */
+ configs->low_power[ch].dfi_lp_mode_apb =
+ (mmio_read_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0) >> 31) & 0x1;
+}
+
+static void resume_low_power(uint32_t ch, struct rk3576_dmc_config *configs)
+{
+ /* DFI_LP_CON0: [31]dfi_lp_mode_apb */
+ if (configs->low_power[ch].dfi_lp_mode_apb != 0)
+ mmio_setbits_32(DDRPHY_BASE_CH(ch) + DFI_LP_CON0, DFI_LP_MODE_APB);
+
+ /* CLKGATECTL: [5:0]bsm_clk_on */
+ mmio_clrsetbits_32(UMCTL_BASE_CH(ch) + DDRCTL_CLKGATECTL,
+ 0x3f, configs->low_power[ch].clkgatectl & 0x3f);
+
+ /* DDR_GRF_CHA_CON6: [6:0]rd_lat_delay, [14:8]wr_lat_delay, [15]cmd_dly_eq0_en */
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 6),
+ (0xff7ful << 16) | configs->low_power[ch].grf_ddr_con6);
+
+ mmio_write_32(HWLP_BASE_CH(ch) + 0xc, configs->low_power[ch].hwlp_c);
+ mmio_write_32(HWLP_BASE_CH(ch) + 0x0, configs->low_power[ch].hwlp_0);
+
+ /* DDR_GRF_CHA_CON0: [12:8]ddrctl_axi_cg_en */
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 0),
+ (0x1f00ul << 16) | configs->low_power[ch].grf_ddr_con0);
+
+ /*
+ * DDR_GRF_CHA_CON1:
+ * [15]ddrctl_apb_pclk_cg_en, [12]ddrmon_pclk_cg_en, [7]dfi_scramble_cg_en,
+ * [6]ddrctl_mem_cg_en, [5]bsm_clk_cg_en, [2]ddrctl_core_cg_en, [1]ddrctl_apb_cg_en
+ */
+ mmio_write_32(DDR_GRF_BASE + GRF_CH_CON(ch, 1),
+ (0x90e6ul << 16) | configs->low_power[ch].grf_ddr_con1);
+
+ /* DDR_GRF_CHA_PHY_CON0: [14]ddrphy_pclk_cg_en */
+ mmio_write_32(DDR_GRF_BASE + GRF_DDRPHY_CON0(ch),
+ BIT(14 + 16) | configs->low_power[ch].grf_ddrphy_con0);
+
+ /* reset low power activities */
+ mmio_write_32(UMCTL_BASE_CH(ch) + DDRCTL_PWRCTL, configs->low_power[ch].pwrctl);
+
+ /* LP_CON0: [12]pcl_pd */
+ if (configs->low_power[ch].pcl_pd != 0)
+ mmio_setbits_32(DDRPHY_BASE_CH(ch) + LP_CON0, PCL_PD);
+}
+
+void dmc_save(void)
+{
+ uint32_t i, channel_num;
+
+ channel_num =
+ SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
+
+ for (i = 0; i < channel_num; i++)
+ exit_low_power(i, &dmc_config);
+}
+
+void dmc_restore(void)
+{
+ uint32_t i, channel_num;
+
+ channel_num = SYS_REG_DEC_NUM_CH_V3(mmio_read_32(PMU1_GRF_BASE + PMUGRF_OS_REG(2)));
+
+ for (i = 0; i < channel_num; i++)
+ resume_low_power(i, &dmc_config);
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..717b55c
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+
+.globl clst_warmboot_data
+
+.macro func_rockchip_clst_warmboot
+.endm
+
+.macro rockchip_clst_warmboot_data
+clst_warmboot_data:
+ .rept PLATFORM_CLUSTER_COUNT
+ .word 0
+ .endr
+.endm
diff --git a/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c
new file mode 100644
index 0000000..de5fa75
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <rk3576_clk.h>
+#include <soc.h>
+
+#define WMSK_VAL 0xffff0000
+
+static struct reg_region qos_reg_rgns[] = {
+ [qos_decom] = REG_REGION(0x08, 0x18, 4, 0x27f00000, 0),
+ [qos_dmac0] = REG_REGION(0x08, 0x18, 4, 0x27f00080, 0),
+ [qos_dmac1] = REG_REGION(0x08, 0x18, 4, 0x27f00100, 0),
+ [qos_dmac2] = REG_REGION(0x08, 0x18, 4, 0x27f00180, 0),
+ [qos_bus_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f00200, 0),
+ [qos_can0] = REG_REGION(0x08, 0x18, 4, 0x27f00280, 0),
+ [qos_can1] = REG_REGION(0x08, 0x18, 4, 0x27f00300, 0),
+ [qos_cci_m0] = REG_REGION(0x08, 0x18, 4, 0x27f01000, 0),
+ [qos_cci_m1] = REG_REGION(0x08, 0x18, 4, 0x27f18880, 0),
+ [qos_cci_m2] = REG_REGION(0x08, 0x18, 4, 0x27f18900, 0),
+ [qos_dap_lite] = REG_REGION(0x08, 0x18, 4, 0x27f01080, 0),
+ [qos_hdcp1] = REG_REGION(0x08, 0x18, 4, 0x27f02000, 0),
+ [qos_ddr_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f03000, 0),
+ [qos_fspi1] = REG_REGION(0x08, 0x18, 4, 0x27f04000, 0),
+ [qos_gmac0] = REG_REGION(0x08, 0x18, 4, 0x27f04080, 0),
+ [qos_gmac1] = REG_REGION(0x08, 0x18, 4, 0x27f04100, 0),
+ [qos_sdio] = REG_REGION(0x08, 0x18, 4, 0x27f04180, 0),
+ [qos_sdmmc] = REG_REGION(0x08, 0x18, 4, 0x27f04200, 0),
+ [qos_flexbus] = REG_REGION(0x08, 0x18, 4, 0x27f04280, 0),
+ [qos_gpu] = REG_REGION(0x08, 0x18, 4, 0x27f05000, 0),
+ [qos_vepu1] = REG_REGION(0x08, 0x18, 4, 0x27f06000, 0),
+ [qos_npu_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f08000, 0),
+ [qos_npu_nsp0] = REG_REGION(0x08, 0x18, 4, 0x27f08080, 0),
+ [qos_npu_nsp1] = REG_REGION(0x08, 0x18, 4, 0x27f08100, 0),
+ [qos_npu_m0] = REG_REGION(0x08, 0x18, 4, 0x27f20000, 0),
+ [qos_npu_m1] = REG_REGION(0x08, 0x18, 4, 0x27f21000, 0),
+ [qos_npu_m0ro] = REG_REGION(0x08, 0x18, 4, 0x27f22080, 0),
+ [qos_npu_m1ro] = REG_REGION(0x08, 0x18, 4, 0x27f22100, 0),
+ [qos_emmc] = REG_REGION(0x08, 0x18, 4, 0x27f09000, 0),
+ [qos_fspi0] = REG_REGION(0x08, 0x18, 4, 0x27f09080, 0),
+ [qos_mmu0] = REG_REGION(0x08, 0x18, 4, 0x27f0a000, 0),
+ [qos_mmu1] = REG_REGION(0x08, 0x18, 4, 0x27f0a080, 0),
+ [qos_pmu_mcu] = REG_REGION(0x08, 0x18, 4, 0x27f0b000, 0),
+ [qos_rkvdec] = REG_REGION(0x08, 0x18, 4, 0x27f0c000, 0),
+ [qos_crypto] = REG_REGION(0x08, 0x18, 4, 0x27f0d000, 0),
+ [qos_mmu2] = REG_REGION(0x08, 0x18, 4, 0x27f0e000, 0),
+ [qos_ufshc] = REG_REGION(0x08, 0x18, 4, 0x27f0e080, 0),
+ [qos_vepu0] = REG_REGION(0x08, 0x18, 4, 0x27f0f000, 0),
+ [qos_isp_mro] = REG_REGION(0x08, 0x18, 4, 0x27f10000, 0),
+ [qos_isp_mwo] = REG_REGION(0x08, 0x18, 4, 0x27f10080, 0),
+ [qos_vicap_m0] = REG_REGION(0x08, 0x18, 4, 0x27f10100, 0),
+ [qos_vpss_mro] = REG_REGION(0x08, 0x18, 4, 0x27f10180, 0),
+ [qos_vpss_mwo] = REG_REGION(0x08, 0x18, 4, 0x27f10200, 0),
+ [qos_hdcp0] = REG_REGION(0x08, 0x18, 4, 0x27f11000, 0),
+ [qos_vop_m0] = REG_REGION(0x08, 0x18, 4, 0x27f12800, 0),
+ [qos_vop_m1ro] = REG_REGION(0x08, 0x18, 4, 0x27f12880, 0),
+ [qos_ebc] = REG_REGION(0x08, 0x18, 4, 0x27f13000, 0),
+ [qos_rga0] = REG_REGION(0x08, 0x18, 4, 0x27f13080, 0),
+ [qos_rga1] = REG_REGION(0x08, 0x18, 4, 0x27f13100, 0),
+ [qos_jpeg] = REG_REGION(0x08, 0x18, 4, 0x27f13180, 0),
+ [qos_vdpp] = REG_REGION(0x08, 0x18, 4, 0x27f13200, 0),
+ [qos_dma2ddr] = REG_REGION(0x08, 0x18, 4, 0x27f15880, 0),
+};
+
+static struct reg_region pd_bcore_reg_rgns[] = {
+ /* bcore cru */
+ /* REG_REGION(0x280, 0x280, 4, BIGCORE0CRU_BASE, WMSK_VAL), */
+ REG_REGION(0x300, 0x30c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0x800, 0x804, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xa00, 0xa0c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xcc0, 0xcc0, 4, BIGCORE_CRU_BASE, 0),
+ REG_REGION(0xf28, 0xf28, 8, BIGCORE_CRU_BASE, 0),
+ REG_REGION(0xf2c, 0xf2c, 8, BIGCORE_CRU_BASE, WMSK_VAL),
+
+ /* bcore_grf */
+ REG_REGION(0x34, 0x3c, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x44, 0x44, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_core_reg_rgns[] = {
+ /* cci cru */
+ REG_REGION(0x310, 0x310, 4, CCI_CRU_BASE, WMSK_VAL),
+ REG_REGION(0x804, 0x808, 4, CCI_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xa04, 0xa08, 4, CCI_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xc50, 0xc58, 4, CCI_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xd00, 0xd00, 8, CCI_CRU_BASE, 0),
+ REG_REGION(0xd04, 0xd04, 8, CCI_CRU_BASE, WMSK_VAL),
+ /* Restore lpll registers after clksel_* registers. Because lpll
+ * may be turned off during restoring, which cause cci_cru to lost clock.
+ */
+ REG_REGION(0x040, 0x044, 4, CCI_CRU_BASE, WMSK_VAL),
+ REG_REGION(0x048, 0x048, 4, CCI_CRU_BASE, 0),
+ REG_REGION(0x04c, 0x058, 4, CCI_CRU_BASE, WMSK_VAL),
+
+ /* lcore cru */
+ /* REG_REGION(0x280, 0x280, 4, BIGCORE1CRU_BASE, WMSK_VAL), */
+ REG_REGION(0x300, 0x30c, 4, LITTLE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0x800, 0x804, 4, LITTLE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xa00, 0xa0c, 4, LITTLE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xcc0, 0xcc0, 4, LITTLE_CRU_BASE, 0),
+ REG_REGION(0xf38, 0xf38, 8, LITTLE_CRU_BASE, 0),
+ REG_REGION(0xf3c, 0xf3c, 8, LITTLE_CRU_BASE, WMSK_VAL),
+
+ /* bcore cru */
+ /* REG_REGION(0x280, 0x280, 4, BIGCORE0CRU_BASE, WMSK_VAL), */
+ REG_REGION(0x300, 0x30c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0x800, 0x804, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xa00, 0xa0c, 4, BIGCORE_CRU_BASE, WMSK_VAL),
+ REG_REGION(0xcc0, 0xcc0, 4, BIGCORE_CRU_BASE, 0),
+ REG_REGION(0xf28, 0xf28, 8, BIGCORE_CRU_BASE, 0),
+ REG_REGION(0xf2c, 0xf2c, 8, BIGCORE_CRU_BASE, WMSK_VAL),
+
+ /* cci grf */
+ REG_REGION(0x00, 0x10, 4, CCI_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x54, 0x54, 4, CCI_GRF_BASE, WMSK_VAL),
+
+ /* lcore_grf */
+ REG_REGION(0x34, 0x3c, 4, LITCORE_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x44, 0x44, 4, LITCORE_GRF_BASE, WMSK_VAL),
+
+ /* bcore_grf */
+ REG_REGION(0x34, 0x3c, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x44, 0x44, 4, BIGCORE_GRF_BASE, WMSK_VAL),
+};
+
+static struct reg_region pd_php_reg_rgns[] = {
+ /* php_grf */
+ REG_REGION(0x004, 0x00c, 4, PHP_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x010, 0x018, 4, PHP_GRF_BASE, 0),
+ REG_REGION(0x01c, 0x020, 4, PHP_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x048, 0x048, 4, PHP_GRF_BASE, 0),
+};
+
+static struct reg_region pd_usb2phy_reg_rgns[] = {
+ /* usb */
+ REG_REGION(0x00, 0x14, 4, USB2PHY0_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x40, 0x40, 4, USB2PHY0_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x44, 0x50, 4, USB2PHY0_GRF_BASE, 0),
+ REG_REGION(0x00, 0x14, 4, USB2PHY1_GRF_BASE, WMSK_VAL),
+ REG_REGION(0x08, 0x08, 4, USBDPPHY_GRF_BASE, WMSK_VAL),
+};
+
+#define PLL_LOCKED_TIMEOUT 600000U
+
+static void pm_pll_wait_lock(uint32_t pll_base)
+{
+ int delay = PLL_LOCKED_TIMEOUT;
+
+ if ((mmio_read_32(pll_base + CRU_PLL_CON(1)) & CRU_PLLCON1_PWRDOWN) != 0)
+ return;
+
+ while (delay-- >= 0) {
+ if ((mmio_read_32(pll_base + CRU_PLL_CON(6)) & CRU_PLLCON6_LOCK_STATUS) != 0)
+ break;
+ udelay(1);
+ }
+
+ if (delay <= 0)
+ ERROR("Can't wait pll(0x%x) lock\n", pll_base);
+}
+
+void qos_save(void)
+{
+ uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+
+ if ((pmu_pd_st & BIT(pmu_pd_nvm)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_emmc], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_fspi0], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_sd_gmac)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_fspi1], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_gmac0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_gmac1], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_sdio], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_sdmmc], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_flexbus], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_php)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu1], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vop)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vop_m0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vop_m1ro], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vo1)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_hdcp1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vo0)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_hdcp0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_usb)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_mmu2], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_ufshc], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vi)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_isp_mro], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_isp_mwo], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vicap_m0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vpss_mro], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vpss_mwo], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vepu0)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vepu0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vepu1)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vepu1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vdec)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_rkvdec], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vpu)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_ebc], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_rga0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_rga1], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_jpeg], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_vdpp], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_nputop)) == 0) {
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_mcu], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_nsp0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_nsp1], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m0ro], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m1ro], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_npu0)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_npu1)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_npu_m1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_gpu)) == 0)
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_gpu], 1);
+}
+
+void qos_restore(void)
+{
+ uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+
+ if ((pmu_pd_st & BIT(pmu_pd_nvm)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_emmc], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_fspi0], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_sd_gmac)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_fspi1], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gmac0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gmac1], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_sdio], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_sdmmc], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_flexbus], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_php)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu1], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vop)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vop_m0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vop_m1ro], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vo1)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_hdcp1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vo0)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_hdcp0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_usb)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_mmu2], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_ufshc], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vi)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_isp_mro], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_isp_mwo], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vicap_m0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vpss_mro], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vpss_mwo], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_vepu0)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vepu0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vepu1)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vepu1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vdec)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rkvdec], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_vpu)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_ebc], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rga0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_rga1], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_jpeg], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_vdpp], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_nputop)) == 0) {
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_mcu], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_nsp0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_nsp1], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m0ro], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m1ro], 1);
+ }
+
+ if ((pmu_pd_st & BIT(pmu_pd_npu0)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m0], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_npu1)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_npu_m1], 1);
+
+ if ((pmu_pd_st & BIT(pmu_pd_gpu)) == 0)
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_gpu], 1);
+}
+
+void pd_usb2phy_save(void)
+{
+ rockchip_reg_rgn_save(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
+
+void pd_usb2phy_restore(void)
+{
+ rockchip_reg_rgn_restore(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
+
+static uint32_t b_cru_mode, l_cru_mode;
+static uint32_t bcore_need_restore;
+
+void pd_bcore_save(void)
+{
+ pvtplls_cpub_suspend();
+
+ b_cru_mode = mmio_read_32(BIGCORE_CRU_BASE + 0x280);
+ rockchip_reg_rgn_save(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+
+ bcore_need_restore = 1;
+}
+
+void pd_bcore_restore(void)
+{
+ if (bcore_need_restore == 0)
+ return;
+
+ /* slow mode */
+ mmio_write_32(BIGCORE_CRU_BASE + 0x280, 0x00030000);
+
+ rockchip_reg_rgn_restore(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+
+ /* trigger lcore/bcore mem_cfg */
+ mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+ udelay(1);
+ mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+
+ /* restore mode */
+ mmio_write_32(BIGCORE_CRU_BASE + 0x280, WITH_16BITS_WMSK(b_cru_mode));
+
+ pvtplls_cpub_resume();
+
+ bcore_need_restore = 0;
+}
+
+void pd_core_save(void)
+{
+ pvtplls_suspend();
+
+ b_cru_mode = mmio_read_32(BIGCORE_CRU_BASE + 0x280);
+ l_cru_mode = mmio_read_32(LITTLE_CRU_BASE + 0x280);
+
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m0], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m1], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_cci_m2], 1);
+ rockchip_reg_rgn_save(&qos_reg_rgns[qos_dap_lite], 1);
+
+ rockchip_reg_rgn_save(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+}
+
+void pd_core_restore(void)
+{
+ /* slow mode */
+ mmio_write_32(BIGCORE_CRU_BASE + 0x280, 0x00030000);
+ mmio_write_32(LITTLE_CRU_BASE + 0x280, 0x00030000);
+
+ rockchip_reg_rgn_restore(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+
+ /* trigger lcore/bcore mem_cfg */
+ mmio_write_32(LITCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+ mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(1, 0x1, 1));
+ udelay(1);
+ mmio_write_32(LITCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+ mmio_write_32(BIGCORE_GRF_BASE + 0x38, BITS_WITH_WMASK(0, 0x1, 1));
+
+ /* wait lock */
+ pm_pll_wait_lock(CCI_CRU_BASE + 0x40);
+
+ /* restore mode */
+ mmio_write_32(BIGCORE_CRU_BASE + 0x280, WITH_16BITS_WMSK(b_cru_mode));
+ mmio_write_32(LITTLE_CRU_BASE + 0x280, WITH_16BITS_WMSK(l_cru_mode));
+
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m0], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m1], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_cci_m2], 1);
+ rockchip_reg_rgn_restore(&qos_reg_rgns[qos_dap_lite], 1);
+
+ pvtplls_resume();
+}
+
+void pd_php_save(void)
+{
+ rockchip_reg_rgn_save(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
+
+void pd_php_restore(void)
+{
+ rockchip_reg_rgn_restore(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+}
+
+void pm_reg_rgns_init(void)
+{
+ rockchip_alloc_region_mem(qos_reg_rgns, ARRAY_SIZE(qos_reg_rgns));
+ rockchip_alloc_region_mem(pd_bcore_reg_rgns, ARRAY_SIZE(pd_bcore_reg_rgns));
+ rockchip_alloc_region_mem(pd_core_reg_rgns, ARRAY_SIZE(pd_core_reg_rgns));
+ rockchip_alloc_region_mem(pd_php_reg_rgns, ARRAY_SIZE(pd_php_reg_rgns));
+ rockchip_alloc_region_mem(pd_usb2phy_reg_rgns, ARRAY_SIZE(pd_usb2phy_reg_rgns));
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h
new file mode 100644
index 0000000..5b4f624
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef PM_PD_REGS_H
+#define PM_PD_REGS_H
+
+#include <stdint.h>
+
+void qos_save(void);
+void qos_restore(void);
+void pd_usb2phy_save(void);
+void pd_usb2phy_restore(void);
+void pd_secure_save(void);
+void pd_secure_restore(void);
+void pd_bcore_save(void);
+void pd_bcore_restore(void);
+void pd_core_save(void);
+void pd_core_restore(void);
+void pd_php_save(void);
+void pd_php_restore(void);
+void pd_center_save(void);
+void pd_center_restore(void);
+void pd_bus_save(void);
+void pd_bus_restore(void);
+void pd_pmu1_save(void);
+void pd_pmu1_restore_early(void);
+void pd_pmu1_restore(void);
+void pd_pmu0_save(void);
+void pd_pmu0_restore(void);
+
+void pm_reg_rgns_init(void);
+void pm_regs_rgn_dump(void);
+
+#endif
diff --git a/plat/rockchip/rk3576/drivers/pmu/pmu.c b/plat/rockchip/rk3576/drivers/pmu/pmu.c
new file mode 100644
index 0000000..c7db176
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pmu.c
@@ -0,0 +1,1069 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <dmc_rk3576.h>
+#include <plat_pm_helpers.h>
+#include <plat_private.h>
+#include <pm_pd_regs.h>
+#include <secure.h>
+#include <soc.h>
+
+static struct psram_data_t *psram_sleep_cfg =
+ (struct psram_data_t *)&sys_sleep_flag_sram;
+
+struct rk3576_sleep_ddr_data {
+ uint32_t cru_mode_con, secure_cru_mode;
+ uint32_t gpio0a_iomux_l, gpio0a_iomux_h, gpio0b_iomux_l;
+ uint32_t pmu2_bisr_glb_con;
+ uint32_t pmu2_c0_ack_sel_con0, pmu2_c1_ack_sel_con0, pmu2_c2_ack_sel_con0;
+ uint32_t pmu2_fast_pwr_con, pmu2_pwrgt_sft_con0;
+ uint32_t pmu0grf_soc_con0, pmu0grf_soc_con1, pmu0grf_soc_con5;
+ uint32_t pmu_pd_st, bus_idle_st;
+ uint32_t sys_sgrf_soc_con0;
+ uint32_t ddrgrf_cha_con2, ddrgrf_chb_con2;
+};
+
+static struct rk3576_sleep_ddr_data ddr_data;
+
+void rockchip_plat_mmu_el3(void)
+{
+#ifdef PLAT_EXTRA_LD_SCRIPT
+ size_t sram_size;
+
+ sram_size = (char *)&__bl31_pmusram_text_end -
+ (char *)PMUSRAM_BASE;
+ mmap_add_region(PMUSRAM_BASE, PMUSRAM_BASE,
+ sram_size, MT_MEMORY | MT_RO | MT_SECURE);
+
+ sram_size = (char *)&__bl31_pmusram_data_end -
+ (char *)&__bl31_pmusram_data_start;
+ mmap_add_region((unsigned long)&__bl31_pmusram_data_start,
+ (unsigned long)&__bl31_pmusram_data_start,
+ sram_size, MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+}
+
+static int check_cpu_wfie(uint32_t cpu)
+{
+ uint32_t loop = 0;
+
+ while ((mmio_read_32(SYS_GRF_BASE + SYSGRF_STATUS0) & BIT(cpu + 12)) == 0 &&
+ (mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST) & BIT(cpu)) == 0 &&
+ (loop < WFEI_CHECK_LOOP)) {
+ udelay(1);
+ loop++;
+ }
+
+ if (loop >= WFEI_CHECK_LOOP) {
+ WARN("%s: error, cpu%d (0x%x 0x%x)!\n", __func__, cpu,
+ mmio_read_32(SYS_GRF_BASE + SYSGRF_STATUS0),
+ mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline uint32_t cpu_power_domain_st(uint32_t cpu)
+{
+ return !!(mmio_read_32(PMU_BASE + PMU2_CLUSTER_PWR_ST) &
+ BIT(cpu + 16));
+}
+
+static int cpu_power_domain_ctr(uint32_t cpu, uint32_t pd_state)
+{
+ uint32_t loop = 0;
+ int ret = 0;
+
+ mmio_write_32(PMU_BASE + PMU2_CPU_PWR_SFTCON(cpu),
+ BITS_WITH_WMASK(pd_state, 0x1, 0));
+
+ dsb();
+ while ((cpu_power_domain_st(cpu) != pd_state) && (loop < PD_CTR_LOOP)) {
+ udelay(1);
+ loop++;
+ }
+
+ if (cpu_power_domain_st(cpu) != pd_state) {
+ WARN("%s: %d, %d, error!\n", __func__, cpu, pd_state);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static inline uint32_t get_cpus_pwr_domain_cfg_info(uint32_t cpu_id)
+{
+ uint32_t val;
+
+ if ((mmio_read_32(PMU_BASE + PMU2_CPU_PWR_SFTCON(cpu_id)) & BIT(0)) != 0)
+ return core_pwr_pd;
+
+ val = mmio_read_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id));
+ if ((val & BIT(pmu_cpu_pm_en)) != 0) {
+ if ((val & BIT(core_pwr_wfi_int)) != 0)
+ return core_pwr_wfi_int;
+ else if ((val & BIT(pmu_cpu_pm_sft_wakeup_en)) != 0)
+ return core_pwr_wfi_reset;
+ else
+ return core_pwr_wfi;
+ } else {
+ return -1;
+ }
+}
+
+static inline void set_cpus_pwr_domain_cfg_info(uint32_t cpu_id, uint32_t value)
+{
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+ uint32_t cfg_info;
+ /*
+ * There are two ways to powering on or off on core.
+ * 1) Control it power domain into on or off in PMU_PWRDN_CON reg
+ * 2) Enable the core power manage in PMU_CORE_PM_CON reg,
+ * then, if the core enter into wfi, it power domain will be
+ * powered off automatically.
+ */
+
+ cfg_info = get_cpus_pwr_domain_cfg_info(cpu_id);
+
+ if (cfg_info == core_pwr_pd) {
+ /* disable core_pm cfg */
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(0, 0xf, 0));
+ /* if the cores have be on, power off it firstly */
+ if (cpu_power_domain_st(cpu_id) == pmu_pd_on)
+ cpu_power_domain_ctr(cpu_id, pmu_pd_off);
+
+ cpu_power_domain_ctr(cpu_id, pmu_pd_on);
+ } else {
+ if (cpu_power_domain_st(cpu_id) == pmu_pd_on) {
+ WARN("%s: cpu%d is not in off,!\n", __func__, cpu_id);
+ return -EINVAL;
+ }
+
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(1, 0x1, pmu_cpu_pm_sft_wakeup_en));
+ dsb();
+ }
+
+ return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+ uint32_t core_pm_value;
+
+ if (cpu_power_domain_st(cpu_id) == pmu_pd_off)
+ return 0;
+
+ if (pd_cfg == core_pwr_pd) {
+ if (check_cpu_wfie(cpu_id))
+ return -EINVAL;
+
+ /* disable core_pm cfg */
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(0, 0xf, 0));
+
+ set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg);
+ cpu_power_domain_ctr(cpu_id, pmu_pd_off);
+ } else {
+ set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg);
+
+ core_pm_value = BIT(pmu_cpu_pm_en) | BIT(pmu_cpu_pm_dis_int);
+ if (pd_cfg == core_pwr_wfi_int)
+ core_pm_value |= BIT(pmu_cpu_pm_int_wakeup_en);
+ else if (pd_cfg == core_pwr_wfi_reset)
+ core_pm_value |= BIT(pmu_cpu_pm_sft_wakeup_en);
+
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(core_pm_value, 0xf, 0));
+ dsb();
+ }
+
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint)
+{
+ uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr);
+
+ assert(cpu_id < PLATFORM_CORE_COUNT);
+ assert(cpuson_flags[cpu_id] == 0);
+ cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+ cpuson_entry_point[cpu_id] = entrypoint;
+ dsb();
+
+ cpus_power_domain_on(cpu_id);
+
+ return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_off(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ cpus_power_domain_off(cpu_id, core_pwr_wfi);
+
+ return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(0, 0xf, 0));
+
+ return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ assert(cpu_id < PLATFORM_CORE_COUNT);
+ assert(cpuson_flags[cpu_id] == 0);
+ cpuson_flags[cpu_id] = PMU_CPU_AUTO_PWRDN;
+ cpuson_entry_point[cpu_id] = plat_get_sec_entrypoint();
+ dsb();
+
+ cpus_power_domain_off(cpu_id, core_pwr_wfi_int);
+
+ return PSCI_E_SUCCESS;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+
+ /* Disable core_pm */
+ mmio_write_32(PMU_BASE + PMU2_CPU_AUTO_PWR_CON(cpu_id),
+ BITS_WITH_WMASK(0, 0xf, 0));
+
+ return PSCI_E_SUCCESS;
+}
+
+void nonboot_cpus_off(void)
+{
+ uint32_t boot_cpu, cpu;
+
+ boot_cpu = plat_my_core_pos();
+
+ /* turn off noboot cpus */
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) {
+ if (cpu == boot_cpu)
+ continue;
+
+ cpus_power_domain_off(cpu, core_pwr_pd);
+ }
+}
+
+static __pmusramfunc void ddr_resume(void)
+{
+ uint32_t key_upd_msk =
+ mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST) & BIT(pmu_pd_vop) ? 0x3 : 0x7;
+
+ /* hptimer is 24M here */
+ write_cntfrq_el0(24000000);
+
+ /* release cpu1~cpu7 to make pmu1_fsm exit */
+ mmio_write_32(CCI_GRF_BASE + CCIGRF_CON(4), 0xffffffff);
+ mmio_write_32(LITCORE_GRF_BASE + COREGRF_CPU_CON(1),
+ BITS_WITH_WMASK(0x77, 0xff, 4));
+
+ /* wait pmu1 fsm over */
+ while ((mmio_read_32(PMU_BASE + PMU1_PWR_FSM) & 0xf) != 0)
+ ;
+
+ /* SOC_CON19.vop/center/cci_ddr_hash_key_update_en */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00070000);
+ dsb();
+
+ /* SOC_CON19.vop/center/cci_ddr_hash_key_update_en */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00070000 | key_upd_msk);
+
+ /* SOC_STATUS.center/cci_ddr_hash_key_shift_ready */
+ while (((mmio_read_32(SYS_SGRF_BASE + SYSSGRF_SOC_STATUS) >> 12) & key_upd_msk) != key_upd_msk)
+ ;
+
+ /* CCI_BASE.ctrl_override_reg Attr:W1C addrmap strobe */
+ mmio_setbits_32(CCI_BASE + 0x0, 0x1 << 29);
+
+ /* SOC_CON19.vop/center/cci_ddr_hash_key_auto_update_en */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19), 0x00700070);
+}
+
+static uint32_t clk_save[CRU_CLKGATE_CON_CNT + PHP_CRU_CLKGATE_CON_CNT +
+ SECURE_CRU_CLKGATE_CON_CNT + SECURE_SCRU_CLKGATE_CON_CNT +
+ PMU1CRU_CLKGATE_CON_CNT + PMU1SCRU_CLKGATE_CON_CNT];
+
+void clk_gate_con_disable(void)
+{
+ int i;
+
+ for (i = 0; i < CRU_CLKGATE_CON_CNT; i++) {
+ /* Don't open wdt0 clk (cru_gate16[7:8] */
+ if (i == 16) {
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+ 0xfe7f0000);
+ } else {
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+ 0xffff0000);
+ }
+ }
+
+ for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++)
+ mmio_write_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i), 0xffff0000);
+
+ for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++)
+ mmio_write_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i), 0xffff0000);
+
+ for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++)
+ mmio_write_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i), 0xffff0000);
+
+ for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++)
+ mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i), 0xffff0000);
+
+ for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++)
+ mmio_write_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i), 0xffff0000);
+}
+
+void clk_gate_con_save(void)
+{
+ int i, j = 0;
+
+ for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(CRU_BASE + CRU_CLKGATE_CON(i));
+
+ for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i));
+
+ for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i));
+
+ for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i));
+
+ for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i));
+
+ for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++, j++)
+ clk_save[j] = mmio_read_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i));
+}
+
+void clk_gate_con_restore(void)
+{
+ int i, j = 0;
+
+ for (i = 0; i < CRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+
+ for (i = 0; i < PHP_CRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(PHP_CRU_BASE + PHP_CRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+
+ for (i = 0; i < SECURE_CRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(SECURE_CRU_BASE + SECURE_CRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+
+ for (i = 0; i < SECURE_SCRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(SECURE_CRU_BASE + SECURE_SCRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+
+ for (i = 0; i < PMU1CRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+
+ for (i = 0; i < PMU1SCRU_CLKGATE_CON_CNT; i++, j++)
+ mmio_write_32(PMU1_CRU_BASE + PMU1SCRU_CLKGATE_CON(i),
+ WITH_16BITS_WMSK(clk_save[j]));
+}
+
+void pmu_bus_idle_req(uint32_t bus, uint32_t state)
+{
+ uint32_t wait_cnt = 0;
+
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_SFTCON(bus / 16),
+ BITS_WITH_WMASK(state, 0x1, bus % 16));
+
+ while (pmu_bus_idle_st(bus) != state ||
+ pmu_bus_idle_ack(bus) != state) {
+ if (++wait_cnt > BUS_IDLE_LOOP)
+ break;
+ udelay(1);
+ }
+
+ if (wait_cnt > BUS_IDLE_LOOP)
+ WARN("%s: can't wait state %d for bus %d (0x%x)\n",
+ __func__, state, bus,
+ mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST));
+}
+
+static inline uint32_t pmu_power_domain_st(uint32_t pd)
+{
+ return mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST) & BIT(pd) ?
+ pmu_pd_off :
+ pmu_pd_on;
+}
+
+int pmu_power_domain_ctr(uint32_t pd, uint32_t pd_state)
+{
+ uint32_t loop = 0;
+ int ret = 0;
+
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(pd / 16),
+ BITS_WITH_WMASK(pd_state, 0x1, pd % 16));
+ dsb();
+
+ while ((pmu_power_domain_st(pd) != pd_state) && (loop < PD_CTR_LOOP)) {
+ udelay(1);
+ loop++;
+ }
+
+ if (pmu_power_domain_st(pd) != pd_state) {
+ WARN("%s: %d, %d, (0x%x) error!\n", __func__, pd, pd_state,
+ mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST));
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int pmu_set_power_domain(uint32_t pd_id, uint32_t pd_state)
+{
+ uint32_t state;
+
+ if (pmu_power_domain_st(pd_id) == pd_state)
+ goto out;
+
+ if (pd_state == pmu_pd_on)
+ pmu_power_domain_ctr(pd_id, pd_state);
+
+ state = (pd_state == pmu_pd_off) ? pmu_bus_idle : pmu_bus_active;
+
+ switch (pd_id) {
+ case pmu_pd_npu:
+ pmu_bus_idle_req(pmu_bus_id_npusys, state);
+ break;
+ case pmu_pd_secure:
+ pmu_bus_idle_req(pmu_bus_id_secure, state);
+ break;
+ case pmu_pd_nvm:
+ pmu_bus_idle_req(pmu_bus_id_nvm, state);
+ break;
+ case pmu_pd_sd_gmac:
+ pmu_bus_idle_req(pmu_bus_id_gmac, state);
+ break;
+ case pmu_pd_audio:
+ pmu_bus_idle_req(pmu_bus_id_audio, state);
+ break;
+ case pmu_pd_php:
+ pmu_bus_idle_req(pmu_bus_id_php, state);
+ break;
+ case pmu_pd_subphp:
+ break;
+ case pmu_pd_vop:
+ pmu_bus_idle_req(pmu_bus_id_vop, state);
+ break;
+ case pmu_pd_vop_smart:
+ break;
+ case pmu_pd_vop_clst:
+ break;
+ case pmu_pd_vo1:
+ pmu_bus_idle_req(pmu_bus_id_vo1, state);
+ break;
+ case pmu_pd_vo0:
+ pmu_bus_idle_req(pmu_bus_id_vo0, state);
+ break;
+ case pmu_pd_usb:
+ pmu_bus_idle_req(pmu_bus_id_usb, state);
+ break;
+ case pmu_pd_vi:
+ pmu_bus_idle_req(pmu_bus_id_vi, state);
+ break;
+ case pmu_pd_vepu0:
+ pmu_bus_idle_req(pmu_bus_id_vepu0, state);
+ break;
+ case pmu_pd_vepu1:
+ pmu_bus_idle_req(pmu_bus_id_vepu1, state);
+ break;
+ case pmu_pd_vdec:
+ pmu_bus_idle_req(pmu_bus_id_vdec, state);
+ break;
+ case pmu_pd_vpu:
+ pmu_bus_idle_req(pmu_bus_id_vpu, state);
+ break;
+ case pmu_pd_nputop:
+ pmu_bus_idle_req(pmu_bus_id_nputop, state);
+ break;
+ case pmu_pd_npu0:
+ pmu_bus_idle_req(pmu_bus_id_npu0, state);
+ break;
+ case pmu_pd_npu1:
+ pmu_bus_idle_req(pmu_bus_id_npu1, state);
+ break;
+ case pmu_pd_gpu:
+ pmu_bus_idle_req(pmu_bus_id_gpu, state);
+ break;
+ default:
+ break;
+ }
+
+ if (pd_state == pmu_pd_off)
+ pmu_power_domain_ctr(pd_id, pd_state);
+
+out:
+ return 0;
+}
+
+static void pmu_power_domains_suspend(void)
+{
+ ddr_data.pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+ ddr_data.bus_idle_st = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST);
+ ddr_data.pmu2_pwrgt_sft_con0 = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(0));
+
+ qos_save();
+
+ pd_usb2phy_save();
+
+ if ((ddr_data.pmu_pd_st & BIT(pmu_pd_php)) == 0)
+ pd_php_save();
+}
+
+static void pmu_power_domains_resume(void)
+{
+ int i;
+
+ for (i = 0; i < pmu_pd_id_max; i++) {
+ /* vop smart/clst pd is not controlled by pmu */
+ if (i == pmu_pd_vop_smart || i == pmu_pd_vop_clst)
+ continue;
+
+ pmu_set_power_domain(i, !!(ddr_data.pmu_pd_st & BIT(i)));
+ }
+
+ /* restore vop smart/clst pd of pmu2_pwrgt_sft_con0 */
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_SFTCON(0),
+ 0x30000000 | ddr_data.pmu2_pwrgt_sft_con0);
+
+ for (i = pmu_bus_id_max - 1; i >= 0; i--)
+ pmu_bus_idle_req(i, !!(ddr_data.bus_idle_st & BIT(i)));
+
+ if ((ddr_data.pmu_pd_st & BIT(pmu_pd_php)) == 0)
+ pd_php_restore();
+
+ pd_usb2phy_restore();
+
+ qos_restore();
+}
+
+static void ddr_sleep_config(void)
+{
+ ddr_data.ddrgrf_cha_con2 =
+ mmio_read_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2));
+ ddr_data.ddrgrf_chb_con2 =
+ mmio_read_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2));
+
+ mmio_write_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2), 0x0a000a00);
+ mmio_write_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2), 0x0a000a00);
+}
+
+static void ddr_sleep_config_restore(void)
+{
+ mmio_write_32(DDR_GRF_BASE + DDRGRF_CHA_CON(2),
+ WITH_16BITS_WMSK(ddr_data.ddrgrf_cha_con2));
+ mmio_write_32(DDR_GRF_BASE + DDRGRF_CHB_CON(2),
+ WITH_16BITS_WMSK(ddr_data.ddrgrf_chb_con2));
+}
+
+static void sleep_pin_config(void)
+{
+ /* pwr0 sleep: gpio0_a3 */
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1),
+ BITS_WITH_WMASK(0x7, 0xf, 0));
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0),
+ BITS_WITH_WMASK(0, 0x1, 7));
+ mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+ BITS_WITH_WMASK(9, 0xfu, 12));
+}
+
+static void pmu_sleep_config(void)
+{
+ uint32_t pmu1_wkup_int_con;
+ uint32_t pmu1_pwr_con, pmu1_ddr_pwr_con, pmu1cru_pwr_con, pmu1_pll_pd_con;
+ uint32_t pmu2_bus_idle_con[2], pmu2_pwr_gt_con[2];
+ uint32_t key_upd_msk = ddr_data.pmu_pd_st & BIT(pmu_pd_vop) ? 0x3 : 0x7;
+ uint32_t fw_lkp_upd_msk = ddr_data.pmu_pd_st & BIT(pmu_pd_npu) ? 0x3 : 0x7;
+ uint32_t fw_ddr_upd_msk = key_upd_msk;
+ uint32_t pmu_pd_st = mmio_read_32(PMU_BASE + PMU2_PWR_GATE_ST);
+ uint32_t bus_idle_st = mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST);
+
+ ddr_data.pmu2_bisr_glb_con = mmio_read_32(PMU_BASE + PMU2_BISR_GLB_CON);
+
+ ddr_data.pmu2_fast_pwr_con =
+ mmio_read_32(PMU_BASE + PMU2_FAST_POWER_CON);
+
+ ddr_data.pmu2_c0_ack_sel_con0 =
+ mmio_read_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0));
+ ddr_data.pmu2_c1_ack_sel_con0 =
+ mmio_read_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0));
+ ddr_data.pmu2_c2_ack_sel_con0 =
+ mmio_read_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0));
+ ddr_data.pmu0grf_soc_con5 =
+ mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5));
+
+ /* set tsadc_shut_m0 pin iomux to gpio */
+ mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+ BITS_WITH_WMASK(0, 0xf, 4));
+
+ pmu1_wkup_int_con =
+ BIT(pmu_wkup_cpu0_int) |
+ BIT(pmu_wkup_gpio0_int);
+
+ pmu1_pwr_con =
+ BIT(pmu_powermode_en) |
+ /* BIT(pmu_scu0_byp) | */
+ /* BIT(pmu_scu1_byp) | */
+ /* BIT(pmu_cci_byp) | */
+ /* BIT(pmu_bus_byp) | */
+ /* BIT(pmu_ddr_byp) | */
+ /* BIT(pmu_pwrgt_byp) | */
+ /* BIT(pmu_cru_byp) | */
+ BIT(pmu_qch_byp) |
+ /* BIT(pmu_wfi_byp) | */
+ BIT(pmu_slp_cnt_en);
+
+ pmu1_ddr_pwr_con = 0;
+
+ pmu1_pll_pd_con =
+ BIT(pmu_bpll_pd_en) |
+ BIT(pmu_lpll_pd_en) |
+ BIT(pmu_spll_pd_en) |
+ BIT(pmu_gpll_pd_en) |
+ BIT(pmu_cpll_pd_en) |
+ BIT(pmu_ppll_pd_en) |
+ BIT(pmu_aupll_pd_en) |
+ BIT(pmu_vpll_pd_en);
+
+ pmu1cru_pwr_con =
+ BIT(pmu_alive_osc_mode_en) |
+ BIT(pmu_io_sleep_en) |
+ BIT(pmu_power_off_en);
+
+ pmu2_bus_idle_con[0] = 0xffff & ~(bus_idle_st & 0xffff);
+ pmu2_bus_idle_con[1] = 0x3fff & ~(bus_idle_st >> 16);
+
+ pmu2_pwr_gt_con[0] = 0xffff & ~(pmu_pd_st & 0xffff);
+ pmu2_pwr_gt_con[1] = 0x03ff & ~(pmu_pd_st >> 16);
+
+ pmu2_pwr_gt_con[0] &=
+ ~(BIT(pmu_pd_secure) |
+ BIT(pmu_pd_bus) |
+ BIT(pmu_pd_center) |
+ BIT(pmu_pd_ddr));
+
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLEACK_BYPASS_CON, 0x00030003);
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0, 0x03ff0000);
+
+ /* disable repair */
+ mmio_write_32(PMU_BASE + PMU2_BISR_GLB_CON, 0x00010000);
+
+ /* disable ddr_hash_key update.
+ * enable disable ddr_hash_key auto update.
+ * wait ddr_hash_key auto update.
+ */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(19),
+ BITS_WITH_WMASK(key_upd_msk, 0x7, 8));
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1,
+ BITS_WITH_WMASK(fw_lkp_upd_msk, 0x7, 10));
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1,
+ BITS_WITH_WMASK(fw_ddr_upd_msk, 0x7u, 13));
+
+ mmio_write_32(PMU_BASE + PMU0_PMIC_STABLE_CNT_THRES, 24000 * 5);
+ mmio_write_32(PMU_BASE + PMU0_OSC_STABLE_CNT_THRES, 24000 * 5);
+
+ mmio_write_32(PMU_BASE + PMU1_OSC_STABLE_CNT_THRESH, 24000 * 5);
+ mmio_write_32(PMU_BASE + PMU1_STABLE_CNT_THRESH, 24000 * 5);
+
+ mmio_write_32(PMU_BASE + PMU1_SLEEP_CNT_THRESH, 24000 * 15);
+
+ /* Pmu's clk has switched to 24M back When pmu FSM counts
+ * the follow counters, so we should use 24M to calculate
+ * these counters.
+ */
+ mmio_write_32(PMU_BASE + PMU0_WAKEUP_RST_CLR_CNT_THRES, 12000);
+
+ mmio_write_32(PMU_BASE + PMU1_WAKEUP_RST_CLR_CNT_THRESH, 12000);
+ mmio_write_32(PMU_BASE + PMU1_PLL_LOCK_CNT_THRESH, 12000);
+ mmio_write_32(PMU_BASE + PMU1_PWM_SWITCH_CNT_THRESH,
+ 24000 * 2);
+
+ mmio_write_32(PMU_BASE + PMU2_SCU0_PWRUP_CNT_THRESH, 0);
+ mmio_write_32(PMU_BASE + PMU2_SCU0_PWRDN_CNT_THRESH, 0);
+ mmio_write_32(PMU_BASE + PMU2_SCU0_STABLE_CNT_THRESH, 0);
+
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_0, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_0, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_1, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_1, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRUP_CNT_THRESH_2, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_PWRDN_CNT_THRESH_2, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_POWER_CON, 0xffff0007);
+
+ /* pmu_clst_idle_con */
+ mmio_write_32(PMU_BASE + PMU2_CLUSTER0_IDLE_CON, 0xffff0007);
+ mmio_write_32(PMU_BASE + PMU2_CLUSTER1_IDLE_CON, 0xffff0007);
+
+ /* pmu_scu_pwr_con */
+ /* L2's flush and idle by hardware, so need to enable wfil2 bypass */
+ mmio_write_32(PMU_BASE + PMU2_SCU0_PWR_CON, 0xffff020f);
+ mmio_write_32(PMU_BASE + PMU2_SCU1_PWR_CON, 0xffff020f);
+ mmio_write_32(PMU_BASE + PMU2_SCU0_AUTO_PWR_CON, 0x00070000);
+ mmio_write_32(PMU_BASE + PMU2_SCU1_AUTO_PWR_CON, 0x00070000);
+
+ mmio_write_32(PMU_BASE + PMU2_CCI_PWR_CON, 0xffff0009);
+
+ /* pmu_int_msk_con */
+ /* mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, BITS_WITH_WMASK(1, 0x1, 0)); */
+
+ /* pmu_pwr_con */
+ mmio_write_32(PMU_BASE + PMU1_PWR_CON, WITH_16BITS_WMSK(pmu1_pwr_con));
+
+ /* pmu_cru_pwr_conx */
+ mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON(0), WITH_16BITS_WMSK(pmu1cru_pwr_con));
+
+ /* pmu_ddr_pwr_con */
+ mmio_write_32(PMU_BASE + PMU0_DDR_RET_CON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(0), WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+ mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(1), WITH_16BITS_WMSK(pmu1_ddr_pwr_con));
+ mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(0), 0x03ff03ff);
+ mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(1), 0x03ff03ff);
+
+ /* pll_pd */
+ mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0), WITH_16BITS_WMSK(pmu1_pll_pd_con));
+
+ /* bus idle */
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(0), WITH_16BITS_WMSK(pmu2_bus_idle_con[0]));
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(1), WITH_16BITS_WMSK(pmu2_bus_idle_con[1]));
+
+ /* power gate */
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0), WITH_16BITS_WMSK(pmu2_pwr_gt_con[0]));
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1), WITH_16BITS_WMSK(pmu2_pwr_gt_con[1]));
+
+ /* vol gate */
+ mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0), 0xffff0031);
+ mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(1), 0xffff0200);
+
+ /* wakeup source */
+ mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, pmu1_wkup_int_con);
+
+ /* ppll clamp */
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5), 0x00400040);
+
+ /* usbphy clamp */
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5),
+ BITS_WITH_WMASK(0x9, 0x9, 2));
+
+ /* big core pwr ack bypass */
+ mmio_write_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0), 0x01000100);
+ mmio_write_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0), 0x01000100);
+ mmio_write_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0), 0x01000100);
+}
+
+static void pmu_sleep_restore(void)
+{
+ mmio_write_32(PMU_BASE + PMU0_INFO_TX_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_DEBUG_INFO_SEL, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_CLUSTER0_IDLE_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_SCU0_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_CCI_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_INT_MASK_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_CRU_PWR_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_DDR_PWR_CON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_DDR_AXIPWR_CON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_PLLPD_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLE_CON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_PWR_GATE_CON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(1), 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU2_BUS_IDLEACK_BYPASS_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU1_WAKEUP_INT_CON, 0);
+ mmio_write_32(PMU_BASE + PMU2_FAST_POWER_CON,
+ WITH_16BITS_WMSK(ddr_data.pmu2_fast_pwr_con));
+ mmio_write_32(PMU_BASE + PMU2_BISR_GLB_CON,
+ WITH_16BITS_WMSK(ddr_data.pmu2_bisr_glb_con));
+
+ mmio_write_32(PMU_BASE + PMU2_C0_PWRACK_BYPASS_CON(0),
+ WITH_16BITS_WMSK(ddr_data.pmu2_c0_ack_sel_con0));
+ mmio_write_32(PMU_BASE + PMU2_C1_PWRACK_BYPASS_CON(0),
+ WITH_16BITS_WMSK(ddr_data.pmu2_c1_ack_sel_con0));
+ mmio_write_32(PMU_BASE + PMU2_C2_PWRACK_BYPASS_CON(0),
+ WITH_16BITS_WMSK(ddr_data.pmu2_c2_ack_sel_con0));
+
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(5),
+ WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con5));
+}
+
+static void secure_watchdog_disable(void)
+{
+ ddr_data.sys_sgrf_soc_con0 =
+ mmio_read_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0));
+
+ /* pause wdt_s */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0),
+ BITS_WITH_WMASK(1, 0x1, 14));
+}
+
+static void secure_watchdog_restore(void)
+{
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0),
+ ddr_data.sys_sgrf_soc_con0 |
+ BITS_WMSK(0x1, 14));
+
+ if (mmio_read_32(WDT_S_BASE + WDT_CR) & WDT_EN)
+ mmio_write_32(WDT_S_BASE + WDT_CRR, 0x76);
+}
+
+static void soc_sleep_config(void)
+{
+ ddr_data.pmu0grf_soc_con0 =
+ mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0));
+ ddr_data.pmu0grf_soc_con1 =
+ mmio_read_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1));
+
+ ddr_data.gpio0a_iomux_l =
+ mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L);
+ ddr_data.gpio0a_iomux_h =
+ mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_H);
+ ddr_data.gpio0b_iomux_l =
+ mmio_read_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0B_IOMUX_SEL_L);
+
+ sleep_pin_config();
+ pmu_sleep_config();
+ ddr_sleep_config();
+ secure_watchdog_disable();
+}
+
+static void soc_sleep_restore(void)
+{
+ secure_watchdog_restore();
+ ddr_sleep_config_restore();
+ pmu_sleep_restore();
+
+ mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_L,
+ WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_l));
+ mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0A_IOMUX_SEL_H,
+ WITH_16BITS_WMSK(ddr_data.gpio0a_iomux_h));
+ mmio_write_32(PMU0_IOC_BASE + PMUIO0_IOC_GPIO0B_IOMUX_SEL_L,
+ WITH_16BITS_WMSK(ddr_data.gpio0b_iomux_l));
+
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(1),
+ WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con1));
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_SOC_CON(0),
+ WITH_16BITS_WMSK(ddr_data.pmu0grf_soc_con0));
+}
+
+static void pm_pll_suspend(void)
+{
+ ddr_data.cru_mode_con = mmio_read_32(CRU_BASE + 0x280);
+ ddr_data.secure_cru_mode = mmio_read_32(SECURE_CRU_BASE + 0x4280);
+
+ /* bpll gpll vpll aupll cpll spll switch to slow mode */
+ mmio_write_32(CRU_BASE + 0x280, 0x03ff0000);
+ mmio_write_32(SECURE_CRU_BASE + 0x4280, 0x00030000);
+
+ /* hclk_pmu_cm0_root_i_sel to 24M */
+ mmio_write_32(PMU1_CRU_BASE + PMU1CRU_CLKSEL_CON(4),
+ BITS_WITH_WMASK(0x3, 0x3, 2));
+}
+
+static void pm_pll_restore(void)
+{
+ mmio_write_32(CRU_BASE + 0x280, WITH_16BITS_WMSK(ddr_data.cru_mode_con));
+ mmio_write_32(SECURE_CRU_BASE + 0x4280,
+ WITH_16BITS_WMSK(ddr_data.secure_cru_mode));
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+ psram_sleep_cfg->pm_flag &= ~PM_WARM_BOOT_BIT;
+
+ clk_gate_con_save();
+ clk_gate_con_disable();
+ dmc_save();
+ pmu_power_domains_suspend();
+ soc_sleep_config();
+ pm_pll_suspend();
+ pd_core_save();
+
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+ pd_core_restore();
+ pm_pll_restore();
+ soc_sleep_restore();
+ pmu_power_domains_resume();
+ plat_rockchip_gic_cpuif_enable();
+ dmc_restore();
+ clk_gate_con_restore();
+
+ psram_sleep_cfg->pm_flag |= PM_WARM_BOOT_BIT;
+
+ return 0;
+}
+
+void __dead2 rockchip_soc_cores_pd_pwr_dn_wfi(const
+ psci_power_state_t *target_state)
+{
+ psci_power_down_wfi();
+ /* should never reach here */
+ panic();
+}
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+ psci_power_down_wfi();
+ /* should never reach here */
+ panic();
+}
+
+static int rockchip_reboot_is_rbrom(void)
+{
+ return mmio_read_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(16)) ==
+ BOOT_BROM_DOWNLOAD;
+}
+
+static void rockchip_soc_soft_reset_check_rstout(void)
+{
+ /*
+ * Maskrom enter maskrom-usb mode according to os_reg0 which
+ * will be reset by NPOR. So disable tsadc_shut_m0 if we want
+ * to maskrom-usb mode.
+ */
+ if (rockchip_reboot_is_rbrom() != 0) {
+ /* write BOOT_BROM_DOWNLOAD to os_reg0 */
+ mmio_write_32(PMU1_GRF_BASE + PMU1GRF_OS_REG(0), BOOT_BROM_DOWNLOAD);
+
+ /* disable first/tsadc/wdt reset output */
+ mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070000);
+
+ /* clear reset hold */
+ mmio_write_32(PMU0SGRF_BASE + PMU0SGRF_SOC_CON(1), 0xffff0000);
+ mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(16), 0xffff0000);
+ mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(17), 0xffff0000);
+ }
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+ rockchip_soc_soft_reset_check_rstout();
+
+ /* pll slow mode */
+ mmio_write_32(CRU_BASE + CRU_MODE_CON, 0x003f0000);
+
+ dsb();
+ isb();
+
+ INFO("system reset......\n");
+ mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
+
+ /*
+ * Maybe the HW needs some times to reset the system,
+ * so we do not hope the core to execute valid codes.
+ */
+ psci_power_down_wfi();
+ /* should never reach here */
+ panic();
+}
+
+void __dead2 rockchip_soc_system_off(void)
+{
+ INFO("system poweroff......\n");
+
+ /* gpio0_a3 config output */
+ mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DDR_L,
+ BITS_WITH_WMASK(1, 0x1, 3));
+
+ /* gpio0_a3 config output high level */
+ mmio_write_32(GPIO0_BASE + GPIO_SWPORT_DR_L,
+ BITS_WITH_WMASK(1, 0x1, 3));
+ dsb();
+
+ /*
+ * Maybe the HW needs some times to reset the system,
+ * so we do not hope the core to execute valid codes.
+ */
+ psci_power_down_wfi();
+ /* should never reach here */
+ panic();
+}
+
+static void rockchip_pmu_pd_repair_init(void)
+{
+ INFO("enable memory repair\n");
+ /* Enable gpu and npu repair */
+ mmio_write_32(PMU_BASE + PMU2_BISR_PDGEN_CON(1),
+ BITS_WITH_WMASK(0xf, 0xf, 6));
+}
+
+void plat_rockchip_pmu_init(void)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+ cpuson_flags[cpu] = 0;
+
+ psram_sleep_cfg->sp = PSRAM_SP_TOP;
+ psram_sleep_cfg->ddr_func = (uint64_t)ddr_resume;
+ psram_sleep_cfg->ddr_data = 0;
+ psram_sleep_cfg->ddr_flag = 0;
+ psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+ nonboot_cpus_off();
+
+ /*
+ * When perform idle operation, corresponding clock can be
+ * opened or gated automatically.
+ */
+ mmio_write_32(PMU_BASE + PMU2_NOC_AUTO_CON(0), 0xffffffff);
+ mmio_write_32(PMU_BASE + PMU2_NOC_AUTO_CON(1), 0xffffffff);
+
+ /* remap pmusram to 0x00000000 */
+ mmio_write_32(PMU0SGRF_BASE + PMU0SGRF_SOC_CON(2), BITS_WITH_WMASK(1, 0x3, 0));
+
+ /* enable power off VD_NPU by hrdware */
+ mmio_write_32(PMU_BASE + PMU2_VOL_GATE_SFTCON(0),
+ BITS_WITH_WMASK(0x1, 0x1, 0));
+
+ rockchip_pmu_pd_repair_init();
+
+ pm_reg_rgns_init();
+}
diff --git a/plat/rockchip/rk3576/drivers/pmu/pmu.h b/plat/rockchip/rk3576/drivers/pmu/pmu.h
new file mode 100644
index 0000000..6340e3f
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/pmu/pmu.h
@@ -0,0 +1,578 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#include <assert.h>
+
+#include <mmio.h>
+
+/* PMU */
+#define PMU1_OFFSET 0x10000
+#define PMU2_OFFSET 0x20000
+
+#define PMU0_PWR_CON 0x0000
+#define PMU0_PWR_STATUS 0x0004
+#define PMU0_WAKEUP_INT_CON 0x0008
+#define PMU0_WAKEUP_INT_ST 0x000c
+#define PMU0_PMIC_STABLE_CNT_THRES 0x0010
+#define PMU0_WAKEUP_RST_CLR_CNT_THRES 0x0014
+#define PMU0_OSC_STABLE_CNT_THRES 0x0018
+#define PMU0_PWR_C0_STABLE_CON 0x001c
+#define PMU0_DDR_RET_CON(i) (0x0020 + (i) * 4)
+#define PMU0_INFO_TX_CON 0x0030
+
+#define PMU1_VERSION_ID (PMU1_OFFSET + 0x0000)
+#define PMU1_PWR_CON (PMU1_OFFSET + 0x0004)
+#define PMU1_PWR_FSM (PMU1_OFFSET + 0x0008)
+#define PMU1_INT_MASK_CON (PMU1_OFFSET + 0x000c)
+#define PMU1_WAKEUP_INT_CON (PMU1_OFFSET + 0x0010)
+#define PMU1_WAKEUP_INT_ST (PMU1_OFFSET + 0x0014)
+#define PMU1_DDR_PWR_CON(i) (PMU1_OFFSET + 0x0100 + (i) * 4)
+#define PMU1_DDR_PWR_SFTCON(i) (PMU1_OFFSET + 0x0110 + (i) * 4)
+#define PMU1_DDR_AXIPWR_CON(i) (PMU1_OFFSET + 0x0120 + (i) * 4)
+#define PMU1_DDR_AXIPWR_SFTCON(i) (PMU1_OFFSET + 0x0130 + (i) * 4)
+#define PMU1_DDR_PWR_FSM (PMU1_OFFSET + 0x0140)
+#define PMU1_DDR_PWR_ST (PMU1_OFFSET + 0x0144)
+#define PMU1_DDR_AXIPWR_ST (PMU1_OFFSET + 0x0148)
+#define PMU1_CRU_PWR_CON(i) (PMU1_OFFSET + 0x0200 + (i) * 4)
+#define PMU1_CRU_PWR_SFTCON(i) (PMU1_OFFSET + 0x0208 + (i) * 4)
+#define PMU1_CRU_PWR_FSM (PMU1_OFFSET + 0x0210)
+#define PMU1_PLLPD_CON(i) (PMU1_OFFSET + 0x0220 + (i) * 4)
+#define PMU1_PLLPD_SFTCON(i) (PMU1_OFFSET + 0x0228 + (i) * 4)
+#define PMU1_STABLE_CNT_THRESH (PMU1_OFFSET + 0x0300)
+#define PMU1_OSC_STABLE_CNT_THRESH (PMU1_OFFSET + 0x0304)
+#define PMU1_WAKEUP_RST_CLR_CNT_THRESH (PMU1_OFFSET + 0x0308)
+#define PMU1_PLL_LOCK_CNT_THRESH (PMU1_OFFSET + 0x030c)
+#define PMU1_WAKEUP_TIMEOUT_THRESH (PMU1_OFFSET + 0x0310)
+#define PMU1_PWM_SWITCH_CNT_THRESH (PMU1_OFFSET + 0x0314)
+#define PMU1_SLEEP_CNT_THRESH (PMU1_OFFSET + 0x0318)
+#define PMU1_INFO_TX_CON (PMU1_OFFSET + 0x0400)
+
+#define PMU2_SCU0_PWR_CON (PMU2_OFFSET + 0x0000)
+#define PMU2_SCU1_PWR_CON (PMU2_OFFSET + 0x0004)
+#define PMU2_SCU0_PWR_SFTCON (PMU2_OFFSET + 0x0008)
+#define PMU2_SCU1_PWR_SFTCON (PMU2_OFFSET + 0x000c)
+#define PMU2_SCU0_AUTO_PWR_CON (PMU2_OFFSET + 0x0010)
+#define PMU2_SCU1_AUTO_PWR_CON (PMU2_OFFSET + 0x0014)
+#define PMU2_SCU_PWR_FSM_STATUS (PMU2_OFFSET + 0x0018)
+#define PMU2_DBG_PWR_CON(i) (PMU2_OFFSET + 0x001c + (i) * 4)
+#define PMU2_CLUSTER_PWR_ST (PMU2_OFFSET + 0x0024)
+#define PMU2_CLUSTER0_IDLE_CON (PMU2_OFFSET + 0x0028)
+#define PMU2_CLUSTER1_IDLE_CON (PMU2_OFFSET + 0x002c)
+#define PMU2_CLUSTER0_IDLE_SFTCON (PMU2_OFFSET + 0x0030)
+#define PMU2_CLUSTER1_IDLE_SFTCON (PMU2_OFFSET + 0x0034)
+#define PMU2_CLUSTER_IDLE_ACK (PMU2_OFFSET + 0x0038)
+#define PMU2_CLUSTER_IDLE_ST (PMU2_OFFSET + 0x003c)
+#define PMU2_SCU0_PWRUP_CNT_THRESH (PMU2_OFFSET + 0x0040)
+#define PMU2_SCU0_PWRDN_CNT_THRESH (PMU2_OFFSET + 0x0044)
+#define PMU2_SCU0_STABLE_CNT_THRESH (PMU2_OFFSET + 0x0048)
+#define PMU2_SCU1_PWRUP_CNT_THRESH (PMU2_OFFSET + 0x004c)
+#define PMU2_SCU1_PWRDN_CNT_THRESH (PMU2_OFFSET + 0x0050)
+#define PMU2_SCU1_STABLE_CNT_THRESH (PMU2_OFFSET + 0x0054)
+#define PMU2_CPU_AUTO_PWR_CON(i) (PMU2_OFFSET + 0x0080 + ((i)) * 4)
+#define PMU2_CPU_PWR_SFTCON(i) (PMU2_OFFSET + 0x00a0 + ((i)) * 4)
+#define PMU2_CCI_PWR_CON (PMU2_OFFSET + 0x00e0)
+#define PMU2_CCI_PWR_SFTCON (PMU2_OFFSET + 0x00e4)
+#define PMU2_CCI_PWR_ST (PMU2_OFFSET + 0x00e8)
+#define PMU2_CCI_POWER_STATE (PMU2_OFFSET + 0x00ec)
+#define PMU2_BUS_IDLE_CON(i) (PMU2_OFFSET + 0x0100 + (i) * 4)
+#define PMU2_BUS_IDLE_SFTCON(i) (PMU2_OFFSET + 0x0110 + (i) * 4)
+#define PMU2_BUS_IDLE_ACK (PMU2_OFFSET + 0x0120)
+#define PMU2_BUS_IDLE_ST (PMU2_OFFSET + 0x0128)
+#define PMU2_NOC_AUTO_CON(i) (PMU2_OFFSET + 0x0130 + (i) * 4)
+#define PMU2_NOC_AUTO_SFTCON(i) (PMU2_OFFSET + 0x0140 + (i) * 4)
+#define PMU2_BUS_IDLEACK_BYPASS_CON (PMU2_OFFSET + 0x0150)
+#define PMU2_PWR_GATE_CON(i) (PMU2_OFFSET + 0x0200 + (i) * 4)
+#define PMU2_PWR_GATE_SFTCON(i) (PMU2_OFFSET + 0x0210 + (i) * 4)
+#define PMU2_VOL_GATE_SFTCON(i) (PMU2_OFFSET + 0x0220 + (i) * 4)
+#define PMU2_PWR_GATE_ST (PMU2_OFFSET + 0x0230)
+#define PMU2_PWR_GATE_FSM (PMU2_OFFSET + 0x0238)
+#define PMU2_PD_DWN_ACK_STATE(i) (PMU2_OFFSET + 0x0240 + (i) * 4)
+#define PMU2_PD_DWN_LC_ACK_STATE(i) (PMU2_OFFSET + 0x0248 + (i) * 4)
+#define PMU2_PD_DWN_MEM_ACK_STATE(i) (PMU2_OFFSET + 0x0250 + (i) * 4)
+#define PMU2_PWR_UP_C0_STABLE_CON(i) (PMU2_OFFSET + 0x0260 + (i) * 4)
+#define PMU2_PWR_DWN_C0_STABLE_CON(i) (PMU2_OFFSET + 0x0270 + (i) * 4)
+#define PMU2_PWR_STABLE_C0_CNT_THRES (PMU2_OFFSET + 0x027c)
+#define PMU2_FAST_POWER_CON (PMU2_OFFSET + 0x0284)
+#define PMU2_FAST_PWRUP_CNT_THRESH_0 (PMU2_OFFSET + 0x0288)
+#define PMU2_FAST_PWRDN_CNT_THRESH_0 (PMU2_OFFSET + 0x028c)
+#define PMU2_FAST_PWRUP_CNT_THRESH_1 (PMU2_OFFSET + 0x0290)
+#define PMU2_FAST_PWRDN_CNT_THRESH_1 (PMU2_OFFSET + 0x0294)
+#define PMU2_FAST_PWRUP_CNT_THRESH_2 (PMU2_OFFSET + 0x0298)
+#define PMU2_FAST_PWRDN_CNT_THRESH_2 (PMU2_OFFSET + 0x029c)
+#define PMU2_MEM_PWR_GATE_SFTCON(i) (PMU2_OFFSET + 0x0300)
+#define PMU2_SUBMEM_PWR_GATE_SFTCON(i) (PMU2_OFFSET + 0x0310)
+#define PMU2_SUBMEM_PWR_ACK_BYPASS_SFTCON(i) (PMU2_OFFSET + 0x0320)
+#define PMU2_SUBMEM_PWR_GATE_STATUS (PMU2_OFFSET + 0x0328)
+#define PMU2_QCHANNEL_PWR_CON0 (PMU2_OFFSET + 0x0400)
+#define PMU2_QCHANNEL_PWR_SFTCON0 (PMU2_OFFSET + 0x0404)
+#define PMU2_QCHANNEL_STATUS0 (PMU2_OFFSET + 0x0408)
+#define PMU2_C0_PWRACK_BYPASS_CON(i) (PMU2_OFFSET + 0x0380 + (i) * 4)
+#define PMU2_C1_PWRACK_BYPASS_CON(i) (PMU2_OFFSET + 0x0390 + (i) * 4)
+#define PMU2_C2_PWRACK_BYPASS_CON(i) (PMU2_OFFSET + 0x03a0 + (i) * 4)
+#define PMU2_DEBUG_INFO_SEL (PMU2_OFFSET + 0x03f0)
+#define PMU2_BISR_GLB_CON (PMU2_OFFSET + 0x500)
+#define PMU2_BISR_TIMEOUT_THRES (PMU2_OFFSET + 0x504)
+#define PMU2_BISR_PDGEN_CON(i) (PMU2_OFFSET + 0x510 + (i) * 4)
+#define PMU2_BISR_PDGEN_SFTCON(i) (PMU2_OFFSET + 0x520 + (i) * 4)
+#define PMU2_BISR_PDGDONE_CON(i) (PMU2_OFFSET + 0x530 + (i) * 4)
+#define PMU2_BISR_PDGINIT_CON(i) (PMU2_OFFSET + 0x540 + (i) * 4)
+#define PMU2_BISR_PDGDONE_STATUS(i) (PMU2_OFFSET + 0x550 + (i) * 4)
+#define PMU2_BISR_PDGCEDIS_STATUS(i) (PMU2_OFFSET + 0x560 + (i) * 4)
+#define PMU2_BISR_PWR_REPAIR_STATUS(i) (PMU2_OFFSET + 0x570 + (i) * 4)
+
+/* PMU1CRU */
+#define PMU1CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define PMU1CRU_CLKSEL_CON_CNT 22
+#define PMU1CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define PMU1CRU_CLKGATE_CON_CNT 8
+#define PMU1CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define PMU1CRU_SOFTRST_CON_CNT 8
+#define PMU1CRU_DEEPSLOW_DET_CON 0xb40
+#define PMU1CRU_DEEPSLOW_DET_ST 0xb44
+
+/* PMU1SCRU */
+#define PMU1SCRU_CLKSEL_CON(i) ((i) * 0x4 + 0x4000)
+#define PMU1SCRU_CLKSEL_CON_CNT 3
+#define PMU1SCRU_CLKGATE_CON(i) ((i) * 0x4 + 0x4028)
+#define PMU1SCRU_CLKGATE_CON_CNT 3
+#define PMU1SCRU_SOFTRST_CON(i) ((i) * 0x4 + 0x4050)
+#define PMU1SCRU_SOFTRST_CONCNT 3
+
+/* PMU0GRF */
+#define PMU0GRF_SOC_CON(i) ((i) * 4)
+#define PMU0GRF_IO_RET_CON(i) (0x20 + (i) * 4)
+#define PMU0GRF_OS_REG(i) ((i) * 4)
+
+/* PMU1GRF */
+#define PMU1GRF_SOC_CON(i) ((i) * 4)
+#define PMU1GRF_SOC_ST 0x60
+#define PMU1GRF_MEM_CON(i) (0x80 + (i) * 4)
+#define PMU1GRF_OS_REG(i) (0x200 + (i) * 4)
+
+#define PMU_MCU_HALT BIT(7)
+#define PMU_MCU_SLEEP BIT(9)
+#define PMU_MCU_DEEPSLEEP BIT(10)
+#define PMU_MCU_STOP_MSK \
+ (PMU_MCU_HALT | PMU_MCU_SLEEP | PMU_MCU_DEEPSLEEP)
+
+#define CORES_PM_DISABLE 0x0
+
+/* pmuioc */
+#define PMUIO0_IOC_GPIO0A_IOMUX_SEL_L 0x000
+#define PMUIO0_IOC_GPIO0A_IOMUX_SEL_H 0x004
+#define PMUIO0_IOC_GPIO0B_IOMUX_SEL_L 0x008
+
+#define PMUIO1_IOC_GPIO0B_IOMUX_SEL_H 0x000
+#define PMUIO1_IOC_GPIO0C_IOMUX_SEL_L 0x004
+#define PMUIO1_IOC_GPIO0C_IOMUX_SEL_H 0x008
+#define PMUIO1_IOC_GPIO0D_IOMUX_SEL_L 0x00c
+#define PMUIO1_IOC_GPIO0D_IOMUX_SEL_H 0x010
+
+/* PMU_PWR_CON */
+enum pmu0_pwr_con {
+ pmu_powermode0_en = 0,
+ pmu_pmu1_pd_byp = 1,
+ pmu_pmu1_bus_byp = 2,
+ pmu_pmu0_wkup_byp = 3,
+ pmu_pmu0_pmic_byp = 4,
+ pmu_pmu0_reset_byp = 5,
+ pmu_pmu0_freq_switch_byp = 6,
+ pmu_pmu0_osc_dis_byp = 7,
+ pmu_pmu1_pwrgt = 8,
+ pmu_pmu1_pwrgt_sft = 9,
+ pmu_pmu1_mempwr_sft_gt = 10,
+ pmu_pmu1_idle_en = 11,
+ pmu_pmu1_idle_sft_en = 12,
+ pmu_pmu1_noc_auto_en = 13,
+ pmu_pmu1_off_io_en = 14,
+};
+
+enum pmu1_pwr_con {
+ pmu_powermode_en = 0,
+ pmu_scu0_byp = 1,
+ pmu_scu1_byp = 2,
+ pmu_cci_byp = 3,
+ pmu_bus_byp = 4,
+ pmu_ddr_byp = 5,
+ pmu_pwrgt_byp = 6,
+ pmu_cru_byp = 7,
+ pmu_qch_byp = 8,
+ pmu_wfi_byp = 12,
+ pmu_slp_cnt_en = 13,
+};
+
+enum pmu_wakeup_int {
+ pmu_wkup_cpu0_int = 0,
+ pmu_wkup_cpu1_int = 1,
+ pmu_wkup_cpu2_int = 2,
+ pmu_wkup_cpu3_int = 3,
+ pmu_wkup_cpu4_int = 4,
+ pmu_wkup_cpu5_int = 5,
+ pmu_wkup_cpu6_int = 6,
+ pmu_wkup_cpu7_int = 7,
+ pmu_wkup_gpio0_int = 8,
+ pmu_wkup_sdmmc_int = 9,
+ pmu_wkup_sdio_int = 10,
+ pmu_wkup_usbdev_int = 11,
+ pmu_wkup_uart_int = 12,
+ pmu_wkup_mcu_int = 13,
+ pmu_wkup_timer_int = 14,
+ pmu_wkup_sys_int = 15,
+ pmu_wkup_pwm_int = 16,
+ pmu_wkup_tsadc_int = 17,
+ pmu_wkup_hptimer_int = 18,
+ pmu_wkup_saradc_int = 19,
+ pmu_wkup_timeout = 20,
+};
+
+/* PMU_DDR_PWR_CON */
+enum pmu_ddr_pwr_con {
+ pmu_ddr_sref_c_en = 0,
+ pmu_ddr_ioret_en = 1,
+ pmu_ddr_ioret_exit_en = 2,
+ pmu_ddr_rstiov_en = 3,
+ pmu_ddr_rstiov_exit_en = 4,
+ pmu_ddr_gating_c_en = 5,
+ pmu_ddr_gating_p_en = 6,
+};
+
+/* PMU_CRU_PWR_CON0 */
+enum pmu_cru_pwr_con0 {
+ pmu_alive_32k_en = 0,
+ pmu_osc_dis_en = 1,
+ pmu_wakeup_rst_en = 2,
+ pmu_input_clamp_en = 3,
+ pmu_alive_osc_mode_en = 4,
+ pmu_power_off_en = 5,
+ pmu_pwm_switch_en = 6,
+ pmu_pwm_gpio_ioe_en = 7,
+ pmu_pwm_switch_io = 8,
+ pmu_io_sleep_en = 9,
+};
+
+/* PMU_CRU_PWR_CON1 */
+enum pmu_cru_pwr_con1 {
+ pmu_bus_clksrc_gt_en = 0,
+ pmu_vpu_clksrc_gt_en = 1,
+ pmu_vo_clksrc_gt_en = 2,
+ pmu_gpu_clksrc_gt_en = 3,
+ pmu_rkenc_clksrc_gt_en = 4,
+ pmu_rkvdec_clksrc_gt_en = 5,
+ pmu_core_clksrc_gt_en = 6,
+ pmu_ddr_clksrc_gt_en = 7,
+};
+
+/* PMU_SCU_PWR_CON */
+enum pmu_scu_pwr_con {
+ pmu_l2_flush_en = 0,
+ pmu_l2_ilde_en = 1,
+ pmu_scu_pd_en = 2,
+ pmu_scu_pwroff_en = 3,
+ pmu_clst_cpu_pd_en = 5,
+ pmu_std_wfi_bypass = 8,
+ pmu_std_wfil2_bypass = 9,
+ pmu_scu_vol_gt_en = 10,
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+ pmu_d0apll_pd_en = 0,
+ pmu_d0bpll_pd_en = 1,
+ pmu_d1apll_pd_en = 2,
+ pmu_d1bpll_pd_en = 3,
+ pmu_bpll_pd_en = 4,
+ pmu_lpll_pd_en = 5,
+ pmu_spll_pd_en = 6,
+ pmu_gpll_pd_en = 7,
+ pmu_cpll_pd_en = 8,
+ pmu_ppll_pd_en = 9,
+ pmu_aupll_pd_en = 10,
+ pmu_vpll_pd_en = 11,
+};
+
+/* PMU_CLST_PWR_ST */
+enum pmu_clst_pwr_st {
+ pmu_cpu0_wfi = 0,
+ pmu_cpu1_wfi = 1,
+ pmu_cpu2_wfi = 2,
+ pmu_cpu3_wfi = 3,
+ pmu_cpu4_wfi = 4,
+ pmu_cpu5_wfi = 5,
+ pmu_cpu6_wfi = 6,
+ pmu_cpu7_wfi = 7,
+ pmu_scu0_standbywfil2 = 8,
+ pmu_scu1_standbywfil2 = 9,
+ pmu_scu0_l2flushdone = 10,
+ pmu_scu1_l2flushdone = 11,
+ pmu_cpu0_pd_st = 16,
+ pmu_cpu1_pd_st = 17,
+ pmu_cpu2_pd_st = 18,
+ pmu_cpu3_pd_st = 19,
+ pmu_cpu4_pd_st = 20,
+ pmu_cpu5_pd_st = 21,
+ pmu_cpu6_pd_st = 22,
+ pmu_cpu7_pd_st = 23,
+ pmu_scu0_pd_st = 24,
+ pmu_scu1_pd_st = 25,
+};
+
+/* PMU_CLST_IDLE_CON */
+enum pmu_clst_idle_con {
+ pmu_adb400s_idle_req = 0,
+ pmu_clst_biu_idle_req = 1,
+ pmu_clst_clk_gt_msk = 2,
+};
+
+enum cores_pm_ctr_mode {
+ core_pwr_pd = 0,
+ core_pwr_wfi = 1,
+ core_pwr_wfi_int = 2,
+ core_pwr_wfi_reset = 3,
+};
+
+/* PMU_CPUX_AUTO_PWR_CON */
+enum pmu_cpu_auto_pwr_con {
+ pmu_cpu_pm_en = 0,
+ pmu_cpu_pm_int_wakeup_en = 1,
+ pmu_cpu_pm_dis_int = 2,
+ pmu_cpu_pm_sft_wakeup_en = 3,
+};
+
+enum qos_id {
+ qos_decom = 0,
+ qos_dmac0 = 1,
+ qos_dmac1 = 2,
+ qos_dmac2 = 3,
+ qos_bus_mcu = 4,
+ qos_can0 = 5,
+ qos_can1 = 6,
+ qos_cci_m0 = 7,
+ qos_cci_m1 = 8,
+ qos_cci_m2 = 9,
+ qos_dap_lite = 10,
+ qos_hdcp1 = 11,
+ qos_ddr_mcu = 12,
+ qos_fspi1 = 13,
+ qos_gmac0 = 14,
+ qos_gmac1 = 15,
+ qos_sdio = 16,
+ qos_sdmmc = 17,
+ qos_flexbus = 18,
+ qos_gpu = 19,
+ qos_vepu1 = 20,
+ qos_npu_mcu = 21,
+ qos_npu_nsp0 = 22,
+ qos_npu_nsp1 = 23,
+ qos_npu_m0 = 24,
+ qos_npu_m1 = 25,
+ qos_npu_m0ro = 26,
+ qos_npu_m1ro = 27,
+ qos_emmc = 28,
+ qos_fspi0 = 29,
+ qos_mmu0 = 30,
+ qos_mmu1 = 31,
+ qos_pmu_mcu = 32,
+ qos_rkvdec = 33,
+ qos_crypto = 34,
+ qos_mmu2 = 35,
+ qos_ufshc = 36,
+ qos_vepu0 = 37,
+ qos_isp_mro = 38,
+ qos_isp_mwo = 39,
+ qos_vicap_m0 = 40,
+ qos_vpss_mro = 41,
+ qos_vpss_mwo = 42,
+ qos_hdcp0 = 43,
+ qos_vop_m0 = 44,
+ qos_vop_m1ro = 45,
+ qos_ebc = 46,
+ qos_rga0 = 47,
+ qos_rga1 = 48,
+ qos_jpeg = 49,
+ qos_vdpp = 50,
+ qos_dma2ddr = 51,
+};
+
+enum pmu_bus_id {
+ pmu_bus_id_gpu = 0,
+ pmu_bus_id_npu0 = 1,
+ pmu_bus_id_npu1 = 2,
+ pmu_bus_id_nputop = 3,
+ pmu_bus_id_npusys = 4,
+ pmu_bus_id_vpu = 5,
+ pmu_bus_id_vdec = 6,
+ pmu_bus_id_vepu0 = 7,
+ pmu_bus_id_vepu1 = 8,
+ pmu_bus_id_vi = 9,
+ pmu_bus_id_usb = 10,
+ pmu_bus_id_vo0 = 11,
+ pmu_bus_id_vo1 = 12,
+ pmu_bus_id_vop = 13,
+ pmu_bus_id_vop_nocddrsch = 14,
+ pmu_bus_id_php = 15,
+ pmu_bus_id_audio = 16,
+ pmu_bus_id_gmac = 17,
+ pmu_bus_id_nvm = 18,
+ pmu_bus_id_center_nocddrsch = 19,
+ pmu_bus_id_center_nocmain = 20,
+ pmu_bus_id_ddr = 21,
+ pmu_bus_id_ddrsch0 = 22,
+ pmu_bus_id_ddrsch1 = 23,
+ pmu_bus_id_bus = 24,
+ pmu_bus_id_secure = 25,
+ pmu_bus_id_top = 26,
+ pmu_bus_id_vo0vop_chn = 27,
+ pmu_bus_id_cci = 28,
+ pmu_bus_id_cci_nocddrsch = 29,
+ pmu_bus_id_max,
+};
+
+enum pmu_pd_id {
+ pmu_pd_npu = 0,
+ pmu_pd_bus = 1,
+ pmu_pd_secure = 2,
+ pmu_pd_center = 3,
+ pmu_pd_ddr = 4,
+ pmu_pd_cci = 5,
+ pmu_pd_nvm = 6,
+ pmu_pd_sd_gmac = 7,
+ pmu_pd_audio = 8,
+ pmu_pd_php = 9,
+ pmu_pd_subphp = 10,
+ pmu_pd_vop = 11,
+ pmu_pd_vop_smart = 12,
+ pmu_pd_vop_clst = 13,
+ pmu_pd_vo1 = 14,
+ pmu_pd_vo0 = 15,
+ pmu_pd_usb = 16,
+ pmu_pd_vi = 17,
+ pmu_pd_vepu0 = 18,
+ pmu_pd_vepu1 = 19,
+ pmu_pd_vdec = 20,
+ pmu_pd_vpu = 21,
+ pmu_pd_nputop = 22,
+ pmu_pd_npu0 = 23,
+ pmu_pd_npu1 = 24,
+ pmu_pd_gpu = 25,
+ pmu_pd_id_max,
+};
+
+enum pmu_vd_id {
+ pmu_vd_npu = 0,
+ pmu_vd_ddr = 1,
+ pmu_vd_cci = 2,
+ pmu_vd_gpu = 3,
+};
+
+enum pmu_bus_state {
+ pmu_bus_active = 0,
+ pmu_bus_idle = 1,
+};
+
+enum pmu_pd_state {
+ pmu_pd_on = 0,
+ pmu_pd_off = 1
+};
+
+enum pmu_scu_fsm_st {
+ pmu_scu_fsm_normal = 0,
+ pmu_scu_fsm_cpu_pwr_down = 1,
+ pmu_scu_fsm_l2_flush = 2,
+ pmu_scu_fsm_l2_idle = 3,
+ pmu_scu_fsm_clust_idle = 4,
+ pmu_scu_fsm_scu_pwr_down = 5,
+ pmu_scu_fsm_sleep = 6,
+ pmu_scu_fsm_wkup = 7,
+ pmu_scu_fsm_scu_pwr_up = 8,
+ pmu_scu_fsm_clust_resume = 9,
+ pmu_scu_fsm_cpu_pwr_up = 10,
+};
+
+#define MAX_MEM_OS_REG_NUM 32
+#define MEM_OS_REG_BASE \
+ (PMUSRAM_BASE + PMUSRAM_RSIZE - MAX_MEM_OS_REG_NUM * 4)
+
+#define PSRAM_SP_TOP MEM_OS_REG_BASE
+
+#define PD_CTR_LOOP 5000
+#define WFEI_CHECK_LOOP 5000
+#define BUS_IDLE_LOOP 1000
+#define NONBOOT_CPUS_OFF_LOOP 500000
+
+#define REBOOT_FLAG 0x5242C300
+#define BOOT_BROM_DOWNLOAD 0xef08a53c
+
+#define BOOTROM_SUSPEND_MAGIC 0x02468ace
+#define BOOTROM_RESUME_MAGIC 0x13579bdf
+#define WARM_BOOT_MAGIC 0x76543210
+#define VALID_GLB_RST_MSK 0xbfff
+
+#define DEFAULT_BOOT_CPU 0
+
+/*******************************************************
+ * sleep mode define
+ *******************************************************/
+#define SLP_ARMPD BIT(0)
+#define SLP_ARMOFF BIT(1)
+#define SLP_ARMOFF_DDRPD BIT(2)
+#define SLP_ARMOFF_LOGOFF BIT(3)
+#define SLP_ARMOFF_PMUOFF BIT(4)
+#define SLP_FROM_UBOOT BIT(5)
+
+/* all plls except ddr's pll*/
+#define SLP_PMU_HW_PLLS_PD BIT(8)
+#define SLP_PMU_PMUALIVE_32K BIT(9)
+#define SLP_PMU_DIS_OSC BIT(10)
+
+#define SLP_CLK_GT BIT(16)
+#define SLP_PMIC_LP BIT(17)
+
+#define SLP_32K_EXT BIT(24)
+#define SLP_TIME_OUT_WKUP BIT(25)
+#define SLP_PMU_DBG BIT(26)
+#define SLP_ARCH_TIMER_RESET BIT(27)
+
+#define PM_INVALID_GPIO 0xffff
+#define MAX_GPIO_POWER_CFG_CNT 10
+#define MAX_VIRTUAL_PWROFF_IRQ_CNT 20
+
+enum {
+ RK_PM_VIRT_PWROFF_EN = 0,
+ RK_PM_VIRT_PWROFF_IRQ_CFG = 1,
+ RK_PM_VIRT_PWROFF_MAX,
+};
+
+/* sleep pin */
+#define RKPM_SLEEP_PIN0_EN BIT(0) /* GPIO0_A3 */
+#define RKPM_SLEEP_PIN1_EN BIT(1) /* GPIO0_A4 */
+#define RKPM_SLEEP_PIN2_EN BIT(2) /* GPIO0_A5 */
+
+#define RKPM_SLEEP_PIN0_ACT_LOW BIT(0) /* GPIO0_A3 */
+#define RKPM_SLEEP_PIN1_ACT_LOW BIT(1) /* GPIO0_A4 */
+#define RKPM_SLEEP_PIN2_ACT_LOW BIT(2) /* GPIO0_A5 */
+
+#define pmu_bus_idle_st(id) \
+ (!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ST) & BIT(id)))
+
+#define pmu_bus_idle_ack(id) \
+ (!!(mmio_read_32(PMU_BASE + PMU2_BUS_IDLE_ACK) & BIT(id)))
+
+static inline uint32_t read_mem_os_reg(uint32_t id)
+{
+ assert((id) < MAX_MEM_OS_REG_NUM);
+
+ return mmio_read_32(MEM_OS_REG_BASE + 4 * (id));
+}
+
+static inline void write_mem_os_reg(uint32_t id, uint32_t val)
+{
+ assert((id) < MAX_MEM_OS_REG_NUM);
+
+ mmio_write_32(MEM_OS_REG_BASE + 4 * (id), val);
+}
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3576/drivers/secure/firewall.c b/plat/rockchip/rk3576/drivers/secure/firewall.c
new file mode 100644
index 0000000..5da9ea8
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/firewall.c
@@ -0,0 +1,693 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <firewall.h>
+#include <soc.h>
+
+enum {
+ FW_NS_A_S_A = 0x0,
+ FW_NS_A_S_NA = 0x1,
+ FW_NS_NA_S_A = 0x2,
+ FW_NS_NA_S_NA = 0x3,
+};
+
+/* group type */
+enum {
+ FW_GRP_TYPE_INV = 0,
+ FW_GRP_TYPE_DDR_RGN = 1,
+ FW_GRP_TYPE_SYSMEM_RGN = 2,
+ FW_GRP_TYPE_CBUF_RGN = 3,
+ FW_GRP_TYPE_SLV = 4,
+ FW_GRP_TYPE_DM = 5,
+};
+
+enum {
+ FW_SLV_TYPE_INV = 0,
+ FW_MST_TYPE_INV = 0,
+ FW_SLV_TYPE_BUS = 1,
+ FW_SLV_TYPE_TOP = 2,
+ FW_SLV_TYPE_CENTER = 3,
+ FW_SLV_TYPE_CCI = 4,
+ FW_SLV_TYPE_PHP = 5,
+ FW_SLV_TYPE_GPU = 6,
+ FW_SLV_TYPE_NPU = 7,
+ FW_SLV_TYPE_PMU = 8,
+ FW_MST_TYPE_SYS = 9,
+ FW_MST_TYPE_PMU = 10,
+};
+
+#define FW_ID(type, id) \
+ ((((type) & 0xff) << 16) | ((id) & 0xffff))
+
+#define FW_MST_ID(type, id) FW_ID(type, id)
+#define FW_SLV_ID(type, id) FW_ID(type, id)
+#define FW_GRP_ID(type, id) FW_ID(type, id)
+
+/* group id */
+#define FW_GRP_ID_DDR_RGN(id) FW_GRP_ID(FW_GRP_TYPE_DDR_RGN, id)
+#define FW_GRP_ID_SYSMEM_RGN(id) FW_GRP_ID(FW_GRP_TYPE_SYSMEM_RGN, id)
+#define FW_GRP_ID_CBUF(id) FW_GRP_ID(FW_GRP_TYPE_CBUF_RGN, id)
+#define FW_GRP_ID_SLV(id) FW_GRP_ID(FW_GRP_TYPE_SLV, id)
+#define FW_GRP_ID_DM(id) FW_GRP_ID(FW_GRP_TYPE_DM, id)
+
+#define FW_GRP_ID_SLV_CNT 8
+#define FW_GRP_ID_DM_CNT 8
+
+#define FW_GET_ID(id) ((id) & 0xffff)
+#define FW_GET_TYPE(id) (((id) >> 16) & 0xff)
+
+#define FW_INVLID_MST_ID FW_MST_ID(FW_MST_TYPE_INV, 0)
+#define FW_INVLID_SLV_ID FW_SLV_ID(FW_SLV_TYPE_INV, 0)
+
+typedef struct {
+ uint32_t domain[FW_SGRF_MST_DOMAIN_CON_CNT];
+ uint32_t pmu_domain;
+ uint32_t bus_slv_grp[FW_SGRF_BUS_SLV_CON_CNT];
+ uint32_t top_slv_grp[FW_SGRF_TOP_SLV_CON_CNT];
+ uint32_t center_slv_grp[FW_SGRF_CENTER_SLV_CON_CNT];
+ uint32_t cci_slv_grp[FW_SGRF_CCI_SLV_CON_CNT];
+ uint32_t php_slv_grp[FW_SGRF_PHP_SLV_CON_CNT];
+ uint32_t gpu_slv_grp;
+ uint32_t npu_slv_grp[FW_SGRF_NPU_SLV_CON_CNT];
+ uint32_t pmu_slv_grp[FW_PMU_SGRF_SLV_CON_CNT];
+ uint32_t ddr_rgn[FW_SGRF_DDR_RGN_CNT];
+ uint32_t ddr_size;
+ uint32_t ddr_con;
+ uint32_t sysmem_rgn[FW_SGRF_SYSMEM_RGN_CNT];
+ uint32_t sysmem_con;
+ uint32_t cbuf_rgn[FW_SGRF_CBUF_RGN_CNT];
+ uint32_t cbuf_con;
+ uint32_t ddr_lookup[FW_SGRF_DDR_LOOKUP_CNT];
+ uint32_t sysmem_lookup[FW_SGRF_SYSMEM_LOOKUP_CNT];
+ uint32_t cbuf_lookup[FW_SGRF_CBUF_LOOKUP_CNT];
+ uint32_t slv_lookup[FW_SGRF_SLV_LOOKUP_CNT];
+ uint32_t pmu_slv_lookup[FW_PMU_SGRF_SLV_LOOKUP_CNT];
+} fw_config_t;
+
+static fw_config_t fw_config_buf;
+
+/****************************************************************************
+ * Access rights between domains and groups are as follows:
+ *
+ * 00: NS access, S access
+ * 01: NS access, S not access
+ * 10: NS not access, S access
+ * 11: NS not access, S not access
+ * |---------------------------------------------------------|
+ * | | d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 |
+ * |---------------------------------------------------------|
+ * | slave g0 | 00 | 00 | 11 | 11 | 11 | 11 | 11 | 00 |
+ * |---------------------------------------------------------|
+ * | slave g1 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | slave g2~7 | 11 | 11 | 11 | 11 | 11 | 11 | 11 | 11 |
+ * |---------------------------------------------------------|
+ * | ddr region 0~15 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | sram region 0~3 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ * | cbuf region 0~7 | 10 | 11 | 11 | 11 | 11 | 11 | 11 | 10 |
+ * |---------------------------------------------------------|
+ *
+ * PS:
+ * Domain 0/1/7 NS/S can access group 0.
+ * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+ * Other domains NS/S can't access all groups.
+ *
+ * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
+ * Other domains NS/S can't access ddr/sram/cbuf region.
+ *
+ ******************************************************************************/
+
+/* Masters in dm1 */
+static const int dm1_mst[] = {
+ FW_MST_ID(FW_MST_TYPE_SYS, 1), /* keylad_apbm */
+ FW_MST_ID(FW_MST_TYPE_SYS, 2), /* dft2apbm */
+ FW_MST_ID(FW_MST_TYPE_SYS, 11), /* dma2ddr */
+ FW_MST_ID(FW_MST_TYPE_SYS, 12), /* dmac0 */
+ FW_MST_ID(FW_MST_TYPE_SYS, 13), /* dmac1 */
+ FW_MST_ID(FW_MST_TYPE_SYS, 14), /* dmac2 */
+ FW_MST_ID(FW_MST_TYPE_SYS, 19), /* gpu */
+ FW_MST_ID(FW_MST_TYPE_SYS, 31), /* vop_m0 */
+ FW_MST_ID(FW_MST_TYPE_SYS, 32), /* vop_m1 */
+ FW_MST_ID(FW_MST_TYPE_SYS, 36), /* bus_mcu */
+ FW_MST_ID(FW_MST_TYPE_SYS, 38), /* npu_mcu */
+ FW_MST_ID(FW_MST_TYPE_SYS, 56), /* dap_lite */
+
+ FW_INVLID_MST_ID
+};
+
+/* Slaves in group1 */
+static const int sec_slv[] = {
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 28), /* crypto_s */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 29), /* keyladder_s */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 30), /* rkrng_s */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 33), /* jtag_lock */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 34), /* otp_s */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 35), /* otpmsk */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 37), /* scru_s */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 38), /* sys_sgrf */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 39), /* bootrom */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 41), /* wdts */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 44), /* sevice_secure */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 61), /* timers0_ch0~5 */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 62),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 63),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 64),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 65),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 66),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 67), /* timers1_ch0~5 */
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 68),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 69),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 70),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 71),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 72),
+ FW_SLV_ID(FW_SLV_TYPE_TOP, 73), /* sys_fw */
+
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 3), /* ddr grf */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 4), /* ddr ctl0 */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 5), /* ddr ctl1 */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 6), /* ddr phy0 */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 7), /* ddr0 cru */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 8), /* ddr phy1 */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 9), /* ddr1 cru */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 15), /* ddr wdt */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 19), /* service ddr */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 58), /* ddr timer ch0 */
+ FW_SLV_ID(FW_SLV_TYPE_CENTER, 59), /* ddr timer ch1 */
+
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 1), /* pmu mem */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 15), /* pmu1_scru */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 30), /* osc chk */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 31), /* pmu0_sgrf */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 32), /* pmu1_sgrf */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 34), /* scramble key */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 36), /* pmu remap */
+ FW_SLV_ID(FW_SLV_TYPE_PMU, 43), /* pmu fw */
+
+ FW_INVLID_SLV_ID
+};
+
+static void fw_buf_sys_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+ int sft = (mst_id & 0x7) << 2;
+
+ fw_config_buf.domain[mst_id >> 3] &= ~(0xf << sft);
+ fw_config_buf.domain[mst_id >> 3] |= (dm_id & 0xf) << sft;
+}
+
+static void fw_buf_pmu_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+ int sft = (mst_id & 0x7) << 2;
+
+ fw_config_buf.pmu_domain &= ~(0xf << sft);
+ fw_config_buf.pmu_domain |= (dm_id & 0xf) << sft;
+}
+
+void fw_buf_mst_dm_cfg(int mst_id, uint32_t dm_id)
+{
+ int type = FW_GET_TYPE(mst_id);
+
+ mst_id = FW_GET_ID(mst_id);
+
+ switch (type) {
+ case FW_MST_TYPE_SYS:
+ fw_buf_sys_mst_dm_cfg(mst_id, dm_id);
+ break;
+ case FW_MST_TYPE_PMU:
+ fw_buf_pmu_mst_dm_cfg(mst_id, dm_id);
+ break;
+
+ default:
+ ERROR("%s: unknown FW_DOMAIN_TYPE (0x%x)\n", __func__, type);
+ break;
+ }
+}
+
+static void fw_buf_ddr_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+ int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+ fw_config_buf.ddr_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+ fw_config_buf.ddr_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_sysmem_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+ int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+ fw_config_buf.sysmem_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+ fw_config_buf.sysmem_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_cbuf_lookup_cfg(int rgn_id, int dm_id, uint32_t priv)
+{
+ int sft = (dm_id << 1) + (rgn_id & 0x1) * 16;
+
+ fw_config_buf.cbuf_lookup[rgn_id >> 1] &= ~(0x3 << sft);
+ fw_config_buf.cbuf_lookup[rgn_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+ int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
+
+ fw_config_buf.slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
+ fw_config_buf.slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
+}
+
+static void fw_buf_pmu_slv_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+ int sft = (dm_id << 1) + (grp_id & 0x1) * 16;
+
+ fw_config_buf.pmu_slv_lookup[grp_id >> 1] &= ~(0x3 << sft);
+ fw_config_buf.pmu_slv_lookup[grp_id >> 1] |= (priv & 0x3) << sft;
+}
+
+void fw_buf_grp_lookup_cfg(int grp_id, int dm_id, uint32_t priv)
+{
+ uint32_t type = FW_GET_TYPE(grp_id);
+
+ grp_id = FW_GET_ID(grp_id);
+
+ switch (type) {
+ case FW_GRP_TYPE_DDR_RGN:
+ fw_buf_ddr_lookup_cfg(grp_id, dm_id, priv);
+ break;
+ case FW_GRP_TYPE_SYSMEM_RGN:
+ fw_buf_sysmem_lookup_cfg(grp_id, dm_id, priv);
+ break;
+ case FW_GRP_TYPE_CBUF_RGN:
+ fw_buf_cbuf_lookup_cfg(grp_id, dm_id, priv);
+ break;
+ case FW_GRP_TYPE_SLV:
+ fw_buf_slv_lookup_cfg(grp_id, dm_id, priv);
+ fw_buf_pmu_slv_lookup_cfg(grp_id, dm_id, priv);
+ break;
+
+ default:
+ ERROR("%s: unknown FW_LOOKUP_TYPE (0x%x)\n", __func__, type);
+ break;
+ }
+}
+
+static void fw_buf_bus_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.bus_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.bus_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_top_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.top_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.top_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_center_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.center_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.center_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_cci_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.cci_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.cci_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_php_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.php_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.php_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_gpu_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.gpu_slv_grp &= ~(0xf << sft);
+ fw_config_buf.gpu_slv_grp |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_npu_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.npu_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.npu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+static void fw_buf_pmu_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int sft = slv_id % 5 << 2;
+
+ fw_config_buf.pmu_slv_grp[slv_id / 5] &= ~(0xf << sft);
+ fw_config_buf.pmu_slv_grp[slv_id / 5] |= (grp_id & 0xf) << sft;
+}
+
+void fw_buf_slv_grp_cfg(int slv_id, int grp_id)
+{
+ int type = FW_GET_TYPE(slv_id);
+
+ slv_id = FW_GET_ID(slv_id);
+ grp_id = FW_GET_ID(grp_id);
+
+ switch (type) {
+ case FW_SLV_TYPE_BUS:
+ fw_buf_bus_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_TOP:
+ fw_buf_top_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_CENTER:
+ fw_buf_center_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_CCI:
+ fw_buf_cci_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_PHP:
+ fw_buf_php_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_GPU:
+ fw_buf_gpu_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_NPU:
+ fw_buf_npu_slv_grp_cfg(slv_id, grp_id);
+ break;
+ case FW_SLV_TYPE_PMU:
+ fw_buf_pmu_slv_grp_cfg(slv_id, grp_id);
+ break;
+
+ default:
+ ERROR("%s: unknown FW_SLV_TYPE (0x%x)\n", __func__, type);
+ break;
+ }
+}
+
+void fw_buf_add_msts(const int *mst_ids, int dm_id)
+{
+ int i;
+
+ for (i = 0; FW_GET_TYPE(mst_ids[i]) != FW_INVLID_SLV_ID; i++)
+ fw_buf_mst_dm_cfg(mst_ids[i], dm_id);
+}
+
+void fw_buf_add_slvs(const int *slv_ids, int grp_id)
+{
+ int i;
+
+ for (i = 0; FW_GET_TYPE(slv_ids[i]) != FW_INVLID_SLV_ID; i++)
+ fw_buf_slv_grp_cfg(slv_ids[i], grp_id);
+}
+
+/* unit: Mb */
+void fw_buf_ddr_size_cfg(uint64_t base_mb, uint64_t top_mb, int id)
+{
+ fw_config_buf.ddr_size = RG_MAP_SECURE(top_mb, base_mb);
+ fw_config_buf.ddr_con |= BIT(16);
+}
+
+/* unit: Mb */
+void fw_buf_ddr_rgn_cfg(uint64_t base_mb, uint64_t top_mb, int rgn_id)
+{
+ fw_config_buf.ddr_rgn[rgn_id] = RG_MAP_SECURE(top_mb, base_mb);
+ fw_config_buf.ddr_con |= BIT(rgn_id);
+}
+
+/* Unit: kb */
+void fw_buf_sysmem_rgn_cfg(uint64_t base_kb, uint64_t top_kb, int rgn_id)
+{
+ fw_config_buf.sysmem_rgn[rgn_id] = RG_MAP_SRAM_SECURE(top_kb, base_kb);
+ fw_config_buf.sysmem_con |= BIT(rgn_id);
+}
+
+static void fw_domain_init(void)
+{
+ int i;
+
+ /* select to domain0 by default */
+ for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
+ fw_config_buf.domain[i] = 0x0;
+
+ /* select to domain0 by default */
+ fw_config_buf.pmu_domain = 0x0;
+}
+
+static void fw_slv_grp_init(void)
+{
+ int i;
+
+ /* select to group0 by default */
+ for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
+ fw_config_buf.bus_slv_grp[i] = 0x0;
+
+ for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
+ fw_config_buf.top_slv_grp[i] = 0x0;
+
+ for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
+ fw_config_buf.center_slv_grp[i] = 0x0;
+
+ for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
+ fw_config_buf.cci_slv_grp[i] = 0x0;
+
+ for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
+ fw_config_buf.php_slv_grp[i] = 0x0;
+
+ fw_config_buf.gpu_slv_grp = 0x0;
+
+ for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
+ fw_config_buf.npu_slv_grp[i] = 0x0;
+}
+
+static void fw_region_init(void)
+{
+ /* Use FW_DDR_RGN0_REG to config 1024~1025M space to secure */
+ fw_buf_ddr_rgn_cfg(1024, 1025, 0);
+
+ /* Use FW_SYSMEM_RGN0_REG to config 0~32k space to secure */
+ fw_buf_sysmem_rgn_cfg(0, 32, 0);
+}
+
+static void fw_lookup_init(void)
+{
+ int i;
+
+ /*
+ * Domain 0/7 NS can't access ddr/sram/cbuf region and Domain 0/7 S can access.
+ * Other domains NS/S can't access ddr/sram/cbuf region.
+ */
+ for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+ fw_config_buf.ddr_lookup[i] = 0xbffebffe;
+
+ for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+ fw_config_buf.sysmem_lookup[i] = 0xbffebffe;
+
+ for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+ fw_config_buf.cbuf_lookup[i] = 0xbffebffe;
+
+ /*
+ * Domain 0/1/7 NS/S can access group 0.
+ * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+ * Other domains NS/S can't access all groups.
+ */
+ fw_config_buf.slv_lookup[0] = 0xbffe3ff0;
+ fw_config_buf.slv_lookup[1] = 0xffffffff;
+ fw_config_buf.slv_lookup[2] = 0xffffffff;
+ fw_config_buf.slv_lookup[3] = 0xffffffff;
+
+ /*
+ * Domain 0/1/7 NS/S can access group 0.
+ * Domain 0/1/7 NS and Domain1 NS/S can't access group 1, domain 0/7 S can access.
+ * Other domains NS/S can't access all groups.
+ */
+ fw_config_buf.pmu_slv_lookup[0] = 0xbffe3ff0;
+ fw_config_buf.pmu_slv_lookup[1] = 0xffffffff;
+ fw_config_buf.pmu_slv_lookup[2] = 0xffffffff;
+ fw_config_buf.pmu_slv_lookup[3] = 0xffffffff;
+}
+
+static void fw_config_buf_flush(void)
+{
+ int i;
+
+ /* domain */
+ for (i = 0; i < FW_SGRF_MST_DOMAIN_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_MST_DOMAIN_CON(i),
+ fw_config_buf.domain[i]);
+
+ mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_DOMAIN_CON,
+ fw_config_buf.pmu_domain);
+
+ /* slave group */
+ for (i = 0; i < FW_SGRF_BUS_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_BUS_SLV_CON(i),
+ fw_config_buf.bus_slv_grp[i]);
+
+ for (i = 0; i < FW_SGRF_TOP_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_TOP_SLV_CON(i),
+ fw_config_buf.top_slv_grp[i]);
+
+ for (i = 0; i < FW_SGRF_CENTER_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CENTER_SLV_CON(i),
+ fw_config_buf.center_slv_grp[i]);
+
+ for (i = 0; i < FW_SGRF_CCI_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CCI_SLV_CON(i),
+ fw_config_buf.cci_slv_grp[i]);
+
+ for (i = 0; i < FW_SGRF_PHP_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_PHP_SLV_CON(i),
+ fw_config_buf.php_slv_grp[i]);
+
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_GPU_SLV_CON,
+ fw_config_buf.gpu_slv_grp);
+
+ for (i = 0; i < FW_SGRF_NPU_SLV_CON_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_NPU_SLV_CON(i),
+ fw_config_buf.npu_slv_grp[i]);
+
+ for (i = 0; i < FW_PMU_SGRF_SLV_CON_CNT; i++)
+ mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_CON(i),
+ fw_config_buf.pmu_slv_grp[i]);
+
+ /* region */
+ for (i = 0; i < FW_SGRF_DDR_RGN_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_RGN(i),
+ fw_config_buf.ddr_rgn[i]);
+
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_SIZE, fw_config_buf.ddr_size);
+
+ for (i = 0; i < FW_SGRF_SYSMEM_RGN_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_RGN(i),
+ fw_config_buf.sysmem_rgn[i]);
+
+ for (i = 0; i < FW_SGRF_CBUF_RGN_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_RGN(i),
+ fw_config_buf.cbuf_rgn[i]);
+
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, fw_config_buf.ddr_con);
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, fw_config_buf.sysmem_con);
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, fw_config_buf.cbuf_con);
+
+ dsb();
+ isb();
+
+ /* lookup */
+ for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i),
+ fw_config_buf.ddr_lookup[i]);
+
+ for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i),
+ fw_config_buf.sysmem_lookup[i]);
+
+ for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i),
+ fw_config_buf.cbuf_lookup[i]);
+
+ for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i),
+ fw_config_buf.slv_lookup[i]);
+
+ for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
+ mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i),
+ fw_config_buf.pmu_slv_lookup[i]);
+
+ dsb();
+ isb();
+}
+
+static __pmusramfunc void pmusram_udelay(uint32_t us)
+{
+ uint64_t orig;
+ uint64_t to_wait;
+
+ orig = read_cntpct_el0();
+ to_wait = read_cntfrq_el0() * us / 1000000;
+
+ while (read_cntpct_el0() - orig <= to_wait)
+ ;
+}
+
+__pmusramfunc void pmusram_fw_update_msk(uint32_t msk)
+{
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
+ BITS_WITH_WMASK(0, 0x3ff, 0));
+ dsb();
+
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON0,
+ BITS_WITH_WMASK(msk, msk, 0));
+ dsb();
+ isb();
+ pmusram_udelay(20);
+ dsb();
+ isb();
+}
+
+__pmusramfunc void pmusram_all_fw_bypass(void)
+{
+ int i;
+
+ /* disable regions */
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_CON, 0);
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_CON, 0);
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_CON, 0);
+
+ for (i = 0; i < FW_SGRF_DDR_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_DDR_LOOKUP(i), 0x0);
+
+ for (i = 0; i < FW_SGRF_SYSMEM_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SYSMEM_LOOKUP(i), 0x0);
+
+ for (i = 0; i < FW_SGRF_CBUF_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_CBUF_LOOKUP(i), 0x0);
+
+ for (i = 0; i < FW_SGRF_SLV_LOOKUP_CNT; i++)
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_SLV_LOOKUP(i), 0x0);
+
+ for (i = 0; i < FW_PMU_SGRF_SLV_LOOKUP_CNT; i++)
+ mmio_write_32(PMU1SGRF_FW_BASE + FW_PMU_SGRF_SLV_LOOKUP(i), 0x0);
+
+ dsb();
+
+ pmusram_fw_update_msk(0x3ff);
+}
+
+void fw_init(void)
+{
+ /* Enable all fw auto-update */
+ mmio_write_32(SYS_SGRF_FW_BASE + FW_SGRF_KEYUPD_CON1, 0x03ff03ff);
+
+ pmusram_all_fw_bypass();
+
+ fw_domain_init();
+ fw_slv_grp_init();
+ fw_region_init();
+
+ fw_buf_add_slvs(sec_slv, 1);
+ fw_buf_add_msts(dm1_mst, 1);
+
+ fw_lookup_init();
+
+ fw_config_buf_flush();
+ pmusram_fw_update_msk(0x3ff);
+}
diff --git a/plat/rockchip/rk3576/drivers/secure/firewall.h b/plat/rockchip/rk3576/drivers/secure/firewall.h
new file mode 100644
index 0000000..7b13071
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/firewall.h
@@ -0,0 +1,499 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __FIREWALL_H__
+#define __FIREWALL_H__
+
+#include <plat_private.h>
+
+/* FW SGRF */
+#define FW_SGRF_MST_DOMAIN_CON(i) ((i) * 4)
+#define FW_SGRF_MST_DOMAIN_CON_CNT 8
+#define FW_SGRF_DDR_RGN(i) (0x0100 + (i) * 4)
+#define FW_SGRF_DDR_RGN_CNT 16
+#define FW_SGRF_DDR_LOOKUP(i) (0x0140 + (i) * 0x4)
+#define FW_SGRF_DDR_LOOKUP_CNT 8
+#define FW_SGRF_DDR_SIZE 0x0160
+#define FW_SGRF_DDR_CON 0x0168
+#define FW_SGRF_SYSMEM_RGN(i) (0x0200 + (i) * 4)
+#define FW_SGRF_SYSMEM_RGN_CNT 4
+#define FW_SGRF_SYSMEM_LOOKUP(i) (0x0210 + (i) * 4)
+#define FW_SGRF_SYSMEM_LOOKUP_CNT 2
+#define FW_SGRF_SYSMEM_CON 0x0218
+#define FW_SGRF_CBUF_RGN(i) (0x0300 + (i) * 4)
+#define FW_SGRF_CBUF_RGN_CNT 8
+#define FW_SGRF_CBUF_LOOKUP(i) (0x0320 + (i) * 4)
+#define FW_SGRF_CBUF_LOOKUP_CNT 4
+#define FW_SGRF_CBUF_CON 0x0330
+#define FW_SGRF_SLV_LOOKUP(i) (0x0400 + (i) * 4)
+#define FW_SGRF_SLV_LOOKUP_CNT 4
+#define FW_SGRF_BUS_SLV_CON(i) (0x0500 + (i) * 4)
+#define FW_SGRF_BUS_SLV_CON_CNT 25
+#define FW_SGRF_BUS_SLV_STAT 0x0580
+#define FW_SGRF_TOP_SLV_CON(i) (0x0600 + (i) * 4)
+#define FW_SGRF_TOP_SLV_CON_CNT 16
+#define FW_SGRF_TOP_SLV_STAT 0x0680
+#define FW_SGRF_CENTER_SLV_CON(i) (0x0700 + (i) * 4)
+#define FW_SGRF_CENTER_SLV_CON_CNT 13
+#define FW_SGRF_CCI_SLV_CON(i) (0x0800 + (i) * 4)
+#define FW_SGRF_CCI_SLV_CON_CNT 3
+#define FW_SGRF_PHP_SLV_CON(i) (0x0900 + (i) * 4)
+#define FW_SGRF_PHP_SLV_CON_CNT 4
+#define FW_SGRF_PHP_SLV_STAT 0x0940
+#define FW_SGRF_GPU_SLV_CON 0x0980
+#define FW_SGRF_NPU_SLV_CON(i) (0x09a0 + (i) * 4)
+#define FW_SGRF_NPU_SLV_CON_CNT 2
+#define FW_SGRF_STATCLR_CON0 0x0a00
+#define FW_SGRF_KEYUPD_CON0 0x0a80
+#define FW_SGRF_KEYUPD_CON1 0x0a84
+#define FW_SGRF_KEYUPD_STAT 0x0ab0
+
+/* FW PMUSGRF */
+#define FW_PMU_SGRF_SLV_CON(i) ((i) * 4)
+#define FW_PMU_SGRF_SLV_CON_CNT 9
+#define FW_PMU_SGRF_SLV_LOOKUP(i) (0x0080 + (i) * 0x4)
+#define FW_PMU_SGRF_SLV_LOOKUP_CNT 4
+#define FW_PMU_SGRF_DOMAIN_CON 0x00a0
+#define FW_PMU_SGRF_SLV_STAT 0x00c0
+
+/* master id */
+#define FW_MST_ID_USB0 FW_MST_ID(FW_MST_TYPE_SYS, 0)
+#define FW_MST_ID_KEYLAD_APB FW_MST_ID(FW_MST_TYPE_SYS, 1)
+#define FW_MST_ID_DFT2APB FW_MST_ID(FW_MST_TYPE_SYS, 2)
+#define FW_MST_ID_PCIE0 FW_MST_ID(FW_MST_TYPE_SYS, 3)
+#define FW_MST_ID_PCIE1 FW_MST_ID(FW_MST_TYPE_SYS, 4)
+#define FW_MST_ID_SATA0 FW_MST_ID(FW_MST_TYPE_SYS, 6)
+#define FW_MST_ID_SATA1 FW_MST_ID(FW_MST_TYPE_SYS, 7)
+#define FW_MST_ID_CRYPTO FW_MST_ID(FW_MST_TYPE_SYS, 8)
+#define FW_MST_ID_FLEXBUS FW_MST_ID(FW_MST_TYPE_SYS, 9)
+#define FW_MST_ID_DECOM FW_MST_ID(FW_MST_TYPE_SYS, 10)
+#define FW_MST_ID_DMA2DDR FW_MST_ID(FW_MST_TYPE_SYS, 11)
+#define FW_MST_ID_DMAC0 FW_MST_ID(FW_MST_TYPE_SYS, 12)
+#define FW_MST_ID_DMAC1 FW_MST_ID(FW_MST_TYPE_SYS, 13)
+#define FW_MST_ID_DMAC2 FW_MST_ID(FW_MST_TYPE_SYS, 14)
+#define FW_MST_ID_EBC FW_MST_ID(FW_MST_TYPE_SYS, 15)
+#define FW_MST_ID_EMMC FW_MST_ID(FW_MST_TYPE_SYS, 16)
+#define FW_MST_ID_GMAC0 FW_MST_ID(FW_MST_TYPE_SYS, 17)
+#define FW_MST_ID_GMAC1 FW_MST_ID(FW_MST_TYPE_SYS, 18)
+#define FW_MST_ID_GPU FW_MST_ID(FW_MST_TYPE_SYS, 19)
+#define FW_MST_ID_HDCP0 FW_MST_ID(FW_MST_TYPE_SYS, 20)
+#define FW_MST_ID_HDCP1 FW_MST_ID(FW_MST_TYPE_SYS, 21)
+#define FW_MST_ID_ISP FW_MST_ID(FW_MST_TYPE_SYS, 22)
+#define FW_MST_ID_RGA0 FW_MST_ID(FW_MST_TYPE_SYS, 23)
+#define FW_MST_ID_RGA1 FW_MST_ID(FW_MST_TYPE_SYS, 24)
+#define FW_MST_ID_JPEG FW_MST_ID(FW_MST_TYPE_SYS, 25)
+#define FW_MST_ID_RKVDEC FW_MST_ID(FW_MST_TYPE_SYS, 26)
+#define FW_MST_ID_VEPU0 FW_MST_ID(FW_MST_TYPE_SYS, 27)
+#define FW_MST_ID_UFSHC FW_MST_ID(FW_MST_TYPE_SYS, 28)
+#define FW_MST_ID_VDPP FW_MST_ID(FW_MST_TYPE_SYS, 29)
+#define FW_MST_ID_VICAP FW_MST_ID(FW_MST_TYPE_SYS, 30)
+#define FW_MST_ID_VOP_M0 FW_MST_ID(FW_MST_TYPE_SYS, 31)
+#define FW_MST_ID_VOP_M1 FW_MST_ID(FW_MST_TYPE_SYS, 32)
+#define FW_MST_ID_VPSS FW_MST_ID(FW_MST_TYPE_SYS, 33)
+#define FW_MST_ID_FSPI0 FW_MST_ID(FW_MST_TYPE_SYS, 34)
+#define FW_MST_ID_FSPI1 FW_MST_ID(FW_MST_TYPE_SYS, 35)
+#define FW_MST_ID_BUS_MCU FW_MST_ID(FW_MST_TYPE_SYS, 36)
+#define FW_MST_ID_DDR_MCU FW_MST_ID(FW_MST_TYPE_SYS, 37)
+#define FW_MST_ID_NPU_MCU FW_MST_ID(FW_MST_TYPE_SYS, 38)
+#define FW_MST_ID_CAN0 FW_MST_ID(FW_MST_TYPE_SYS, 39)
+#define FW_MST_ID_CAN1 FW_MST_ID(FW_MST_TYPE_SYS, 40)
+#define FW_MST_ID_SDIO FW_MST_ID(FW_MST_TYPE_SYS, 41)
+#define FW_MST_ID_SDMMC0 FW_MST_ID(FW_MST_TYPE_SYS, 42)
+#define FW_MST_ID_USB1 FW_MST_ID(FW_MST_TYPE_SYS, 43)
+#define FW_MST_ID_NPU_M0 FW_MST_ID(FW_MST_TYPE_SYS, 44)
+#define FW_MST_ID_NPU_M0RO FW_MST_ID(FW_MST_TYPE_SYS, 45)
+#define FW_MST_ID_NPU_M1 FW_MST_ID(FW_MST_TYPE_SYS, 46)
+#define FW_MST_ID_NPU_M1RO FW_MST_ID(FW_MST_TYPE_SYS, 47)
+#define FW_MST_ID_A53_0 FW_MST_ID(FW_MST_TYPE_SYS, 48)
+#define FW_MST_ID_A53_1 FW_MST_ID(FW_MST_TYPE_SYS, 49)
+#define FW_MST_ID_A53_2 FW_MST_ID(FW_MST_TYPE_SYS, 50)
+#define FW_MST_ID_A53_3 FW_MST_ID(FW_MST_TYPE_SYS, 51)
+#define FW_MST_ID_A72_0 FW_MST_ID(FW_MST_TYPE_SYS, 52)
+#define FW_MST_ID_A72_1 FW_MST_ID(FW_MST_TYPE_SYS, 53)
+#define FW_MST_ID_A72_2 FW_MST_ID(FW_MST_TYPE_SYS, 54)
+#define FW_MST_ID_A72_3 FW_MST_ID(FW_MST_TYPE_SYS, 55)
+#define FW_MST_ID_DAP_LITE FW_MST_ID(FW_MST_TYPE_SYS, 56)
+#define FW_MST_ID_VEPU1 FW_MST_ID(FW_MST_TYPE_SYS, 57)
+#define FW_MST_ID_SYS_CNT 64
+
+#define FW_MST_ID_PMU_MCU FW_MST_ID(FW_MST_TYPE_PMU, 0)
+#define FW_MST_ID_VDMA FW_MST_ID(FW_MST_TYPE_PMU, 1)
+#define FW_MST_ID_PMU_CNT 8
+
+/* slave id */
+#define FW_SLV_ID_CAN0 FW_SLV_ID(FW_SLV_TYPE_BUS, 0)
+#define FW_SLV_ID_CAN1 FW_SLV_ID(FW_SLV_TYPE_BUS, 1)
+#define FW_SLV_ID_I3C0 FW_SLV_ID(FW_SLV_TYPE_BUS, 2)
+#define FW_SLV_ID_I3C1 FW_SLV_ID(FW_SLV_TYPE_BUS, 3)
+#define FW_SLV_ID_BUS_IOC FW_SLV_ID(FW_SLV_TYPE_BUS, 4)
+#define FW_SLV_ID_COMBO_PIPE_PHY0 FW_SLV_ID(FW_SLV_TYPE_BUS, 5)
+#define FW_SLV_ID_COMBO_PIPE_PHY1 FW_SLV_ID(FW_SLV_TYPE_BUS, 6)
+#define FW_SLV_ID_CRU FW_SLV_ID(FW_SLV_TYPE_BUS, 7)
+#define FW_SLV_ID_DECOM FW_SLV_ID(FW_SLV_TYPE_BUS, 8)
+#define FW_SLV_ID_CRU_PVTPLL FW_SLV_ID(FW_SLV_TYPE_BUS, 9)
+#define FW_SLV_ID_I2C1 FW_SLV_ID(FW_SLV_TYPE_BUS, 13)
+#define FW_SLV_ID_I2C2 FW_SLV_ID(FW_SLV_TYPE_BUS, 14)
+#define FW_SLV_ID_I2C3 FW_SLV_ID(FW_SLV_TYPE_BUS, 15)
+#define FW_SLV_ID_I2C4 FW_SLV_ID(FW_SLV_TYPE_BUS, 16)
+#define FW_SLV_ID_I2C5 FW_SLV_ID(FW_SLV_TYPE_BUS, 17)
+#define FW_SLV_ID_I2C6 FW_SLV_ID(FW_SLV_TYPE_BUS, 18)
+#define FW_SLV_ID_I2C7 FW_SLV_ID(FW_SLV_TYPE_BUS, 19)
+#define FW_SLV_ID_I2C8 FW_SLV_ID(FW_SLV_TYPE_BUS, 20)
+#define FW_SLV_ID_I2C9 FW_SLV_ID(FW_SLV_TYPE_BUS, 21)
+#define FW_SLV_ID_INTMUX2BUS FW_SLV_ID(FW_SLV_TYPE_BUS, 22)
+#define FW_SLV_ID_INTMUX2DDR FW_SLV_ID(FW_SLV_TYPE_BUS, 23)
+#define FW_SLV_ID_INTMUX2PMU FW_SLV_ID(FW_SLV_TYPE_BUS, 24)
+#define FW_SLV_ID_PPLL_CRU FW_SLV_ID(FW_SLV_TYPE_BUS, 25)
+#define FW_SLV_ID_COMBO_PIPE_PHY0_GRF FW_SLV_ID(FW_SLV_TYPE_BUS, 26)
+#define FW_SLV_ID_COMBO_PIPE_PHY1_GRF FW_SLV_ID(FW_SLV_TYPE_BUS, 27)
+#define FW_SLV_ID_PMU2 FW_SLV_ID(FW_SLV_TYPE_BUS, 28)
+#define FW_SLV_ID_SARADC FW_SLV_ID(FW_SLV_TYPE_BUS, 32)
+#define FW_SLV_ID_SPI0 FW_SLV_ID(FW_SLV_TYPE_BUS, 33)
+#define FW_SLV_ID_SPI1 FW_SLV_ID(FW_SLV_TYPE_BUS, 34)
+#define FW_SLV_ID_SPI2 FW_SLV_ID(FW_SLV_TYPE_BUS, 35)
+#define FW_SLV_ID_SPI3 FW_SLV_ID(FW_SLV_TYPE_BUS, 36)
+#define FW_SLV_ID_SPI4 FW_SLV_ID(FW_SLV_TYPE_BUS, 37)
+#define FW_SLV_ID_SYS_GRF FW_SLV_ID(FW_SLV_TYPE_BUS, 38)
+#define FW_SLV_ID_TSADC FW_SLV_ID(FW_SLV_TYPE_BUS, 41)
+#define FW_SLV_ID_UART0 FW_SLV_ID(FW_SLV_TYPE_BUS, 42)
+#define FW_SLV_ID_UART10 FW_SLV_ID(FW_SLV_TYPE_BUS, 43)
+#define FW_SLV_ID_UART11 FW_SLV_ID(FW_SLV_TYPE_BUS, 44)
+#define FW_SLV_ID_UART2 FW_SLV_ID(FW_SLV_TYPE_BUS, 45)
+#define FW_SLV_ID_UART3 FW_SLV_ID(FW_SLV_TYPE_BUS, 46)
+#define FW_SLV_ID_UART4 FW_SLV_ID(FW_SLV_TYPE_BUS, 47)
+#define FW_SLV_ID_UART5 FW_SLV_ID(FW_SLV_TYPE_BUS, 48)
+#define FW_SLV_ID_UART6 FW_SLV_ID(FW_SLV_TYPE_BUS, 49)
+#define FW_SLV_ID_UART7 FW_SLV_ID(FW_SLV_TYPE_BUS, 50)
+#define FW_SLV_ID_UART8 FW_SLV_ID(FW_SLV_TYPE_BUS, 51)
+#define FW_SLV_ID_UART9 FW_SLV_ID(FW_SLV_TYPE_BUS, 52)
+#define FW_SLV_ID_VCCIO0_1_3_IOC FW_SLV_ID(FW_SLV_TYPE_BUS, 53)
+#define FW_SLV_ID_VCCIO2_4_5_IOC FW_SLV_ID(FW_SLV_TYPE_BUS, 54)
+#define FW_SLV_ID_BUS_WDT FW_SLV_ID(FW_SLV_TYPE_BUS, 55)
+#define FW_SLV_ID_WDT_NS FW_SLV_ID(FW_SLV_TYPE_BUS, 56)
+#define FW_SLV_ID_DMAC0_NS FW_SLV_ID(FW_SLV_TYPE_BUS, 57)
+#define FW_SLV_ID_DMAC1_NS FW_SLV_ID(FW_SLV_TYPE_BUS, 58)
+#define FW_SLV_ID_DMAC2_NS FW_SLV_ID(FW_SLV_TYPE_BUS, 59)
+#define FW_SLV_ID_DMAC0_S FW_SLV_ID(FW_SLV_TYPE_BUS, 60)
+#define FW_SLV_ID_DMAC1_S FW_SLV_ID(FW_SLV_TYPE_BUS, 61)
+#define FW_SLV_ID_DMAC2_S FW_SLV_ID(FW_SLV_TYPE_BUS, 62)
+#define FW_SLV_ID_GIC400 FW_SLV_ID(FW_SLV_TYPE_BUS, 63)
+#define FW_SLV_ID_SERVICE_BUS FW_SLV_ID(FW_SLV_TYPE_BUS, 64)
+#define FW_SLV_ID_SPINLOCK FW_SLV_ID(FW_SLV_TYPE_BUS, 65)
+#define FW_SLV_ID_MAILBOX_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 66)
+#define FW_SLV_ID_MAILBOX_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 67)
+#define FW_SLV_ID_MAILBOX_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 68)
+#define FW_SLV_ID_MAILBOX_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 69)
+#define FW_SLV_ID_MAILBOX_CH4 FW_SLV_ID(FW_SLV_TYPE_BUS, 70)
+#define FW_SLV_ID_MAILBOX_CH5 FW_SLV_ID(FW_SLV_TYPE_BUS, 71)
+#define FW_SLV_ID_MAILBOX_CH6 FW_SLV_ID(FW_SLV_TYPE_BUS, 72)
+#define FW_SLV_ID_MAILBOX_CH7 FW_SLV_ID(FW_SLV_TYPE_BUS, 73)
+#define FW_SLV_ID_MAILBOX_CH8 FW_SLV_ID(FW_SLV_TYPE_BUS, 74)
+#define FW_SLV_ID_MAILBOX_CH9 FW_SLV_ID(FW_SLV_TYPE_BUS, 75)
+#define FW_SLV_ID_MAILBOX_CH10 FW_SLV_ID(FW_SLV_TYPE_BUS, 76)
+#define FW_SLV_ID_MAILBOX_CH11 FW_SLV_ID(FW_SLV_TYPE_BUS, 77)
+#define FW_SLV_ID_MAILBOX_CH12 FW_SLV_ID(FW_SLV_TYPE_BUS, 78)
+#define FW_SLV_ID_MAILBOX_CH13 FW_SLV_ID(FW_SLV_TYPE_BUS, 79)
+#define FW_SLV_ID_PWM1_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 82)
+#define FW_SLV_ID_PWM1_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 83)
+#define FW_SLV_ID_PWM1_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 84)
+#define FW_SLV_ID_PWM1_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 85)
+#define FW_SLV_ID_PWM1_CH4 FW_SLV_ID(FW_SLV_TYPE_BUS, 86)
+#define FW_SLV_ID_PWM1_CH5 FW_SLV_ID(FW_SLV_TYPE_BUS, 87)
+#define FW_SLV_ID_PWM2_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 88)
+#define FW_SLV_ID_PWM2_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 89)
+#define FW_SLV_ID_PWM2_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 90)
+#define FW_SLV_ID_PWM2_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 91)
+#define FW_SLV_ID_PWM2_CH4 FW_SLV_ID(FW_SLV_TYPE_BUS, 92)
+#define FW_SLV_ID_PWM2_CH5 FW_SLV_ID(FW_SLV_TYPE_BUS, 93)
+#define FW_SLV_ID_PWM2_CH6 FW_SLV_ID(FW_SLV_TYPE_BUS, 94)
+#define FW_SLV_ID_PWM2_CH7 FW_SLV_ID(FW_SLV_TYPE_BUS, 95)
+#define FW_SLV_ID_TIMER_NS_0_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 96)
+#define FW_SLV_ID_TIMER_NS_0_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 97)
+#define FW_SLV_ID_TIMER_NS_0_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 98)
+#define FW_SLV_ID_TIMER_NS_0_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 99)
+#define FW_SLV_ID_TIMER_NS_0_CH4 FW_SLV_ID(FW_SLV_TYPE_BUS, 100)
+#define FW_SLV_ID_TIMER_NS_0_CH5 FW_SLV_ID(FW_SLV_TYPE_BUS, 101)
+#define FW_SLV_ID_TIMER_NS_1_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 102)
+#define FW_SLV_ID_TIMER_NS_1_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 103)
+#define FW_SLV_ID_TIMER_NS_1_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 104)
+#define FW_SLV_ID_TIMER_NS_1_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 105)
+#define FW_SLV_ID_TIMER_NS_1_CH4 FW_SLV_ID(FW_SLV_TYPE_BUS, 106)
+#define FW_SLV_ID_TIMER_NS_1_CH5 FW_SLV_ID(FW_SLV_TYPE_BUS, 107)
+#define FW_SLV_ID_GPIO1_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 108)
+#define FW_SLV_ID_GPIO1_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 109)
+#define FW_SLV_ID_GPIO1_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 110)
+#define FW_SLV_ID_GPIO1_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 111)
+#define FW_SLV_ID_GPIO2_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 112)
+#define FW_SLV_ID_GPIO2_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 113)
+#define FW_SLV_ID_GPIO2_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 114)
+#define FW_SLV_ID_GPIO2_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 115)
+#define FW_SLV_ID_GPIO3_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 116)
+#define FW_SLV_ID_GPIO3_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 117)
+#define FW_SLV_ID_GPIO3_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 118)
+#define FW_SLV_ID_GPIO3_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 119)
+#define FW_SLV_ID_GPIO4_CH0 FW_SLV_ID(FW_SLV_TYPE_BUS, 120)
+#define FW_SLV_ID_GPIO4_CH1 FW_SLV_ID(FW_SLV_TYPE_BUS, 121)
+#define FW_SLV_ID_GPIO4_CH2 FW_SLV_ID(FW_SLV_TYPE_BUS, 122)
+#define FW_SLV_ID_GPIO4_CH3 FW_SLV_ID(FW_SLV_TYPE_BUS, 123)
+#define FW_SLV_ID_BUS_CNT 125
+
+#define FW_SLV_ID_ACDCDIG_DSM FW_SLV_ID(FW_SLV_TYPE_TOP, 0)
+#define FW_SLV_ID_ASRC2CH_0 FW_SLV_ID(FW_SLV_TYPE_TOP, 1)
+#define FW_SLV_ID_ASRC2CH_1 FW_SLV_ID(FW_SLV_TYPE_TOP, 2)
+#define FW_SLV_ID_ASRC4CH_0 FW_SLV_ID(FW_SLV_TYPE_TOP, 3)
+#define FW_SLV_ID_ASRC4CH_1 FW_SLV_ID(FW_SLV_TYPE_TOP, 4)
+#define FW_SLV_ID_PDM1 FW_SLV_ID(FW_SLV_TYPE_TOP, 5)
+#define FW_SLV_ID_SAI0_8CH FW_SLV_ID(FW_SLV_TYPE_TOP, 6)
+#define FW_SLV_ID_SAI1_8CH FW_SLV_ID(FW_SLV_TYPE_TOP, 7)
+#define FW_SLV_ID_SAI2_8CH FW_SLV_ID(FW_SLV_TYPE_TOP, 8)
+#define FW_SLV_ID_SAI3_2CH FW_SLV_ID(FW_SLV_TYPE_TOP, 9)
+#define FW_SLV_ID_SAI4_2CH FW_SLV_ID(FW_SLV_TYPE_TOP, 10)
+#define FW_SLV_ID_SPDIF_RX0 FW_SLV_ID(FW_SLV_TYPE_TOP, 11)
+#define FW_SLV_ID_SPDIF_RX1 FW_SLV_ID(FW_SLV_TYPE_TOP, 12)
+#define FW_SLV_ID_SPDIF_TX0 FW_SLV_ID(FW_SLV_TYPE_TOP, 13)
+#define FW_SLV_ID_SPDIF_TX1 FW_SLV_ID(FW_SLV_TYPE_TOP, 14)
+#define FW_SLV_ID_DSMC_MEM FW_SLV_ID(FW_SLV_TYPE_TOP, 15)
+#define FW_SLV_ID_FSPI1 FW_SLV_ID(FW_SLV_TYPE_TOP, 16)
+#define FW_SLV_ID_FLEXBUS FW_SLV_ID(FW_SLV_TYPE_TOP, 17)
+#define FW_SLV_ID_SDIO FW_SLV_ID(FW_SLV_TYPE_TOP, 18)
+#define FW_SLV_ID_SDMMC FW_SLV_ID(FW_SLV_TYPE_TOP, 19)
+#define FW_SLV_ID_DSMC_CFG FW_SLV_ID(FW_SLV_TYPE_TOP, 20)
+#define FW_SLV_ID_GMAC0 FW_SLV_ID(FW_SLV_TYPE_TOP, 21)
+#define FW_SLV_ID_GMAC1 FW_SLV_ID(FW_SLV_TYPE_TOP, 22)
+#define FW_SLV_ID_SDGMAC_GRF FW_SLV_ID(FW_SLV_TYPE_TOP, 23)
+#define FW_SLV_ID_EMMC FW_SLV_ID(FW_SLV_TYPE_TOP, 24)
+#define FW_SLV_ID_FSPI0 FW_SLV_ID(FW_SLV_TYPE_TOP, 25)
+#define FW_SLV_ID_NSCRYPTO FW_SLV_ID(FW_SLV_TYPE_TOP, 26)
+#define FW_SLV_ID_RKRNG_NS FW_SLV_ID(FW_SLV_TYPE_TOP, 27)
+#define FW_SLV_ID_SCRYPTO FW_SLV_ID(FW_SLV_TYPE_TOP, 28)
+#define FW_SLV_ID_KEYLAD FW_SLV_ID(FW_SLV_TYPE_TOP, 29)
+#define FW_SLV_ID_RKRNG_S FW_SLV_ID(FW_SLV_TYPE_TOP, 30)
+#define FW_SLV_ID_OTPC_NS FW_SLV_ID(FW_SLV_TYPE_TOP, 31)
+#define FW_SLV_ID_JTAG_LOCK FW_SLV_ID(FW_SLV_TYPE_TOP, 33)
+#define FW_SLV_ID_OTPC_S FW_SLV_ID(FW_SLV_TYPE_TOP, 34)
+#define FW_SLV_ID_OTPMASK FW_SLV_ID(FW_SLV_TYPE_TOP, 35)
+#define FW_SLV_ID_SECURE_CRU FW_SLV_ID(FW_SLV_TYPE_TOP, 36)
+#define FW_SLV_ID_SECURE_CRU_S FW_SLV_ID(FW_SLV_TYPE_TOP, 37)
+#define FW_SLV_ID_SYS_SGRF FW_SLV_ID(FW_SLV_TYPE_TOP, 38)
+#define FW_SLV_ID_BOOTROM FW_SLV_ID(FW_SLV_TYPE_TOP, 39)
+#define FW_SLV_ID_WDT_S FW_SLV_ID(FW_SLV_TYPE_TOP, 41)
+#define FW_SLV_ID_SERVICE_GMAC FW_SLV_ID(FW_SLV_TYPE_TOP, 42)
+#define FW_SLV_ID_SERVICE_NVM FW_SLV_ID(FW_SLV_TYPE_TOP, 43)
+#define FW_SLV_ID_SERVICE_SECURE FW_SLV_ID(FW_SLV_TYPE_TOP, 44)
+#define FW_SLV_ID_SERVICE_VENC FW_SLV_ID(FW_SLV_TYPE_TOP, 45)
+#define FW_SLV_ID_SERVICE_VI FW_SLV_ID(FW_SLV_TYPE_TOP, 46)
+#define FW_SLV_ID_SERVICE_VPU FW_SLV_ID(FW_SLV_TYPE_TOP, 47)
+#define FW_SLV_ID_VEPU0 FW_SLV_ID(FW_SLV_TYPE_TOP, 48)
+#define FW_SLV_ID_ISP FW_SLV_ID(FW_SLV_TYPE_TOP, 49)
+#define FW_SLV_ID_VICAP FW_SLV_ID(FW_SLV_TYPE_TOP, 50)
+#define FW_SLV_ID_VPSS FW_SLV_ID(FW_SLV_TYPE_TOP, 51)
+#define FW_SLV_ID_CSIHOST0 FW_SLV_ID(FW_SLV_TYPE_TOP, 52)
+#define FW_SLV_ID_CSIHOST1 FW_SLV_ID(FW_SLV_TYPE_TOP, 53)
+#define FW_SLV_ID_CSIHOST2 FW_SLV_ID(FW_SLV_TYPE_TOP, 54)
+#define FW_SLV_ID_VI_GRF FW_SLV_ID(FW_SLV_TYPE_TOP, 55)
+#define FW_SLV_ID_EBC FW_SLV_ID(FW_SLV_TYPE_TOP, 56)
+#define FW_SLV_ID_JPEG FW_SLV_ID(FW_SLV_TYPE_TOP, 57)
+#define FW_SLV_ID_RGA0 FW_SLV_ID(FW_SLV_TYPE_TOP, 58)
+#define FW_SLV_ID_RGA1 FW_SLV_ID(FW_SLV_TYPE_TOP, 59)
+#define FW_SLV_ID_VDPP FW_SLV_ID(FW_SLV_TYPE_TOP, 60)
+#define FW_SLV_ID_TIMER_S_0_CH0 FW_SLV_ID(FW_SLV_TYPE_TOP, 61)
+#define FW_SLV_ID_TIMER_S_0_CH1 FW_SLV_ID(FW_SLV_TYPE_TOP, 62)
+#define FW_SLV_ID_TIMER_S_0_CH2 FW_SLV_ID(FW_SLV_TYPE_TOP, 63)
+#define FW_SLV_ID_TIMER_S_0_CH3 FW_SLV_ID(FW_SLV_TYPE_TOP, 64)
+#define FW_SLV_ID_TIMER_S_0_CH4 FW_SLV_ID(FW_SLV_TYPE_TOP, 65)
+#define FW_SLV_ID_TIMER_S_0_CH5 FW_SLV_ID(FW_SLV_TYPE_TOP, 66)
+#define FW_SLV_ID_TIMER_S_1_CH0 FW_SLV_ID(FW_SLV_TYPE_TOP, 67)
+#define FW_SLV_ID_TIMER_S_1_CH1 FW_SLV_ID(FW_SLV_TYPE_TOP, 68)
+#define FW_SLV_ID_TIMER_S_1_CH2 FW_SLV_ID(FW_SLV_TYPE_TOP, 69)
+#define FW_SLV_ID_TIMER_S_1_CH3 FW_SLV_ID(FW_SLV_TYPE_TOP, 70)
+#define FW_SLV_ID_TIMER_S_1_CH4 FW_SLV_ID(FW_SLV_TYPE_TOP, 71)
+#define FW_SLV_ID_TIMER_S_1_CH5 FW_SLV_ID(FW_SLV_TYPE_TOP, 72)
+#define FW_SLV_ID_SYS_FW FW_SLV_ID(FW_SLV_TYPE_TOP, 73)
+#define FW_SLV_ID_VEPU1 FW_SLV_ID(FW_SLV_TYPE_TOP, 75)
+#define FW_SLV_ID_SERVICE_VEPU1 FW_SLV_ID(FW_SLV_TYPE_TOP, 76)
+#define FW_SLV_ID_CSIHOST3 FW_SLV_ID(FW_SLV_TYPE_TOP, 77)
+#define FW_SLV_ID_CSIHOST4 FW_SLV_ID(FW_SLV_TYPE_TOP, 78)
+#define FW_SLV_ID_TOP_CNT 80
+
+#define FW_SLV_ID_CENTER_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 0)
+#define FW_SLV_ID_DMA2DDR FW_SLV_ID(FW_SLV_TYPE_CENTER, 1)
+#define FW_SLV_ID_AHB2APB FW_SLV_ID(FW_SLV_TYPE_CENTER, 2)
+#define FW_SLV_ID_DDR_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 3)
+#define FW_SLV_ID_DDRCTL0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 4)
+#define FW_SLV_ID_DDRCTL_1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 5)
+#define FW_SLV_ID_DDRPHY0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 6)
+#define FW_SLV_ID_DDR0_CRU FW_SLV_ID(FW_SLV_TYPE_CENTER, 7)
+#define FW_SLV_ID_DDRPHY1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 8)
+#define FW_SLV_ID_DDR1_CRU FW_SLV_ID(FW_SLV_TYPE_CENTER, 9)
+#define FW_SLV_ID_DDRMON0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 10)
+#define FW_SLV_ID_DDRMON1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 11)
+#define FW_SLV_ID_HWLP0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 12)
+#define FW_SLV_ID_HWLP1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 13)
+#define FW_SLV_ID_DDR_PVTPLL FW_SLV_ID(FW_SLV_TYPE_CENTER, 14)
+#define FW_SLV_ID_DDR_WDT FW_SLV_ID(FW_SLV_TYPE_CENTER, 15)
+#define FW_SLV_ID_RKVDEC FW_SLV_ID(FW_SLV_TYPE_CENTER, 16)
+#define FW_SLV_ID_SERVICE_CCI2 FW_SLV_ID(FW_SLV_TYPE_CENTER, 17)
+#define FW_SLV_ID_SERVICE_CENTER FW_SLV_ID(FW_SLV_TYPE_CENTER, 18)
+#define FW_SLV_ID_SERVICE_DDR FW_SLV_ID(FW_SLV_TYPE_CENTER, 19)
+#define FW_SLV_ID_SERVICE_RKVDEC FW_SLV_ID(FW_SLV_TYPE_CENTER, 20)
+#define FW_SLV_ID_SERVICE_USB FW_SLV_ID(FW_SLV_TYPE_CENTER, 21)
+#define FW_SLV_ID_SERVICE_VO0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 22)
+#define FW_SLV_ID_SERVICE_VO1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 23)
+#define FW_SLV_ID_SERVICE_VOP FW_SLV_ID(FW_SLV_TYPE_CENTER, 24)
+#define FW_SLV_ID_UFS_APBS FW_SLV_ID(FW_SLV_TYPE_CENTER, 25)
+#define FW_SLV_ID_UFS_AXIS FW_SLV_ID(FW_SLV_TYPE_CENTER, 26)
+#define FW_SLV_ID_USB0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 27)
+#define FW_SLV_ID_MMU2 FW_SLV_ID(FW_SLV_TYPE_CENTER, 28)
+#define FW_SLV_ID_USB_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 29)
+#define FW_SLV_ID_HDCP0_MMU FW_SLV_ID(FW_SLV_TYPE_CENTER, 30)
+#define FW_SLV_ID_SAI5_8CH FW_SLV_ID(FW_SLV_TYPE_CENTER, 31)
+#define FW_SLV_ID_SAI6_8CH FW_SLV_ID(FW_SLV_TYPE_CENTER, 32)
+#define FW_SLV_ID_SPDIF_RX2 FW_SLV_ID(FW_SLV_TYPE_CENTER, 33)
+#define FW_SLV_ID_SPDIF_TX2 FW_SLV_ID(FW_SLV_TYPE_CENTER, 34)
+#define FW_SLV_ID_HDCP0_KEY FW_SLV_ID(FW_SLV_TYPE_CENTER, 35)
+#define FW_SLV_ID_DSIHOST FW_SLV_ID(FW_SLV_TYPE_CENTER, 36)
+#define FW_SLV_ID_EDP0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 37)
+#define FW_SLV_ID_HDCP0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 38)
+#define FW_SLV_ID_HDCP0_TRNG FW_SLV_ID(FW_SLV_TYPE_CENTER, 39)
+#define FW_SLV_ID_HDMITX FW_SLV_ID(FW_SLV_TYPE_CENTER, 40)
+#define FW_SLV_ID_VO0_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 41)
+#define FW_SLV_ID_EDP0_S FW_SLV_ID(FW_SLV_TYPE_CENTER, 42)
+#define FW_SLV_ID_HDCP1_MMU FW_SLV_ID(FW_SLV_TYPE_CENTER, 43)
+#define FW_SLV_ID_SAI7_8CH FW_SLV_ID(FW_SLV_TYPE_CENTER, 44)
+#define FW_SLV_ID_SPDIF_TX3 FW_SLV_ID(FW_SLV_TYPE_CENTER, 45)
+#define FW_SLV_ID_HDCP1_KEY FW_SLV_ID(FW_SLV_TYPE_CENTER, 46)
+#define FW_SLV_ID_DP FW_SLV_ID(FW_SLV_TYPE_CENTER, 47)
+#define FW_SLV_ID_HDCP1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 48)
+#define FW_SLV_ID_HDCP1_TRNG FW_SLV_ID(FW_SLV_TYPE_CENTER, 49)
+#define FW_SLV_ID_VO1_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 50)
+#define FW_SLV_ID_VOP_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 52)
+#define FW_SLV_ID_UFS_GRF FW_SLV_ID(FW_SLV_TYPE_CENTER, 53)
+#define FW_SLV_ID_SPDIF_TX4 FW_SLV_ID(FW_SLV_TYPE_CENTER, 54)
+#define FW_SLV_ID_SPDIF_TX5 FW_SLV_ID(FW_SLV_TYPE_CENTER, 55)
+#define FW_SLV_ID_SAI8_8CH FW_SLV_ID(FW_SLV_TYPE_CENTER, 56)
+#define FW_SLV_ID_SAI9_8CH FW_SLV_ID(FW_SLV_TYPE_CENTER, 57)
+#define FW_SLV_ID_DDR_TIMER_CH0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 58)
+#define FW_SLV_ID_DDR_TIMER_CH1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 59)
+#define FW_SLV_ID_VOP_RGN0 FW_SLV_ID(FW_SLV_TYPE_CENTER, 60)
+#define FW_SLV_ID_VOP_RGN1 FW_SLV_ID(FW_SLV_TYPE_CENTER, 61)
+#define FW_SLV_ID_VOP_RGN2 FW_SLV_ID(FW_SLV_TYPE_CENTER, 62)
+#define FW_SLV_ID_VOP_RGN3 FW_SLV_ID(FW_SLV_TYPE_CENTER, 63)
+#define FW_SLV_ID_VOP_OTHERS FW_SLV_ID(FW_SLV_TYPE_CENTER, 64)
+#define FW_SLV_ID_CENTER_CNT 65
+
+#define FW_SLV_ID_BIGCORE_CRU FW_SLV_ID(FW_SLV_TYPE_CCI, 0)
+#define FW_SLV_ID_BIGCORE_GRF FW_SLV_ID(FW_SLV_TYPE_CCI, 1)
+#define FW_SLV_ID_CCI FW_SLV_ID(FW_SLV_TYPE_CCI, 2)
+#define FW_SLV_ID_CCI_CRU FW_SLV_ID(FW_SLV_TYPE_CCI, 3)
+#define FW_SLV_ID_CCI_PVTPLL FW_SLV_ID(FW_SLV_TYPE_CCI, 4)
+#define FW_SLV_ID_CCI_GRF FW_SLV_ID(FW_SLV_TYPE_CCI, 5)
+#define FW_SLV_ID_DAP_LITE_A53 FW_SLV_ID(FW_SLV_TYPE_CCI, 6)
+#define FW_SLV_ID_DAP_LITE_A72 FW_SLV_ID(FW_SLV_TYPE_CCI, 7)
+#define FW_SLV_ID_LITCORE_GRF FW_SLV_ID(FW_SLV_TYPE_CCI, 8)
+#define FW_SLV_ID_LITCORE_CRU FW_SLV_ID(FW_SLV_TYPE_CCI, 9)
+#define FW_SLV_ID_SERVICE_CCI FW_SLV_ID(FW_SLV_TYPE_CCI, 10)
+#define FW_SLV_ID_BIGCORE_PVTPLL FW_SLV_ID(FW_SLV_TYPE_CCI, 11)
+#define FW_SLV_ID_LITCORE_PVTPLL FW_SLV_ID(FW_SLV_TYPE_CCI, 12)
+#define FW_SLV_ID_CCI_CNT 15
+
+#define FW_SLV_ID_PCIE0_DBI FW_SLV_ID(FW_SLV_TYPE_PHP, 0)
+#define FW_SLV_ID_PCIE0_DBI_L FW_SLV_ID(FW_SLV_TYPE_PHP, 1)
+#define FW_SLV_ID_PCIE0_S FW_SLV_ID(FW_SLV_TYPE_PHP, 2)
+#define FW_SLV_ID_PCIE0_S_L FW_SLV_ID(FW_SLV_TYPE_PHP, 3)
+#define FW_SLV_ID_PCIE1_DBI FW_SLV_ID(FW_SLV_TYPE_PHP, 4)
+#define FW_SLV_ID_PCIE1_DBI_L FW_SLV_ID(FW_SLV_TYPE_PHP, 5)
+#define FW_SLV_ID_PCIE1_S FW_SLV_ID(FW_SLV_TYPE_PHP, 6)
+#define FW_SLV_ID_PCIE1_S_L FW_SLV_ID(FW_SLV_TYPE_PHP, 7)
+#define FW_SLV_ID_USB1 FW_SLV_ID(FW_SLV_TYPE_PHP, 8)
+#define FW_SLV_ID_PCIE0_APB FW_SLV_ID(FW_SLV_TYPE_PHP, 9)
+#define FW_SLV_ID_PCIE1_APB FW_SLV_ID(FW_SLV_TYPE_PHP, 10)
+#define FW_SLV_ID_PHP_GRF FW_SLV_ID(FW_SLV_TYPE_PHP, 11)
+#define FW_SLV_ID_SATA0 FW_SLV_ID(FW_SLV_TYPE_PHP, 12)
+#define FW_SLV_ID_SATA1 FW_SLV_ID(FW_SLV_TYPE_PHP, 13)
+#define FW_SLV_ID_SERVICE_PHP FW_SLV_ID(FW_SLV_TYPE_PHP, 14)
+#define FW_SLV_ID_MMU0 FW_SLV_ID(FW_SLV_TYPE_PHP, 15)
+#define FW_SLV_ID_MMU1 FW_SLV_ID(FW_SLV_TYPE_PHP, 16)
+#define FW_SLV_ID_PHP_CNT 20
+
+#define FW_SLV_ID_GPU_GRF FW_SLV_ID(FW_SLV_TYPE_GPU, 0)
+#define FW_SLV_ID_GPU FW_SLV_ID(FW_SLV_TYPE_GPU, 1)
+#define FW_SLV_ID_SERVICE_GPU FW_SLV_ID(FW_SLV_TYPE_GPU, 2)
+#define FW_SLV_ID_GPU_PVTPLL FW_SLV_ID(FW_SLV_TYPE_GPU, 3)
+#define FW_SLV_ID_GPU_CNT 5
+
+#define FW_SLV_ID_RKNN_TOP FW_SLV_ID(FW_SLV_TYPE_NPU, 0)
+#define FW_SLV_ID_SERVICE_NPU0 FW_SLV_ID(FW_SLV_TYPE_NPU, 1)
+#define FW_SLV_ID_SERVICE_NPU1 FW_SLV_ID(FW_SLV_TYPE_NPU, 2)
+#define FW_SLV_ID_SERVICE_NPUSUBSYS FW_SLV_ID(FW_SLV_TYPE_NPU, 3)
+#define FW_SLV_ID_RKNN_NSP FW_SLV_ID(FW_SLV_TYPE_NPU, 4)
+#define FW_SLV_ID_NPU_GRF FW_SLV_ID(FW_SLV_TYPE_NPU, 5)
+#define FW_SLV_ID_NPU_PVTPLL FW_SLV_ID(FW_SLV_TYPE_NPU, 6)
+#define FW_SLV_ID_NPU_WDT FW_SLV_ID(FW_SLV_TYPE_NPU, 7)
+#define FW_SLV_ID_NPU_TIMER_CH0 FW_SLV_ID(FW_SLV_TYPE_NPU, 8)
+#define FW_SLV_ID_NPU_TIMER_CH1 FW_SLV_ID(FW_SLV_TYPE_NPU, 9)
+#define FW_SLV_ID_NPU_CNT 10
+
+#define FW_SLV_ID_PDM0 FW_SLV_ID(FW_SLV_TYPE_PMU, 0)
+#define FW_SLV_ID_PMU_MEM FW_SLV_ID(FW_SLV_TYPE_PMU, 1)
+#define FW_SLV_ID_CSIDPHY_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 2)
+#define FW_SLV_ID_VDMA FW_SLV_ID(FW_SLV_TYPE_PMU, 3)
+#define FW_SLV_ID_HDPTXPHY FW_SLV_ID(FW_SLV_TYPE_PMU, 4)
+#define FW_SLV_ID_HDPTXPHY0_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 5)
+#define FW_SLV_ID_I2C0 FW_SLV_ID(FW_SLV_TYPE_PMU, 6)
+#define FW_SLV_ID_DCPHY FW_SLV_ID(FW_SLV_TYPE_PMU, 7)
+#define FW_SLV_ID_CSIDPHY0 FW_SLV_ID(FW_SLV_TYPE_PMU, 8)
+#define FW_SLV_ID_DCPHY_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 9)
+#define FW_SLV_ID_PMU0 FW_SLV_ID(FW_SLV_TYPE_PMU, 10)
+#define FW_SLV_ID_PMU0_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 11)
+#define FW_SLV_ID_PMU0_IOC FW_SLV_ID(FW_SLV_TYPE_PMU, 12)
+#define FW_SLV_ID_PMU1 FW_SLV_ID(FW_SLV_TYPE_PMU, 13)
+#define FW_SLV_ID_PMU1_CRU FW_SLV_ID(FW_SLV_TYPE_PMU, 14)
+#define FW_SLV_ID_PMU1_CRU_S FW_SLV_ID(FW_SLV_TYPE_PMU, 15)
+#define FW_SLV_ID_PMU1_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 16)
+#define FW_SLV_ID_PMU1_IOC FW_SLV_ID(FW_SLV_TYPE_PMU, 17)
+#define FW_SLV_ID_PWM0_CH0 FW_SLV_ID(FW_SLV_TYPE_PMU, 18)
+#define FW_SLV_ID_PWM0_CH1 FW_SLV_ID(FW_SLV_TYPE_PMU, 19)
+#define FW_SLV_ID_UART1 FW_SLV_ID(FW_SLV_TYPE_PMU, 20)
+#define FW_SLV_ID_MPHY_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 21)
+#define FW_SLV_ID_MPHY FW_SLV_ID(FW_SLV_TYPE_PMU, 22)
+#define FW_SLV_ID_USB2PHY0_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 23)
+#define FW_SLV_ID_USB2PHY1_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 24)
+#define FW_SLV_ID_USBDPPHY FW_SLV_ID(FW_SLV_TYPE_PMU, 25)
+#define FW_SLV_ID_USBDPPHY_GRF FW_SLV_ID(FW_SLV_TYPE_PMU, 26)
+#define FW_SLV_ID_VCCIO6_IOC FW_SLV_ID(FW_SLV_TYPE_PMU, 27)
+#define FW_SLV_ID_PMU_WDT FW_SLV_ID(FW_SLV_TYPE_PMU, 28)
+#define FW_SLV_ID_HPTIMER FW_SLV_ID(FW_SLV_TYPE_PMU, 29)
+#define FW_SLV_ID_OSC_CHK FW_SLV_ID(FW_SLV_TYPE_PMU, 30)
+#define FW_SLV_ID_PMU0_SGRF FW_SLV_ID(FW_SLV_TYPE_PMU, 31)
+#define FW_SLV_ID_PMU1_SGRF FW_SLV_ID(FW_SLV_TYPE_PMU, 32)
+#define FW_SLV_ID_PMU_PVTM FW_SLV_ID(FW_SLV_TYPE_PMU, 33)
+#define FW_SLV_ID_SCRAMBLE_KEY FW_SLV_ID(FW_SLV_TYPE_PMU, 34)
+#define FW_SLV_ID_SERVICE_PMU FW_SLV_ID(FW_SLV_TYPE_PMU, 35)
+#define FW_SLV_ID_PMU_SRAM_REMAP FW_SLV_ID(FW_SLV_TYPE_PMU, 36)
+#define FW_SLV_ID_PMU_TIMER_CH0 FW_SLV_ID(FW_SLV_TYPE_PMU, 37)
+#define FW_SLV_ID_PMU_TIMER_CH1 FW_SLV_ID(FW_SLV_TYPE_PMU, 38)
+#define FW_SLV_ID_GPIO0_CH0 FW_SLV_ID(FW_SLV_TYPE_PMU, 39)
+#define FW_SLV_ID_GPIO0_CH1 FW_SLV_ID(FW_SLV_TYPE_PMU, 40)
+#define FW_SLV_ID_GPIO0_CH2 FW_SLV_ID(FW_SLV_TYPE_PMU, 41)
+#define FW_SLV_ID_GPIO0_CH3 FW_SLV_ID(FW_SLV_TYPE_PMU, 42)
+#define FW_SLV_ID_PMU_FW FW_SLV_ID(FW_SLV_TYPE_PMU, 43)
+#define FW_SLV_ID_PMU_CNT 45
+
+#define PLAT_MAX_DDR_CAPACITY_MB 0x8000 /* for 32Gb */
+#define RG_MAP_SECURE(top, base) \
+ (((((top) - 1) & 0x7fff) << 16) | ((base) & 0x7fff))
+#define RG_MAP_SRAM_SECURE(top_kb, base_kb) \
+ (((((top_kb) / 4 - 1) & 0xff) << 8) | ((base_kb) / 4 & 0xff))
+#define RG_MAP_CBUF_SECURE(top_kb, base_kb) \
+ (((((top_kb) / 4 - 1) & 0xff) << 8) | ((base_kb) / 4 & 0xff))
+
+#define FW_UPDATE_WAIT_LOOP 500000
+
+__pmusramfunc void pmusram_fw_update_msk(uint32_t msk);
+__pmusramfunc void pmusram_all_fw_bypass(void);
+
+void fw_init(void);
+
+#endif /* __FIREWALL_H__ */
diff --git a/plat/rockchip/rk3576/drivers/secure/secure.c b/plat/rockchip/rk3576/drivers/secure/secure.c
new file mode 100644
index 0000000..55b8d93
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/secure.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#include <secure.h>
+#include <soc.h>
+
+static void secure_timer_init(void)
+{
+ /* gpu's cntvalue comes from stimer1 channel_5 */
+ mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+ TIMER_DIS);
+
+ mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
+ TIMER_EN | TIMER_FMODE);
+}
+
+void secure_init(void)
+{
+ secure_timer_init();
+ fw_init();
+
+ /* crypto secure controlled by crypto */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), BITS_WITH_WMASK(0, 0x1, 4));
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), BITS_WITH_WMASK(0, 0x1, 5));
+
+ /* disable DP encryption mode */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(1), BITS_WITH_WMASK(1, 0x1, 14));
+}
diff --git a/plat/rockchip/rk3576/drivers/secure/secure.h b/plat/rockchip/rk3576/drivers/secure/secure.h
new file mode 100644
index 0000000..f00e519
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/secure/secure.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+#include <firewall.h>
+
+/* PMU0SGRF */
+#define PMU0SGRF_SOC_CON(i) ((i) * 4)
+
+ /* PMU1SGRF */
+#define PMU1SGRF_SOC_CON(i) ((i) * 4)
+
+ /* CCISGRF */
+#define CCISGRF_SOC_CON(i) (0x20 + (i) * 4)
+#define CCISGRF_DDR_HASH_CON(i) (0x40 + (i) * 4)
+
+ /* SGRF */
+#define SYSSGRF_DDR_BANK_MSK(i) (0x04 + (i) * 4)
+#define SYSSGRF_DDR_CH_MSK(i) (0x18 + (i) * 4)
+#define SYSSGRF_SOC_CON(i) (0x20 + (i) * 4)
+#define SYSSGRF_DMAC_CON(i) (0x80 + (i) * 4)
+#define SYSSGRF_SOC_STATUS 0x240
+
+void secure_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/rk3576/drivers/soc/soc.c b/plat/rockchip/rk3576/drivers/soc/soc.c
new file mode 100644
index 0000000..a78e82e
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/soc/soc.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <arch_helpers.h>
+#include <bl31/bl31.h>
+#include <common/debug.h>
+#include <drivers/console.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <plat_private.h>
+#include <rk3576_clk.h>
+#include <secure.h>
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+ MAP_REGION_FLAT(RK3576_DEV_RNG0_BASE, RK3576_DEV_RNG0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(DDR_SHARE_MEM, DDR_SHARE_SIZE,
+ MT_DEVICE | MT_RW | MT_NS),
+ { 0 }
+};
+
+/* The RockChip power domain tree descriptor */
+const unsigned char rockchip_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ PLATFORM_SYSTEM_COUNT,
+ /* No of children for the root node */
+ PLATFORM_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ PLATFORM_CLUSTER0_CORE_COUNT,
+ /* No of children for the second cluster node */
+ PLATFORM_CLUSTER1_CORE_COUNT
+};
+
+static void clear_glb_reset_status(void)
+{
+ uint32_t cru_sel55 = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(55));
+
+ /* switch pclk_bus_root to 24M before writing CRU_GLB_RST_ST */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
+ BITS_WITH_WMASK(2, 0x3, 2));
+ dsb();
+
+ mmio_write_32(CRU_BASE + CRU_GLB_RST_ST, 0xffff);
+ dsb();
+
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(55),
+ WITH_16BITS_WMSK(cru_sel55));
+}
+
+static void print_glb_reset_status(void)
+{
+ uint32_t glb_rst_st = 0, warm_boot = 0;
+
+ /* clear CRU_GLB_RST_ST_NCLR if cold boot */
+ if (mmio_read_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17)) == WARM_BOOT_MAGIC) {
+ /* ignore npu_wdt*/
+ glb_rst_st = mmio_read_32(CRU_BASE + CRU_GLB_RST_ST_NCLR) & VALID_GLB_RST_MSK;
+ warm_boot = 1;
+ } else {
+ mmio_write_32(PMU0_GRF_BASE + PMU0GRF_OS_REG(17), WARM_BOOT_MAGIC);
+ }
+
+ clear_glb_reset_status();
+
+ /* save glb_rst_st in mem_os_reg31 */
+ write_mem_os_reg(31, glb_rst_st);
+
+ if (warm_boot != 0)
+ INFO("soc warm boot, reset status: 0x%x\n", glb_rst_st);
+ else
+ INFO("soc cold boot\n");
+}
+
+static void system_reset_init(void)
+{
+ /*
+ * enable tsadc trigger global reset and select first reset.
+ * enable global reset and wdt trigger pmu reset.
+ * select first reset trigger pmu reset.
+ */
+ mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, 0xffdf);
+
+ /* enable wdt_s reset */
+ mmio_write_32(SYS_SGRF_BASE + SYSSGRF_SOC_CON(0), 0x20002000);
+
+ /* enable wdt_ns reset */
+ mmio_write_32(SYS_GRF_BASE + SYSGRF_SOC_CON(4), 0x01000100);
+
+ /* reset width = 0xffff */
+ mmio_write_32(PMU1_GRF_BASE + PMU1GRF_SOC_CON(6), 0xffffffff);
+
+ /* enable first/tsadc/wdt reset output */
+ mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(0), 0x00070007);
+
+ /* pmu0sgrf pmu0_ioc hold */
+ mmio_write_32(PMU0SGRF_BASE + PMU1SGRF_SOC_CON(0), 0xffff1800);
+
+ /* pmu1sgrf pmu1_grf hold */
+ mmio_write_32(PMU1SGRF_BASE + PMU1SGRF_SOC_CON(16), 0xffff8800);
+
+ /* select tsadc_shut_m0 ionmux*/
+ mmio_write_32(PMU0_IOC_BASE + 0x0, 0x00f00090);
+
+ print_glb_reset_status();
+}
+
+void plat_rockchip_soc_init(void)
+{
+ rockchip_clock_init();
+ system_reset_init();
+ secure_init();
+ rockchip_init_scmi_server();
+
+ /* release cpu1~cpu7 */
+ mmio_write_32(CCI_GRF_BASE + CCIGRF_CON(4), 0xffffffff);
+ mmio_write_32(LITCORE_GRF_BASE + COREGRF_CPU_CON(1),
+ BITS_WITH_WMASK(0x77, 0xff, 4));
+}
diff --git a/plat/rockchip/rk3576/drivers/soc/soc.h b/plat/rockchip/rk3576/drivers/soc/soc.h
new file mode 100644
index 0000000..f96a42d
--- /dev/null
+++ b/plat/rockchip/rk3576/drivers/soc/soc.h
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+enum pll_id {
+ APLL_ID,
+ CPLL_ID,
+ DPLL_ID,
+ GPLL_ID,
+};
+
+enum cru_mode_con00 {
+ CLK_APLL,
+ CLK_CPLL,
+ CLK_GPLL,
+ CLK_DPLL,
+};
+
+#define KHz 1000
+#define MHz (1000 * KHz)
+#define OSC_HZ (24 * MHz)
+
+#define MCU_VALID_START_ADDRESS 0x800000
+
+/* CRU */
+#define GLB_SRST_FST_CFG_VAL 0xfdb9
+
+#define CRU_PLLS_CON(pll_id, i) ((pll_id) * 0x20 + (i) * 0x4)
+#define CRU_PLL_CON(i) ((i) * 0x4)
+#define CRU_MODE_CON 0x280
+#define CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define CRU_CLKSEL_CON_CNT 181
+#define CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define CRU_CLKGATE_CON_CNT 80
+#define CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define CRU_SOFTRST_CON_CNT 80
+
+#define CRU_GLB_CNT_TH 0xc00
+#define CRU_GLB_RST_ST 0xc04
+#define CRU_GLB_SRST_FST 0xc08
+#define CRU_GLB_SRST_SND 0xc0c
+#define CRU_GLB_RST_CON 0xc10
+#define CRU_GLB_RST_ST_NCLR 0xc14
+#define CRU_LITCOREWFI_CON0 0xc40
+#define CRU_BIGCOREWFI_CON0 0xc44
+#define CRU_NON_SECURE_GT_CON0 0xc48
+
+#define CRU_PLLCON0_M_MASK 0x3ff
+#define CRU_PLLCON0_M_SHIFT 0
+#define CRU_PLLCON1_P_MASK 0x3f
+#define CRU_PLLCON1_P_SHIFT 0
+#define CRU_PLLCON1_S_MASK 0x7
+#define CRU_PLLCON1_S_SHIFT 6
+#define CRU_PLLCON2_K_MASK 0xffff
+#define CRU_PLLCON2_K_SHIFT 0
+#define CRU_PLLCON1_PWRDOWN BIT(13)
+#define CRU_PLLCON6_LOCK_STATUS BIT(15)
+
+/* LCORE_CRU */
+#define LCORE_CRU_MODE_CON 0x280
+#define LCORE_CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define LCORE_CRU_CLKSEL_CON_CNT 4
+#define LCORE_CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define LCORE_CRU_CLKGATE_CON_CNT 2
+#define LCORE_CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define LCORE_CRU_SOFTRST_CON_CNT 4
+
+/* BCORE_CRU */
+#define BCORE_CRU_MODE_CON 0x280
+#define BCORE_CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define BCORE_CRU_CLKSEL_CON_CNT 5
+#define BCORE_CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define BCORE_CRU_CLKGATE_CON_CNT 3
+#define BCORE_CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define BCORE_CRU_SOFTRST_CON_CNT 4
+
+/* DDRCRU */
+#define DDRCRU_MODE_CON 0x280
+#define DDRCRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define DDRCRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define DDRCRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+
+/* CCICRU */
+#define CCICRU_MODE_CON 0x280
+#define CCICRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define CCICRU_CLKSEL_CON_CNT 10
+#define CCICRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define CCICRU_CLKGATE_CON_CNT 7
+#define CCICRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define CCICRU_SOFTRST_CON_CNT 7
+
+/* CRU AUTOCS */
+#define CRU_AUTOCS_CON(offset) (CRU_BASE + (offset))
+#define CRU_AUTOCS_SEC_CON(offset) (SECURE_CRU_BASE + (offset))
+#define CRU_AUTOCS_CCI_CON(offset) (CCI_CRU_BASE + (offset))
+#define AUTOCS_EN_BIT BIT(12)
+
+/* PHP_CRU */
+#define PHP_CRU_MODE_CON 0x280
+#define PHP_CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define PHP_CRU_CLKSEL_CON_CNT 2
+#define PHP_CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define PHP_CRU_CLKGATE_CON_CNT 2
+#define PHP_CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define PHP_CRU_SOFTRST_CON_CNT 2
+
+/* SECURE CRU */
+#define SECURE_CRU_CLKSEL_CON(i) ((i) * 0x4 + 0x300)
+#define SECURE_CRU_CLKSEL_CON_CNT 1
+#define SECURE_CRU_CLKGATE_CON(i) ((i) * 0x4 + 0x800)
+#define SECURE_CRU_CLKGATE_CON_CNT 1
+#define SECURE_CRU_SOFTRST_CON(i) ((i) * 0x4 + 0xa00)
+#define SECURE_CRU_SOFTRST_CON_CNT 1
+
+/* SECURE SCRU */
+#define SECURE_SCRU_CLKSEL_CON(i) ((i) * 0x4 + 0x4000)
+#define SECURE_SCRU_CLKSEL_CON_CNT 7
+#define SECURE_SCRU_CLKGATE_CON(i) ((i) * 0x4 + 0x4028)
+#define SECURE_SCRU_CLKGATE_CON_CNT 6
+#define SECURE_SCRU_SOFTRST_CON(i) ((i) * 0x4 + 0x4050)
+#define SECURE_SCRU_SOFTRST_CON_CNT 6
+#define SECURE_SCRU_MODE_CON 0x4280
+
+/* SYSGRF */
+#define SYSGRF_SOC_CON(i) ((i) * 4)
+#define SYSGRF_SOC_STATUS 0x30
+#define SYSGRF_NOC_CON(i) (0x40 + (i) * 4)
+#define SYSGRF_NOC_STATUS(i) (0x60 + (i) * 4)
+#define SYSGRF_MEM_CON(i) (0x80 + (i) * 4)
+#define SYSGRF_STATUS0 0x140
+#define SYSGRF_STATUS1 0x144
+
+/* COREGRF */
+#define COREGRF_SOC_STATUS(i) (0x2c + (i) * 4)
+#define COREGRF_CPU_CON(i) (0x34 + (i) * 4)
+
+/* DDRGRF */
+#define DDRGRF_CHA_CON(i) ((i) * 4)
+#define DDRGRF_CHB_CON(i) (0x100 + (i) * 4)
+#define DDRGRF_CHA_ST(i) (0x60 + (i) * 4)
+#define DDRGRF_CHB_ST(i) (0xb0 + (i) * 4)
+#define DDRGRF_CON(i) (0x140 + (i) * 4)
+
+/* CCIGRF */
+#define CCIGRF_CON(i) ((i) * 4)
+#define CCIGRF_STATUS(i) (0x34 + (i) * 4)
+
+/* IOC */
+#define VCCIO_IOC_MISC_CON(i) (0x400 + (i) * 4)
+
+/* pvtm */
+#define PVTM_CON(i) (0x4 + (i) * 4)
+#define PVTM_INTEN 0x70
+#define PVTM_INTSTS 0x74
+#define PVTM_STATUS(i) (0x80 + (i) * 4)
+#define PVTM_CALC_CNT 0x200
+
+enum pvtm_con0 {
+ pvtm_start = 0,
+ pvtm_osc_en = 1,
+ pvtm_osc_sel = 2,
+ pvtm_rnd_seed_en = 5,
+};
+
+/* WDT */
+#define WDT_CR 0x0
+#define WDT_TORR 0x4
+#define WDT_CCVR 0x8
+#define WDT_CRR 0xc
+#define WDT_STAT 0x10
+#define WDT_EOI 0x14
+
+#define WDT_EN BIT(0)
+#define WDT_RSP_MODE BIT(1)
+
+/* timer */
+#define TIMER_LOAD_COUNT0 0x00
+#define TIMER_LOAD_COUNT1 0x04
+#define TIMER_CURRENT_VALUE0 0x08
+#define TIMER_CURRENT_VALUE1 0x0c
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_INTSTATUS 0x18
+
+#define TIMER_DIS 0x0
+#define TIMER_EN 0x1
+
+#define TIMER_FMODE (0x0 << 1)
+#define TIMER_RMODE (0x1 << 1)
+
+/* hp timer */
+#define TIMER_HP_REVISION 0x00
+#define TIMER_HP_CTRL 0x04
+#define TIMER_HP_INTR_EN 0x08
+#define TIMER_HP_T24_GCD 0x0c
+#define TIMER_HP_T32_GCD 0x10
+#define TIMER_HP_LOAD_COUNT0 0x14
+#define TIMER_HP_LOAD_COUNT1 0x18
+#define TIMER_HP_T24_DELAT_COUNT0 0x1c
+#define TIMER_HP_T24_DELAT_COUNT1 0x20
+#define TIMER_HP_CURR_32K_VALUE0 0x24
+#define TIMER_HP_CURR_32K_VALUE1 0x28
+#define TIMER_HP_CURR_TIMER_VALUE0 0x2c
+#define TIMER_HP_CURR_TIMER_VALUE1 0x30
+#define TIMER_HP_T24_32BEGIN0 0x34
+#define TIMER_HP_T24_32BEGIN1 0x38
+#define TIMER_HP_T32_24END0 0x3c
+#define TIMER_HP_T32_24END1 0x40
+#define TIMER_HP_BEGIN_END_VALID 0x44
+#define TIMER_HP_SYNC_REQ 0x48
+#define TIMER_HP_INTR_STATUS 0x4c
+#define TIMER_HP_UPD_EN 0x50
+
+ /* GPIO */
+#define GPIO_SWPORT_DR_L 0x0000
+#define GPIO_SWPORT_DR_H 0x0004
+#define GPIO_SWPORT_DDR_L 0x0008
+#define GPIO_SWPORT_DDR_H 0x000c
+#define GPIO_INT_EN_L 0x0010
+#define GPIO_INT_EN_H 0x0014
+#define GPIO_INT_MASK_L 0x0018
+#define GPIO_INT_MASK_H 0x001c
+#define GPIO_INT_TYPE_L 0x0020
+#define GPIO_INT_TYPE_H 0x0024
+#define GPIO_INT_POLARITY_L 0x0028
+#define GPIO_INT_POLARITY_H 0x002c
+#define GPIO_INT_BOTHEDGE_L 0x0030
+#define GPIO_INT_BOTHEDGE_H 0x0034
+#define GPIO_DEBOUNCE_L 0x0038
+#define GPIO_DEBOUNCE_H 0x003c
+#define GPIO_DBCLK_DIV_EN_L 0x0040
+#define GPIO_DBCLK_DIV_EN_H 0x0044
+#define GPIO_DBCLK_DIV_CON 0x0048
+#define GPIO_INT_STATUS 0x0050
+#define GPIO_INT_RAWSTATUS 0x0058
+#define GPIO_PORT_EOI_L 0x0060
+#define GPIO_PORT_EOI_H 0x0064
+#define GPIO_EXT_PORT 0x0070
+#define GPIO_VER_ID 0x0078
+#define GPIO_STORE_ST_L 0x0080
+#define GPIO_STORE_ST_H 0x0084
+#define GPIO_REG_GROUP_L 0x0100
+#define GPIO_REG_GROUP_H 0x0104
+#define GPIO_VIRTUAL_EN 0x0108
+#define GPIO_REG_GROUP1_L 0x0110
+#define GPIO_REG_GROUP1_H 0x0114
+#define GPIO_REG_GROUP2_L 0x0118
+#define GPIO_REG_GROUP2_H 0x011c
+#define GPIO_REG_GROUP3_L 0x0120
+#define GPIO_REG_GROUP3_H 0x0124
+
+/* PWM */
+#define PMW_PWRCAPTURE_VAL 0x15c
+
+#define SOC_RK3576A1 0x35760101
+#define SOC_RK3576J1 0x35760a01
+#define SOC_RK3576M1 0x35760d01
+#define SOC_RK3576S1 0x35761301
+#define SOC_UNKNOWN 0xeeee
+#define SOC_ROOT 0x0
+
+int rk_soc_is_(uint32_t soc_id);
+uint32_t timer_hp_get_freq(void);
+int soc_bus_div_sip_handler(uint32_t id, uint32_t cfg, uint32_t enable_msk);
+void autocs_suspend(void);
+void autocs_resume(void);
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3576/include/plat.ld.S b/plat/rockchip/rk3576/include/plat.ld.S
new file mode 100644
index 0000000..4d0096f
--- /dev/null
+++ b/plat/rockchip/rk3576/include/plat.ld.S
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef ROCKCHIP_PLAT_LD_S
+#define ROCKCHIP_PLAT_LD_S
+
+MEMORY {
+ PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
+}
+
+SECTIONS
+{
+ . = PMUSRAM_BASE;
+
+ /*
+ * pmu_cpuson_entrypoint request address
+ * align 64K when resume, so put it in the
+ * start of pmusram
+ */
+ .text_pmusram : {
+ ASSERT(. == ALIGN(64 * 1024),
+ ".pmusram.entry request 64K aligned.");
+ KEEP(*(.pmusram.entry))
+ __bl31_pmusram_text_start = .;
+ *(.pmusram.text)
+ *(.pmusram.rodata)
+ . = ALIGN(PAGE_SIZE);
+ __bl31_pmusram_text_end = .;
+ __bl31_pmusram_data_start = .;
+ *(.pmusram.data)
+ . = ALIGN(PAGE_SIZE);
+ __bl31_pmusram_data_end = .;
+
+ ASSERT(__bl31_pmusram_data_end <= PMUSRAM_BASE + PMUSRAM_RSIZE,
+ ".pmusram has exceeded its limit.");
+ } >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3576/include/plat_sip_calls.h b/plat/rockchip/rk3576/include/plat_sip_calls.h
new file mode 100644
index 0000000..c33f24f
--- /dev/null
+++ b/plat/rockchip/rk3576/include/plat_sip_calls.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_SIP_CALLS_H__
+#define __PLAT_SIP_CALLS_H__
+
+#define RK_PLAT_SIP_NUM_CALLS 0
+
+#endif /* __PLAT_SIP_CALLS_H__ */
diff --git a/plat/rockchip/rk3576/include/platform_def.h b/plat/rockchip/rk3576/include/platform_def.h
new file mode 100644
index 0000000..03a80b0
--- /dev/null
+++ b/plat/rockchip/rk3576/include/platform_def.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3576_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT 1
+#define PLATFORM_CLUSTER_COUNT 2
+#define PLATFORM_CLUSTER0_CORE_COUNT 4
+#define PLATFORM_CLUSTER1_CORE_COUNT 4
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
+ PLATFORM_CLUSTER0_CORE_COUNT)
+
+#define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \
+ PLATFORM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2
+
+#define PLAT_RK_CLST_TO_CPUID_SHIFT 6
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE 1
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE 2
+/*******************************************************************************
+ * Platform memory map related constants
+ ******************************************************************************/
+/* TF txet, ro, rw, Size: 512KB */
+#define TZRAM_BASE RK_DRAM_BASE
+#define TZRAM_SIZE 0x100000
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL3-1 at the top of the Trusted RAM
+ */
+#define BL31_BASE (TZRAM_BASE + 0x40000)
+#define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+
+#define ADDR_SPACE_SIZE (1ULL << 32)
+#define MAX_XLAT_TABLES 18
+#define MAX_MMAP_REGIONS 27
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Define GICD and GICC and GICR base
+ */
+#define PLAT_RK_GICD_BASE PLAT_GICD_BASE
+#define PLAT_RK_GICC_BASE PLAT_GICC_BASE
+#define PLAT_RK_GICR_BASE PLAT_GICR_BASE
+
+#define PLAT_RK_UART_BASE RK_DBG_UART_BASE
+#define PLAT_RK_UART_CLOCK RK_DBG_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE RK_DBG_UART_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU 0x0
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3576/plat_sip_calls.c b/plat/rockchip/rk3576/plat_sip_calls.c
new file mode 100644
index 0000000..b0ff5fb
--- /dev/null
+++ b/plat/rockchip/rk3576/plat_sip_calls.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <drivers/scmi-msg.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ 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/rk3576/platform.mk b/plat/rockchip/rk3576/platform.mk
new file mode 100644
index 0000000..861cb4f
--- /dev/null
+++ b/plat/rockchip/rk3576/platform.mk
@@ -0,0 +1,115 @@
+#
+# Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+RK_PLAT := plat/rockchip
+RK_PLAT_SOC := ${RK_PLAT}/${PLAT}
+RK_PLAT_COMMON := ${RK_PLAT}/common
+
+DISABLE_BIN_GENERATION := 1
+
+include drivers/arm/gic/v2/gicv2.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_INCLUDES := -Idrivers/arm/gic/common/ \
+ -Idrivers/arm/gic/v2/ \
+ -Idrivers/scmi-msg/ \
+ -Iinclude/bl31 \
+ -Iinclude/common \
+ -Iinclude/drivers \
+ -Iinclude/drivers/arm \
+ -Iinclude/drivers/io \
+ -Iinclude/drivers/ti/uart \
+ -Iinclude/lib \
+ -Iinclude/lib/cpus/${ARCH} \
+ -Iinclude/lib/el3_runtime \
+ -Iinclude/lib/psci \
+ -Iinclude/plat/common \
+ -Iinclude/services \
+ -I${RK_PLAT_COMMON}/ \
+ -I${RK_PLAT_COMMON}/pmusram/ \
+ -I${RK_PLAT_COMMON}/include/ \
+ -I${RK_PLAT_COMMON}/drivers/pmu/ \
+ -I${RK_PLAT_COMMON}/drivers/parameter/ \
+ -I${RK_PLAT_COMMON}/scmi/ \
+ -I${RK_PLAT_SOC}/ \
+ -I${RK_PLAT_SOC}/drivers/dmc/ \
+ -I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/secure/ \
+ -I${RK_PLAT_SOC}/drivers/soc/ \
+ -I${RK_PLAT_SOC}/include/ \
+ -I${RK_PLAT_SOC}/scmi/
+
+RK_GIC_SOURCES := ${GICV2_SOURCES} \
+ plat/common/plat_gicv2.c \
+ ${RK_PLAT}/common/rockchip_gicv2.c
+
+PLAT_BL_COMMON_SOURCES := ${XLAT_TABLES_LIB_SRCS} \
+ common/desc_image_load.c \
+ lib/bl_aux_params/bl_aux_params.c \
+ plat/common/aarch64/crash_console_helpers.S \
+ plat/common/plat_psci_common.c
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += ${RK_PLAT_COMMON}/rockchip_stack_protector.c
+endif
+
+BL31_SOURCES += ${RK_GIC_SOURCES} \
+ drivers/arm/cci/cci.c \
+ 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_a53.S \
+ lib/cpus/aarch64/cortex_a72.S \
+ $(LIBFDT_SRCS) \
+ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
+ ${RK_PLAT_COMMON}/aarch64/platform_common.c \
+ ${RK_PLAT_COMMON}/bl31_plat_setup.c \
+ ${RK_PLAT_COMMON}/plat_pm.c \
+ ${RK_PLAT_COMMON}/plat_pm_helpers.c \
+ ${RK_PLAT_COMMON}/plat_topology.c \
+ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \
+ ${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/rockchip_common_clock.c \
+ ${RK_PLAT_COMMON}/scmi/scmi.c \
+ ${RK_PLAT_COMMON}/scmi/scmi_clock.c \
+ ${RK_PLAT_COMMON}/scmi/scmi_rstd.c \
+ ${RK_PLAT_SOC}/scmi/rk3576_clk.c \
+ ${RK_PLAT_SOC}/plat_sip_calls.c \
+ ${RK_PLAT_SOC}/drivers/dmc/suspend.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pm_pd_regs.c \
+ ${RK_PLAT_SOC}/drivers/secure/firewall.c \
+ ${RK_PLAT_SOC}/drivers/secure/secure.c \
+ ${RK_PLAT_SOC}/drivers/soc/soc.c
+
+# Enable workarounds for selected Cortex-A53 errata
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
+ERRATA_A53_1530924 := 1
+
+ERRATA_A72_1319367 := 1
+
+ENABLE_PLAT_COMPAT := 0
+MULTI_CONSOLE_API := 1
+CTX_INCLUDE_EL2_REGS := 0
+GICV2_G0_FOR_EL3 := 1
+CTX_INCLUDE_AARCH32_REGS := 0
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS := 0
+
+WORKAROUND_CVE_2017_5715 := 0
+
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/rockchip/rk3576/rk3576_def.h b/plat/rockchip/rk3576/rk3576_def.h
new file mode 100644
index 0000000..35f38ca
--- /dev/null
+++ b/plat/rockchip/rk3576/rk3576_def.h
@@ -0,0 +1,207 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define SIZE_K(n) ((n) * 1024)
+#define SIZE_M(n) ((n) * 1024 * 1024)
+
+#define WITH_16BITS_WMSK(bits) (0xffff0000 | (bits))
+#define BITS_WMSK(msk, shift) ((msk) << ((shift) + REG_MSK_SHIFT))
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+#define RK3576_DEV_RNG0_BASE 0x00000000
+#define RK3576_DEV_RNG0_SIZE 0x40000000
+
+#define RK_DRAM_BASE 0x40000000
+
+/* All slave base address declare below */
+#define MCU_TCM_BASE 0x23800000
+#define MCU_CACHE_BASE 0x23810000
+#define MCU_RAM_TEST_BASE 0x23820000
+#define MCU_BOOT_BASE 0x00000000
+#define MCU_MAIN_BASE 0x00010000
+#define PMU0SGRF_BASE 0x26000000
+#define PMU1SGRF_BASE 0x26002000
+#define PMU1SGRF_FW_BASE 0x26003000
+#define SYS_SGRF_BASE 0x26004000
+#define SYS_SGRF_FW_BASE 0x26005000
+#define SYS_GRF_BASE 0x2600a000
+#define BIGCORE_GRF_BASE 0x2600c000
+#define LITCORE_GRF_BASE 0x2600e000
+#define CCI_GRF_BASE 0x26010000
+#define DDR_GRF_BASE 0x26012000
+#define CENTER_GRF_BASE 0x26014000
+#define GPUGRF_BASE 0x26016000
+#define NPUGRF_BASE 0x26018000
+#define VO_GRF_BASE 0x2601a000
+#define VI_GRF_BASE 0x2601c000
+#define USB_GRF_BASE 0x2601e000
+#define PHP_GRF_BASE 0x26020000
+#define VOP_GRF_BASE 0x26022000
+#define PMU0_GRF_BASE 0x26024000
+#define PMU1_GRF_BASE 0x26026000
+#define USBDPPHY_GRF_BASE 0x2602c000
+#define USB2PHY0_GRF_BASE 0x2602e000
+#define USB2PHY1_GRF_BASE 0x26030000
+#define PMU0_IOC_BASE 0x26040000
+#define PMU1_IOC_BASE 0x26042000
+#define TOP_IOC_BASE 0x26044000
+#define VCCIO_IOC_BASE 0x26046000
+#define VCCIO6_IOC_BASE 0x2604a000
+#define VCCIO7_IOC_BASE 0x2604b000
+#define CRU_BASE 0x27200000
+#define PHP_CRU_BASE 0x27208000
+#define SECURE_CRU_BASE 0x27210000
+#define PMU1_CRU_BASE 0x27220000
+#define DDRPHY0_CRU_BASE 0x27228000
+#define DDRPHY1_CRU_BASE 0x27230000
+#define BIGCORE_CRU_BASE 0x27238000
+#define LITTLE_CRU_BASE 0x27240000
+#define CCI_CRU_BASE 0x27248000
+#define PVTPLL_CCI_BASE 0x27250000
+#define PVTPLL_BIGCORE_BASE 0x27258000
+#define PVTPLL_LITCORE_BASE 0x27260000
+#define PVTPLL_GPU_BASE 0x27268000
+#define PVTPLL_NPU_BASE 0x27270000
+#define PVTPLL_CRU_BASE 0x27278000
+#define I2C0_BASE 0x27300000
+#define UART1_BASE 0x27310000
+#define GPIO0_BASE 0x27320000
+#define PWM0_BASE 0x27330000
+#define WDT_PMU_BASE 0x27340000
+#define TIMER_PMU_BASE 0x27350000
+#define PMU_BASE 0x27360000
+#define PMU0_BASE 0x27360000
+#define PMU1_BASE 0x27370000
+#define PMU2_BASE 0x27380000
+#define PVTM_PMU_BASE 0x273f0000
+#define HPTIMER_BASE 0x27400000
+#define CCI_BASE 0x27500000
+#define VOP_BASE 0x27d00000
+#define INTERCONNECT_BASE 0x27f00000
+#define FW_CCI2DDR_BASE 0x27f80000
+#define FW_CENTER2DDR_BASE 0x27f90000
+#define FW_SYSMEM_BASE 0x27fa0000
+#define FW_VOP2DDR_BASE 0x27fb0000
+#define FW_CBUF_BASE 0x27fc0000
+#define FIREWALL_DDR_BASE 0x27f80000
+#define DDRCTL0_BASE 0x28000000
+#define DDRCTL1_BASE 0x29000000
+#define DDR_MONITOR0_BASE 0x2a000000
+#define DDR_MONITOR1_BASE 0x2a010000
+#define DDRPHY0_BASE 0x2a020000
+#define DDRPHY1_BASE 0x2a030000
+#define HWLP0_BASE 0x2a060000
+#define HWLP1_BASE 0x2a070000
+#define KEYLADDER_BASE 0x2a420000
+#define CRYPTO_S_BASE 0x2a430000
+#define OTP_S_BASE 0x2a480000
+#define DCF_BASE 0x2a490000
+#define STIMER0_BASE 0x2a4a0000
+#define STIMER1_BASE 0x2a4b0000
+#define WDT_S_BASE 0x2a4c0000
+#define OTP_MASK_BASE 0x2a4d0000
+#define OTP_NS_BASE 0x2a580000
+#define GIC400_BASE 0x2a700000
+#define I2C1_BASE 0x2ac40000
+#define NSTIMER0_BASE 0x2acc0000
+#define NSTIMER1_BASE 0x2acd0000
+#define WDT_NS_BASE 0x2ace0000
+#define UART0_BASE 0x2ad40000
+#define UART2_BASE 0x2ad50000
+#define UART3_BASE 0x2ad60000
+#define UART4_BASE 0x2ad70000
+#define UART5_BASE 0x2ad80000
+#define UART6_BASE 0x2ad90000
+#define UART7_BASE 0x2ada0000
+#define UART8_BASE 0x2adb0000
+#define UART9_BASE 0x2adc0000
+#define PWM1_BASE 0x2add0000
+#define PWM2_BASE 0x2ade0000
+#define PWM3_BASE 0x2adf0000
+#define GPIO1_BASE 0x2ae10000
+#define GPIO2_BASE 0x2ae20000
+#define GPIO3_BASE 0x2ae30000
+#define GPIO4_BASE 0x2ae40000
+#define TSADC_BASE 0x2ae70000
+
+#define PMUSRAM_BASE 0x3fe70000
+#define PMUSRAM_RSIZE SIZE_K(32)
+
+#define CBUF_BASE 0x3fe80000
+#define SRAM_BASE 0x3ff80000
+
+#define STIMER0_CHN_BASE(i) (STIMER0_BASE + 0x1000 * (i))
+#define STIMER1_CHN_BASE(i) (STIMER1_BASE + 0x1000 * (i))
+
+#define NSTIMER0_CHN_BASE(i) (NSTIMER0_BASE + 0x1000 * (i))
+#define NSTIMER1_CHN_BASE(i) (NSTIMER1_BASE + 0x1000 * (i))
+
+#define DDRPHY_BASE_CH(n) (DDRPHY0_BASE + ((n) * 0x10000))
+#define DDRPHY_CRU_BASE_CH(n) (DDRPHY0_CRU_BASE + ((n) * 0x8000))
+#define UMCTL_BASE_CH(n) (DDRCTL0_BASE + ((n) * 0x1000000))
+#define HWLP_BASE_CH(n) (HWLP0_BASE + ((n) * 0x10000))
+#define MAILBOX1_BASE (0x2ae50000 + 0xb000)
+
+#define CRYPTO_S_BY_KEYLAD_BASE CRYPTO_S_BASE
+
+#define DDR_SHARE_MEM (RK_DRAM_BASE + SIZE_K(1024))
+#define DDR_SHARE_SIZE SIZE_K(64)
+
+#define SHARE_MEM_BASE DDR_SHARE_MEM
+#define SHARE_MEM_PAGE_NUM 15
+#define SHARE_MEM_SIZE SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#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
+
+#define ROCKCHIP_PM_REG_REGION_MEM_SIZE SIZE_K(8)
+
+/******************************************************************************
+ * sgi, ppi
+ ******************************************************************************/
+#define RK_IRQ_SEC_PHY_TIMER 29
+
+#define RK_IRQ_SEC_SGI_0 8
+#define RK_IRQ_SEC_SGI_1 9
+#define RK_IRQ_SEC_SGI_2 10
+#define RK_IRQ_SEC_SGI_3 11
+#define RK_IRQ_SEC_SGI_4 12
+#define RK_IRQ_SEC_SGI_5 13
+#define RK_IRQ_SEC_SGI_6 14
+#define RK_IRQ_SEC_SGI_7 15
+
+/*
+ * Define a list of Group 0 interrupts.
+ */
+#define PLAT_RK_GICV2_G0_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
+ GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+/* UART related constants */
+#define RK_DBG_UART_BASE UART0_BASE
+#define RK_DBG_UART_BAUDRATE 1500000
+#define RK_DBG_UART_CLOCK 24000000
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE (GIC400_BASE + 0x1000)
+#define PLAT_GICC_BASE (GIC400_BASE + 0x2000)
+#define PLAT_GICR_BASE 0
+
+/* CCI */
+#define PLAT_RK_CCI_BASE CCI_BASE
+#define PLAT_RK_CCI_CLUSTER0_SL_IFACE_IX 1
+#define PLAT_RK_CCI_CLUSTER1_SL_IFACE_IX 2
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/rockchip/rk3576/scmi/rk3576_clk.c b/plat/rockchip/rk3576/scmi/rk3576_clk.c
new file mode 100644
index 0000000..7b36a05
--- /dev/null
+++ b/plat/rockchip/rk3576/scmi/rk3576_clk.c
@@ -0,0 +1,1353 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <drivers/delay_timer.h>
+#include <drivers/scmi.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+#include <platform_def.h>
+
+#include <plat_private.h>
+#include <rk3576_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 RK3576_PVTPLL_RING_EN 0x00
+#define RK3576_PVTPLL_RING0_LENGTH 0x04
+#define RK3576_PVTPLL_RING1_LENGTH 0x08
+#define RK3576_PVTPLL_RING2_LENGTH 0x0c
+#define RK3576_PVTPLL_RING3_LENGTH 0x10
+#define RK3576_PVTPLL_GCK_CFG 0x20
+#define RK3576_PVTPLL_GCK_LEN 0x24
+#define RK3576_PVTPLL_GCK_DIV 0x28
+#define RK3576_PVTPLL_GCK_CAL_CNT 0x2c
+#define RK3576_PVTPLL_GCK_REF_VAL 0x30
+#define RK3576_PVTPLL_GCK_CFG_VAL 0x34
+#define RK3576_PVTPLL_GCK_THR 0x38
+#define RK3576_PVTPLL_GFREE_CON 0x3c
+#define RK3576_PVTPLL_ADC_CFG 0x40
+#define RK3576_PVTPLL_ADC_CAL_CNT 0x48
+#define RK3576_PVTPLL_GCK_CNT 0x50
+#define RK3576_PVTPLL_GCK_CNT_AVG 0x54
+#define RK3576_PVTPLL_GCK_STATE 0x5c
+#define RK3576_PVTPLL_ADC_CNT 0x60
+#define RK3576_PVTPLL_ADC_CNT_AVG 0x68
+#define RK3576_PVTPLL_VERSION 0x70
+#define RK3576_PVTPLL_MAX_LENGTH 0x3f
+
+#define GPLL_RATE 1188000000
+#define CPLL_RATE 1000000000
+#define SPLL_RATE 702000000
+#define AUPLL_RATE 786431952
+
+#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)
+
+/* clk_core:
+ * from normal pll(core_i: gpll or apll) path or direct pass from apll
+ */
+
+/* cpul clk path */
+#define CPUL_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 12)
+#define CPUL_CLK_PATH_NOR_LPLL BITS_WITH_WMASK(0U, 0x3U, 12)
+#define CPUL_CLK_PATH_NOR_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CPUL_CLK_PATH_LPLL BITS_WITH_WMASK(0U, 0x3U, 6)
+#define CPUL_CLK_PATH_DIR_LPLL BITS_WITH_WMASK(2U, 0x3U, 6)
+#define CPUL_CLK_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 6)
+
+#define CPUL_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 13)
+#define CPUL_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(0x1, 0x1U, 13)
+
+/* cpub clk path */
+#define CPUB_CLK_PATH_NOR_GPLL BITS_WITH_WMASK(1U, 0x3U, 12)
+#define CPUB_CLK_PATH_NOR_BPLL BITS_WITH_WMASK(0U, 0x3U, 12)
+#define CPUB_CLK_PATH_NOR_PVTPLL BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CPUB_CLK_PATH_BPLL BITS_WITH_WMASK(0U, 0x3U, 14)
+#define CPUB_CLK_PATH_DIR_BPLL BITS_WITH_WMASK(2U, 0x3U, 14)
+#define CPUB_CLK_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 14)
+
+#define CPUB_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 5)
+#define CPUB_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(0x1, 0x1U, 5)
+
+#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)
+
+/* cci clk path */
+#define SCLK_CCI_PATH_XIN BITS_WITH_WMASK(0U, 0x3U, 12)
+#define SCLK_CCI_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x3U, 12)
+#define SCLK_CCI_PATH_NOR_LPLL BITS_WITH_WMASK(3U, 0x3U, 12)
+#define SCLK_CCI_PATH_NOR_GPLL BITS_WITH_WMASK(2U, 0x3U, 12)
+
+#define CCI_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 14)
+#define CCI_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 14)
+
+/* 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_SPLL BITS_WITH_WMASK(3U, 0x7U, 7)
+
+#define NPU_CLK_PATH_NOR_PLL WMSK_BIT(15)
+#define NPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(15)
+#define NPU_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 9)
+#define NPU_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 9)
+
+/* 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_SPLL BITS_WITH_WMASK(3U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_LPLL BITS_WITH_WMASK(4U, 0x7U, 5)
+#define GPU_CLK_PATH_NOR_PLL WMSK_BIT(8)
+#define GPU_CLK_PATH_PVTPLL BIT_WITH_WMSK(8)
+#define GPU_PVTPLL_PATH_DEEP_SLOW BITS_WITH_WMASK(0U, 0x1U, 9)
+#define GPU_PVTPLL_PATH_PVTPLL BITS_WITH_WMASK(1U, 0x1U, 9)
+
+#define PVTPLL_NEED(type, length) (((type) == PLL_SEL_PVT || \
+ (type) == PLL_SEL_AUTO) && \
+ (length))
+/*
+ * [0]: set intermediate rate
+ * [1]: scaling up rate or scaling down rate
+ * [1]: add length for pvtpll
+ * [2:5]: length
+ * [2]: use low length for pvtpll
+ * [3:5]: reserved
+ */
+#define OPP_RATE_MASK 0x3f
+#define OPP_INTERMEDIATE_RATE BIT(0)
+#define OPP_SCALING_UP_RATE BIT(1)
+#define OPP_ADD_LENGTH BIT(1)
+#define OPP_LENGTH_MASK GENMASK_32(5, 2)
+#define OPP_LENGTH_SHIFT 2
+#define OPP_LENGTH_LOW BIT(2)
+
+#define PRATE(x) static const unsigned long const x[]
+#define PINFO(x) static const uint32_t const x[]
+
+PRATE(p_24m) = { OSC_HZ };
+PRATE(p_100m_24m) = { 100 * MHz, OSC_HZ };
+PRATE(p_350m_175m_116m_24m) = { 350 * MHz, 175 * MHz, 116 * MHz, OSC_HZ };
+PRATE(p_175m_116m_58m_24m) = { 175 * MHz, 116 * MHz, 58 * MHz, OSC_HZ };
+PRATE(p_116m_58m_24m) = { 116 * MHz, 58 * MHz, OSC_HZ };
+PRATE(p_pclk_secure_s) = { PCLK_SECURE_S };
+PRATE(p_hclk_secure_s) = { HCLK_SECURE_S };
+PRATE(p_aclk_secure_s) = { ACLK_SECURE_S };
+PRATE(p_hclk_vo0_s) = { HCLK_VO0_S };
+PRATE(p_pclk_vo0_s) = { PCLK_VO0_S };
+PRATE(p_hclk_vo1_s) = { HCLK_VO1_S };
+PRATE(p_pclk_vo1_s) = { PCLK_VO1_S };
+
+PINFO(clk_stimer0_root_info) = { 0x27214004, 6, 1, 0, 0, 0, 0x27214028, 9 };
+PINFO(clk_stimer1_root_info) = { 0x27214004, 7, 1, 0, 0, 0, 0x2721402c, 1 };
+PINFO(pclk_secure_s_info) = { 0x27214004, 4, 2, 0, 0, 0, 0x27214028, 2 };
+PINFO(hclk_secure_s_info) = { 0x27214004, 2, 2, 0, 0, 0, 0x27214028, 1 };
+PINFO(aclk_secure_s_info) = { 0x27214004, 0, 2, 0, 0, 0, 0x27214028, 0 };
+PINFO(clk_pka_crypto_s_info) = { 0x27214004, 11, 2, 0, 0, 0, 0x27214030, 11 };
+PINFO(hclk_vo1_s_info) = { 0x27214010, 0, 2, 0, 0, 0, 0x27214038, 1 };
+PINFO(pclk_vo1_s_info) = { 0x27214010, 2, 2, 0, 0, 0, 0x27214038, 4 };
+PINFO(hclk_vo0_s_info) = { 0x27214018, 0, 2, 0, 0, 0, 0x2721403c, 1 };
+PINFO(pclk_vo0_s_info) = { 0x27214018, 2, 2, 0, 0, 0, 0x2721403c, 4 };
+PINFO(pclk_klad_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 7 };
+PINFO(hclk_crypto_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 8 };
+PINFO(hclk_klad_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 9 };
+PINFO(aclk_crypto_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214030, 12 };
+PINFO(hclk_trng_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 0 };
+PINFO(pclk_otpc_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 3 };
+PINFO(clk_otpc_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 4 };
+PINFO(pclk_wdt_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 9 };
+PINFO(tclk_wdt_s_info) = { 0, 0, 0, 0, 0, 0, 0x27214034, 10 };
+PINFO(pclk_hdcp1_trng_info) = { 0, 0, 0, 0, 0, 0, 0x27214038, 0 };
+PINFO(hclk_hdcp_key1_info) = { 0, 0, 0, 0, 0, 0, 0x27214038, 3 };
+PINFO(pclk_hdcp0_trng_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 0 };
+PINFO(hclk_hdcp_key0_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 3 };
+PINFO(pclk_edp_s_info) = { 0, 0, 0, 0, 0, 0, 0x2721403c, 5 };
+
+struct pvtpll_table {
+ unsigned int rate;
+ uint32_t length;
+ uint32_t length_frac;
+ uint32_t length_low;
+ uint32_t length_low_frac;
+ uint32_t ring_sel;
+ uint32_t volt_sel_thr;
+};
+
+struct sys_clk_info_t {
+ struct pvtpll_table *cpul_table;
+ struct pvtpll_table *cci_table;
+ struct pvtpll_table *cpub_table;
+ struct pvtpll_table *gpu_table;
+ struct pvtpll_table *npu_table;
+ unsigned int cpul_rate_count;
+ unsigned int cci_rate_count;
+ unsigned int cpub_rate_count;
+ unsigned int gpu_rate_count;
+ unsigned int npu_rate_count;
+ unsigned long cpul_rate;
+ unsigned long cci_rate;
+ unsigned long cpub_rate;
+ unsigned long gpu_rate;
+ unsigned long npu_rate;
+};
+
+struct otp_opp_info {
+ uint16_t min_freq;
+ uint16_t max_freq;
+ uint8_t volt;
+ uint8_t length;
+} __packed;
+
+#define RK3576_SCMI_CLOCK(_id, _name, _data, _table, _cnt, _is_s) \
+rk_scmi_clock_t _name = { \
+ .id = _id, \
+ .name = #_name, \
+ .clk_ops = _data, \
+ .rate_table = _table, \
+ .rate_cnt = _cnt, \
+ .is_security = _is_s, \
+}
+
+#define RK3576_SCMI_CLOCK_COM(_id, _name, _parent_table, _info, _data, \
+ _table, is_d, _is_s) \
+rk_scmi_clock_t _name = { \
+ .id = _id, \
+ .name = #_name, \
+ .parent_table = _parent_table, \
+ .info = _info, \
+ .clk_ops = _data, \
+ .rate_table = _table, \
+ .rate_cnt = ARRAY_SIZE(_table), \
+ .is_dynamic_prate = is_d, \
+ .is_security = _is_s, \
+}
+
+#define ROCKCHIP_PVTPLL(_rate, _sel, _len, _len_frac) \
+{ \
+ .rate = _rate##U, \
+ .ring_sel = _sel, \
+ .length = _len, \
+ .length_frac = _len_frac, \
+}
+
+static struct pvtpll_table rk3576_cpul_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length, length_frac */
+ ROCKCHIP_PVTPLL(2016000000, 0, 6, 0),
+ ROCKCHIP_PVTPLL(1920000000, 0, 6, 1),
+ ROCKCHIP_PVTPLL(1800000000, 0, 6, 1),
+ ROCKCHIP_PVTPLL(1608000000, 0, 6, 1),
+ ROCKCHIP_PVTPLL(1416000000, 0, 8, 0),
+ ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
+ ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
+ ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
+ ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
+ ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_cci_pvtpll_table[] = {
+ /* cpul_rate_hz, ring_sel, length, length_frac */
+ ROCKCHIP_PVTPLL(2016000000 / 2, 0, 27, 0),
+ ROCKCHIP_PVTPLL(1920000000 / 2, 0, 28, 0),
+ ROCKCHIP_PVTPLL(1800000000 / 2, 0, 28, 0),
+ ROCKCHIP_PVTPLL(1608000000 / 2, 0, 30, 0),
+ ROCKCHIP_PVTPLL(1416000000 / 2, 0, 34, 0),
+ ROCKCHIP_PVTPLL(1200000000 / 2, 0, 34, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_cpub_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+ ROCKCHIP_PVTPLL(2208000000, 0, 4, 3),
+ ROCKCHIP_PVTPLL(2112000000, 0, 5, 0),
+ ROCKCHIP_PVTPLL(2016000000, 0, 5, 0),
+ ROCKCHIP_PVTPLL(1800000000, 0, 5, 0),
+ ROCKCHIP_PVTPLL(1608000000, 0, 5, 0),
+ ROCKCHIP_PVTPLL(1416000000, 0, 7, 0),
+ ROCKCHIP_PVTPLL(1200000000, 0, 11, 0),
+ ROCKCHIP_PVTPLL(1008000000, 0, 17, 0),
+ ROCKCHIP_PVTPLL(816000000, 0, 26, 0),
+ ROCKCHIP_PVTPLL(600000000, 0, 0, 0),
+ ROCKCHIP_PVTPLL(408000000, 0, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_gpu_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+ ROCKCHIP_PVTPLL(900000000, 0, 20, 0),
+ ROCKCHIP_PVTPLL(800000000, 0, 21, 0),
+ ROCKCHIP_PVTPLL(700000000, 0, 21, 0),
+ ROCKCHIP_PVTPLL(600000000, 0, 23, 0),
+ ROCKCHIP_PVTPLL(500000000, 0, 32, 0),
+ ROCKCHIP_PVTPLL(400000000, 0, 48, 0),
+ ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
+ ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
+ { /* sentinel */ },
+};
+
+static struct pvtpll_table rk3576_npu_pvtpll_table[] = {
+ /* rate_hz, ring_sel, length, length_frac, length_low, length_low_frac */
+ ROCKCHIP_PVTPLL(950000000, 0, 16, 0),
+ ROCKCHIP_PVTPLL(900000000, 0, 17, 0),
+ ROCKCHIP_PVTPLL(800000000, 0, 18, 0),
+ ROCKCHIP_PVTPLL(700000000, 0, 22, 0),
+ ROCKCHIP_PVTPLL(600000000, 0, 25, 0),
+ ROCKCHIP_PVTPLL(500000000, 0, 35, 0),
+ ROCKCHIP_PVTPLL(400000000, 0, 46, 0),
+ ROCKCHIP_PVTPLL(300000000, 0, 63, 0),
+ ROCKCHIP_PVTPLL(200000000, 0, 0, 0),
+ { /* sentinel */ },
+};
+
+static unsigned long rk3576_cpul_rates[] = {
+ 408000000, 600000000, 816000000, 1008000000,
+ 1200000000, 1416000000, 1608000000, 1800000000,
+ 2016000000, 2208000000, 2304000063
+};
+
+static unsigned long rk3576_cpub_rates[] = {
+ 408000000, 600000000, 816000000, 1008000000,
+ 1200000000, 1416000000, 1608000000, 1800000000,
+ 2016000000, 2208000000, 2304000000, 2400000063
+};
+
+static unsigned long rk3576_gpu_rates[] = {
+ 200000000, 300000000, 400000000, 500000000,
+ 600000000, 700000000, 800000000, 900000000,
+ 1000000063
+};
+
+static unsigned long rk3576_npu_rates[] = {
+ 200000000, 300000000, 400000000, 500000000,
+ 600000000, 700000000, 800000000, 900000000,
+ 1000000063
+};
+
+static unsigned long rk3576_common_rates[] = {
+ 400000, 24000000, 58000000, 100000000, 116000000, 175000000, 350000000,
+};
+
+static unsigned long rk3576_aclk_secure_s_rates[] = {
+ 116000000, 175000000, 350000000,
+};
+
+static int aclk_crypto_s_enable;
+static int aclk_klad_enable;
+static spinlock_t crypto_lock;
+static bool cpub_suspended;
+
+static struct sys_clk_info_t sys_clk_info;
+static int clk_scmi_cci_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_scmi_set_low_length(struct pvtpll_table *pvtpll, unsigned int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (pvtpll[i].length_low) {
+ pvtpll[i].length = pvtpll[i].length_low;
+ pvtpll[i].length_frac = pvtpll[i].length_low_frac;
+ }
+ }
+
+ return 0;
+}
+
+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;
+
+ /*
+ * |-\
+ * -----lpll-----| \
+ * | \ |-\
+ * -----gpll-----|mux|--litcore unclean src--[div]--[autocs]--| \
+ * | / | \
+ * --pvtpll src--| / --pvtpll src--|mux|--litcore--
+ * |-/ | /
+ * --litcore clean src--| /
+ * |-/
+ */
+ if (PVTPLL_NEED(type, pvtpll->length)) {
+ /* set ring sel and length */
+ mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_LEN,
+ 0x1dff0000 |
+ (pvtpll->ring_sel << 10) |
+ (pvtpll->length << 2) |
+ (pvtpll->length_frac));
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+ /* enable pvtpll */
+ mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+ /* start pvtpll */
+ mmio_write_32(PVTPLL_LITCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+
+ /* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+ CPUL_PVTPLL_PATH_PVTPLL);
+
+ /* set litcore unclean_src parent to pvtpll_src */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+ CPUL_CLK_PATH_NOR_PVTPLL);
+ /*
+ * set litcore parent from pvtpll_src to unclean_src,
+ * because autocs is on litcore unclean_src.
+ */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+ CPUL_CLK_PATH_LPLL);
+ /* set litcore unclean_src div to 0 */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(0, 7));
+
+ return 0;
+ }
+ /* set litcore unclean_src div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+ CLKDIV_5BITS_SHF(div, 7));
+ /* set litcore unclean_src parent to gpll */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0),
+ CPUL_CLK_PATH_NOR_GPLL);
+ /* set litcore parent to unclean_src */
+ mmio_write_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1),
+ 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_cci_set_rate(clock, rate / 2);
+ }
+
+ return ret;
+}
+
+static unsigned long rk3576_lpll_get_rate(void)
+{
+ unsigned int m, p, s, k;
+ uint64_t rate64 = 24000000, postdiv;
+ int mode;
+
+ mode = mmio_read_32(LITTLE_CRU_BASE + CRU_MODE_CON) &
+ 0x3;
+
+ if (mode == 0)
+ return rate64;
+
+ m = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(16)) >>
+ CRU_PLLCON0_M_SHIFT) &
+ CRU_PLLCON0_M_MASK;
+ p = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
+ CRU_PLLCON1_P_SHIFT) &
+ CRU_PLLCON1_P_MASK;
+ s = (mmio_read_32(CCI_CRU_BASE + CRU_PLL_CON(17)) >>
+ CRU_PLLCON1_S_SHIFT) &
+ CRU_PLLCON1_S_MASK;
+ k = (mmio_read_32(CCI_CRU_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 * 65536;
+ 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(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(1)) & 0x00c0;
+ src = src >> 6;
+ if (src == 1)
+ return sys_clk_info.cpul_rate;
+
+ src = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(0)) & 0x3000;
+ src = src >> 12;
+ div = mmio_read_32(LITTLE_CRU_BASE + LCORE_CRU_CLKSEL_CON(6)) & 0x0f80;
+ div = div >> 7;
+ switch (src) {
+ case 0:
+ return rk3576_lpll_get_rate();
+ case 1:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.cpul_rate != 0)
+ return sys_clk_info.cpul_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 2:
+ return sys_clk_info.cpul_rate;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_cpul_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static int clk_cpub_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.cpub_table,
+ sys_clk_info.cpub_rate_count, rate);
+ if (pvtpll == NULL)
+ return SCMI_INVALID_PARAMETERS;
+
+ /*
+ * |-\
+ * -----bpll-----| \
+ * | \ |-\
+ * -----gpll-----|mux|--bigcore unclean src--[div]--[autocs]--| \
+ * | / | \
+ * --pvtpll src--| / --pvtpll src--|mux|--bigcore--
+ * |-/ | /
+ * --bigcore clean src--| /
+ * |-/
+ */
+ if (PVTPLL_NEED(type, pvtpll->length) != 0) {
+ /* set ring sel and length */
+ mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_LEN,
+ 0x1dff0000 |
+ (pvtpll->ring_sel << 10) |
+ (pvtpll->length << 2) |
+ (pvtpll->length_frac));
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+ /* enable pvtpll */
+ mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+ /* start pvtpll */
+ mmio_write_32(PVTPLL_BIGCORE_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+
+ /* set pvtpll_src parent from 24MHz/32KHz to pvtpll */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(2),
+ CPUB_PVTPLL_PATH_PVTPLL);
+
+ /* set bigcore unclean_src parent to pvtpll_src */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CPUB_CLK_PATH_NOR_PVTPLL);
+ /*
+ * set bigcore parent from pvtpll_src to unclean_src,
+ * because autocs is on bigcore unclean_src.
+ */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CPUB_CLK_PATH_BPLL);
+
+ /* set bigcore unclean_src div to 0 */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CLKDIV_5BITS_SHF(0, 7));
+
+ return 0;
+ }
+
+ /* set bigcore unclean_src div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate) - 1;
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CLKDIV_5BITS_SHF(div, 7));
+ /* set bigcore unclean_src parent to gpll */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CPUB_CLK_PATH_NOR_GPLL);
+ /* set bigcore parent to unclean_src */
+ mmio_write_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1),
+ CPUB_CLK_PATH_BPLL);
+
+ return 0;
+}
+
+static int clk_scmi_cpub_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ int ret;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ if ((rate & OPP_LENGTH_LOW) != 0) {
+ clk_scmi_set_low_length(sys_clk_info.cpub_table,
+ sys_clk_info.cpub_rate_count);
+ return 0;
+ }
+
+ ret = clk_cpub_set_rate(rate, PLL_SEL_AUTO);
+ if (ret == 0)
+ sys_clk_info.cpub_rate = rate;
+
+ return ret;
+}
+
+static unsigned long rk3576_bpll_get_rate(void)
+{
+ unsigned int m, p, s, k;
+ uint64_t rate64 = 24000000, postdiv;
+ int mode;
+
+ mode = mmio_read_32(CRU_BASE + CRU_MODE_CON) &
+ 0x3;
+
+ if (mode == 0)
+ return rate64;
+
+ m = (mmio_read_32(CRU_BASE + CRU_PLL_CON(0)) >>
+ CRU_PLLCON0_M_SHIFT) &
+ CRU_PLLCON0_M_MASK;
+ p = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
+ CRU_PLLCON1_P_SHIFT) &
+ CRU_PLLCON1_P_MASK;
+ s = (mmio_read_32(CRU_BASE + CRU_PLL_CON(1)) >>
+ CRU_PLLCON1_S_SHIFT) &
+ CRU_PLLCON1_S_MASK;
+ k = (mmio_read_32(CRU_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 * 65536;
+ frac_rate64 = frac_rate64 / postdiv;
+ rate64 += frac_rate64;
+ }
+ rate64 = rate64 >> s;
+
+ return (unsigned long)rate64;
+}
+
+static unsigned long clk_scmi_cpub_get_rate(rk_scmi_clock_t *clock)
+{
+ int value, src, div;
+
+ if (cpub_suspended != 0)
+ return sys_clk_info.cpub_rate;
+
+ value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
+ src = (value & 0xc000) >> 14;
+ if (src == 1)
+ return sys_clk_info.cpub_rate;
+
+ value = mmio_read_32(BIGCORE_CRU_BASE + BCORE_CRU_CLKSEL_CON(1));
+ src = (value & 0x3000) >> 12;
+ div = (value & 0x0f80) >> 7;
+ switch (src) {
+ case 0:
+ return rk3576_bpll_get_rate();
+ case 1:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.cpub_rate != 0)
+ return sys_clk_info.cpub_rate;
+ else
+ return GPLL_RATE / (div + 1);
+ case 2:
+ return sys_clk_info.cpub_rate;
+ default:
+ return 0;
+ }
+}
+
+static int clk_scmi_cpub_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ return 0;
+}
+
+static unsigned long clk_scmi_cci_get_rate(rk_scmi_clock_t *clock)
+{
+ int src, div;
+
+ src = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0x3000;
+ src = src >> 12;
+ if (src == 1)
+ return sys_clk_info.cci_rate;
+
+ div = mmio_read_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4)) & 0xf80;
+ div = div >> 7;
+ switch (src) {
+ case 0:
+ return OSC_HZ;
+ case 1:
+ return sys_clk_info.cci_rate;
+ case 2:
+ return GPLL_RATE / (div + 1);
+ case 3:
+ return rk3576_lpll_get_rate() / (div + 1);
+ default:
+ return 0;
+ }
+}
+
+static int clk_cci_set_rate(unsigned long rate, enum pll_type_sel type)
+{
+ struct pvtpll_table *pvtpll;
+ uint32_t pvtpll_en = 0;
+
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ pvtpll = rkclk_get_pvtpll_config(sys_clk_info.cci_table,
+ sys_clk_info.cci_rate_count, rate);
+
+ /* set pvtpll */
+ if ((pvtpll != 0) && (PVTPLL_NEED(type, pvtpll->length) != 0)) {
+ /* set ring sel and length */
+ mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_LEN,
+ 0x1dff0000 |
+ (pvtpll->ring_sel << 10) |
+ (pvtpll->length << 2) |
+ (pvtpll->length_frac));
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+ /* enable pvtpll */
+ pvtpll_en = mmio_read_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG);
+ if (pvtpll_en && 0x22 != 0x22)
+ mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+ /* start pvtpll */
+ mmio_write_32(PVTPLL_CCI_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+
+ /* set cci mux pvtpll */
+ mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+ CCI_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+ SCLK_CCI_PATH_PVTPLL);
+ mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+ CLKDIV_5BITS_SHF(0, 7));
+ sys_clk_info.cci_rate = rate;
+ return 0;
+ }
+ sys_clk_info.cci_rate = 594000000;
+ /* set cci div */
+ mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+ CLKDIV_5BITS_SHF(1, 7));
+ /* set cci mux gpll */
+ mmio_write_32(CCI_CRU_BASE + CCICRU_CLKSEL_CON(4),
+ SCLK_CCI_PATH_NOR_GPLL);
+
+ return 0;
+}
+
+static int clk_scmi_cci_set_rate(rk_scmi_clock_t *clock, unsigned long rate)
+{
+ if (rate == 0)
+ return SCMI_INVALID_PARAMETERS;
+
+ return clk_cci_set_rate(rate, PLL_SEL_AUTO);
+}
+
+static int clk_scmi_cci_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(165)) & 0x100) != 0)
+ return sys_clk_info.gpu_rate;
+
+ div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x1f;
+ src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(165)) & 0x00e0;
+ src = src >> 5;
+ switch (src) {
+ case 0:
+ /* Make the return rate is equal to the set rate */
+ if (sys_clk_info.gpu_rate != 0)
+ 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 SPLL_RATE / (div + 1);
+ case 4:
+ return rk3576_lpll_get_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) != 0) {
+ /* set ring sel and length */
+ mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_LEN,
+ 0x1dff0000 |
+ (pvtpll->ring_sel << 10) |
+ (pvtpll->length << 2) |
+ (pvtpll->length_frac));
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+ /* enable pvtpll */
+ mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+ /* start pvtpll */
+ mmio_write_32(PVTPLL_GPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+ /* set gpu mux pvtpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+ GPU_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+ GPU_CLK_PATH_PVTPLL);
+ return 0;
+ }
+
+ /* set gpu div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+ CLKDIV_5BITS_SHF(div - 1, 0));
+ /* set gpu mux gpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+ GPU_CLK_PATH_NOR_GPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(165),
+ 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;
+
+ if ((rate & OPP_LENGTH_LOW) != 0) {
+ clk_scmi_set_low_length(sys_clk_info.gpu_table,
+ sys_clk_info.gpu_rate_count);
+ return 0;
+ }
+
+ 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, div_src;
+
+ if ((mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x8000) != 0)
+ return sys_clk_info.npu_rate;
+
+ div_src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x07c;
+ div_src = div_src >> 2;
+ src = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x0180;
+ src = src >> 7;
+ div = mmio_read_32(CRU_BASE + CRU_CLKSEL_CON(86)) & 0x7c00;
+ div = div >> 10;
+ 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_src + 1) / (div + 1);
+ case 1:
+ return CPLL_RATE / (div_src + 1) / (div + 1);
+ case 2:
+ return AUPLL_RATE / (div_src + 1) / (div + 1);
+ case 3:
+ return SPLL_RATE / (div_src + 1) / (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) != 0) {
+ /* set ring sel and length */
+ mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_LEN,
+ 0x1dff0000 |
+ (pvtpll->ring_sel << 10) |
+ (pvtpll->length << 2) |
+ (pvtpll->length_frac));
+ /* set cal cnt = 24, T = 1us */
+ mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CAL_CNT, 0x18);
+ /* enable pvtpll */
+ mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00220022);
+ /* start pvtpll */
+ mmio_write_32(PVTPLL_NPU_BASE + RK3576_PVTPLL_GCK_CFG, 0x00230023);
+ /* set npu mux pvtpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ NPU_PVTPLL_PATH_PVTPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ NPU_CLK_PATH_PVTPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ CLKDIV_5BITS_SHF(0, 10));
+ return 0;
+ }
+
+ /* set npu div */
+ div = DIV_ROUND_UP(GPLL_RATE, rate);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ CLKDIV_5BITS_SHF(div - 1, 2));
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ CLKDIV_5BITS_SHF(0, 10));
+ /* set npu mux gpll */
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ NPU_CLK_PATH_NOR_GPLL);
+ mmio_write_32(CRU_BASE + CRU_CLKSEL_CON(86),
+ 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;
+
+ if ((rate & OPP_LENGTH_LOW) != 0) {
+ clk_scmi_set_low_length(sys_clk_info.npu_table,
+ sys_clk_info.npu_rate_count);
+ return 0;
+ }
+
+ 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;
+}
+
+int clk_scmi_crypto_set_status(rk_scmi_clock_t *clock, bool status)
+{
+ spin_lock(&crypto_lock);
+
+ if (clock->id == ACLK_CRYPTO_S)
+ aclk_crypto_s_enable = status;
+ else
+ aclk_klad_enable = status;
+
+ if ((aclk_crypto_s_enable != 0) || (aclk_klad_enable != 0))
+ clk_scmi_common_set_status(clock, 1);
+ else
+ clk_scmi_common_set_status(clock, 0);
+
+ spin_unlock(&crypto_lock);
+ return 0;
+}
+
+static int clk_scmi_common_set_status_critical(rk_scmi_clock_t *clock, bool status)
+{
+ 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_cci_ops = {
+ .get_rate = clk_scmi_cci_get_rate,
+ .set_rate = clk_scmi_cci_set_rate,
+ .set_status = clk_scmi_cci_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_cpub_ops = {
+ .get_rate = clk_scmi_cpub_get_rate,
+ .set_rate = clk_scmi_cpub_set_rate,
+ .set_status = clk_scmi_cpub_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_ops_com_critical = {
+ .get_rate = clk_scmi_common_get_rate,
+ .set_rate = clk_scmi_common_set_rate,
+ .set_status = clk_scmi_common_set_status_critical,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_com = {
+ .get_rate = clk_scmi_common_get_rate,
+ .set_rate = clk_scmi_common_set_rate,
+ .set_status = clk_scmi_common_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_gate = {
+ .get_rate = clk_scmi_common_get_rate,
+ .set_status = clk_scmi_common_set_status,
+};
+
+static const struct rk_clk_ops clk_scmi_ops_crypto = {
+ .get_rate = clk_scmi_common_get_rate,
+ .set_status = clk_scmi_crypto_set_status,
+};
+
+RK3576_SCMI_CLOCK(ARMCLK_L, scmi_armclkl, &clk_scmi_cpul_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
+RK3576_SCMI_CLOCK(ACLK_CCI_ROOT, scmi_aclk_cci, &clk_scmi_cci_ops, rk3576_cpul_rates, ARRAY_SIZE(rk3576_cpul_rates), false);
+RK3576_SCMI_CLOCK(ARMCLK_B, scmi_armclkb, &clk_scmi_cpub_ops, rk3576_cpub_rates, ARRAY_SIZE(rk3576_cpub_rates), false);
+RK3576_SCMI_CLOCK(CLK_GPU, scmi_clk_gpu, &clk_scmi_gpu_ops, rk3576_gpu_rates, ARRAY_SIZE(rk3576_gpu_rates), false);
+RK3576_SCMI_CLOCK(CLK_RKNN_DSU0, scmi_clk_npu, &clk_scmi_npu_ops, rk3576_npu_rates, ARRAY_SIZE(rk3576_npu_rates), false);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+RK3576_SCMI_CLOCK_COM(PCLK_KLAD, pclk_klad, p_pclk_secure_s, pclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+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);
+RK3576_SCMI_CLOCK_COM(HCLK_KLAD, hclk_klad, p_hclk_secure_s, hclk_klad_info, &clk_scmi_ops_gate, rk3576_common_rates, true, true);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+
+rk_scmi_clock_t *clock_table[] = {
+ [ARMCLK_L] = &scmi_armclkl,
+ [ACLK_CCI_ROOT] = &scmi_aclk_cci,
+ [ARMCLK_B] = &scmi_armclkb,
+ [CLK_GPU] = &scmi_clk_gpu,
+ [CLK_RKNN_DSU0] = &scmi_clk_npu,
+ [CLK_STIMER0_ROOT] = &clk_stimer0_root,
+ [CLK_STIMER1_ROOT] = &clk_stimer1_root,
+ [PCLK_SECURE_S] = &pclk_secure_s,
+ [HCLK_SECURE_S] = &hclk_secure_s,
+ [ACLK_SECURE_S] = &aclk_secure_s,
+ [CLK_PKA_CRYPTO_S] = &clk_pka_crypto_s,
+ [HCLK_VO1_S] = &hclk_vo1_s,
+ [PCLK_VO1_S] = &pclk_vo1_s,
+ [HCLK_VO0_S] = &hclk_vo0_s,
+ [PCLK_VO0_S] = &pclk_vo0_s,
+ [PCLK_KLAD] = &pclk_klad,
+ [HCLK_CRYPTO_S] = &hclk_crypto_s,
+ [HCLK_KLAD] = &hclk_klad,
+ [ACLK_CRYPTO_S] = &aclk_crypto_s,
+ [HCLK_TRNG_S] = &hclk_trng_s,
+ [PCLK_OTPC_S] = &plk_otpc_s,
+ [CLK_OTPC_S] = &clk_otpc_s,
+ [PCLK_WDT_S] = &pclk_wdt_s,
+ [TCLK_WDT_S] = &tclk_wdt_s,
+ [PCLK_HDCP0_TRNG] = &pclk_hdcp0_trng,
+ [PCLK_HDCP1_TRNG] = &pclk_hdcp1_trng,
+ [HCLK_HDCP_KEY0] = &hclk_hdcp_key0,
+ [HCLK_HDCP_KEY1] = &hclk_hdcp_key1,
+ [PCLK_EDP_S] = &pclk_edp_s,
+ [ACLK_KLAD] = &aclk_klad,
+};
+
+size_t rockchip_scmi_clock_count(unsigned int agent_id __unused)
+{
+ return CLK_NR_CLKS;
+}
+
+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 == NULL)
+ return NULL;
+ }
+
+ if ((table != NULL) && (table->is_security == 0))
+ return table;
+ else
+ return NULL;
+
+ return NULL;
+}
+
+void pvtplls_cpub_suspend(void)
+{
+ clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+ cpub_suspended = true;
+}
+
+void pvtplls_cpub_resume(void)
+{
+ cpub_suspended = false;
+ clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
+}
+
+void pvtplls_suspend(void)
+{
+ clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+ clk_cci_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+}
+
+void pvtplls_resume(void)
+{
+ clk_cpul_set_rate(sys_clk_info.cpul_rate, PLL_SEL_AUTO);
+ clk_cci_set_rate(sys_clk_info.cci_rate, PLL_SEL_AUTO);
+ clk_cpub_set_rate(sys_clk_info.cpub_rate, PLL_SEL_AUTO);
+}
+
+void sys_reset_pvtplls_prepare(void)
+{
+ clk_gpu_set_rate(200000000, PLL_SEL_NOR);
+ clk_npu_set_rate(200000000, PLL_SEL_NOR);
+ clk_cpul_set_rate(408000000, PLL_SEL_NOR);
+ clk_cci_set_rate(408000000, PLL_SEL_NOR);
+ clk_cpub_set_rate(408000000, PLL_SEL_NOR);
+}
+
+int rockchip_opteed_clk_set_rate(uint64_t clk_idx, uint64_t rate)
+{
+ rk_scmi_clock_t *table;
+
+ if (clk_idx > CLK_NR_CLKS) {
+ INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, rate);
+ return SCMI_INVALID_PARAMETERS;
+ }
+
+ table = rockchip_scmi_get_clock(0, clk_idx);
+ if (table != NULL)
+ table->clk_ops->set_rate(table, rate);
+
+ return 0;
+}
+
+int rockchip_opteed_clk_get_rate(uint64_t clk_idx, uint64_t *rate)
+{
+ rk_scmi_clock_t *table;
+
+ if (clk_idx > CLK_NR_CLKS) {
+ INFO("%s: clk-%ld not supported\n", __func__, clk_idx);
+ return SCMI_INVALID_PARAMETERS;
+ }
+
+ table = rockchip_scmi_get_clock(0, clk_idx);
+ if (table != NULL)
+ *rate = (uint64_t)table->clk_ops->get_rate(table);
+ return 0;
+}
+
+int rockchip_opteed_clk_enable(uint64_t clk_idx, uint64_t enable)
+{
+ rk_scmi_clock_t *table;
+
+ if (clk_idx > CLK_NR_CLKS) {
+ INFO("%s: clk-%ld, %ld not supported\n", __func__, clk_idx, enable);
+ return SCMI_INVALID_PARAMETERS;
+ }
+
+ table = rockchip_scmi_get_clock(0, clk_idx);
+ if (table != NULL) {
+ if (enable != 0) {
+ table->clk_ops->set_status(table, enable);
+ table->enable_count++;
+ } else {
+ if (table->enable_count == 0)
+ return 0;
+ if (--table->enable_count > 0)
+ return 0;
+ table->clk_ops->set_status(table, enable);
+ }
+ }
+ return 0;
+}
+
+#define RK3576_CPUB_OPP_INFO_OFFSET 48
+#define RK3576_CPUL_OPP_INFO_OFFSET 54
+#define RK3576_CCI_OPP_INFO_OFFSET 60
+#define RK3576_NPU_OPP_INFO_OFFSET 66
+#define RK3576_GPU_OPP_INFO_OFFSET 72
+
+static void rockchip_init_pvtpll_table(void)
+{
+ sys_clk_info.cpul_table = rk3576_cpul_pvtpll_table;
+ sys_clk_info.cpul_rate_count = ARRAY_SIZE(rk3576_cpul_pvtpll_table);
+ sys_clk_info.cci_table = rk3576_cci_pvtpll_table;
+ sys_clk_info.cci_rate_count = ARRAY_SIZE(rk3576_cci_pvtpll_table);
+ sys_clk_info.cpub_table = rk3576_cpub_pvtpll_table;
+ sys_clk_info.cpub_rate_count = ARRAY_SIZE(rk3576_cpub_pvtpll_table);
+ sys_clk_info.gpu_table = rk3576_gpu_pvtpll_table;
+ sys_clk_info.gpu_rate_count = ARRAY_SIZE(rk3576_gpu_pvtpll_table);
+ sys_clk_info.npu_table = rk3576_npu_pvtpll_table;
+ sys_clk_info.npu_rate_count = ARRAY_SIZE(rk3576_npu_pvtpll_table);
+}
+
+void rockchip_clock_init(void)
+{
+ rockchip_init_pvtpll_table();
+}
+
+static int pvtpll_get_clk(uint64_t clock_id, struct pvtpll_table **table,
+ unsigned int *count)
+{
+ switch (clock_id) {
+ case ARMCLK_L:
+ *table = sys_clk_info.cpul_table;
+ *count = sys_clk_info.cpul_rate_count;
+ break;
+ case ARMCLK_B:
+ *table = sys_clk_info.cpub_table;
+ *count = sys_clk_info.cpub_rate_count;
+ break;
+ case CLK_GPU:
+ *table = sys_clk_info.gpu_table;
+ *count = sys_clk_info.gpu_rate_count;
+ break;
+ case CLK_RKNN_DSU0:
+ *table = sys_clk_info.npu_table;
+ *count = sys_clk_info.npu_rate_count;
+ break;
+ default:
+ return -1;
+ }
+
+ if ((*table == NULL) || (*count == 0))
+ return -1;
+
+ return 0;
+}
+
+int pvtpll_volt_sel_adjust(uint64_t clock_id, uint64_t volt_sel)
+{
+ struct pvtpll_table *table = NULL;
+ uint32_t delta_len = 0;
+ unsigned int count = 0;
+ int i;
+
+ if (pvtpll_get_clk(clock_id, &table, &count) != 0)
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ if (table[i].volt_sel_thr == 0)
+ continue;
+ if (volt_sel >= table[i].volt_sel_thr) {
+ delta_len = volt_sel - table[i].volt_sel_thr + 1;
+ table[i].length += delta_len;
+ if (table[i].length > RK3576_PVTPLL_MAX_LENGTH)
+ table[i].length = RK3576_PVTPLL_MAX_LENGTH;
+ }
+ }
+
+ return 0;
+}
diff --git a/plat/rockchip/rk3576/scmi/rk3576_clk.h b/plat/rockchip/rk3576/scmi/rk3576_clk.h
new file mode 100644
index 0000000..b2c00b9
--- /dev/null
+++ b/plat/rockchip/rk3576/scmi/rk3576_clk.h
@@ -0,0 +1,1151 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2025, Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+/* cru-clocks indices */
+
+/* cru plls */
+#define PLL_BPLL 1
+#define PLL_LPLL 3
+#define PLL_VPLL 4
+#define PLL_AUPLL 5
+#define PLL_CPLL 6
+#define PLL_GPLL 7
+#define PLL_PPLL 9
+#define ARMCLK_L 10
+#define ARMCLK_B 11
+
+/* cru clocks */
+#define CLK_CPLL_DIV20 15
+#define CLK_CPLL_DIV10 16
+#define CLK_GPLL_DIV8 17
+#define CLK_GPLL_DIV6 18
+#define CLK_CPLL_DIV4 19
+#define CLK_GPLL_DIV4 20
+#define CLK_SPLL_DIV2 21
+#define CLK_GPLL_DIV3 22
+#define CLK_CPLL_DIV2 23
+#define CLK_GPLL_DIV2 24
+#define CLK_SPLL_DIV1 25
+#define PCLK_TOP_ROOT 26
+#define ACLK_TOP 27
+#define HCLK_TOP 28
+#define CLK_AUDIO_FRAC_0 29
+#define CLK_AUDIO_FRAC_1 30
+#define CLK_AUDIO_FRAC_2 31
+#define CLK_AUDIO_FRAC_3 32
+#define CLK_UART_FRAC_0 33
+#define CLK_UART_FRAC_1 34
+#define CLK_UART_FRAC_2 35
+#define CLK_UART1_SRC_TOP 36
+#define CLK_AUDIO_INT_0 37
+#define CLK_AUDIO_INT_1 38
+#define CLK_AUDIO_INT_2 39
+#define CLK_PDM0_SRC_TOP 40
+#define CLK_PDM1_OUT 41
+#define CLK_GMAC0_125M_SRC 42
+#define CLK_GMAC1_125M_SRC 43
+#define LCLK_ASRC_SRC_0 44
+#define LCLK_ASRC_SRC_1 45
+#define REF_CLK0_OUT_PLL 46
+#define REF_CLK1_OUT_PLL 47
+#define REF_CLK2_OUT_PLL 48
+#define REFCLKO25M_GMAC0_OUT 49
+#define REFCLKO25M_GMAC1_OUT 50
+#define CLK_CIFOUT_OUT 51
+#define CLK_GMAC0_RMII_CRU 52
+#define CLK_GMAC1_RMII_CRU 53
+#define CLK_OTPC_AUTO_RD_G 54
+#define CLK_OTP_PHY_G 55
+#define CLK_MIPI_CAMERAOUT_M0 56
+#define CLK_MIPI_CAMERAOUT_M1 57
+#define CLK_MIPI_CAMERAOUT_M2 58
+#define MCLK_PDM0_SRC_TOP 59
+#define HCLK_AUDIO_ROOT 60
+#define HCLK_ASRC_2CH_0 61
+#define HCLK_ASRC_2CH_1 62
+#define HCLK_ASRC_4CH_0 63
+#define HCLK_ASRC_4CH_1 64
+#define CLK_ASRC_2CH_0 65
+#define CLK_ASRC_2CH_1 66
+#define CLK_ASRC_4CH_0 67
+#define CLK_ASRC_4CH_1 68
+#define MCLK_SAI0_8CH_SRC 69
+#define MCLK_SAI0_8CH 70
+#define HCLK_SAI0_8CH 71
+#define HCLK_SPDIF_RX0 72
+#define MCLK_SPDIF_RX0 73
+#define HCLK_SPDIF_RX1 74
+#define MCLK_SPDIF_RX1 75
+#define MCLK_SAI1_8CH_SRC 76
+#define MCLK_SAI1_8CH 77
+#define HCLK_SAI1_8CH 78
+#define MCLK_SAI2_2CH_SRC 79
+#define MCLK_SAI2_2CH 80
+#define HCLK_SAI2_2CH 81
+#define MCLK_SAI3_2CH_SRC 82
+#define MCLK_SAI3_2CH 83
+#define HCLK_SAI3_2CH 84
+#define MCLK_SAI4_2CH_SRC 85
+#define MCLK_SAI4_2CH 86
+#define HCLK_SAI4_2CH 87
+#define HCLK_ACDCDIG_DSM 88
+#define MCLK_ACDCDIG_DSM 89
+#define CLK_PDM1 90
+#define HCLK_PDM1 91
+#define MCLK_PDM1 92
+#define HCLK_SPDIF_TX0 93
+#define MCLK_SPDIF_TX0 94
+#define HCLK_SPDIF_TX1 95
+#define MCLK_SPDIF_TX1 96
+#define CLK_SAI1_MCLKOUT 97
+#define CLK_SAI2_MCLKOUT 98
+#define CLK_SAI3_MCLKOUT 99
+#define CLK_SAI4_MCLKOUT 100
+#define CLK_SAI0_MCLKOUT 101
+#define HCLK_BUS_ROOT 102
+#define PCLK_BUS_ROOT 103
+#define ACLK_BUS_ROOT 104
+#define HCLK_CAN0 105
+#define CLK_CAN0 106
+#define HCLK_CAN1 107
+#define CLK_CAN1 108
+#define CLK_KEY_SHIFT 109
+#define PCLK_I2C1 110
+#define PCLK_I2C2 111
+#define PCLK_I2C3 112
+#define PCLK_I2C4 113
+#define PCLK_I2C5 114
+#define PCLK_I2C6 115
+#define PCLK_I2C7 116
+#define PCLK_I2C8 117
+#define PCLK_I2C9 118
+#define PCLK_WDT_BUSMCU 119
+#define TCLK_WDT_BUSMCU 120
+#define ACLK_GIC 121
+#define CLK_I2C1 122
+#define CLK_I2C2 123
+#define CLK_I2C3 124
+#define CLK_I2C4 125
+#define CLK_I2C5 126
+#define CLK_I2C6 127
+#define CLK_I2C7 128
+#define CLK_I2C8 129
+#define CLK_I2C9 130
+#define PCLK_SARADC 131
+#define CLK_SARADC 132
+#define PCLK_TSADC 133
+#define CLK_TSADC 134
+#define PCLK_UART0 135
+#define PCLK_UART2 136
+#define PCLK_UART3 137
+#define PCLK_UART4 138
+#define PCLK_UART5 139
+#define PCLK_UART6 140
+#define PCLK_UART7 141
+#define PCLK_UART8 142
+#define PCLK_UART9 143
+#define PCLK_UART10 144
+#define PCLK_UART11 145
+#define SCLK_UART0 146
+#define SCLK_UART2 147
+#define SCLK_UART3 148
+#define SCLK_UART4 149
+#define SCLK_UART5 150
+#define SCLK_UART6 151
+#define SCLK_UART7 152
+#define SCLK_UART8 153
+#define SCLK_UART9 154
+#define SCLK_UART10 155
+#define SCLK_UART11 156
+#define PCLK_SPI0 157
+#define PCLK_SPI1 158
+#define PCLK_SPI2 159
+#define PCLK_SPI3 160
+#define PCLK_SPI4 161
+#define CLK_SPI0 162
+#define CLK_SPI1 163
+#define CLK_SPI2 164
+#define CLK_SPI3 165
+#define CLK_SPI4 166
+#define PCLK_WDT0 167
+#define TCLK_WDT0 168
+#define PCLK_PWM1 169
+#define CLK_PWM1 170
+#define CLK_OSC_PWM1 171
+#define CLK_RC_PWM1 172
+#define PCLK_BUSTIMER0 173
+#define PCLK_BUSTIMER1 174
+#define CLK_TIMER0_ROOT 175
+#define CLK_TIMER0 176
+#define CLK_TIMER1 177
+#define CLK_TIMER2 178
+#define CLK_TIMER3 179
+#define CLK_TIMER4 180
+#define CLK_TIMER5 181
+#define PCLK_MAILBOX0 182
+#define PCLK_GPIO1 183
+#define DBCLK_GPIO1 184
+#define PCLK_GPIO2 185
+#define DBCLK_GPIO2 186
+#define PCLK_GPIO3 187
+#define DBCLK_GPIO3 188
+#define PCLK_GPIO4 189
+#define DBCLK_GPIO4 190
+#define ACLK_DECOM 191
+#define PCLK_DECOM 192
+#define DCLK_DECOM 193
+#define CLK_TIMER1_ROOT 194
+#define CLK_TIMER6 195
+#define CLK_TIMER7 196
+#define CLK_TIMER8 197
+#define CLK_TIMER9 198
+#define CLK_TIMER10 199
+#define CLK_TIMER11 200
+#define ACLK_DMAC0 201
+#define ACLK_DMAC1 202
+#define ACLK_DMAC2 203
+#define ACLK_SPINLOCK 204
+#define HCLK_I3C0 205
+#define HCLK_I3C1 206
+#define HCLK_BUS_CM0_ROOT 207
+#define FCLK_BUS_CM0_CORE 208
+#define CLK_BUS_CM0_RTC 209
+#define PCLK_PMU2 210
+#define PCLK_PWM2 211
+#define CLK_PWM2 212
+#define CLK_RC_PWM2 213
+#define CLK_OSC_PWM2 214
+#define CLK_FREQ_PWM1 215
+#define CLK_COUNTER_PWM1 216
+#define SAI_SCLKIN_FREQ 217
+#define SAI_SCLKIN_COUNTER 218
+#define CLK_I3C0 219
+#define CLK_I3C1 220
+#define PCLK_CSIDPHY1 221
+#define PCLK_DDR_ROOT 222
+#define PCLK_DDR_MON_CH0 223
+#define TMCLK_DDR_MON_CH0 224
+#define ACLK_DDR_ROOT 225
+#define HCLK_DDR_ROOT 226
+#define FCLK_DDR_CM0_CORE 227
+#define CLK_DDR_TIMER_ROOT 228
+#define CLK_DDR_TIMER0 229
+#define CLK_DDR_TIMER1 230
+#define TCLK_WDT_DDR 231
+#define PCLK_WDT 232
+#define PCLK_TIMER 233
+#define CLK_DDR_CM0_RTC 234
+#define ACLK_RKNN0 235
+#define ACLK_RKNN1 236
+#define HCLK_RKNN_ROOT 237
+#define CLK_RKNN_DSU0 238
+#define PCLK_NPUTOP_ROOT 239
+#define PCLK_NPU_TIMER 240
+#define CLK_NPUTIMER_ROOT 241
+#define CLK_NPUTIMER0 242
+#define CLK_NPUTIMER1 243
+#define PCLK_NPU_WDT 244
+#define TCLK_NPU_WDT 245
+#define ACLK_RKNN_CBUF 246
+#define HCLK_NPU_CM0_ROOT 247
+#define FCLK_NPU_CM0_CORE 248
+#define CLK_NPU_CM0_RTC 249
+#define HCLK_RKNN_CBUF 250
+#define HCLK_NVM_ROOT 251
+#define ACLK_NVM_ROOT 252
+#define SCLK_FSPI_X2 253
+#define HCLK_FSPI 254
+#define CCLK_SRC_EMMC 255
+#define HCLK_EMMC 256
+#define ACLK_EMMC 257
+#define BCLK_EMMC 258
+#define TCLK_EMMC 259
+#define PCLK_PHP_ROOT 260
+#define ACLK_PHP_ROOT 261
+#define PCLK_PCIE0 262
+#define CLK_PCIE0_AUX 263
+#define ACLK_PCIE0_MST 264
+#define ACLK_PCIE0_SLV 265
+#define ACLK_PCIE0_DBI 266
+#define ACLK_USB3OTG1 267
+#define CLK_REF_USB3OTG1 268
+#define CLK_SUSPEND_USB3OTG1 269
+#define ACLK_MMU0 270
+#define ACLK_SLV_MMU0 271
+#define ACLK_MMU1 272
+#define ACLK_SLV_MMU1 273
+#define PCLK_PCIE1 275
+#define CLK_PCIE1_AUX 276
+#define ACLK_PCIE1_MST 277
+#define ACLK_PCIE1_SLV 278
+#define ACLK_PCIE1_DBI 279
+#define CLK_RXOOB0 280
+#define CLK_RXOOB1 281
+#define CLK_PMALIVE0 282
+#define CLK_PMALIVE1 283
+#define ACLK_SATA0 284
+#define ACLK_SATA1 285
+#define CLK_USB3OTG1_PIPE_PCLK 286
+#define CLK_USB3OTG1_UTMI 287
+#define CLK_USB3OTG0_PIPE_PCLK 288
+#define CLK_USB3OTG0_UTMI 289
+#define HCLK_SDGMAC_ROOT 290
+#define ACLK_SDGMAC_ROOT 291
+#define PCLK_SDGMAC_ROOT 292
+#define ACLK_GMAC0 293
+#define ACLK_GMAC1 294
+#define PCLK_GMAC0 295
+#define PCLK_GMAC1 296
+#define CCLK_SRC_SDIO 297
+#define HCLK_SDIO 298
+#define CLK_GMAC1_PTP_REF 299
+#define CLK_GMAC0_PTP_REF 300
+#define CLK_GMAC1_PTP_REF_SRC 301
+#define CLK_GMAC0_PTP_REF_SRC 302
+#define CCLK_SRC_SDMMC0 303
+#define HCLK_SDMMC0 304
+#define SCLK_FSPI1_X2 305
+#define HCLK_FSPI1 306
+#define ACLK_DSMC_ROOT 307
+#define ACLK_DSMC 308
+#define PCLK_DSMC 309
+#define CLK_DSMC_SYS 310
+#define HCLK_HSGPIO 311
+#define CLK_HSGPIO_TX 312
+#define CLK_HSGPIO_RX 313
+#define ACLK_HSGPIO 314
+#define PCLK_PHPPHY_ROOT 315
+#define PCLK_PCIE2_COMBOPHY0 316
+#define PCLK_PCIE2_COMBOPHY1 317
+#define CLK_PCIE_100M_SRC 318
+#define CLK_PCIE_100M_NDUTY_SRC 319
+#define CLK_REF_PCIE0_PHY 320
+#define CLK_REF_PCIE1_PHY 321
+#define CLK_REF_MPHY_26M 322
+#define HCLK_RKVDEC_ROOT 323
+#define ACLK_RKVDEC_ROOT 324
+#define HCLK_RKVDEC 325
+#define CLK_RKVDEC_HEVC_CA 326
+#define CLK_RKVDEC_CORE 327
+#define ACLK_UFS_ROOT 328
+#define ACLK_USB_ROOT 329
+#define PCLK_USB_ROOT 330
+#define ACLK_USB3OTG0 331
+#define CLK_REF_USB3OTG0 332
+#define CLK_SUSPEND_USB3OTG0 333
+#define ACLK_MMU2 334
+#define ACLK_SLV_MMU2 335
+#define ACLK_UFS_SYS 336
+#define ACLK_VPU_ROOT 337
+#define ACLK_VPU_MID_ROOT 338
+#define HCLK_VPU_ROOT 339
+#define ACLK_JPEG_ROOT 340
+#define ACLK_VPU_LOW_ROOT 341
+#define HCLK_RGA2E_0 342
+#define ACLK_RGA2E_0 342
+#define CLK_CORE_RGA2E_0 344
+#define ACLK_JPEG 345
+#define HCLK_JPEG 346
+#define HCLK_VDPP 347
+#define ACLK_VDPP 348
+#define CLK_CORE_VDPP 349
+#define HCLK_RGA2E_1 350
+#define ACLK_RGA2E_1 351
+#define CLK_CORE_RGA2E_1 352
+#define DCLK_EBC_FRAC_SRC 353
+#define HCLK_EBC 354
+#define ACLK_EBC 355
+#define DCLK_EBC 356
+#define HCLK_VEPU0_ROOT 357
+#define ACLK_VEPU0_ROOT 358
+#define HCLK_VEPU0 359
+#define ACLK_VEPU0 360
+#define CLK_VEPU0_CORE 361
+#define ACLK_VI_ROOT 362
+#define HCLK_VI_ROOT 363
+#define PCLK_VI_ROOT 364
+#define DCLK_VICAP 365
+#define ACLK_VICAP 366
+#define HCLK_VICAP 367
+#define CLK_ISP_CORE 368
+#define CLK_ISP_CORE_MARVIN 369
+#define CLK_ISP_CORE_VICAP 370
+#define ACLK_ISP 371
+#define HCLK_ISP 372
+#define ACLK_VPSS 373
+#define HCLK_VPSS 374
+#define CLK_CORE_VPSS 375
+#define PCLK_CSI_HOST_0 376
+#define PCLK_CSI_HOST_1 377
+#define PCLK_CSI_HOST_2 378
+#define PCLK_CSI_HOST_3 379
+#define PCLK_CSI_HOST_4 380
+#define ICLK_CSIHOST01 381
+#define ICLK_CSIHOST0 382
+#define CLK_ISP_PVTPLL_SRC 383
+#define ACLK_VI_ROOT_INTER 384
+#define CLK_VICAP_I0CLK 385
+#define CLK_VICAP_I1CLK 386
+#define CLK_VICAP_I2CLK 387
+#define CLK_VICAP_I3CLK 388
+#define CLK_VICAP_I4CLK 389
+#define ACLK_VOP_ROOT 390
+#define HCLK_VOP_ROOT 391
+#define PCLK_VOP_ROOT 392
+#define HCLK_VOP 393
+#define ACLK_VOP 394
+#define DCLK_VP0_SRC 395
+#define DCLK_VP1_SRC 396
+#define DCLK_VP2_SRC 397
+#define DCLK_VP0 398
+#define DCLK_VP1 400
+#define DCLK_VP2 401
+#define PCLK_VOPGRF 402
+#define ACLK_VO0_ROOT 403
+#define HCLK_VO0_ROOT 404
+#define PCLK_VO0_ROOT 405
+#define PCLK_VO0_GRF 406
+#define ACLK_HDCP0 407
+#define HCLK_HDCP0 408
+#define PCLK_HDCP0 409
+#define CLK_TRNG0_SKP 410
+#define PCLK_DSIHOST0 411
+#define CLK_DSIHOST0 412
+#define PCLK_HDMITX0 413
+#define CLK_HDMITX0_EARC 414
+#define CLK_HDMITX0_REF 415
+#define PCLK_EDP0 416
+#define CLK_EDP0_24M 417
+#define CLK_EDP0_200M 418
+#define MCLK_SAI5_8CH_SRC 419
+#define MCLK_SAI5_8CH 420
+#define HCLK_SAI5_8CH 421
+#define MCLK_SAI6_8CH_SRC 422
+#define MCLK_SAI6_8CH 423
+#define HCLK_SAI6_8CH 424
+#define HCLK_SPDIF_TX2 425
+#define MCLK_SPDIF_TX2 426
+#define HCLK_SPDIF_RX2 427
+#define MCLK_SPDIF_RX2 428
+#define HCLK_SAI8_8CH 429
+#define MCLK_SAI8_8CH_SRC 430
+#define MCLK_SAI8_8CH 431
+#define ACLK_VO1_ROOT 432
+#define HCLK_VO1_ROOT 433
+#define PCLK_VO1_ROOT 434
+#define MCLK_SAI7_8CH_SRC 435
+#define MCLK_SAI7_8CH 436
+#define HCLK_SAI7_8CH 437
+#define HCLK_SPDIF_TX3 438
+#define HCLK_SPDIF_TX4 439
+#define HCLK_SPDIF_TX5 440
+#define MCLK_SPDIF_TX3 441
+#define CLK_AUX16MHZ_0 442
+#define ACLK_DP0 443
+#define PCLK_DP0 444
+#define PCLK_VO1_GRF 445
+#define ACLK_HDCP1 446
+#define HCLK_HDCP1 447
+#define PCLK_HDCP1 448
+#define CLK_TRNG1_SKP 449
+#define HCLK_SAI9_8CH 450
+#define MCLK_SAI9_8CH_SRC 451
+#define MCLK_SAI9_8CH 452
+#define MCLK_SPDIF_TX4 453
+#define MCLK_SPDIF_TX5 454
+#define CLK_GPU_SRC_PRE 455
+#define CLK_GPU 456
+#define PCLK_GPU_ROOT 457
+#define ACLK_CENTER_ROOT 458
+#define ACLK_CENTER_LOW_ROOT 459
+#define HCLK_CENTER_ROOT 460
+#define PCLK_CENTER_ROOT 461
+#define ACLK_DMA2DDR 462
+#define ACLK_DDR_SHAREMEM 463
+#define PCLK_DMA2DDR 464
+#define PCLK_SHAREMEM 465
+#define HCLK_VEPU1_ROOT 466
+#define ACLK_VEPU1_ROOT 467
+#define HCLK_VEPU1 468
+#define ACLK_VEPU1 469
+#define CLK_VEPU1_CORE 470
+#define CLK_JDBCK_DAP 471
+#define PCLK_MIPI_DCPHY 472
+#define CLK_32K_USB2DEBUG 473
+#define PCLK_CSIDPHY 474
+#define PCLK_USBDPPHY 475
+#define CLK_PMUPHY_REF_SRC 476
+#define CLK_USBDP_COMBO_PHY_IMMORTAL 477
+#define CLK_HDMITXHPD 478
+#define PCLK_MPHY 479
+#define CLK_REF_OSC_MPHY 480
+#define CLK_REF_UFS_CLKOUT 481
+#define HCLK_PMU1_ROOT 482
+#define HCLK_PMU_CM0_ROOT 483
+#define CLK_200M_PMU_SRC 484
+#define CLK_100M_PMU_SRC 485
+#define CLK_50M_PMU_SRC 486
+#define FCLK_PMU_CM0_CORE 487
+#define CLK_PMU_CM0_RTC 488
+#define PCLK_PMU1 489
+#define CLK_PMU1 490
+#define PCLK_PMU1WDT 491
+#define TCLK_PMU1WDT 492
+#define PCLK_PMUTIMER 493
+#define CLK_PMUTIMER_ROOT 494
+#define CLK_PMUTIMER0 495
+#define CLK_PMUTIMER1 496
+#define PCLK_PMU1PWM 497
+#define CLK_PMU1PWM 498
+#define CLK_PMU1PWM_OSC 499
+#define PCLK_PMUPHY_ROOT 500
+#define PCLK_I2C0 501
+#define CLK_I2C0 502
+#define SCLK_UART1 503
+#define PCLK_UART1 504
+#define CLK_PMU1PWM_RC 505
+#define CLK_PDM0 506
+#define HCLK_PDM0 507
+#define MCLK_PDM0 508
+#define HCLK_VAD 509
+#define CLK_OSCCHK_PVTM 510
+#define CLK_PDM0_OUT 511
+#define CLK_HPTIMER_SRC 512
+#define PCLK_PMU0_ROOT 516
+#define PCLK_PMU0 517
+#define PCLK_GPIO0 518
+#define DBCLK_GPIO0 519
+#define CLK_OSC0_PMU1 520
+#define PCLK_PMU1_ROOT 521
+#define XIN_OSC0_DIV 522
+#define ACLK_USB 523
+#define ACLK_UFS 524
+#define ACLK_SDGMAC 525
+#define HCLK_SDGMAC 526
+#define PCLK_SDGMAC 527
+#define HCLK_VO1 528
+#define HCLK_VO0 529
+#define PCLK_CCI_ROOT 532
+#define ACLK_CCI_ROOT 533
+#define HCLK_VO0VOP_CHANNEL 534
+#define ACLK_VO0VOP_CHANNEL 535
+#define ACLK_TOP_MID 536
+#define ACLK_SECURE_HIGH 537
+#define CLK_USBPHY_REF_SRC 538
+#define CLK_PHY_REF_SRC 539
+#define CLK_CPLL_REF_SRC 540
+#define CLK_AUPLL_REF_SRC 541
+#define PCLK_SECURE_NS 542
+#define HCLK_SECURE_NS 543
+#define ACLK_SECURE_NS 544
+#define PCLK_OTPC_NS 545
+#define HCLK_CRYPTO_NS 546
+#define HCLK_TRNG_NS 547
+#define CLK_OTPC_NS 548
+#define SCLK_DSU 549
+#define SCLK_DDR 550
+#define ACLK_CRYPTO_NS 551
+#define CLK_PKA_CRYPTO_NS 552
+
+/* secure clk */
+#define CLK_STIMER0_ROOT 600
+#define CLK_STIMER1_ROOT 601
+#define PCLK_SECURE_S 602
+#define HCLK_SECURE_S 603
+#define ACLK_SECURE_S 604
+#define CLK_PKA_CRYPTO_S 605
+#define HCLK_VO1_S 606
+#define PCLK_VO1_S 607
+#define HCLK_VO0_S 608
+#define PCLK_VO0_S 609
+#define PCLK_KLAD 610
+#define HCLK_CRYPTO_S 611
+#define HCLK_KLAD 612
+#define ACLK_CRYPTO_S 613
+#define HCLK_TRNG_S 614
+#define PCLK_OTPC_S 615
+#define CLK_OTPC_S 616
+#define PCLK_WDT_S 617
+#define TCLK_WDT_S 618
+#define PCLK_HDCP0_TRNG 619
+#define PCLK_HDCP1_TRNG 620
+#define HCLK_HDCP_KEY0 621
+#define HCLK_HDCP_KEY1 622
+#define PCLK_EDP_S 623
+#define ACLK_KLAD 624
+
+#define CLK_NR_CLKS (ACLK_KLAD + 1)
+
+/********Name=SOFTRST_CON01,Offset=0xA04********/
+#define SRST_A_TOP_BIU 19
+#define SRST_P_TOP_BIU 21
+#define SRST_A_TOP_MID_BIU 22
+#define SRST_A_SECURE_HIGH_BIU 23
+#define SRST_H_TOP_BIU 30
+/********Name=SOFTRST_CON02,Offset=0xA08********/
+#define SRST_H_VO0VOP_CHANNEL_BIU 32
+#define SRST_A_VO0VOP_CHANNEL_BIU 33
+/********Name=SOFTRST_CON06,Offset=0xA18********/
+#define SRST_BISRINTF 98
+/********Name=SOFTRST_CON07,Offset=0xA1C********/
+#define SRST_H_AUDIO_BIU 114
+#define SRST_H_ASRC_2CH_0 115
+#define SRST_H_ASRC_2CH_1 116
+#define SRST_H_ASRC_4CH_0 117
+#define SRST_H_ASRC_4CH_1 118
+#define SRST_ASRC_2CH_0 119
+#define SRST_ASRC_2CH_1 120
+#define SRST_ASRC_4CH_0 121
+#define SRST_ASRC_4CH_1 122
+#define SRST_M_SAI0_8CH 124
+#define SRST_H_SAI0_8CH 125
+#define SRST_H_SPDIF_RX0 126
+#define SRST_M_SPDIF_RX0 127
+/********Name=SOFTRST_CON08,Offset=0xA20********/
+#define SRST_H_SPDIF_RX1 128
+#define SRST_M_SPDIF_RX1 129
+#define SRST_M_SAI1_8CH 133
+#define SRST_H_SAI1_8CH 134
+#define SRST_M_SAI2_2CH 136
+#define SRST_H_SAI2_2CH 138
+#define SRST_M_SAI3_2CH 140
+#define SRST_H_SAI3_2CH 142
+/********Name=SOFTRST_CON09,Offset=0xA24********/
+#define SRST_M_SAI4_2CH 144
+#define SRST_H_SAI4_2CH 146
+#define SRST_H_ACDCDIG_DSM 147
+#define SRST_M_ACDCDIG_DSM 148
+#define SRST_PDM1 149
+#define SRST_H_PDM1 151
+#define SRST_M_PDM1 152
+#define SRST_H_SPDIF_TX0 153
+#define SRST_M_SPDIF_TX0 154
+#define SRST_H_SPDIF_TX1 155
+#define SRST_M_SPDIF_TX1 156
+/********Name=SOFTRST_CON11,Offset=0xA2C********/
+#define SRST_A_BUS_BIU 179
+#define SRST_P_BUS_BIU 180
+#define SRST_P_CRU 181
+#define SRST_H_CAN0 182
+#define SRST_CAN0 183
+#define SRST_H_CAN1 184
+#define SRST_CAN1 185
+#define SRST_P_INTMUX2BUS 188
+#define SRST_P_VCCIO_IOC 189
+#define SRST_H_BUS_BIU 190
+#define SRST_KEY_SHIFT 191
+/********Name=SOFTRST_CON12,Offset=0xA30********/
+#define SRST_P_I2C1 192
+#define SRST_P_I2C2 193
+#define SRST_P_I2C3 194
+#define SRST_P_I2C4 195
+#define SRST_P_I2C5 196
+#define SRST_P_I2C6 197
+#define SRST_P_I2C7 198
+#define SRST_P_I2C8 199
+#define SRST_P_I2C9 200
+#define SRST_P_WDT_BUSMCU 201
+#define SRST_T_WDT_BUSMCU 202
+#define SRST_A_GIC 203
+#define SRST_I2C1 204
+#define SRST_I2C2 205
+#define SRST_I2C3 206
+#define SRST_I2C4 207
+/********Name=SOFTRST_CON13,Offset=0xA34********/
+#define SRST_I2C5 208
+#define SRST_I2C6 209
+#define SRST_I2C7 210
+#define SRST_I2C8 211
+#define SRST_I2C9 212
+#define SRST_P_SARADC 214
+#define SRST_SARADC 215
+#define SRST_P_TSADC 216
+#define SRST_TSADC 217
+#define SRST_P_UART0 218
+#define SRST_P_UART2 219
+#define SRST_P_UART3 220
+#define SRST_P_UART4 221
+#define SRST_P_UART5 222
+#define SRST_P_UART6 223
+/********Name=SOFTRST_CON14,Offset=0xA38********/
+#define SRST_P_UART7 224
+#define SRST_P_UART8 225
+#define SRST_P_UART9 226
+#define SRST_P_UART10 227
+#define SRST_P_UART11 228
+#define SRST_S_UART0 229
+#define SRST_S_UART2 230
+#define SRST_S_UART3 233
+#define SRST_S_UART4 236
+#define SRST_S_UART5 239
+/********Name=SOFTRST_CON15,Offset=0xA3C********/
+#define SRST_S_UART6 242
+#define SRST_S_UART7 245
+#define SRST_S_UART8 248
+#define SRST_S_UART9 249
+#define SRST_S_UART10 250
+#define SRST_S_UART11 251
+#define SRST_P_SPI0 253
+#define SRST_P_SPI1 254
+#define SRST_P_SPI2 255
+/********Name=SOFTRST_CON16,Offset=0xA40********/
+#define SRST_P_SPI3 256
+#define SRST_P_SPI4 257
+#define SRST_SPI0 258
+#define SRST_SPI1 259
+#define SRST_SPI2 260
+#define SRST_SPI3 261
+#define SRST_SPI4 262
+#define SRST_P_WDT0 263
+#define SRST_T_WDT0 264
+#define SRST_P_SYS_GRF 265
+#define SRST_P_PWM1 266
+#define SRST_PWM1 267
+
+/********Name=SOFTRST_CON17,Offset=0xA44********/
+#define SRST_P_BUSTIMER0 275
+#define SRST_P_BUSTIMER1 276
+#define SRST_TIMER0 278
+#define SRST_TIMER1 279
+#define SRST_TIMER2 280
+#define SRST_TIMER3 281
+#define SRST_TIMER4 282
+#define SRST_TIMER5 283
+#define SRST_P_BUSIOC 284
+#define SRST_P_MAILBOX0 285
+#define SRST_P_GPIO1 287
+/********Name=SOFTRST_CON18,Offset=0xA48********/
+#define SRST_GPIO1 288
+#define SRST_P_GPIO2 289
+#define SRST_GPIO2 290
+#define SRST_P_GPIO3 291
+#define SRST_GPIO3 292
+#define SRST_P_GPIO4 293
+#define SRST_GPIO4 294
+#define SRST_A_DECOM 295
+#define SRST_P_DECOM 296
+#define SRST_D_DECOM 297
+#define SRST_TIMER6 299
+#define SRST_TIMER7 300
+#define SRST_TIMER8 301
+#define SRST_TIMER9 302
+#define SRST_TIMER10 303
+/********Name=SOFTRST_CON19,Offset=0xA4C********/
+#define SRST_TIMER11 304
+#define SRST_A_DMAC0 305
+#define SRST_A_DMAC1 306
+#define SRST_A_DMAC2 307
+#define SRST_A_SPINLOCK 308
+#define SRST_REF_PVTPLL_BUS 309
+#define SRST_H_I3C0 311
+#define SRST_H_I3C1 313
+#define SRST_H_BUS_CM0_BIU 315
+#define SRST_F_BUS_CM0_CORE 316
+#define SRST_T_BUS_CM0_JTAG 317
+/********Name=SOFTRST_CON20,Offset=0xA50********/
+#define SRST_P_INTMUX2PMU 320
+#define SRST_P_INTMUX2DDR 321
+#define SRST_P_PVTPLL_BUS 323
+#define SRST_P_PWM2 324
+#define SRST_PWM2 325
+#define SRST_FREQ_PWM1 328
+#define SRST_COUNTER_PWM1 329
+#define SRST_I3C0 332
+#define SRST_I3C1 333
+/********Name=SOFTRST_CON21,Offset=0xA54********/
+#define SRST_P_DDR_MON_CH0 337
+#define SRST_P_DDR_BIU 338
+#define SRST_P_DDR_UPCTL_CH0 339
+#define SRST_TM_DDR_MON_CH0 340
+#define SRST_A_DDR_BIU 341
+#define SRST_DFI_CH0 342
+#define SRST_DDR_MON_CH0 346
+#define SRST_P_DDR_HWLP_CH0 349
+#define SRST_P_DDR_MON_CH1 350
+#define SRST_P_DDR_HWLP_CH1 351
+/********Name=SOFTRST_CON22,Offset=0xA58********/
+#define SRST_P_DDR_UPCTL_CH1 352
+#define SRST_TM_DDR_MON_CH1 353
+#define SRST_DFI_CH1 354
+#define SRST_A_DDR01_MSCH0 355
+#define SRST_A_DDR01_MSCH1 356
+#define SRST_DDR_MON_CH1 358
+#define SRST_DDR_SCRAMBLE_CH0 361
+#define SRST_DDR_SCRAMBLE_CH1 362
+#define SRST_P_AHB2APB 364
+#define SRST_H_AHB2APB 365
+#define SRST_H_DDR_BIU 366
+#define SRST_F_DDR_CM0_CORE 367
+/********Name=SOFTRST_CON23,Offset=0xA5C********/
+#define SRST_P_DDR01_MSCH0 369
+#define SRST_P_DDR01_MSCH1 370
+#define SRST_DDR_TIMER0 372
+#define SRST_DDR_TIMER1 373
+#define SRST_T_WDT_DDR 374
+#define SRST_P_WDT 375
+#define SRST_P_TIMER 376
+#define SRST_T_DDR_CM0_JTAG 377
+#define SRST_P_DDR_GRF 379
+/********Name=SOFTRST_CON25,Offset=0xA64********/
+#define SRST_DDR_UPCTL_CH0 401
+#define SRST_A_DDR_UPCTL_0_CH0 402
+#define SRST_A_DDR_UPCTL_1_CH0 403
+#define SRST_A_DDR_UPCTL_2_CH0 404
+#define SRST_A_DDR_UPCTL_3_CH0 405
+#define SRST_A_DDR_UPCTL_4_CH0 406
+/********Name=SOFTRST_CON26,Offset=0xA68********/
+#define SRST_DDR_UPCTL_CH1 417
+#define SRST_A_DDR_UPCTL_0_CH1 418
+#define SRST_A_DDR_UPCTL_1_CH1 419
+#define SRST_A_DDR_UPCTL_2_CH1 420
+#define SRST_A_DDR_UPCTL_3_CH1 421
+#define SRST_A_DDR_UPCTL_4_CH1 422
+/********Name=SOFTRST_CON27,Offset=0xA6C********/
+#define SRST_REF_PVTPLL_DDR 432
+#define SRST_P_PVTPLL_DDR 433
+
+/********Name=SOFTRST_CON28,Offset=0xA70********/
+#define SRST_A_RKNN0 457
+#define SRST_A_RKNN0_BIU 459
+#define SRST_L_RKNN0_BIU 460
+/********Name=SOFTRST_CON29,Offset=0xA74********/
+#define SRST_A_RKNN1 464
+#define SRST_A_RKNN1_BIU 466
+#define SRST_L_RKNN1_BIU 467
+/********Name=SOFTRST_CON31,Offset=0xA7C********/
+#define SRST_NPU_DAP 496
+#define SRST_L_NPUSUBSYS_BIU 497
+#define SRST_P_NPUTOP_BIU 505
+#define SRST_P_NPU_TIMER 506
+#define SRST_NPUTIMER0 508
+#define SRST_NPUTIMER1 509
+#define SRST_P_NPU_WDT 510
+#define SRST_T_NPU_WDT 511
+/********Name=SOFTRST_CON32,Offset=0xA80********/
+#define SRST_A_RKNN_CBUF 512
+#define SRST_A_RVCORE0 513
+#define SRST_P_NPU_GRF 514
+#define SRST_P_PVTPLL_NPU 515
+#define SRST_NPU_PVTPLL 516
+#define SRST_H_NPU_CM0_BIU 518
+#define SRST_F_NPU_CM0_CORE 519
+#define SRST_T_NPU_CM0_JTAG 520
+#define SRST_A_RKNNTOP_BIU 523
+#define SRST_H_RKNN_CBUF 524
+#define SRST_H_RKNNTOP_BIU 525
+/********Name=SOFTRST_CON33,Offset=0xA84********/
+#define SRST_H_NVM_BIU 530
+#define SRST_A_NVM_BIU 531
+#define SRST_S_FSPI 534
+#define SRST_H_FSPI 535
+#define SRST_C_EMMC 536
+#define SRST_H_EMMC 537
+#define SRST_A_EMMC 538
+#define SRST_B_EMMC 539
+#define SRST_T_EMMC 540
+/********Name=SOFTRST_CON34,Offset=0xA88********/
+#define SRST_P_GRF 545
+#define SRST_P_PHP_BIU 549
+#define SRST_A_PHP_BIU 553
+#define SRST_P_PCIE0 557
+#define SRST_PCIE0_POWER_UP 559
+/********Name=SOFTRST_CON35,Offset=0xA8C********/
+#define SRST_A_USB3OTG1 563
+#define SRST_A_MMU0 571
+#define SRST_A_SLV_MMU0 573
+#define SRST_A_MMU1 574
+/********Name=SOFTRST_CON36,Offset=0xA90********/
+#define SRST_A_SLV_MMU1 576
+#define SRST_P_PCIE1 583
+#define SRST_PCIE1_POWER_UP 585
+/********Name=SOFTRST_CON37,Offset=0xA94********/
+#define SRST_RXOOB0 592
+#define SRST_RXOOB1 593
+#define SRST_PMALIVE0 594
+#define SRST_PMALIVE1 595
+#define SRST_A_SATA0 596
+#define SRST_A_SATA1 597
+#define SRST_ASIC1 598
+#define SRST_ASIC0 599
+/********Name=SOFTRST_CON40,Offset=0xAA0********/
+#define SRST_P_CSIDPHY1 642
+#define SRST_SCAN_CSIDPHY1 643
+/********Name=SOFTRST_CON42,Offset=0xAA8********/
+#define SRST_P_SDGMAC_GRF 675
+#define SRST_P_SDGMAC_BIU 676
+#define SRST_A_SDGMAC_BIU 677
+#define SRST_H_SDGMAC_BIU 678
+#define SRST_A_GMAC0 679
+#define SRST_A_GMAC1 680
+#define SRST_P_GMAC0 681
+#define SRST_P_GMAC1 682
+#define SRST_H_SDIO 684
+/********Name=SOFTRST_CON43,Offset=0xAAC********/
+#define SRST_H_SDMMC0 690
+#define SRST_S_FSPI1 691
+#define SRST_H_FSPI1 692
+#define SRST_A_DSMC_BIU 694
+#define SRST_A_DSMC 695
+#define SRST_P_DSMC 696
+#define SRST_H_HSGPIO 698
+#define SRST_HSGPIO 699
+#define SRST_A_HSGPIO 701
+/********Name=SOFTRST_CON45,Offset=0xAB4********/
+#define SRST_H_RKVDEC 723
+#define SRST_H_RKVDEC_BIU 725
+#define SRST_A_RKVDEC_BIU 726
+#define SRST_RKVDEC_HEVC_CA 728
+#define SRST_RKVDEC_CORE 729
+/********Name=SOFTRST_CON47,Offset=0xABC********/
+#define SRST_A_USB_BIU 755
+#define SRST_P_USBUFS_BIU 756
+#define SRST_A_USB3OTG0 757
+#define SRST_A_UFS_BIU 762
+#define SRST_A_MMU2 764
+#define SRST_A_SLV_MMU2 765
+#define SRST_A_UFS_SYS 767
+/********Name=SOFTRST_CON48,Offset=0xAC0********/
+#define SRST_A_UFS 768
+#define SRST_P_USBUFS_GRF 769
+#define SRST_P_UFS_GRF 770
+/********Name=SOFTRST_CON49,Offset=0xAC4********/
+#define SRST_H_VPU_BIU 790
+#define SRST_A_JPEG_BIU 791
+#define SRST_A_RGA_BIU 794
+#define SRST_A_VDPP_BIU 795
+#define SRST_A_EBC_BIU 796
+#define SRST_H_RGA2E_0 797
+#define SRST_A_RGA2E_0 798
+#define SRST_CORE_RGA2E_0 799
+/********Name=SOFTRST_CON50,Offset=0xAC8********/
+#define SRST_A_JPEG 800
+#define SRST_H_JPEG 801
+#define SRST_H_VDPP 802
+#define SRST_A_VDPP 803
+#define SRST_CORE_VDPP 804
+#define SRST_H_RGA2E_1 805
+#define SRST_A_RGA2E_1 806
+#define SRST_CORE_RGA2E_1 807
+#define SRST_H_EBC 810
+#define SRST_A_EBC 811
+#define SRST_D_EBC 812
+/********Name=SOFTRST_CON51,Offset=0xACC********/
+#define SRST_H_VEPU0_BIU 818
+#define SRST_A_VEPU0_BIU 819
+#define SRST_H_VEPU0 820
+#define SRST_A_VEPU0 821
+#define SRST_VEPU0_CORE 822
+/********Name=SOFTRST_CON53,Offset=0xAD4********/
+#define SRST_A_VI_BIU 851
+#define SRST_H_VI_BIU 852
+#define SRST_P_VI_BIU 853
+#define SRST_D_VICAP 854
+#define SRST_A_VICAP 855
+#define SRST_H_VICAP 856
+#define SRST_ISP0 858
+#define SRST_ISP0_VICAP 859
+/********Name=SOFTRST_CON54,Offset=0xAD8********/
+#define SRST_CORE_VPSS 865
+#define SRST_P_CSI_HOST_0 868
+#define SRST_P_CSI_HOST_1 869
+#define SRST_P_CSI_HOST_2 870
+#define SRST_P_CSI_HOST_3 871
+#define SRST_P_CSI_HOST_4 872
+/********Name=SOFTRST_CON59,Offset=0xAEC********/
+#define SRST_CIFIN 944
+#define SRST_VICAP_I0CLK 945
+#define SRST_VICAP_I1CLK 946
+#define SRST_VICAP_I2CLK 947
+#define SRST_VICAP_I3CLK 948
+#define SRST_VICAP_I4CLK 949
+/********Name=SOFTRST_CON61,Offset=0xAF4********/
+#define SRST_A_VOP_BIU 980
+#define SRST_A_VOP2_BIU 981
+#define SRST_H_VOP_BIU 982
+#define SRST_P_VOP_BIU 983
+#define SRST_H_VOP 984
+#define SRST_A_VOP 985
+#define SRST_D_VP0 989
+/********Name=SOFTRST_CON62,Offset=0xAF8********/
+#define SRST_D_VP1 992
+#define SRST_D_VP2 993
+#define SRST_P_VOP2_BIU 994
+#define SRST_P_VOPGRF 995
+/********Name=SOFTRST_CON63,Offset=0xAFC********/
+#define SRST_H_VO0_BIU 1013
+#define SRST_P_VO0_BIU 1015
+#define SRST_A_HDCP0_BIU 1017
+#define SRST_P_VO0_GRF 1018
+#define SRST_A_HDCP0 1020
+#define SRST_H_HDCP0 1021
+#define SRST_HDCP0 1022
+/********Name=SOFTRST_CON64,Offset=0xB00********/
+#define SRST_P_DSIHOST0 1029
+#define SRST_DSIHOST0 1030
+#define SRST_P_HDMITX0 1031
+#define SRST_HDMITX0_REF 1033
+#define SRST_P_EDP0 1037
+#define SRST_EDP0_24M 1038
+/********Name=SOFTRST_CON65,Offset=0xB04********/
+#define SRST_M_SAI5_8CH 1044
+#define SRST_H_SAI5_8CH 1045
+#define SRST_M_SAI6_8CH 1048
+#define SRST_H_SAI6_8CH 1049
+#define SRST_H_SPDIF_TX2 1050
+#define SRST_M_SPDIF_TX2 1053
+#define SRST_H_SPDIF_RX2 1054
+#define SRST_M_SPDIF_RX2 1055
+/********Name=SOFTRST_CON66,Offset=0xB08********/
+#define SRST_H_SAI8_8CH 1056
+#define SRST_M_SAI8_8CH 1058
+/********Name=SOFTRST_CON67,Offset=0xB0C********/
+#define SRST_H_VO1_BIU 1077
+#define SRST_P_VO1_BIU 1078
+#define SRST_M_SAI7_8CH 1081
+#define SRST_H_SAI7_8CH 1082
+#define SRST_H_SPDIF_TX3 1083
+#define SRST_H_SPDIF_TX4 1084
+#define SRST_H_SPDIF_TX5 1085
+#define SRST_M_SPDIF_TX3 1086
+/********Name=SOFTRST_CON68,Offset=0xB10********/
+#define SRST_DP0 1088
+#define SRST_P_VO1_GRF 1090
+#define SRST_A_HDCP1_BIU 1091
+#define SRST_A_HDCP1 1092
+#define SRST_H_HDCP1 1093
+#define SRST_HDCP1 1094
+#define SRST_H_SAI9_8CH 1097
+#define SRST_M_SAI9_8CH 1099
+#define SRST_M_SPDIF_TX4 1100
+#define SRST_M_SPDIF_TX5 1101
+/********Name=SOFTRST_CON69,Offset=0xB14********/
+#define SRST_GPU 1107
+#define SRST_A_S_GPU_BIU 1110
+#define SRST_A_M0_GPU_BIU 1111
+#define SRST_P_GPU_BIU 1113
+#define SRST_P_GPU_GRF 1117
+#define SRST_GPU_PVTPLL 1118
+#define SRST_P_PVTPLL_GPU 1119
+/********Name=SOFTRST_CON72,Offset=0xB20********/
+#define SRST_A_CENTER_BIU 1156
+#define SRST_A_DMA2DDR 1157
+#define SRST_A_DDR_SHAREMEM 1158
+#define SRST_A_DDR_SHAREMEM_BIU 1159
+#define SRST_H_CENTER_BIU 1160
+#define SRST_P_CENTER_GRF 1161
+#define SRST_P_DMA2DDR 1162
+#define SRST_P_SHAREMEM 1163
+#define SRST_P_CENTER_BIU 1164
+/********Name=SOFTRST_CON75,Offset=0xB2C********/
+#define SRST_LINKSYM_HDMITXPHY0 1201
+/********Name=SOFTRST_CON78,Offset=0xB38********/
+#define SRST_DP0_PIXELCLK 1249
+#define SRST_PHY_DP0_TX 1250
+#define SRST_DP1_PIXELCLK 1251
+#define SRST_DP2_PIXELCLK 1252
+/********Name=SOFTRST_CON79,Offset=0xB3C********/
+#define SRST_H_VEPU1_BIU 1265
+#define SRST_A_VEPU1_BIU 1266
+#define SRST_H_VEPU1 1267
+#define SRST_A_VEPU1 1268
+#define SRST_VEPU1_CORE 1269
+
+/********Name=PHPPHYSOFTRST_CON00,Offset=0x8A00********/
+#define SRST_P_PHPPHY_CRU 131073
+#define SRST_P_APB2ASB_SLV_CHIP_TOP 131075
+#define SRST_P_PCIE2_COMBOPHY0 131077
+#define SRST_P_PCIE2_COMBOPHY0_GRF 131078
+#define SRST_P_PCIE2_COMBOPHY1 131079
+#define SRST_P_PCIE2_COMBOPHY1_GRF 131080
+/********Name=PHPPHYSOFTRST_CON01,Offset=0x8A04********/
+#define SRST_PCIE0_PIPE_PHY 131093
+#define SRST_PCIE1_PIPE_PHY 131096
+
+/********Name=SECURENSSOFTRST_CON00,Offset=0x10A00********/
+#define SRST_H_CRYPTO_NS 262147
+#define SRST_H_TRNG_NS 262148
+#define SRST_P_OTPC_NS 262152
+#define SRST_OTPC_NS 262153
+
+/********Name=PMU1SOFTRST_CON00,Offset=0x20A00********/
+#define SRST_P_HDPTX_GRF 524288
+#define SRST_P_HDPTX_APB 524289
+#define SRST_P_MIPI_DCPHY 524290
+#define SRST_P_DCPHY_GRF 524291
+#define SRST_P_BOT0_APB2ASB 524292
+#define SRST_P_BOT1_APB2ASB 524293
+#define SRST_USB2DEBUG 524294
+#define SRST_P_CSIPHY_GRF 524295
+#define SRST_P_CSIPHY 524296
+#define SRST_P_USBPHY_GRF_0 524297
+#define SRST_P_USBPHY_GRF_1 524298
+#define SRST_P_USBDP_GRF 524299
+#define SRST_P_USBDPPHY 524300
+#define SRST_USBDP_COMBO_PHY_INIT 524303
+/********Name=PMU1SOFTRST_CON01,Offset=0x20A04********/
+#define SRST_USBDP_COMBO_PHY_CMN 524304
+#define SRST_USBDP_COMBO_PHY_LANE 524305
+#define SRST_USBDP_COMBO_PHY_PCS 524306
+#define SRST_M_MIPI_DCPHY 524307
+#define SRST_S_MIPI_DCPHY 524308
+#define SRST_SCAN_CSIPHY 524309
+#define SRST_P_VCCIO6_IOC 524310
+#define SRST_OTGPHY_0 524311
+#define SRST_OTGPHY_1 524312
+#define SRST_HDPTX_INIT 524313
+#define SRST_HDPTX_CMN 524314
+#define SRST_HDPTX_LANE 524315
+#define SRST_HDMITXHPD 524317
+/********Name=PMU1SOFTRST_CON02,Offset=0x20A08********/
+#define SRST_MPHY_INIT 524320
+#define SRST_P_MPHY_GRF 524321
+#define SRST_P_VCCIO7_IOC 524323
+/********Name=PMU1SOFTRST_CON03,Offset=0x20A0C********/
+#define SRST_H_PMU1_BIU 524345
+#define SRST_P_PMU1_NIU 524346
+#define SRST_H_PMU_CM0_BIU 524347
+#define SRST_PMU_CM0_CORE 524348
+#define SRST_PMU_CM0_JTAG 524349
+/********Name=PMU1SOFTRST_CON04,Offset=0x20A10********/
+#define SRST_P_CRU_PMU1 524353
+#define SRST_P_PMU1_GRF 524355
+#define SRST_P_PMU1_IOC 524356
+#define SRST_P_PMU1WDT 524357
+#define SRST_T_PMU1WDT 524358
+#define SRST_P_PMUTIMER 524359
+#define SRST_PMUTIMER0 524361
+#define SRST_PMUTIMER1 524362
+#define SRST_P_PMU1PWM 524363
+#define SRST_PMU1PWM 524364
+/********Name=PMU1SOFTRST_CON05,Offset=0x20A14********/
+#define SRST_P_I2C0 524369
+#define SRST_I2C0 524371
+#define SRST_S_UART1 525373
+#define SRST_P_UART1 525374
+#define SRST_PDM0 524381
+#define SRST_H_PDM0 524383
+/********Name=PMU1SOFTRST_CON06,Offset=0xA18********/
+#define SRST_M_PDM0 524384
+#define SRST_H_VAD 524385
+/********Name=PMU1SOFTRST_CON07,Offset=0x20A1C********/
+#define SRST_P_PMU0GRF 524404
+#define SRST_P_PMU0IOC 524405
+#define SRST_P_GPIO0 524406
+#define SRST_DB_GPIO0 524407
+
+#define SRST_NR_RSTS (SRST_DB_GPIO0 + 1)
+
+void pvtplls_cpub_suspend(void);
+void pvtplls_cpub_resume(void);
+
+void pvtplls_suspend(void);
+void pvtplls_resume(void);
+
+void rockchip_clock_init(void);
+
+#endif