mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
1721 lines
49 KiB
Diff
1721 lines
49 KiB
Diff
diff --git a/docs/plat/rockchip.rst b/docs/plat/rockchip.rst
|
|
index b7c43fb..30c1945 100644
|
|
--- a/docs/plat/rockchip.rst
|
|
+++ b/docs/plat/rockchip.rst
|
|
@@ -5,6 +5,7 @@
|
|
AARCH32 and AARCH64 fields.
|
|
|
|
This includes right now:
|
|
+- rk3568: Quad-Core Cortex-a55
|
|
- px30: Quad-Core Cortex-A53
|
|
- rk3288: Quad-Core Cortex-A17 (past A12)
|
|
- rk3328: Quad-Core Cortex-A53
|
|
diff --git a/include/lib/cpus/aarch64/cortex_a55.h b/include/lib/cpus/aarch64/cortex_a55.h
|
|
index 60ed957..276d5c2 100644
|
|
--- a/include/lib/cpus/aarch64/cortex_a55.h
|
|
+++ b/include/lib/cpus/aarch64/cortex_a55.h
|
|
@@ -18,6 +18,9 @@
|
|
#define CORTEX_A55_CPUPWRCTLR_EL1 S3_0_C15_C2_7
|
|
#define CORTEX_A55_CPUECTLR_EL1 S3_0_C15_C1_4
|
|
|
|
+#define CORTEX_A55_CLUSTERPWRCTLR_EL1 S3_0_C15_C3_5
|
|
+#define CORTEX_A55_CLUSTERPWRDN_EL1 S3_0_C15_C3_6
|
|
+
|
|
#define CORTEX_A55_CPUECTLR_EL1_L1WSCTL (ULL(3) << 25)
|
|
|
|
/*******************************************************************************
|
|
@@ -44,5 +47,9 @@
|
|
#define CPUPCR_EL3 S3_6_C15_C8_1
|
|
#define CPUPOR_EL3 S3_6_C15_C8_2
|
|
#define CPUPMR_EL3 S3_6_C15_C8_3
|
|
-
|
|
+#ifndef __ASSEMBLER__
|
|
+#include <stdint.h>
|
|
+void cortex_a55_core_pwr_dwn(void);
|
|
+void cortex_a55_dsu_pwr_dwn(void);
|
|
+#endif /* __ASSEMBLER__ */
|
|
#endif /* CORTEX_A55_H */
|
|
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
|
|
index 0e0388b..a97e045 100644
|
|
--- a/lib/cpus/aarch64/cortex_a55.S
|
|
+++ b/lib/cpus/aarch64/cortex_a55.S
|
|
@@ -18,6 +18,7 @@
|
|
|
|
.globl cortex_a55_reset_func
|
|
.globl cortex_a55_core_pwr_dwn
|
|
+ .globl cortex_a55_dsu_pwr_dwn
|
|
/* --------------------------------------------------
|
|
* Errata Workaround for Cortex A55 Errata #768277.
|
|
* This applies only to revision r0p0 of Cortex A55.
|
|
@@ -301,6 +302,13 @@
|
|
ret
|
|
endfunc cortex_a55_core_pwr_dwn
|
|
|
|
+func cortex_a55_dsu_pwr_dwn
|
|
+ mov x1, #0x00
|
|
+ msr CORTEX_A55_CLUSTERPWRCTLR_EL1, x0
|
|
+ isb
|
|
+ ret
|
|
+endfunc cortex_a55_dsu_pwr_dwn
|
|
+
|
|
#if REPORT_ERRATA
|
|
/*
|
|
* Errata printing function for Cortex A55. Must follow AAPCS & can use stack.
|
|
diff --git a/plat/rockchip/common/aarch32/platform_common.c b/plat/rockchip/common/aarch32/platform_common.c
|
|
index 9030951..dbbff46 100644
|
|
--- a/plat/rockchip/common/aarch32/platform_common.c
|
|
+++ b/plat/rockchip/common/aarch32/platform_common.c
|
|
@@ -12,7 +12,6 @@
|
|
#include <common/bl_common.h>
|
|
#include <common/debug.h>
|
|
#include <lib/utils.h>
|
|
-#include <lib/xlat_tables/xlat_tables.h>
|
|
|
|
#include <plat_private.h>
|
|
|
|
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
|
|
index c4c0dec..4d8a209 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-2022, 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..8931abe 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-2022, 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
|
|
@@ -28,6 +26,7 @@
|
|
* Macro generating the code for the function setting up the pagetables as per
|
|
* the platform memory map & initialize the mmu, for the given exception level
|
|
******************************************************************************/
|
|
+#if USE_COHERENT_MEM
|
|
#define DEFINE_CONFIGURE_MMU_EL(_el) \
|
|
void plat_configure_mmu_el ## _el(unsigned long total_base, \
|
|
unsigned long total_size, \
|
|
@@ -51,6 +50,25 @@
|
|
\
|
|
enable_mmu_el ## _el(0); \
|
|
}
|
|
+#else
|
|
+#define DEFINE_CONFIGURE_MMU_EL(_el) \
|
|
+ void plat_configure_mmu_el ## _el(unsigned long total_base, \
|
|
+ unsigned long total_size, \
|
|
+ unsigned long ro_start, \
|
|
+ unsigned long ro_limit) \
|
|
+ { \
|
|
+ mmap_add_region(total_base, total_base, \
|
|
+ total_size, \
|
|
+ MT_MEMORY | MT_RW | MT_SECURE); \
|
|
+ mmap_add_region(ro_start, ro_start, \
|
|
+ ro_limit - ro_start, \
|
|
+ MT_MEMORY | MT_RO | MT_SECURE); \
|
|
+ mmap_add(plat_rk_mmap); \
|
|
+ rockchip_plat_mmu_el##_el(); \
|
|
+ init_xlat_tables(); \
|
|
+ enable_mmu_el ## _el(0); \
|
|
+ }
|
|
+#endif
|
|
|
|
/* Define EL3 variants of the function initialising the MMU */
|
|
DEFINE_CONFIGURE_MMU_EL(3)
|
|
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
|
|
index 98ef415..a720b91 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-2022, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
@@ -93,10 +93,17 @@
|
|
{
|
|
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);
|
|
+#endif
|
|
}
|
|
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
|
|
index 990d106..027295e 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-2022, 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_v2.h>
|
|
#include <plat_params.h>
|
|
|
|
#define __sramdata __attribute__((section(".sram.data")))
|
|
@@ -61,12 +61,19 @@
|
|
* Function and variable prototypes
|
|
*****************************************************************************/
|
|
#ifdef __aarch64__
|
|
+#if USE_COHERENT_MEM
|
|
void plat_configure_mmu_el3(unsigned long total_base,
|
|
unsigned long total_size,
|
|
unsigned long,
|
|
unsigned long,
|
|
unsigned long,
|
|
unsigned long);
|
|
+#else
|
|
+void plat_configure_mmu_el3(unsigned long total_base,
|
|
+ unsigned long total_size,
|
|
+ unsigned long,
|
|
+ unsigned long);
|
|
+#endif
|
|
|
|
void rockchip_plat_mmu_el3(void);
|
|
#else
|
|
@@ -135,7 +142,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..3652451
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/drivers/pmu/plat_pmu_macros.S
|
|
@@ -0,0 +1,17 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
|
|
+ *
|
|
+ * SPDX-License-Identifier: BSD-3-Clause
|
|
+ */
|
|
+
|
|
+#include <asm_macros.S>
|
|
+#include <arch.h>
|
|
+#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..cc94b13
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.c
|
|
@@ -0,0 +1,535 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
|
|
+ *
|
|
+ * SPDX-License-Identifier: BSD-3-Clause
|
|
+ */
|
|
+
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+#include <bakery_lock.h>
|
|
+#include <cortex_a55.h>
|
|
+#include <mmio.h>
|
|
+#include <platform.h>
|
|
+#include <pmu.h>
|
|
+#include <cpus_on_fixed_addr.h>
|
|
+#include <plat_private.h>
|
|
+#include <platform_def.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)
|
|
+
|
|
+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)));
|
|
+ cortex_a55_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));
|
|
+ cortex_a55_core_pwr_dwn();
|
|
+ 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();
|
|
+ cortex_a55_core_pwr_dwn();
|
|
+ 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;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Cortex-a55
|
|
+ * Debug Power/Reset Control Register(DBGPRCR_EL1)
|
|
+ *
|
|
+ * CORENPDRQ, bit[0]
|
|
+ * Core no powerdown request. Requests emulation of powerdown. Possible values
|
|
+ * of this bit are:
|
|
+ * 0: On a powerdown request, the system powers down the Core power domain
|
|
+ * 1: On a powerdown request, the system emulates powerdown of the Core power domain.
|
|
+ *
|
|
+ * In this emulation mode the Core power domain is not actually powered down.
|
|
+ * On Cold reset, the field resets to the value of EDPRCR.COREPURQ.
|
|
+ *
|
|
+ * S3_0_C15_C2_7: CORTEX_A55_CPUPWRCTLR_EL1.
|
|
+ */
|
|
+static inline void core_dbgprcr_pwrdown_wfi(void)
|
|
+{
|
|
+ __asm__ volatile (
|
|
+ "msr DBGPRCR_EL1, xzr\n"
|
|
+ "mrs x0, S3_0_C15_C2_7\n"
|
|
+ "orr x0, x0, #0x1\n"
|
|
+ "msr S3_0_C15_C2_7, x0\n"
|
|
+ "wfi_loop:\n"
|
|
+ "isb\n"
|
|
+ "wfi\n"
|
|
+ "b wfi_loop\n");
|
|
+}
|
|
+
|
|
+static void cpus_pd_req_enter_wfi(void)
|
|
+{
|
|
+ core_dbgprcr_pwrdown_wfi();
|
|
+}
|
|
+
|
|
+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)&cpus_pd_req_enter_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..4c6f73a
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/drivers/pmu/pmu.h
|
|
@@ -0,0 +1,304 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..23f65b2
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/drivers/soc/soc.c
|
|
@@ -0,0 +1,101 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..45d1e9a
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/drivers/soc/soc.h
|
|
@@ -0,0 +1,63 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..dbad83a
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/include/plat.ld.S
|
|
@@ -0,0 +1,36 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..10fd0e7
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/include/plat_sip_calls.h
|
|
@@ -0,0 +1,12 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..a1a60da
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/include/platform_def.h
|
|
@@ -0,0 +1,136 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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..3eb1821
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/plat_sip_calls.c
|
|
@@ -0,0 +1,27 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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 <plat_sip_calls.h>
|
|
+#include <platform_def.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..33769dd
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/platform.mk
|
|
@@ -0,0 +1,86 @@
|
|
+#
|
|
+# Copyright (c) 2022, 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
|
|
+
|
|
+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
|
|
+
|
|
+ENABLE_PLAT_COMPAT := 0
|
|
+MULTI_CONSOLE_API := 1
|
|
+# System coherency is managed in hardware
|
|
+HW_ASSISTED_COHERENCY := 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))
|
|
diff --git a/plat/rockchip/rk3568/rk3568_def.h b/plat/rockchip/rk3568/rk3568_def.h
|
|
new file mode 100644
|
|
index 0000000..e28c51c
|
|
--- /dev/null
|
|
+++ b/plat/rockchip/rk3568/rk3568_def.h
|
|
@@ -0,0 +1,104 @@
|
|
+/*
|
|
+ * Copyright (c) 2022, 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__ */
|