Merge changes from topic "mb/refactor-cot" into integration
* changes:
refactor(juno): add explicit entry for HW_CONFIG in BL2 CoT file
refactor(auth): remove HW_CONFIG reference from BL1 CoT file
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
index 01cf176..53f63b5 100644
--- a/docs/plat/rockchip.rst
+++ b/docs/plat/rockchip.rst
@@ -10,6 +10,7 @@
- rk3328: Quad-Core Cortex-A53
- rk3368: Octa-Core Cortex-A53
- rk3399: Hexa-Core Cortex-A53/A72
+- rk3566/rk3568: Quad-Core Cortex-A55
Boot Sequence
diff --git a/fdts/cca_cot_descriptors.dtsi b/fdts/cca_cot_descriptors.dtsi
index d52431b..821f600 100644
--- a/fdts/cca_cot_descriptors.dtsi
+++ b/fdts/cca_cot_descriptors.dtsi
@@ -136,30 +136,12 @@
images {
compatible = "arm, img-descs";
- fw_config {
- image-id = <FW_CONFIG_ID>;
- parent = <&cca_content_cert>;
- hash = <&fw_config_hash>;
- };
-
hw_config {
image-id = <HW_CONFIG_ID>;
parent = <&cca_content_cert>;
hash = <&hw_config_hash>;
};
- tb_fw_hash {
- image-id = <BL2_IMAGE_ID>;
- parent = <&cca_content_cert>;
- hash = <&tb_fw_hash>;
- };
-
- tb_fw_config {
- image-id = <TB_FW_CONFIG_ID>;
- parent = <&cca_content_cert>;
- hash = <&tb_fw_config_hash>;
- };
-
bl31_image {
image-id = <BL31_IMAGE_ID>;
parent = <&cca_content_cert>;
diff --git a/fdts/tbbr_cot_descriptors.dtsi b/fdts/tbbr_cot_descriptors.dtsi
index ac39e4e..d11e2be 100644
--- a/fdts/tbbr_cot_descriptors.dtsi
+++ b/fdts/tbbr_cot_descriptors.dtsi
@@ -190,12 +190,6 @@
hash = <&hw_config_hash>;
};
- tb_fw_config {
- image-id = <TB_FW_CONFIG_ID>;
- parent = <&trusted_boot_fw_cert>;
- hash = <&tb_fw_config_hash>;
- };
-
scp_bl2_image {
image-id = <SCP_BL2_IMAGE_ID>;
parent = <&scp_fw_content_cert>;
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
index 577de61..51fbfd1 100644
--- a/include/lib/cpus/aarch64/dsu_def.h
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -30,6 +30,7 @@
* DSU Cluster Auxiliary Control registers definitions
********************************************************************/
#define CLUSTERACTLR_EL1 S3_0_C15_C3_3
+#define CLUSTERPWRCTLR_EL1 S3_0_C15_C3_5
#define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING (ULL(1) << 15)
#define CLUSTERACTLR_EL1_DISABLE_SCLK_GATING (ULL(3) << 15)
@@ -39,4 +40,7 @@
********************************************************************/
#define DSU_ERRATA_936184_MASK (U(0x3) << 15)
+#ifndef __ASSEMBLER__
+void dsu_pwr_dwn(void);
+#endif
#endif /* DSU_DEF_H */
diff --git a/include/plat/nuvoton/npcm845x/platform_def.h b/include/plat/nuvoton/npcm845x/platform_def.h
index 9cbf839..c70ef22 100644
--- a/include/plat/nuvoton/npcm845x/platform_def.h
+++ b/include/plat/nuvoton/npcm845x/platform_def.h
@@ -157,7 +157,8 @@
/* MMU entry for internal (register) space access */
#define MAP_DEVICE0 \
- MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, MT_DEVICE | MT_RW | MT_NS)
+ MAP_REGION_FLAT(PLAT_REG_BASE, PLAT_REG_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
#define MAP_DEVICE1 \
MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, \
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
index 8e5b459..3c5bf2e 100644
--- a/lib/cpus/aarch64/dsu_helpers.S
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -24,6 +24,7 @@
*/
.globl check_errata_dsu_798953
.globl errata_dsu_798953_wa
+ .globl dsu_pwr_dwn
func check_errata_dsu_798953
mov x2, #ERRATA_APPLIES
@@ -202,3 +203,15 @@
1:
ret x8
endfunc errata_dsu_2313941_wa
+
+ /* ---------------------------------------------
+ * controls power features of the cluster
+ * 1. Cache portion power not request
+ * 2. Disable the retention circuit
+ * ---------------------------------------------
+ */
+func dsu_pwr_dwn
+ msr CLUSTERPWRCTLR_EL1, xzr
+ isb
+ ret
+endfunc dsu_pwr_dwn
diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c
index 4d80373..ee502de 100644
--- a/lib/gpt_rme/gpt_rme.c
+++ b/lib/gpt_rme/gpt_rme.c
@@ -700,8 +700,8 @@
* Return
* Address of next granule in range.
*/
-static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
- size_t length, unsigned int gpi)
+__unused static uintptr_t fill_l1_cont_desc(uint64_t *l1, uintptr_t first,
+ size_t length, unsigned int gpi)
{
/*
* Look up table for contiguous blocks and descriptors.
@@ -826,8 +826,10 @@
/*
* Helper function to fill out GPI entries in a single L1 table.
- * This function fills out an entire L1 table with either Contiguous
- * or Granules descriptors depending on region length and alignment.
+ * This function fills out an entire L1 table with either Granules or Contiguous
+ * (RME_GPT_MAX_BLOCK != 0) descriptors depending on region length and alignment.
+ * Note. If RME_GPT_MAX_BLOCK == 0, then the L1 tables are filled with regular
+ * Granules descriptors.
*
* Parameters
* l1 Pointer to L1 table to fill out
@@ -844,13 +846,14 @@
assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1UL)) == 0UL);
assert(GPT_L0_IDX(first) == GPT_L0_IDX(last));
+#if (RME_GPT_MAX_BLOCK != 0)
while (first < last) {
/* Region length */
size_t length = last - first + GPT_PGS_ACTUAL_SIZE(gpt_config.p);
if (length < SZ_2M) {
/*
- * Fill with Granule descriptor in case of
+ * Fill with Granule descriptors in case of
* region length < 2MB.
*/
first = fill_l1_gran_desc(l1, first, last, gpi);
@@ -874,7 +877,10 @@
first = fill_l1_gran_desc(l1, first, new_last, gpi);
}
}
-
+#else
+ /* Fill with Granule descriptors */
+ first = fill_l1_gran_desc(l1, first, last, gpi);
+#endif
assert(first == (last + GPT_PGS_ACTUAL_SIZE(gpt_config.p)));
}
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
index 1293f06..da3d3d5 100644
--- a/lib/romlib/Makefile
+++ b/lib/romlib/Makefile
@@ -23,8 +23,10 @@
MAPFILE = $(BUILD_PLAT)/romlib/romlib.map
ifneq ($(PLAT_DIR),)
- WRAPPER_SOURCES = $(shell $(ROMLIB_GEN) genwrappers -b $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i)
- WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
+ WRAPPER_SOURCES = $(sort $(shell $(ROMLIB_GEN) genwrappers -b $\
+ $(WRAPPER_DIR) --list ../../$(PLAT_DIR)/jmptbl.i))
+
+ WRAPPER_OBJS = $(WRAPPER_SOURCES:.s=.o)
endif
V ?= 0
@@ -82,14 +84,11 @@
@echo " PRE $@"
$(Q)$(ROMLIB_GEN) pre --output $@ --deps $(BUILD_DIR)/jmptbl.d $<
-$(BUILD_DIR)/wrappers.stamp: $(BUILD_DIR)/jmptbl.i
+$(WRAPPER_SOURCES) &: $(BUILD_DIR)/jmptbl.i
@echo " WRP $<"
$(Q)$(ROMLIB_GEN) genwrappers --bti=$(ENABLE_BTI) -b $(WRAPPER_DIR) $<
- @touch $@
-
-$(WRAPPER_SOURCES): $(BUILD_DIR)/wrappers.stamp
-$(WRAPPER_OBJS): $(WRAPPER_SOURCES) $(BUILD_DIR)/wrappers.stamp
+$(WRAPPER_OBJS): $(WRAPPER_DIR)/%.o: $(WRAPPER_DIR)/%.s
$(BUILD_DIR)/jmptbl.s: $(BUILD_DIR)/jmptbl.i
@echo " TBL $@"
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index cf4595c..fabd74e 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -559,8 +559,8 @@
$$(ECHO) " LD $$@"
ifeq ($($(ARCH)-ld-id),arm-link)
$$(Q)$($(ARCH)-ld) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \
- --predefine="-D__LINKER__=$(__LINKER__)" \
- --predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \
+ --predefine=$(call escape-shell,-D__LINKER__=$(__LINKER__)) \
+ --predefine=$(call escape-shell,-DTF_CFLAGS=$(TF_CFLAGS)) \
--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \
$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) $(OBJS)
else ifeq ($($(ARCH)-ld-id),gnu-gcc)
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index e154530..404a829 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -62,8 +62,16 @@
u_register_t x2, u_register_t x3);
int imx_gpc_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
+#if IMX_DRAM_RETENTION
int dram_dvfs_handler(uint32_t smc_fid, void *handle,
u_register_t x1, u_register_t x2, u_register_t x3);
+#else
+static inline int dram_dvfs_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2, u_register_t x3)
+{
+ SMC_RET1(handle, SMC_UNK);
+}
+#endif
#endif
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
int dram_dvfs_handler(uint32_t smc_fid, void *handle,
diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk
index d5c553a..3a87e44 100644
--- a/plat/imx/imx8m/imx8mm/platform.mk
+++ b/plat/imx/imx8m/imx8mm/platform.mk
@@ -54,7 +54,6 @@
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
${XLAT_TABLES_LIB_SRCS} \
- ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES}
ifeq (${NEED_BL2},yes)
@@ -155,6 +154,14 @@
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+IMX_DRAM_RETENTION ?= 1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES += ${IMX_DRAM_SOURCES}
+endif
+
ifneq (${PRELOADED_BL33_BASE},)
$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
endif
diff --git a/plat/imx/imx8m/imx8mn/platform.mk b/plat/imx/imx8m/imx8mn/platform.mk
index 87b3a6f..6a9d22e 100644
--- a/plat/imx/imx8m/imx8mn/platform.mk
+++ b/plat/imx/imx8m/imx8mn/platform.mk
@@ -48,7 +48,6 @@
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
- ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
@@ -61,6 +60,14 @@
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+IMX_DRAM_RETENTION ?= 1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES += ${IMX_DRAM_SOURCES}
+endif
+
ifneq (${PRELOADED_BL33_BASE},)
$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
endif
diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk
index 631dd29..42dc781 100644
--- a/plat/imx/imx8m/imx8mp/platform.mk
+++ b/plat/imx/imx8m/imx8mp/platform.mk
@@ -49,7 +49,6 @@
drivers/arm/tzc/tzc380.c \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
- ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES} \
${XLAT_TABLES_LIB_SRCS}
@@ -152,6 +151,14 @@
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+IMX_DRAM_RETENTION ?= 1
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES += ${IMX_DRAM_SOURCES}
+endif
+
ifneq (${PRELOADED_BL33_BASE},)
$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
endif
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 6556c7f..73179dd 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -43,7 +43,6 @@
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
${XLAT_TABLES_LIB_SRCS} \
- ${IMX_DRAM_SOURCES} \
${IMX_GIC_SOURCES}
ENABLE_PIE := 1
@@ -56,6 +55,14 @@
ERRATA_A53_843419 := 1
ERRATA_A53_855873 := 1
+IMX_DRAM_RETENTION ?= 0
+$(eval $(call assert_boolean,IMX_DRAM_RETENTION))
+$(eval $(call add_define,IMX_DRAM_RETENTION))
+
+ifeq (${IMX_DRAM_RETENTION},1)
+BL31_SOURCES += ${IMX_DRAM_SOURCES}
+endif
+
ifneq (${PRELOADED_BL33_BASE},)
$(eval $(call add_define_val,PLAT_NS_IMAGE_OFFSET,${PRELOADED_BL33_BASE}))
endif
diff --git a/plat/imx/imx8m/include/dram.h b/plat/imx/imx8m/include/dram.h
index 719c390..1cf0666 100644
--- a/plat/imx/imx8m/include/dram.h
+++ b/plat/imx/imx8m/include/dram.h
@@ -70,13 +70,19 @@
extern struct dram_info dram_info;
-void dram_info_init(unsigned long dram_timing_base);
void dram_umctl2_init(struct dram_timing_info *timing);
void dram_phy_init(struct dram_timing_info *timing);
/* dram retention */
+#if IMX_DRAM_RETENTION
+void dram_info_init(unsigned long dram_timing_base);
void dram_enter_retention(void);
void dram_exit_retention(void);
+#else
+static inline void dram_info_init(unsigned long dram_timing_base) {}
+static inline void dram_enter_retention(void) {}
+static inline void dram_exit_retention(void) {}
+#endif
void dram_clock_switch(unsigned int target_drate, bool bypass_mode);
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index c4c0dec..dde66aa 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -150,7 +150,12 @@
* Per-CPU Secure entry point - resume or power up
* --------------------------------------------------------------------
*/
+
+#if USE_COHERENT_MEM
.section .tzfw_coherent_mem, "a"
+#else
+ .data
+#endif
.align 3
cpuson_entry_point:
.rept PLATFORM_CORE_COUNT
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index 81e8520..d563dfd 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,8 +13,6 @@
#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables.h>
-
#include <plat_private.h>
#ifdef PLAT_RK_CCI_BASE
@@ -42,9 +40,10 @@
mmap_add_region(ro_start, ro_start, \
ro_limit - ro_start, \
MT_MEMORY | MT_RO | MT_SECURE); \
- mmap_add_region(coh_start, coh_start, \
- coh_limit - coh_start, \
- MT_DEVICE | MT_RW | MT_SECURE); \
+ if ((coh_limit - coh_start) != 0) \
+ mmap_add_region(coh_start, coh_start, \
+ coh_limit - coh_start, \
+ MT_DEVICE | MT_RW | MT_SECURE); \
mmap_add(plat_rk_mmap); \
rockchip_plat_mmu_el##_el(); \
init_xlat_tables(); \
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index 59db3d8..6214722 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -93,10 +93,19 @@
{
plat_cci_init();
plat_cci_enable();
+#if USE_COHERENT_MEM
plat_configure_mmu_el3(BL_CODE_BASE,
BL_COHERENT_RAM_END - BL_CODE_BASE,
BL_CODE_BASE,
BL_CODE_END,
BL_COHERENT_RAM_BASE,
BL_COHERENT_RAM_END);
+#else
+ plat_configure_mmu_el3(BL31_START,
+ BL31_END - BL31_START,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ 0,
+ 0);
+#endif
}
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index 990d106..465f372 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,9 +11,9 @@
#include <stdint.h>
-#include <lib/psci/psci.h>
-#include <lib/xlat_tables/xlat_tables.h>
#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat_params.h>
#define __sramdata __attribute__((section(".sram.data")))
@@ -135,7 +135,6 @@
extern void *pmu_cpuson_entrypoint;
extern u_register_t cpuson_entry_point[PLATFORM_CORE_COUNT];
extern uint32_t cpuson_flags[PLATFORM_CORE_COUNT];
-
extern const mmap_region_t plat_rk_mmap[];
uint32_t rockchip_get_uart_base(void);
diff --git a/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
new file mode 100644
index 0000000..8ddea0e
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+#include <platform_def.h>
+
+.macro func_rockchip_clst_warmboot
+ /* Nothing to do for rk3568 */
+.endm
+
+.macro rockchip_clst_warmboot_data
+ /* Nothing to do for rk3568 */
+.endm
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.c b/plat/rockchip/rk3568/drivers/pmu/pmu.c
new file mode 100644
index 0000000..970caec
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * The power management unit (PMU) is designed for controlling power resources.
+ * The PMU is dedicated for managing the power of the whole chip.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <bakery_lock.h>
+#include <cortex_a55.h>
+#include <dsu_def.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+
+#include <cpus_on_fixed_addr.h>
+#include <plat_private.h>
+#include <soc.h>
+
+/*
+ * Use this macro to instantiate lock before it is used in below
+ * rockchip_pd_lock_xxx() macros
+ */
+DECLARE_BAKERY_LOCK(rockchip_pd_lock);
+
+static uint32_t grf_ddr_con3;
+static struct psram_data_t *psram_sleep_cfg =
+ (struct psram_data_t *)&sys_sleep_flag_sram;
+
+/*
+ * These are wrapper macros to the powe domain Bakery Lock API.
+ */
+#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock)
+#define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock)
+#define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock)
+
+void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void)
+{
+ uint64_t ctrl;
+
+ __asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl));
+ ctrl |= 0x01;
+ __asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl));
+ isb();
+
+ while (1)
+ wfi();
+}
+
+static void pmu_pmic_sleep_mode_config(void)
+{
+ /* pmic sleep function selection
+ * 1'b0: From reset pulse generator, can reset external PMIC
+ * 1'b1: From pmu block, only support sleep function for external PMIC
+ */
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), WRITE_MASK_SET(BIT(7)));
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN);
+}
+
+static void pmu_wakeup_source_config(void)
+{
+ /* config wakeup source */
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN)));
+
+ INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n",
+ mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON);
+}
+
+static void pmu_pll_powerdown_config(void)
+{
+ uint32_t pll_id;
+
+ /* PLL power down by PMU */
+ pll_id = BIT(APLL_PD_ENA) |
+ BIT(CPLL_PD_ENA) |
+ BIT(GPLL_PD_ENA) |
+ BIT(MPLL_PD_ENA) |
+ BIT(NPLL_PD_ENA) |
+ BIT(HPLL_PD_ENA) |
+ BIT(PPLL_PD_ENA) |
+ BIT(VPLL_PD_ENA);
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id));
+ INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n",
+ PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+}
+
+static void pmu_stable_count_config(void)
+{
+ mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180);
+ mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180);
+}
+
+static void pmu_pd_powerdown_config(void)
+{
+ uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0;
+ uint32_t pmu_bus_idle_con1;
+
+ /* Pd power down by PMU */
+ pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST);
+ pwr_gate_con = ~pwr_dwn_st & 0x3ff;
+
+ if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU);
+ }
+
+ if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU);
+ }
+
+ if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC);
+ }
+
+ if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC);
+ }
+
+ if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA);
+ }
+
+ if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI);
+ }
+
+ if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO);
+ }
+
+ if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) {
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE);
+ }
+
+ pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) |
+ BIT(IDLE_REQ_MSCH) |
+ BIT(IDLE_REQ_PHP) |
+ BIT(IDLE_REQ_SECURE_FLASH) |
+ BIT(IDLE_REQ_PERIMID) |
+ BIT(IDLE_REQ_USB) |
+ BIT(IDLE_REQ_BUS);
+
+ /* Enable power down PD by PMU automatically */
+ pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) |
+ BIT(PD_NPU_DWN_ENA) |
+ BIT(PD_VPU_DWN_ENA) |
+ BIT(PD_RKVENC_DWN_ENA) |
+ BIT(PD_RKVDEC_DWN_ENA) |
+ BIT(PD_RGA_DWN_ENA) |
+ BIT(PD_VI_DWN_ENA) |
+ BIT(PD_VO_DWN_ENA) |
+ BIT(PD_PIPE_DWN_ENA)) << 16;
+
+ pmu_bus_idle_con1 = 0;
+
+ mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0));
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1));
+
+ /* When perform idle operation,
+ * corresponding clock can be opened or gated automatically
+ */
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+ mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA)));
+
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS)));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS)));
+
+ INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n",
+ PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST));
+ INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n",
+ PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON));
+ INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n",
+ PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0));
+ INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n",
+ PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1));
+ INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_ddr_suspend_config(void)
+{
+ uint32_t pmu_ddr_pwr_con;
+
+ pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) |
+ BIT(DDRIO_RET_ENTER_ENA) |
+ BIT(DDRIO_RET_EXIT_ENA) |
+ BIT(DDRPHY_AUTO_GATING_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con));
+ /* DPLL power down by PMU */
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA)));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS)));
+
+ grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3);
+
+ mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020);
+
+ pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON);
+
+ INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n",
+ PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON));
+ INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n",
+ PMU_DDR_PWR_CON, pmu_ddr_pwr_con);
+
+ if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) {
+ INFO("\t DDR_SREF_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) {
+ INFO("\t DDRIO_RET_ENTER_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) {
+ INFO("\t DDRIO_RET_EXIT_ENA\n");
+ }
+
+ if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) {
+ INFO("\t DDRPHY_AUTO_GATING_ENA\n");
+ }
+}
+
+static void pmu_dsu_suspend_config(void)
+{
+ uint32_t pmu_dsu_pwr_con;
+
+ pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS)));
+ dsu_pwr_dwn();
+
+ INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n",
+ PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON));
+ INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n",
+ PMU_CLUSTER_IDLE_CON, mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON));
+ INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pmu_cpu_powerdown_config(void)
+{
+ uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass;
+
+ pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+ cpus_state = pmu_cluster_pwr_st & 0x0f;
+
+ cpus_bypass = cpus_state << CPU0_BYPASS;
+
+ INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n",
+ PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST));
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass);
+
+ INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n",
+ PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON));
+}
+
+static void pvtm_32k_config(void)
+{
+ uint32_t pmu_cru_pwr_con;
+ uint32_t pvtm_freq_khz, pvtm_div;
+
+ mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000);
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002);
+ dsb();
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000);
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT);
+ dsb();
+
+ mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001);
+ dsb();
+
+ while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) {
+ ;
+ }
+
+ dsb();
+ while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) {
+ ;
+ }
+
+ pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 +
+ PVTM_CALC_CNT / 2) / PVTM_CALC_CNT;
+ pvtm_div = (pvtm_freq_khz + 16) / 32;
+
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div);
+
+ mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000);
+
+ pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10);
+
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+ INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+ PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_cru_suspendmode_config(void)
+{
+ uint32_t pmu_cru_pwr_con;
+
+ pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA);
+
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con));
+ INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n",
+ PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON));
+}
+
+static void pmu_suspend_cru_fsm(void)
+{
+ pmu_pmic_sleep_mode_config();
+
+ /* Global interrupt disable */
+ mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE);
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS);
+
+ pmu_stable_count_config();
+ pmu_wakeup_source_config();
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000);
+ /* default cru config */
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA)));
+
+ pmu_cru_suspendmode_config();
+ pmu_cpu_powerdown_config();
+ pmu_pll_powerdown_config();
+ pmu_pd_powerdown_config();
+ pmu_ddr_suspend_config();
+ pmu_dsu_suspend_config();
+ pvtm_32k_config();
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001);
+}
+
+static void pmu_reinit(void)
+{
+ mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000);
+
+ mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000);
+
+ mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000);
+ mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000);
+}
+
+void rockchip_plat_mmu_el3(void)
+{
+}
+
+int rockchip_soc_cores_pwr_dm_suspend(void)
+{
+ return 0;
+}
+
+int rockchip_soc_cores_pwr_dm_resume(void)
+{
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_suspend(void)
+{
+ psram_sleep_cfg->pm_flag = 0;
+ flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+ sizeof(uint32_t));
+ pmu_suspend_cru_fsm();
+
+ return 0;
+}
+
+int rockchip_soc_sys_pwr_dm_resume(void)
+{
+ pmu_reinit();
+ plat_rockchip_gic_cpuif_enable();
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+ flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag),
+ sizeof(uint32_t));
+
+ return 0;
+}
+
+static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg)
+{
+ uint32_t apm_value, offset, idx;
+
+ apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk);
+
+ if (pd_cfg == core_pwr_wfi_int) {
+ apm_value |= BIT(core_pm_int_wakeup_en);
+ }
+
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BITS_WITH_WMASK(apm_value, 0xf, offset));
+ dsb();
+
+ return 0;
+}
+
+static int cpus_power_domain_on(uint32_t cpu_id)
+{
+ uint32_t offset, idx;
+
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ WMSK_BIT(core_pm_en + offset));
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset));
+ 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);
+
+ cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG;
+ cpuson_entry_point[cpu_id] = entrypoint;
+ flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags));
+ flush_dcache_range((uintptr_t)cpuson_entry_point,
+ sizeof(cpuson_entry_point));
+
+ cpus_power_domain_on(cpu_id);
+ return 0;
+}
+
+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 0;
+}
+
+int rockchip_soc_cores_pwr_dm_on_finish(void)
+{
+ uint32_t cpu_id = plat_my_core_pos();
+ uint32_t offset, idx;
+
+ /* Disable core_pm */
+ idx = cpu_id / 2;
+ offset = (cpu_id % 2) << 3;
+ mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx),
+ BITS_WITH_WMASK(0, 0xf, offset));
+
+ return 0;
+}
+
+static void nonboot_cpus_off(void)
+{
+ uint32_t tmp;
+
+ cpus_power_domain_off(1, 0);
+ cpus_power_domain_off(2, 0);
+ cpus_power_domain_off(3, 0);
+
+ mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf);
+ mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi);
+ sev();
+
+ do {
+ tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST);
+ } while ((tmp & 0xe) != 0xe);
+}
+
+void plat_rockchip_pmu_init(void)
+{
+ uint32_t cpu;
+
+ rockchip_pd_lock_init();
+ nonboot_cpus_off();
+ for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
+ cpuson_flags[cpu] = PMU_CPU_HOTPLUG;
+
+ psram_sleep_cfg->ddr_data = (uint64_t)0;
+ psram_sleep_cfg->sp = PSRAM_SP_TOP;
+ psram_sleep_cfg->ddr_flag = 0x00;
+ psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
+ psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT;
+
+ /*
+ * When perform idle operation, corresponding clock can be
+ * opened or gated automatically.
+ */
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff);
+ mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007);
+
+ /* grf_con_pmic_sleep_sel
+ * pmic sleep function selection
+ * 1'b0: From reset pulse generator, can reset external PMIC
+ * 1'b1: From pmu block, only support sleep function for external PMIC
+ */
+ mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080);
+
+ /*
+ * force jtag control
+ * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status
+ * 1'b0: CPU debug port IO mux IS controlled by GRF
+ */
+ mmio_write_32(SGRF_BASE + 0x008, 0x00100000);
+
+ /*
+ * remap
+ * 2'b00: Boot from boot-rom.
+ * 2'b01: Boot from pmu mem.
+ * 2'b10: Boot from sys mem.
+ */
+ mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800);
+}
diff --git a/plat/rockchip/rk3568/drivers/pmu/pmu.h b/plat/rockchip/rk3568/drivers/pmu/pmu.h
new file mode 100644
index 0000000..5821514
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PMU_H__
+#define __PMU_H__
+
+#define PMU_VERSION 0x0000
+#define PMU_PWR_CON 0x0004
+#define PMU_MAIN_PWR_STATE 0x0008
+#define PMU_INT_MASK_CON 0x000C
+#define PMU_WAKEUP_INT_CON 0x0010
+#define PMU_WAKEUP_INT_ST 0x0014
+#define PMU_WAKEUP_EDGE_CON 0x0018
+#define PMU_WAKEUP_EDGE_ST 0x001C
+#define PMU_BUS_IDLE_CON0 0x0040
+#define PMU_BUS_IDLE_CON1 0x0044
+#define PMU_BUS_IDLE_SFTCON0 0x0050
+#define PMU_BUS_IDLE_SFTCON1 0x0054
+#define PMU_BUS_IDLE_ACK 0x0060
+#define PMU_BUS_IDLE_ST 0x0068
+#define PMU_NOC_AUTO_CON0 0x0070
+#define PMU_NOC_AUTO_CON1 0x0074
+#define PMU_DDR_PWR_CON 0x0080
+#define PMU_DDR_PWR_SFTCON 0x0084
+#define PMU_DDR_PWR_STATE 0x0088
+#define PMU_DDR_PWR_ST 0x008C
+#define PMU_PWR_GATE_CON 0x0090
+#define PMU_PWR_GATE_STATE 0x0094
+#define PMU_PWR_DWN_ST 0x0098
+#define PMU_PWR_GATE_SFTCON 0x00A0
+#define PMU_VOL_GATE_SFTCON 0x00A8
+#define PMU_CRU_PWR_CON 0x00B0
+#define PMU_CRU_PWR_SFTCON 0x00B4
+#define PMU_CRU_PWR_STATE 0x00B8
+#define PMU_PLLPD_CON 0x00C0
+#define PMU_PLLPD_SFTCON 0x00C4
+#define PMU_INFO_TX_CON 0x00D0
+#define PMU_DSU_STABLE_CNT 0x0100
+#define PMU_PMIC_STABLE_CNT 0x0104
+#define PMU_OSC_STABLE_CNT 0x0108
+#define PMU_WAKEUP_RSTCLR_CNT 0x010C
+#define PMU_PLL_LOCK_CNT 0x0110
+#define PMU_DSU_PWRUP_CNT 0x0118
+#define PMU_DSU_PWRDN_CNT 0x011C
+#define PMU_GPU_VOLUP_CNT 0x0120
+#define PMU_GPU_VOLDN_CNT 0x0124
+#define PMU_WAKEUP_TIMEOUT_CNT 0x0128
+#define PMU_PWM_SWITCH_CNT 0x012C
+#define PMU_DBG_RST_CNT 0x0130
+#define PMU_SYS_REG0 0x0180
+#define PMU_SYS_REG1 0x0184
+#define PMU_SYS_REG2 0x0188
+#define PMU_SYS_REG3 0x018C
+#define PMU_SYS_REG4 0x0190
+#define PMU_SYS_REG5 0x0194
+#define PMU_SYS_REG6 0x0198
+#define PMU_SYS_REG7 0x019C
+#define PMU_DSU_PWR_CON 0x0300
+#define PMU_DSU_PWR_SFTCON 0x0304
+#define PMU_DSU_AUTO_CON 0x0308
+#define PMU_DSU_PWR_STATE 0x030C
+#define PMU_CPU_AUTO_PWR_CON0 0x0310
+#define PMU_CPU_AUTO_PWR_CON1 0x0314
+#define PMU_CPU_PWR_SFTCON 0x0318
+#define PMU_CLUSTER_PWR_ST 0x031C
+#define PMU_CLUSTER_IDLE_CON 0x0320
+#define PMU_CLUSTER_IDLE_SFTCON 0x0324
+#define PMU_CLUSTER_IDLE_ACK 0x0328
+#define PMU_CLUSTER_IDLE_ST 0x032C
+#define PMU_DBG_PWR_CON 0x0330
+
+/* PMU_SGRF */
+#define PMU_SGRF_SOC_CON1 0x0004
+#define PMU_SGRF_FAST_BOOT_ADDR 0x0180
+
+/* sys grf */
+#define GRF_CPU_STATUS0 0x0420
+
+#define CRU_SOFTRST_CON00 0x0400
+
+#define CORES_PM_DISABLE 0x0
+#define PD_CHECK_LOOP 500
+#define WFEI_CHECK_LOOP 500
+
+#define PMUSGRF_SOC_CON(i) ((i) * 0x4)
+/* Needed aligned 16 bytes for sp stack top */
+#define PSRAM_SP_TOP ((PMUSRAM_BASE + PMUSRAM_RSIZE) & ~0xf)
+#define PMU_CPUAPM_CON(cpu) (0x0310 + (cpu) * 0x4)
+
+#define PMIC_SLEEP_FUN 0x07000100
+#define PMIC_SLEEP_GPIO 0x07000000
+#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 PMIC_SLEEP_HIGH_LEVEL 0x00040004
+#define PMIC_SLEEP_LOW_LEVEL 0x00040000
+#define PMIC_SLEEP_OUT 0x00040004
+#define CPUS_BYPASS 0x007e4f7e
+#define CLB_INT_DISABLE 0x00010001
+#define WRITE_MASK_SET(value) ((value << 16) | value)
+#define WRITE_MASK_CLR(value) ((value << 16))
+
+enum pmu_cores_pm_by_wfi {
+ core_pm_en = 0,
+ core_pm_int_wakeup_en,
+ core_pm_int_wakeup_glb_msk,
+ core_pm_sft_wakeup_en,
+};
+
+/* The ways of cores power domain contorlling */
+enum cores_pm_ctr_mode {
+ core_pwr_pd = 0,
+ core_pwr_wfi = 1,
+ core_pwr_wfi_int = 2
+};
+
+/* PMU_PWR_DWN_ST */
+enum pmu_pdid {
+ PD_GPU,
+ PD_NPU,
+ PD_VPU,
+ PD_RKVENC,
+ PD_RKVDEC,
+ PD_RGA,
+ PD_VI,
+ PD_VO,
+ PD_PIPE,
+ PD_CENTER,
+ PD_END
+};
+
+/* PMU_PWR_CON */
+enum pmu_pwr_con {
+ POWRMODE_EN,
+ DSU_BYPASS,
+ BUS_BYPASS = 4,
+ DDR_BYPASS,
+ PWRDN_BYPASS,
+ CRU_BYPASS,
+ CPU0_BYPASS,
+ CPU1_BYPASS,
+ CPU2_BYPASS,
+ CPU3_BYPASS,
+ PMU_SLEEP_LOW = 15,
+};
+
+/* PMU_CRU_PWR_CON */
+enum pmu_cru_pwr_con {
+ ALIVE_32K_ENA,
+ OSC_DIS_ENA,
+ WAKEUP_RST_ENA,
+ INPUT_CLAMP_ENA,
+
+ ALIVE_OSC_ENA,
+ POWER_OFF_ENA,
+ PWM_SWITCH_ENA,
+ PWM_GPIO_IOE_ENA,
+
+ PWM_SWITCH_IOUT,
+ PD_BUS_CLK_SRC_GATE_ENA,
+ PD_PERI_CLK_SRC_GATE_ENA,
+ PD_PMU_CLK_SRC_GATE_ENA,
+
+ PMUMEM_CLK_SRC_GATE_ENA,
+ PWR_CON_END
+};
+
+/* PMU_PLLPD_CON */
+enum pmu_pllpd_con {
+ APLL_PD_ENA,
+ DPLL_PD_ENA,
+ CPLL_PD_ENA,
+ GPLL_PD_ENA,
+ MPLL_PD_ENA,
+ NPLL_PD_ENA,
+ HPLL_PD_ENA,
+ PPLL_PD_ENA,
+ VPLL_PD_ENA,
+ PLL_PD_END
+};
+
+/* PMU_DSU_PWR_CON */
+enum pmu_dsu_pwr_con {
+ DSU_PWRDN_ENA = 2,
+ DSU_PWROFF_ENA,
+ DSU_RET_ENA = 6,
+ CLUSTER_CLK_SRC_GATE_ENA,
+ DSU_PWR_CON_END
+};
+
+enum cpu_power_state {
+ CPU_POWER_ON,
+ CPU_POWER_OFF,
+ CPU_EMULATION_OFF,
+ CPU_RETENTION,
+ CPU_DEBUG
+};
+
+enum dsu_power_state {
+ DSU_POWER_ON,
+ CLUSTER_TRANSFER_IDLE,
+ DSU_POWER_DOWN,
+ DSU_OFF,
+ DSU_WAKEUP,
+ DSU_POWER_UP,
+ CLUSTER_TRANSFER_RESUME,
+ DSU_FUNCTION_RETENTION
+};
+
+enum pmu_wakeup_int_con {
+ WAKEUP_CPU0_INT_EN,
+ WAKEUP_CPU1_INT_EN,
+ WAKEUP_CPU2_INT_EN,
+ WAKEUP_CPU3_INT_EN,
+ WAKEUP_GPIO0_INT_EN,
+ WAKEUP_UART0_EN,
+ WAKEUP_SDMMC0_EN,
+ WAKEUP_SDMMC1_EN,
+ WAKEUP_SDMMC2_EN,
+ WAKEUP_USB_EN,
+ WAKEUP_PCIE_EN,
+ WAKEUP_VAD_EN,
+ WAKEUP_TIMER_EN,
+ WAKEUP_PWM0_EN,
+ WAKEUP_TIMEROUT_EN,
+ WAKEUP_MCU_SFT_EN,
+};
+
+enum pmu_wakeup_int_st {
+ WAKEUP_CPU0_INT_ST,
+ WAKEUP_CPU1_INT_ST,
+ WAKEUP_CPU2_INT_ST,
+ WAKEUP_CPU3_INT_ST,
+ WAKEUP_GPIO0_INT_ST,
+ WAKEUP_UART0_ST,
+ WAKEUP_SDMMC0_ST,
+ WAKEUP_SDMMC1_ST,
+ WAKEUP_SDMMC2_ST,
+ WAKEUP_USB_ST,
+ WAKEUP_PCIE_ST,
+ WAKEUP_VAD_ST,
+ WAKEUP_TIMER_ST,
+ WAKEUP_PWM0_ST,
+ WAKEUP_TIMEOUT_ST,
+ WAKEUP_SYS_INT_ST,
+};
+
+enum pmu_bus_idle_con0 {
+ IDLE_REQ_MSCH,
+ IDLE_REQ_GPU,
+ IDLE_REQ_NPU,
+ IDLE_REQ_VI,
+ IDLE_REQ_VO,
+ IDLE_REQ_RGA,
+ IDLE_REQ_VPU,
+ IDLE_REQ_RKVENC,
+ IDLE_REQ_RKVDEC,
+ IDLE_REQ_GIC_AUDIO,
+ IDLE_REQ_PHP,
+ IDLE_REQ_PIPE,
+ IDLE_REQ_SECURE_FLASH,
+ IDLE_REQ_PERIMID,
+ IDLE_REQ_USB,
+ IDLE_REQ_BUS,
+};
+
+enum pmu_bus_idle_con1 {
+ IDLE_REQ_TOP1,
+ IDLE_REQ_TOP2,
+ IDLE_REQ_PMU,
+};
+
+enum pmu_pwr_gate_con {
+ PD_GPU_DWN_ENA,
+ PD_NPU_DWN_ENA,
+ PD_VPU_DWN_ENA,
+ PD_RKVENC_DWN_ENA,
+
+ PD_RKVDEC_DWN_ENA,
+ PD_RGA_DWN_ENA,
+ PD_VI_DWN_ENA,
+ PD_VO_DWN_ENA,
+
+ PD_PIPE_DWN_ENA,
+ PD_CENTER_DWN_ENA,
+};
+
+enum pmu_ddr_pwr_con {
+ DDR_SREF_ENA,
+ DDRIO_RET_ENTER_ENA,
+ DDRIO_RET_EXIT_ENA = 2,
+ DDRPHY_AUTO_GATING_ENA = 4,
+};
+
+enum pmu_vol_gate_soft_con {
+ VD_GPU_ENA,
+ VD_NPU_ENA,
+};
+
+#endif /* __PMU_H__ */
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.c b/plat/rockchip/rk3568/drivers/soc/soc.c
new file mode 100644
index 0000000..2af3887
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include <soc.h>
+
+const mmap_region_t plat_rk_mmap[] = {
+ MAP_REGION_FLAT(RKFPGA_DEV_RNG0_BASE, RKFPGA_DEV_RNG0_SIZE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+
+ { 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,
+};
+
+static void secure_timer_init(void)
+{
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_DIS);
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER0_CHN_BASE(1) + TIMER_CONTROL_REG, TIMER_EN);
+}
+
+static void sgrf_init(void)
+{
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(0), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(1), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(2), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(3), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(4), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(5), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(6), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(7), 0xffff0000);
+ mmio_write_32(SGRF_BASE + SGRF_FIREWALL_SLV_CON(8), 0xffff0000);
+
+ mmio_write_32(DDRSGRF_BASE + FIREWALL_DDR_FW_DDR_CON_REG, 0xffff0000);
+}
+
+static void set_pll_slow_mode(uint32_t clk_pll)
+{
+ mmio_write_32(CRU_BASE + CRU_MODE_CON00, 0x03 << (16 + clk_pll * 2));
+}
+
+static void __dead2 soc_global_soft_reset(void)
+{
+ set_pll_slow_mode(CLK_CPLL);
+ set_pll_slow_mode(CLK_GPLL);
+ set_pll_slow_mode(CLK_NPLL);
+ set_pll_slow_mode(CLK_VPLL);
+ set_pll_slow_mode(CLK_USBPLL);
+ set_pll_slow_mode(CLK_APLL);
+ mmio_write_32(PMUCRU_BASE + PMUCRU_MODE_CON00, 0x000f0000);
+
+ dsb();
+ 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 excute valid codes.
+ */
+ while (1) {
+ ;
+ }
+}
+
+static void rockchip_system_reset_init(void)
+{
+ mmio_write_32(GRF_BASE + 0x0508, 0x00100010);
+ mmio_write_32(CRU_BASE + 0x00dc, 0x01030103);
+}
+
+void __dead2 rockchip_soc_soft_reset(void)
+{
+ soc_global_soft_reset();
+}
+
+void plat_rockchip_soc_init(void)
+{
+ secure_timer_init();
+ sgrf_init();
+ rockchip_system_reset_init();
+ NOTICE("BL31: Rockchip release version: v%d.%d\n",
+ MAJOR_VERSION, MINOR_VERSION);
+}
+
diff --git a/plat/rockchip/rk3568/drivers/soc/soc.h b/plat/rockchip/rk3568/drivers/soc/soc.h
new file mode 100644
index 0000000..41a2586
--- /dev/null
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SOC_H__
+#define __SOC_H__
+
+#define RKFPGA_DEV_RNG0_BASE 0xf8000000
+#define RKFPGA_DEV_RNG0_SIZE 0x07fff000
+
+#define CRU_MODE_CON00 0x00c0
+#define PMUCRU_MODE_CON00 0x0080
+
+#define CRU_GLB_SRST_FST 0x00d4
+#define GLB_SRST_FST_CFG_VAL 0xfdb9
+
+#define PMU_GRF_GPIO0A_IOMUX_L 0x00
+#define PMU_GRF_SOC_CON(i) (0x0100 + i * 4)
+
+#define CRU_SOFTRST_CON 0x300
+#define CRU_SOFTRSTS_CON(n) (CRU_SOFTRST_CON + ((n) * 4))
+#define CRU_SOFTRSTS_CON_CNT 26
+#define GRF_DDR_CON3 0x000c
+#define SGRF_FIREWALL_SLV_CON(i) (0x240 + i * 4)
+
+#define FIREWALL_DDR_FW_DDR_CON_REG 0x80
+
+ /* low 32 bits */
+#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 STIMER0_CHN_BASE(n) (STIME_BASE + 0x20 * (n))
+
+#define PMU_GRF_GPIO0B_IOMUX_L 0x0008
+#define PMUCRU_PMUCLKSEL_CON00 0x0100
+#define PMUPVTM_BASE 0xfdd80000
+#define PVTM_CON0 0x0004
+#define PVTM_CON1 0x0008
+#define PVTM_STATUS0 0x0080
+#define PVTM_STATUS1 0x0084
+#define PMUCRU_PMUGATE_CON01 0x0184
+#define PVTM_CALC_CNT 0x200
+#define PMU_GRF_DLL_CON0 0x0180
+
+enum cru_mode_con00 {
+ CLK_APLL,
+ CLK_DPLL,
+ CLK_CPLL,
+ CLK_GPLL,
+ CLK_REVSERVED,
+ CLK_NPLL,
+ CLK_VPLL,
+ CLK_USBPLL,
+};
+
+#endif /* __SOC_H__ */
diff --git a/plat/rockchip/rk3568/include/plat.ld.S b/plat/rockchip/rk3568/include/plat.ld.S
new file mode 100644
index 0000000..ddd584d
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat.ld.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#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
+ */
+ .pmusram : {
+ ASSERT(. == ALIGN(64 * 1024),
+ ".pmusram.entry request 64K aligned.");
+ KEEP(*(.pmusram.entry))
+
+ __bl31_pmusram_text_start = .;
+ *(.pmusram.text)
+ *(.pmusram.rodata)
+ __bl31_pmusram_text_end = .;
+ __bl31_pmusram_data_start = .;
+ *(.pmusram.data)
+ __bl31_pmusram_data_end = .;
+ } >PMUSRAM
+}
+#endif /* ROCKCHIP_PLAT_LD_S */
diff --git a/plat/rockchip/rk3568/include/plat_sip_calls.h b/plat/rockchip/rk3568/include/plat_sip_calls.h
new file mode 100644
index 0000000..6acb876
--- /dev/null
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#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/rk3568/include/platform_def.h b/plat/rockchip/rk3568/include/platform_def.h
new file mode 100644
index 0000000..19363a4
--- /dev/null
+++ b/plat/rockchip/rk3568/include/platform_def.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <rk3568_def.h>
+
+#define DEBUG_XLAT_TABLE 0
+
+/*******************************************************************************
+ * Platform binary types for linking
+ ******************************************************************************/
+#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH aarch64
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#define PLATFORM_STACK_SIZE 0x440
+#elif IMAGE_BL2
+#define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL31
+#define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL32
+#define PLATFORM_STACK_SIZE 0x440
+#endif
+
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+
+#define PLATFORM_SYSTEM_COUNT 1
+#define PLATFORM_CLUSTER_COUNT 1
+#define PLATFORM_CLUSTER0_CORE_COUNT 4
+
+#define PLATFORM_CLUSTER1_CORE_COUNT 0
+#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 8
+
+/*
+ * 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 (0x0)
+#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 a list of Group 1 Secure and Group 0 interrupts as per GICv3
+ * terminology. On a GICv2 system or mode, the lists will be merged and treated
+ * as Group 0 interrupts.
+ */
+
+#define PLAT_RK_GICV3_G1S_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_GROUP1S, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_GICV3_G0_IRQS \
+ INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
+ INTR_GROUP0, GIC_INTR_CFG_LEVEL)
+
+#define PLAT_RK_UART_BASE FPGA_UART_BASE
+#define PLAT_RK_UART_CLOCK FPGA_UART_CLOCK
+#define PLAT_RK_UART_BAUDRATE FPGA_BAUDRATE
+
+#define PLAT_RK_PRIMARY_CPU 0x0
+
+#define ATAGS_PHYS_SIZE 0x2000
+#define ATAGS_PHYS_BASE (0x200000 - ATAGS_PHYS_SIZE)/* [2M-8K, 2M] */
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rockchip/rk3568/plat_sip_calls.c b/plat/rockchip/rk3568/plat_sip_calls.c
new file mode 100644
index 0000000..b0f3a03
--- /dev/null
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#include <plat_sip_calls.h>
+#include <rockchip_sip_svc.h>
+
+uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/rockchip/rk3568/platform.mk b/plat/rockchip/rk3568/platform.mk
new file mode 100644
index 0000000..1155ff8
--- /dev/null
+++ b/plat/rockchip/rk3568/platform.mk
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2023, 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
+GICV3_SUPPORT_GIC600 := 1
+include lib/coreboot/coreboot.mk
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+# GIC-600 configuration
+GICV3_IMPL := GIC600
+# Include GICv3 driver files
+include drivers/arm/gic/v3/gicv3.mk
+
+PLAT_INCLUDES := -Iinclude/bl31 \
+ -Iinclude/common \
+ -Iinclude/drivers \
+ -Iinclude/drivers/arm \
+ -Iinclude/drivers/auth \
+ -Iinclude/drivers/io \
+ -Iinclude/drivers/ti/uart \
+ -Iinclude/lib \
+ -Iinclude/lib/cpus/${ARCH} \
+ -Iinclude/lib/el3_runtime \
+ -Iinclude/lib/pmf \
+ -Iinclude/lib/psci \
+ -Iinclude/plat/common \
+ -Iinclude/services \
+ -Iinclude/plat/common/ \
+ -Idrivers/arm/gic/v3/ \
+ -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_SOC}/ \
+ -I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/soc/ \
+ -I${RK_PLAT_SOC}/include/
+
+RK_GIC_SOURCES := ${GICV3_SOURCES} \
+ plat/common/plat_gicv3.c \
+ ${RK_PLAT}/common/rockchip_gicv3.c
+
+PLAT_BL_COMMON_SOURCES := ${XLAT_TABLES_LIB_SRCS} \
+ common/desc_image_load.c \
+ plat/common/aarch64/crash_console_helpers.S \
+ lib/bl_aux_params/bl_aux_params.c \
+ 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 \
+ lib/cpus/aarch64/cortex_a55.S \
+ drivers/ti/uart/aarch64/16550_console.S \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ $(LIBFDT_SRCS) \
+ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
+ ${RK_PLAT_COMMON}/bl31_plat_setup.c \
+ ${RK_PLAT_COMMON}/params_setup.c \
+ ${RK_PLAT_COMMON}/plat_pm.c \
+ ${RK_PLAT_COMMON}/plat_topology.c \
+ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \
+ ${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S \
+ ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
+ ${RK_PLAT_COMMON}/aarch64/platform_common.c \
+ ${RK_PLAT_SOC}/drivers/soc/soc.c \
+ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/plat_sip_calls.c
+
+ENABLE_PLAT_COMPAT := 0
+MULTI_CONSOLE_API := 1
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+#Enable errata for cortex_a55
+ERRATA_A55_1530923 := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Do not enable SVE
+ENABLE_SVE_FOR_NS := 0
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
new file mode 100644
index 0000000..0d1e5d1
--- /dev/null
+++ b/plat/rockchip/rk3568/rk3568_def.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2023, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_DEF_H__
+#define __PLAT_DEF_H__
+
+#define MAJOR_VERSION (1)
+#define MINOR_VERSION (0)
+
+#define SIZE_K(n) ((n) * 1024)
+
+/* Special value used to verify platform parameters from BL2 to BL3-1 */
+#define RK_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+#define GIC600_BASE 0xfd400000
+#define GIC600_SIZE SIZE_K(64)
+
+#define PMUSGRF_BASE 0xfdc00000
+#define SYSSGRF_BASE 0xfdc10000
+#define PMUGRF_BASE 0xfdc20000
+#define CPUGRF_BASE 0xfdc30000
+#define DDRGRF_BASE 0xfdc40000
+#define PIPEGRF_BASE 0xfdc50000
+#define GRF_BASE 0xfdc60000
+#define PIPEPHY_GRF0 0xfdc70000
+#define PIPEPHY_GRF1 0xfdc80000
+#define PIPEPHY_GRF2 0xfdc90000
+#define USBPHY_U3_GRF 0xfdca0000
+#define USB2PHY_U2_GRF 0xfdca8000
+#define EDPPHY_GRF 0xfdcb0000
+#define SYSSRAM_BASE 0xfdcc0000
+#define PCIE30PHY_GRF 0xfdcb8000
+#define USBGRF_BASE 0xfdcf0000
+
+#define PMUCRU_BASE 0xfdd00000
+#define SCRU_BASE 0xfdd10000
+#define SGRF_BASE 0xfdd18000
+#define STIME_BASE 0xfdd1c000
+#define CRU_BASE 0xfdd20000
+#define PMUSCRU_BASE 0xfdd30000
+#define I2C0_BASE 0xfdd40000
+
+#define UART0_BASE 0xfdd50000
+#define GPIO0_BASE 0xfdd60000
+#define PMUPVTM_BASE 0xfdd80000
+#define PMU_BASE 0xfdd90000
+#define PMUSRAM_BASE 0xfdcd0000
+#define PMUSRAM_SIZE SIZE_K(128)
+#define PMUSRAM_RSIZE SIZE_K(8)
+
+#define DDRSGRF_BASE 0xfe200000
+#define UART1_BASE 0xfe650000
+#define UART2_BASE 0xfe660000
+#define GPIO1_BASE 0xfe740000
+#define GPIO2_BASE 0xfe750000
+#define GPIO3_BASE 0xfe760000
+#define GPIO4_BASE 0xfe770000
+
+#define REMAP_BASE 0xffff0000
+#define REMAP_SIZE SIZE_K(64)
+/**************************************************************************
+ * UART related constants
+ **************************************************************************/
+#define FPGA_UART_BASE UART2_BASE
+#define FPGA_BAUDRATE 1500000
+#define FPGA_UART_CLOCK 24000000
+
+/******************************************************************************
+ * System counter frequency related constants
+ ******************************************************************************/
+#define SYS_COUNTER_FREQ_IN_TICKS 24000000
+#define SYS_COUNTER_FREQ_IN_MHZ 24
+
+/******************************************************************************
+ * GIC-600 & interrupt handling related constants
+ ******************************************************************************/
+
+/* Base rk_platform compatible GIC memory map */
+#define PLAT_GICD_BASE GIC600_BASE
+#define PLAT_GICC_BASE 0
+#define PLAT_GICR_BASE (GIC600_BASE + 0x60000)
+
+/******************************************************************************
+ * 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 SHARE_MEM_BASE 0x100000/* [1MB, 1MB+60K]*/
+#define SHARE_MEM_PAGE_NUM 15
+#define SHARE_MEM_SIZE SIZE_K(SHARE_MEM_PAGE_NUM * 4)
+
+#endif /* __PLAT_DEF_H__ */
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 3fcb62f..ffee805 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -53,9 +53,6 @@
uint32_t flag);
enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype,
uint32_t flag);
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t arg3,
- uint32_t *value, uint32_t flag);
enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
uint32_t arg3, uint32_t *data, uint32_t flag);
uint32_t pm_get_shutdown_scope(void);
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index c1872d0..055fa3d 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -95,8 +95,6 @@
IOCTL_GET_LAST_RESET_REASON = 23,
/* AI engine NPI ISR clear */
IOCTL_AIE_ISR_CLEAR = 24,
- /* Register SGI to TF-A */
- IOCTL_SET_SGI = 25,
};
/**
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 36ea8ed..0a6e810 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -287,112 +287,6 @@
}
/**
- * pm_pll_set_param() - Set PLL parameter.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Value to set for PLL parameter.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param,
- uint32_t value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER,
- clk_id, param, value);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_param() - Get PLL parameter value.
- * @clk_id: PLL clock ID.
- * @param: PLL parameter ID.
- * @value: Buffer to store PLL parameter value.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param,
- uint32_t *value, uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER,
- clk_id, param);
-
- return pm_ipi_send_sync(primary_proc, payload, value, 1);
-}
-
-/**
- * pm_pll_set_mode() - Set PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: PLL mode.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE,
- clk_id, mode);
-
- return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
-}
-
-/**
- * pm_pll_get_mode() - Get PLL mode.
- * @clk_id: PLL clock ID.
- * @mode: Buffer to store PLL mode.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: Returns status, either success or error+reason.
- *
- */
-enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode,
- uint32_t flag)
-{
- uint32_t payload[PAYLOAD_ARG_CNT];
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE,
- clk_id);
-
- return pm_ipi_send_sync(primary_proc, payload, mode, 1);
-}
-
-/**
* pm_force_powerdown() - PM call to request for another PU or subsystem to
* be powered down forcefully.
* @target: Device ID of the PU node to be forced powered down.
@@ -448,110 +342,6 @@
}
/**
- * pm_query_data() - PM API for querying firmware data.
- * @qid: The type of data to query.
- * @arg1: Argument 1 to requested query data call.
- * @arg2: Argument 2 to requested query data call.
- * @arg3: Argument 3 to requested query data call.
- * @data: Returned output data.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * Return: 0 if success else non-zero error code of type
- * enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2,
- uint32_t arg3, uint32_t *data, uint32_t flag)
-{
- uint32_t ret;
- uint32_t version[PAYLOAD_ARG_CNT] = {0};
- uint32_t payload[PAYLOAD_ARG_CNT];
- uint32_t fw_api_version;
-
- /* Send request to the PMC */
- PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid,
- arg1, arg2, arg3);
-
- ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag);
- if (ret == PM_RET_SUCCESS) {
- fw_api_version = version[0] & 0xFFFFU;
- if ((fw_api_version == 2U) &&
- ((qid == XPM_QID_CLOCK_GET_NAME) ||
- (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) {
- ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
- if (ret == PM_RET_SUCCESS) {
- ret = data[0];
- data[0] = data[1];
- data[1] = data[2];
- data[2] = data[3];
- }
- } else {
- ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT);
- }
- }
- return ret;
-}
-/**
- * pm_api_ioctl() - PM IOCTL API for device control and configs.
- * @device_id: Device ID.
- * @ioctl_id: ID of the requested IOCTL.
- * @arg1: Argument 1 to requested IOCTL call.
- * @arg2: Argument 2 to requested IOCTL call.
- * @arg3: Argument 3 to requested IOCTL call.
- * @value: Returned output value.
- * @flag: 0 - Call from secure source.
- * 1 - Call from non-secure source.
- *
- * This API is deprecated and maintained here for backward compatibility.
- * New use of this API should be avoided for versal platform.
- * This API and its use cases will be removed for versal platform.
- *
- * This function calls IOCTL to firmware for device control and configuration.
- *
- * Return: Returns status, either 0 on success or non-zero error code
- * of type enum pm_ret_status.
- *
- */
-enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id,
- uint32_t arg1, uint32_t arg2, uint32_t arg3,
- uint32_t *value, uint32_t flag)
-{
- enum pm_ret_status ret;
-
- switch (ioctl_id) {
- case IOCTL_SET_PLL_FRAC_MODE:
- ret = pm_pll_set_mode(arg1, arg2, flag);
- break;
- case IOCTL_GET_PLL_FRAC_MODE:
- ret = pm_pll_get_mode(arg1, value, flag);
- break;
- case IOCTL_SET_PLL_FRAC_DATA:
- ret = pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag);
- break;
- case IOCTL_GET_PLL_FRAC_DATA:
- ret = pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag);
- break;
- case IOCTL_SET_SGI:
- /* Get the sgi number */
- ret = pm_register_sgi(arg1, arg2);
- if (ret != 0) {
- return PM_RET_ERROR_ARGS;
- }
- ret = PM_RET_SUCCESS;
- break;
- default:
- return PM_RET_ERROR_NOTSUPPORTED;
- }
-
- return ret;
-}
-
-/**
* pm_set_wakeup_source() - PM call to specify the wakeup source while
* suspended.
* @target: Device id of the targeted PU or subsystem
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index 7d8f244..7ac0ac1 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -149,6 +149,9 @@
}
}
notify_os();
+ } else if (payload[2] == EVENT_CPU_PWRDWN) {
+ request_cpu_pwrdwn();
+ (void)psci_cpu_off();
}
break;
case PM_RET_ERROR_INVALID_CRC:
@@ -240,6 +243,14 @@
}
gicd_write_irouter(gicv3_driver_data->gicd_base, PLAT_VERSAL_IPI_IRQ, MODE);
+
+ /* Register for idle callback during force power down/restart */
+ ret = pm_register_notifier(primary_proc->node_id, EVENT_CPU_PWRDWN,
+ 0x0U, 0x1U, SECURE_FLAG);
+ if (ret != 0) {
+ WARN("BL31: registering idle callback for restart/force power down failed\n");
+ }
+
return ret;
}
@@ -265,30 +276,6 @@
switch (api_id) {
- case (uint32_t)PM_IOCTL:
- {
- uint32_t value = 0U;
-
- ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], pm_arg[4],
- &value, security_flag);
- if (ret == PM_RET_ERROR_NOTSUPPORTED)
- return (uintptr_t)0;
-
- SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32U);
- }
-
- case (uint32_t)PM_QUERY_DATA:
- {
- uint32_t data[PAYLOAD_ARG_CNT] = { 0 };
-
- ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2],
- pm_arg[3], data, security_flag);
-
- SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32U),
- (uint64_t)data[1] | ((uint64_t)data[2] << 32U));
- }
-
case (uint32_t)PM_FEATURE_CHECK:
{
uint32_t result[PAYLOAD_ARG_CNT] = {0U};