From 036935a8144b9c4b9f95f249ff4384945b846d40 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Fri, 7 Feb 2025 18:07:46 +0800 Subject: [PATCH] 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 --- docs/plat/rockchip.rst | 1 + .../rockchip/common/aarch64/platform_common.c | 14 +- plat/rockchip/common/include/plat_private.h | 5 +- .../common/scmi/rockchip_common_clock.c | 143 ++ plat/rockchip/common/scmi/scmi_clock.h | 8 +- plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h | 44 + plat/rockchip/rk3576/drivers/dmc/suspend.c | 191 +++ .../rk3576/drivers/pmu/plat_pmu_macros.S | 20 + plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c | 451 ++++++ plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h | 36 + plat/rockchip/rk3576/drivers/pmu/pmu.c | 1069 +++++++++++++ plat/rockchip/rk3576/drivers/pmu/pmu.h | 578 +++++++ .../rockchip/rk3576/drivers/secure/firewall.c | 693 +++++++++ .../rockchip/rk3576/drivers/secure/firewall.h | 499 ++++++ plat/rockchip/rk3576/drivers/secure/secure.c | 39 + plat/rockchip/rk3576/drivers/secure/secure.h | 30 + plat/rockchip/rk3576/drivers/soc/soc.c | 129 ++ plat/rockchip/rk3576/drivers/soc/soc.h | 271 ++++ plat/rockchip/rk3576/include/plat.ld.S | 40 + plat/rockchip/rk3576/include/plat_sip_calls.h | 11 + plat/rockchip/rk3576/include/platform_def.h | 116 ++ plat/rockchip/rk3576/plat_sip_calls.c | 31 + plat/rockchip/rk3576/platform.mk | 115 ++ plat/rockchip/rk3576/rk3576_def.h | 207 +++ plat/rockchip/rk3576/scmi/rk3576_clk.c | 1353 +++++++++++++++++ plat/rockchip/rk3576/scmi/rk3576_clk.h | 1151 ++++++++++++++ 26 files changed, 7242 insertions(+), 3 deletions(-) create mode 100644 plat/rockchip/common/scmi/rockchip_common_clock.c create mode 100644 plat/rockchip/rk3576/drivers/dmc/dmc_rk3576.h create mode 100644 plat/rockchip/rk3576/drivers/dmc/suspend.c create mode 100644 plat/rockchip/rk3576/drivers/pmu/plat_pmu_macros.S create mode 100644 plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.c create mode 100644 plat/rockchip/rk3576/drivers/pmu/pm_pd_regs.h create mode 100644 plat/rockchip/rk3576/drivers/pmu/pmu.c create mode 100644 plat/rockchip/rk3576/drivers/pmu/pmu.h create mode 100644 plat/rockchip/rk3576/drivers/secure/firewall.c create mode 100644 plat/rockchip/rk3576/drivers/secure/firewall.h create mode 100644 plat/rockchip/rk3576/drivers/secure/secure.c create mode 100644 plat/rockchip/rk3576/drivers/secure/secure.h create mode 100644 plat/rockchip/rk3576/drivers/soc/soc.c create mode 100644 plat/rockchip/rk3576/drivers/soc/soc.h create mode 100644 plat/rockchip/rk3576/include/plat.ld.S create mode 100644 plat/rockchip/rk3576/include/plat_sip_calls.h create mode 100644 plat/rockchip/rk3576/include/platform_def.h create mode 100644 plat/rockchip/rk3576/plat_sip_calls.c create mode 100644 plat/rockchip/rk3576/platform.mk create mode 100644 plat/rockchip/rk3576/rk3576_def.h create mode 100644 plat/rockchip/rk3576/scmi/rk3576_clk.c create mode 100644 plat/rockchip/rk3576/scmi/rk3576_clk.h diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst index 384cd73d8..016bed707 100644 --- a/docs/plat/rockchip.rst +++ b/docs/plat/rockchip.rst @@ -11,6 +11,7 @@ This includes right now: - 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 df51d895f..e88855abf 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 #include #include @@ -58,7 +59,18 @@ DEFINE_CONFIGURE_MMU_EL(3) 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 1e13a9e8c..6388c478c 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_text_start, __bl31_sram_text_end; 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 000000000..d77bde399 --- /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 +#include + +#include +#include +#include + +#include +#include + +#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 e640fe196..4b94adf8c 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 @@ typedef struct rk_scmi_clock { 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 @@ size_t rockchip_scmi_clock_count(unsigned int agent_id); 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 000000000..d8c231c95 --- /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 000000000..389cc1b70 --- /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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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 000000000..717b55cf7 --- /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 +#include +#include + +.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 000000000..de5fa7509 --- /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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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 000000000..5b4f624da --- /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 + +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 000000000..c7db17634 --- /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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +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 000000000..6340e3f26 --- /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 + +#include + +/* 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 000000000..5da9ea80e --- /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 +#include + +#include +#include +#include + +#include +#include + +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 000000000..7b1307138 --- /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 + +/* 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 000000000..55b8d93b7 --- /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 +#include + +#include + +#include +#include + +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 000000000..f00e519de --- /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 + +/* 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 000000000..a78e82e85 --- /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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 000000000..f96a42d06 --- /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 000000000..4d0096fc1 --- /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 000000000..c33f24fa6 --- /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 000000000..03a80b0e7 --- /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 +#include +#include + +#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 000000000..b0ff5fb10 --- /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 +#include +#include + +#include +#include + +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 000000000..861cb4fda --- /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 000000000..35f38cab8 --- /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 000000000..7b36a05f4 --- /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 +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 000000000..b2c00b991 --- /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