diff options
author | Caesar Wang <wxt@rock-chips.com> | 2016-04-10 14:11:07 +0800 |
---|---|---|
committer | Caesar Wang <wxt@rock-chips.com> | 2016-05-04 19:39:21 +0800 |
commit | f47a25ddd876738c7b078efc002a48c53e48d7c0 (patch) | |
tree | 40ca9db40892e669759d446ff52d2c06005297a6 /plat | |
parent | 32d4f826875a49fe1c4632aa71d1c04372b386aa (diff) |
rockchip: support the suspend/resume for rk3399
This patch adds to support the suspend/resume for rk3399 SoCs.
Signed-off-by: Shengfei xu <xsf@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Diffstat (limited to 'plat')
-rw-r--r-- | plat/rockchip/common/aarch64/plat_helpers.S | 20 | ||||
-rw-r--r-- | plat/rockchip/common/drivers/pmu/pmu_com.h | 10 | ||||
-rw-r--r-- | plat/rockchip/common/include/plat_private.h | 4 | ||||
-rw-r--r-- | plat/rockchip/common/plat_pm.c | 3 | ||||
-rw-r--r-- | plat/rockchip/common/pmusram/pmu_sram.h | 14 | ||||
-rw-r--r-- | plat/rockchip/common/pmusram/pmu_sram_cpus_on.S | 7 | ||||
-rw-r--r-- | plat/rockchip/rk3368/drivers/pmu/pmu.c | 24 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/pmu/pmu.c | 145 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/pmu/pmu.h | 110 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/soc/soc.c | 14 | ||||
-rw-r--r-- | plat/rockchip/rk3399/drivers/soc/soc.h | 28 | ||||
-rw-r--r-- | plat/rockchip/rk3399/rk3399_def.h | 3 |
12 files changed, 305 insertions, 77 deletions
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S index a90dcd7e..1bbb6145 100644 --- a/plat/rockchip/common/aarch64/plat_helpers.S +++ b/plat/rockchip/common/aarch64/plat_helpers.S @@ -189,6 +189,7 @@ endfunc plat_crash_console_putc * cpus online or resume enterpoint * -------------------------------------------------------------------- */ + .align 16 func platform_cpu_warmboot mrs x0, MPIDR_EL1 and x1, x0, #MPIDR_CPU_MASK @@ -207,12 +208,6 @@ func platform_cpu_warmboot add x4, x4, x0, lsl #2 ldr w1, [x4] /* -------------------------------------------------------------------- - * get per cpuup boot addr - * -------------------------------------------------------------------- - */ - adr x5, cpuson_entry_point - ldr x2, [x5, x0, lsl #3] - /* -------------------------------------------------------------------- * check cpuon reason * -------------------------------------------------------------------- */ @@ -231,8 +226,15 @@ wfe_loop: wfe b wfe_loop boot_entry: - mov w0, #0 - str w0, [x4] + mov w1, #0 + str w1, [x4] + /* -------------------------------------------------------------------- + * get per cpuup boot addr + * -------------------------------------------------------------------- + */ + adr x5, cpuson_entry_point + ldr x2, [x5, x0, lsl #3] + br x2 endfunc platform_cpu_warmboot @@ -248,5 +250,5 @@ cpuson_entry_point: .endr cpuson_flags: .rept PLATFORM_CORE_COUNT - .quad 0 + .word 0 .endr diff --git a/plat/rockchip/common/drivers/pmu/pmu_com.h b/plat/rockchip/common/drivers/pmu/pmu_com.h index 0cab53c9..4cffb614 100644 --- a/plat/rockchip/common/drivers/pmu/pmu_com.h +++ b/plat/rockchip/common/drivers/pmu/pmu_com.h @@ -27,13 +27,19 @@ #ifndef __PMU_COM_H__ #define __PMU_COM_H__ +/* + * Use this macro to instantiate lock before it is used in below + * rockchip_pd_lock_xxx() macros + */ DEFINE_BAKERY_LOCK(rockchip_pd_lock); +/* + * 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) -#define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock) /***************************************************************************** * power domain on or off *****************************************************************************/ diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h index 67fb8276..e05bda41 100644 --- a/plat/rockchip/common/include/plat_private.h +++ b/plat/rockchip/common/include/plat_private.h @@ -77,7 +77,7 @@ struct rockchip_pm_ops_cb { #endif #ifndef BITS_WITH_WMASK -#define BITS_WITH_WMASK(msk, bits, shift)\ +#define BITS_WITH_WMASK(bits, msk, shift)\ (BITS_SHIFT(bits, shift) | BITS_SHIFT(msk, (shift + REG_MSK_SHIFT))) #endif @@ -108,6 +108,8 @@ void plat_rockchip_pmu_init(void); void plat_rockchip_soc_init(void); void plat_setup_rockchip_pm_ops(struct rockchip_pm_ops_cb *ops); +void platform_cpu_warmboot(void); + extern const unsigned char rockchip_power_domain_tree_desc[]; extern void *pmu_cpuson_entrypoint_start; diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index fcd47a8c..43558b65 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -52,7 +52,6 @@ static struct rockchip_pm_ops_cb *rockchip_ops; static void plat_rockchip_sys_pwr_domain_resume(void) { - plat_rockchip_gic_init(); if (rockchip_ops && rockchip_ops->sys_pwr_dm_resume) rockchip_ops->sys_pwr_dm_resume(); } @@ -62,8 +61,6 @@ static void plat_rockchip_cores_pwr_domain_resume(void) if (rockchip_ops && rockchip_ops->cores_pwr_dm_resume) rockchip_ops->cores_pwr_dm_resume(); - /* Enable the gic cpu interface */ - plat_rockchip_gic_pcpu_init(); /* Program the gic per-cpu distributor or re-distributor interface */ plat_rockchip_gic_cpuif_enable(); } diff --git a/plat/rockchip/common/pmusram/pmu_sram.h b/plat/rockchip/common/pmusram/pmu_sram.h index a2ab460b..f2904612 100644 --- a/plat/rockchip/common/pmusram/pmu_sram.h +++ b/plat/rockchip/common/pmusram/pmu_sram.h @@ -27,21 +27,14 @@ #define __PMU_SRAM_H__ /***************************************************************************** - * cpu up status - *****************************************************************************/ -#define PMU_SYS_SLP_MODE 0xa5 -#define PMU_SYS_ON_MODE 0x0 - -/***************************************************************************** * define data offset in struct psram_data *****************************************************************************/ #define PSRAM_DT_SP 0x0 #define PSRAM_DT_DDR_FUNC 0x8 #define PSRAM_DT_DDR_DATA 0x10 #define PSRAM_DT_DDRFLAG 0x18 -#define PSRAM_DT_SYS_MODE 0x1c -#define PSRAM_DT_MPIDR 0x20 -#define PSRAM_DT_END 0x24 +#define PSRAM_DT_MPIDR 0x1c +#define PSRAM_DT_END 0x20 /****************************************************************************** * Allocate data region for struct psram_data_t in pmusram ******************************************************************************/ @@ -67,7 +60,6 @@ struct psram_data_t { uint64_t ddr_func; uint64_t ddr_data; uint32_t ddr_flag; - uint32_t sys_mode; uint32_t boot_mpidr; }; @@ -81,8 +73,6 @@ CASSERT(__builtin_offsetof(struct psram_data_t, ddr_data) == PSRAM_DT_DDR_DATA, assert_psram_dt_ddr_data_offset_mistmatch); CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG, assert_psram_dt_ddr_flag_offset_mistmatch); -CASSERT(__builtin_offsetof(struct psram_data_t, sys_mode) == PSRAM_DT_SYS_MODE, - assert_psram_dt_sys_mode_offset_mistmatch); CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR, assert_psram_dt_mpidr_offset_mistmatch); void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes); diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S index 33a4646d..9f94b0c1 100644 --- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S +++ b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S @@ -35,11 +35,6 @@ func pmu_cpuson_entrypoint pmu_cpuson_entrypoint_start: ldr x5, psram_data - ldr w0, [x5, #PSRAM_DT_SYS_MODE] - cmp w0, #PMU_SYS_SLP_MODE - b.eq check_wake_cpus - ldr x6, warm_boot_func - br x6 check_wake_cpus: mrs x0, MPIDR_EL1 and x1, x0, #MPIDR_CPU_MASK @@ -74,8 +69,6 @@ sys_resume: .align 3 psram_data: .quad PSRAM_DT_BASE -warm_boot_func: - .quad platform_cpu_warmboot sys_wakeup_entry: .quad psci_entrypoint pmu_cpuson_entrypoint_end: diff --git a/plat/rockchip/rk3368/drivers/pmu/pmu.c b/plat/rockchip/rk3368/drivers/pmu/pmu.c index e9906348..50e2bf87 100644 --- a/plat/rockchip/rk3368/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3368/drivers/pmu/pmu.c @@ -43,6 +43,8 @@ static struct psram_data_t *psram_sleep_cfg = (struct psram_data_t *)PSRAM_DT_BASE; +static uint32_t cpu_warm_boot_addr; + void rk3368_flash_l2_b(void) { uint32_t wait_cnt = 0; @@ -353,7 +355,7 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) /* Switch boot addr to pmusram */ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster), - (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | + (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); dsb(); @@ -368,19 +370,17 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) static int cores_pwr_domain_on_finish(void) { - uint32_t cpuon_id; - - cpuon_id = plat_my_core_pos(); - assert(cpuson_flags[cpuon_id] == 0); - cpuson_flags[cpuon_id] = 0x00; - return 0; } static int sys_pwr_domain_resume(void) { - psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE; - + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), + (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) | + CPU_BOOT_ADDR_WMASK); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(2), + (COLD_BOOT_BASE >> CPU_BOOT_ADDR_ALIGN) | + CPU_BOOT_ADDR_WMASK); pm_plls_resume(); pmu_scu_b_pwrup(); @@ -392,7 +392,6 @@ static int sys_pwr_domain_suspend(void) nonboot_cpus_off(); pmu_set_sleep_mode(); - psram_sleep_cfg->sys_mode = PMU_SYS_SLP_MODE; psram_sleep_cfg->ddr_flag = 0; return 0; @@ -412,11 +411,12 @@ void plat_rockchip_pmu_init(void) plat_setup_rockchip_pm_ops(&pm_ops); + /* register requires 32bits mode, switch it to 32 bits */ + cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot; + for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) cpuson_flags[cpu] = 0; - psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE; - psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; nonboot_cpus_off(); diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 351de7df..1493a4dd 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -47,6 +47,8 @@ static struct psram_data_t *psram_sleep_cfg = (struct psram_data_t *)PSRAM_DT_BASE; +static uint32_t cpu_warm_boot_addr; + /* * There are two ways to powering on or off on core. * 1) Control it power domain into on or off in PMU_PWRDN_CON reg, @@ -63,6 +65,53 @@ __attribute__ ((section("tzfw_coherent_mem"))) #endif ;/* coheront */ +void rk3399_flash_l2_b(void) +{ + uint32_t wait_cnt = 0; + + mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(L2_FLUSH_REQ_CLUSTER_B)); + dsb(); + + while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & + BIT(L2_FLUSHDONE_CLUSTER_B))) { + wait_cnt++; + if (!(wait_cnt % MAX_WAIT_CONUT)) + WARN("%s:reg %x,wait\n", __func__, + mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)); + } + + mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(L2_FLUSH_REQ_CLUSTER_B)); +} + +static void pmu_scu_b_pwrdn(void) +{ + uint32_t wait_cnt = 0; + + if ((mmio_read_32(PMU_BASE + PMU_PWRDN_ST) & + (BIT(PMU_A72_B0_PWRDWN_ST) | BIT(PMU_A72_B1_PWRDWN_ST))) != + (BIT(PMU_A72_B0_PWRDWN_ST) | BIT(PMU_A72_B1_PWRDWN_ST))) { + ERROR("%s: not all cpus is off\n", __func__); + return; + } + + rk3399_flash_l2_b(); + + mmio_setbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG)); + + while (!(mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST) & + BIT(STANDBY_BY_WFIL2_CLUSTER_B))) { + wait_cnt++; + if (!(wait_cnt % MAX_WAIT_CONUT)) + ERROR("%s:wait cluster-b l2(%x)\n", __func__, + mmio_read_32(PMU_BASE + PMU_CORE_PWR_ST)); + } +} + +static void pmu_scu_b_pwrup(void) +{ + mmio_clrbits_32(PMU_BASE + PMU_SFT_CON, BIT(ACINACTM_CLUSTER_B_CFG)); +} + void plat_rockchip_pmusram_prepare(void) { uint32_t *sram_dst, *sram_src; @@ -128,6 +177,7 @@ static int cpus_power_domain_on(uint32_t cpu_id) mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), BIT(core_pm_sft_wakeup_en)); + dsb(); } return 0; @@ -160,6 +210,7 @@ static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg) core_pm_value |= BIT(core_pm_int_wakeup_en); mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), core_pm_value); + dsb(); } return 0; @@ -220,9 +271,6 @@ static int cores_pwr_domain_on_finish(void) { uint32_t cpu_id = plat_my_core_pos(); - cpuson_flags[cpu_id] = 0; - cpuson_entry_point[cpu_id] = 0; - /* Disable core_pm */ mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); @@ -233,9 +281,6 @@ static int cores_pwr_domain_resume(void) { uint32_t cpu_id = plat_my_core_pos(); - cpuson_flags[cpu_id] = 0; - cpuson_entry_point[cpu_id] = 0; - /* Disable core_pm */ mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); @@ -246,33 +291,92 @@ static void sys_slp_config(void) { uint32_t slp_mode_cfg = 0; - slp_mode_cfg = PMU_PWR_MODE_EN | - PMU_CPU0_PD_EN | - PMU_L2_FLUSH_EN | - PMU_L2_IDLE_EN | - PMU_SCU_PD_EN | - PMU_CLK_CORE_SRC_GATE_EN; + mmio_write_32(PMU_BASE + PMU_CCI500_CON, + BIT_WITH_WMSK(PMU_CLR_PREQ_CCI500_HW) | + BIT_WITH_WMSK(PMU_CLR_QREQ_CCI500_HW) | + BIT_WITH_WMSK(PMU_QGATING_CCI500_CFG)); + + mmio_write_32(PMU_BASE + PMU_ADB400_CON, + BIT_WITH_WMSK(PMU_CLR_CORE_L_HW) | + BIT_WITH_WMSK(PMU_CLR_CORE_L_2GIC_HW) | + BIT_WITH_WMSK(PMU_CLR_GIC2_CORE_L_HW)); + + mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1A_IOMUX, + BIT_WITH_WMSK(AP_PWROFF)); + + slp_mode_cfg = BIT(PMU_PWR_MODE_EN) | + BIT(PMU_POWER_OFF_REQ_CFG) | + BIT(PMU_CPU0_PD_EN) | + BIT(PMU_L2_FLUSH_EN) | + BIT(PMU_L2_IDLE_EN) | + BIT(PMU_SCU_PD_EN); + mmio_setbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_CLUSTER_L_WKUP_EN); mmio_setbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_CLUSTER_B_WKUP_EN); mmio_clrbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_GPIO_WKUP_EN); + mmio_write_32(PMU_BASE + PMU_PWRMODE_CON, slp_mode_cfg); + + mmio_write_32(PMU_BASE + PMU_STABLE_CNT, CYCL_24M_CNT_MS(5)); + mmio_write_32(PMU_BASE + PMU_SCU_L_PWRDN_CNT, CYCL_24M_CNT_MS(2)); + mmio_write_32(PMU_BASE + PMU_SCU_L_PWRUP_CNT, CYCL_24M_CNT_MS(2)); + mmio_write_32(PMU_BASE + PMU_SCU_B_PWRDN_CNT, CYCL_24M_CNT_MS(2)); + mmio_write_32(PMU_BASE + PMU_SCU_B_PWRUP_CNT, CYCL_24M_CNT_MS(2)); } static int sys_pwr_domain_suspend(void) { sys_slp_config(); plls_suspend(); - psram_sleep_cfg->sys_mode = PMU_SYS_SLP_MODE; pmu_sgrf_rst_hld(); + + mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), + (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | + CPU_BOOT_ADDR_WMASK); + + pmu_scu_b_pwrdn(); + + mmio_write_32(PMU_BASE + PMU_ADB400_CON, + BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | + BIT_WITH_WMSK(PMU_PWRDWN_REQ_CORE_B_SW) | + BIT_WITH_WMSK(PMU_PWRDWN_REQ_GIC2_CORE_B_SW)); + dsb(); + mmio_setbits_32(PMU_BASE + PMU_PWRDN_CON, BIT(PMU_SCU_B_PWRDWN_EN)); + return 0; } static int sys_pwr_domain_resume(void) { - pmu_sgrf_rst_hld_release(); - psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE; + pmu_sgrf_rst_hld(); + + mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), + (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | + CPU_BOOT_ADDR_WMASK); + plls_resume(); + mmio_write_32(PMU_BASE + PMU_CCI500_CON, + WMSK_BIT(PMU_CLR_PREQ_CCI500_HW) | + WMSK_BIT(PMU_CLR_QREQ_CCI500_HW) | + WMSK_BIT(PMU_QGATING_CCI500_CFG)); + + mmio_write_32(PMU_BASE + PMU_ADB400_CON, + WMSK_BIT(PMU_CLR_CORE_L_HW) | + WMSK_BIT(PMU_CLR_CORE_L_2GIC_HW) | + WMSK_BIT(PMU_CLR_GIC2_CORE_L_HW)); + + mmio_clrbits_32(PMU_BASE + PMU_PWRDN_CON, + BIT(PMU_SCU_B_PWRDWN_EN)); + + mmio_write_32(PMU_BASE + PMU_ADB400_CON, + WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | + WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_SW) | + WMSK_BIT(PMU_PWRDWN_REQ_GIC2_CORE_B_SW)); + + pmu_scu_b_pwrup(); + + plat_rockchip_gic_cpuif_enable(); return 0; } @@ -294,19 +398,24 @@ void plat_rockchip_pmu_init(void) rockchip_pd_lock_init(); plat_setup_rockchip_pm_ops(&pm_ops); + /* register requires 32bits mode, switch it to 32 bits */ + cpu_warm_boot_addr = (uint64_t)platform_cpu_warmboot; + for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) cpuson_flags[cpu] = 0; - psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE; - + psram_sleep_cfg->ddr_func = 0x00; + psram_sleep_cfg->ddr_data = 0x00; + psram_sleep_cfg->ddr_flag = 0x00; psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; /* cpu boot from pmusram */ mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), - (PMUSRAM_BASE >> CPU_BOOT_ADDR_ALIGN) | + (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); nonboot_cpus_off(); + INFO("%s(%d): pd status %x\n", __func__, __LINE__, mmio_read_32(PMU_BASE + PMU_PWRDN_ST)); } diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.h b/plat/rockchip/rk3399/drivers/pmu/pmu.h index 053b6ee5..d5ff8ce0 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.h +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h @@ -341,6 +341,25 @@ enum pmu_sft_con { PMU_DDRCTL1_C_SYSREQ_CFG = 12, PMU_DDR1_IO_RET_CFG, + DBG_PWRUP_B0_CFG = 15, + + DBG_NOPWERDWN_L0_EN, + DBG_NOPWERDWN_L1_EN, + DBG_NOPWERDWN_L2_EN, + DBG_NOPWERDWN_L3_EN, + + DBG_PWRUP_REQ_L_EN = 20, + CLUSTER_L_CLK_SRC_GATING_CFG, + L2_FLUSH_REQ_CLUSTER_L, + ACINACTM_CLUSTER_L_CFG, + + DBG_NO_PWERDWN_B0_EN, + DBG_NO_PWERDWN_B1_EN, + + DBG_PWRUP_REQ_B_EN = 28, + CLUSTER_B_CLK_SRC_GATING_CFG, + L2_FLUSH_REQ_CLUSTER_B, + ACINACTM_CLUSTER_B_CFG, }; enum pmu_int_con { @@ -638,12 +657,100 @@ enum pmu_bus_idle_ack { PMU_IDLE_ACK_SDIOAUDIO, }; +enum pmu_cci500_con { + PMU_PREQ_CCI500_CFG_SW = 0, + PMU_CLR_PREQ_CCI500_HW, + PMU_PSTATE_CCI500_0, + PMU_PSTATE_CCI500_1, + + PMU_PSTATE_CCI500_2, + PMU_QREQ_CCI500_CFG_SW, + PMU_CLR_QREQ_CCI500_HW, + PMU_QGATING_CCI500_CFG, + + PMU_PREQ_CCI500_CFG_SW_WMSK = 16, + PMU_CLR_PREQ_CCI500_HW_WMSK, + PMU_PSTATE_CCI500_0_WMSK, + PMU_PSTATE_CCI500_1_WMSK, + + PMU_PSTATE_CCI500_2_WMSK, + PMU_QREQ_CCI500_CFG_SW_WMSK, + PMU_CLR_QREQ_CCI500_HW_WMSK, + PMU_QGATING_CCI500_CFG_WMSK, +}; + +enum pmu_adb400_con { + PMU_PWRDWN_REQ_CXCS_SW = 0, + PMU_PWRDWN_REQ_CORE_L_SW, + PMU_PWRDWN_REQ_CORE_L_2GIC_SW, + PMU_PWRDWN_REQ_GIC2_CORE_L_SW, + + PMU_PWRDWN_REQ_CORE_B_SW, + PMU_PWRDWN_REQ_CORE_B_2GIC_SW, + PMU_PWRDWN_REQ_GIC2_CORE_B_SW, + + PMU_CLR_CXCS_HW = 8, + PMU_CLR_CORE_L_HW, + PMU_CLR_CORE_L_2GIC_HW, + PMU_CLR_GIC2_CORE_L_HW, + + PMU_CLR_CORE_B_HW, + PMU_CLR_CORE_B_2GIC_HW, + PMU_CLR_GIC2_CORE_B_HW, + + PMU_PWRDWN_REQ_CXCS_SW_WMSK = 16, + PMU_PWRDWN_REQ_CORE_L_SW_WMSK, + PMU_PWRDWN_REQ_CORE_L_2GIC_SW_WMSK, + PMU_PWRDWN_REQ_GIC2_CORE_L_SW_WMSK, + + PMU_PWRDWN_REQ_CORE_B_SW_WMSK, + PMU_PWRDWN_REQ_CORE_B_2GIC_SW_WMSK, + PMU_PWRDWN_REQ_GIC2_CORE_B_SW_WMSK, + + PMU_CLR_CXCS_HW_WMSK = 24, + PMU_CLR_CORE_L_HW_WMSK, + PMU_CLR_CORE_L_2GIC_HW_WMSK, + PMU_CLR_GIC2_CORE_L_HW_WMSK, + + PMU_CLR_CORE_B_HW_WMSK, + PMU_CLR_CORE_B_2GIC_HW_WMSK, + PMU_CLR_GIC2_CORE_B_HW_WMSK, +}; + +enum pmu_adb400_st { + PMU_PWRDWN_REQ_CXCS_SW_ST = 0, + PMU_PWRDWN_REQ_CORE_L_SW_ST, + PMU_PWRDWN_REQ_CORE_L_2GIC_SW_ST, + PMU_PWRDWN_REQ_GIC2_CORE_L_SW_ST, + + PMU_PWRDWN_REQ_CORE_B_SW_ST, + PMU_PWRDWN_REQ_CORE_B_2GIC_SW_ST, + PMU_PWRDWN_REQ_GIC2_CORE_B_SW_ST, + + PMU_CLR_CXCS_HW_ST = 8, + PMU_CLR_CORE_L_HW_ST, + PMU_CLR_CORE_L_2GIC_HW_ST, + PMU_CLR_GIC2_CORE_L_HW_ST, + + PMU_CLR_CORE_B_HW_ST, + PMU_CLR_CORE_B_2GIC_HW_ST, + PMU_CLR_GIC2_CORE_B_HW_ST, +}; + enum pmu_pwrdn_con1 { PMU_VD_SCU_L_PWRDN_EN = 0, PMU_VD_SCU_B_PWRDN_EN, PMU_VD_CENTER_PWRDN_EN, }; +enum pmu_core_pwr_st { + L2_FLUSHDONE_CLUSTER_L = 0, + STANDBY_BY_WFIL2_CLUSTER_L, + + L2_FLUSHDONE_CLUSTER_B = 10, + STANDBY_BY_WFIL2_CLUSTER_B, +}; + #define PMU_WKUP_CFG0 0x00 #define PMU_WKUP_CFG1 0x04 #define PMU_WKUP_CFG2 0x08 @@ -701,9 +808,12 @@ enum pmu_pwrdn_con1 { #define PMU_NOC_AUTO_ENA 0xd8 #define PMU_PWRDN_CON1 0xdc +#define PMUGRF_GPIO1A_IOMUX 0x10 +#define AP_PWROFF 0x0a #define CORES_PM_DISABLE 0x0 #define PD_CTR_LOOP 500 #define CHK_CPU_LOOP 500 +#define MAX_WAIT_CONUT 1000 #endif /* __PMU_H__ */ diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index f8d66c2c..5b7613d7 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -55,6 +55,9 @@ const mmap_region_t plat_rk_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(RK3399_UART2_BASE, RK3399_UART2_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(PMUGRF_BASE, PMUGRF_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), + { 0 } }; @@ -313,12 +316,13 @@ void soc_global_soft_reset_init(void) { mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), CRU_PMU_SGRF_RST_RLS); + + mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON, + CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK); } void __dead2 soc_global_soft_reset(void) { - uint32_t temp_val; - set_pll_slow_mode(VPLL_ID); set_pll_slow_mode(NPLL_ID); set_pll_slow_mode(GPLL_ID); @@ -326,9 +330,9 @@ void __dead2 soc_global_soft_reset(void) set_pll_slow_mode(PPLL_ID); set_pll_slow_mode(ABPLL_ID); set_pll_slow_mode(ALPLL_ID); - temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON) | - PMU_RST_BY_FIRST_SFT; - mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val); + + dsb(); + mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL); /* diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h index 9100d02b..e48f2f03 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.h +++ b/plat/rockchip/rk3399/drivers/soc/soc.h @@ -52,14 +52,16 @@ #define NO_PLL_BYPASS (0x00) #define NO_PLL_PWRDN (0x00) -#define PLL_SLOW_MODE BITS_WITH_WMASK(PLL_MODE_MSK,\ - SLOW_MODE, PLL_MODE_SHIFT) -#define PLL_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS_MSK,\ - PLL_BYPASS, PLL_BYPASS_SHIFT) -#define PLL_NO_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS_MSK,\ - NO_PLL_BYPASS, PLL_BYPASS_SHIFT) -#define PLL_NOMAL_MODE BITS_WITH_WMASK(PLL_MODE_MSK,\ - NORMAL_MODE, PLL_MODE_SHIFT) +#define PLL_SLOW_MODE BITS_WITH_WMASK(SLOW_MODE,\ + PLL_MODE_MSK, PLL_MODE_SHIFT) +#define PLL_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS,\ + PLL_BYPASS_MSK,\ + PLL_BYPASS_SHIFT) +#define PLL_NO_BYPASS_MODE BITS_WITH_WMASK(NO_PLL_BYPASS,\ + PLL_BYPASS_MSK,\ + PLL_BYPASS_SHIFT) +#define PLL_NOMAL_MODE BITS_WITH_WMASK(NORMAL_MODE,\ + PLL_MODE_MSK, PLL_MODE_SHIFT) #define PLL_CON_COUNT 0x06 #define CRU_CLKSEL_COUNT 0x108 @@ -100,6 +102,9 @@ struct deepsleep_data_s { uint32_t cru_clksel_con[CRU_CLKSEL_COUNT]; }; +#define CYCL_24M_CNT_US(us) (24 * us) +#define CYCL_24M_CNT_MS(ms) (ms * CYCL_24M_CNT_US(1000)) + /************************************************** * secure timer **************************************************/ @@ -155,6 +160,13 @@ struct deepsleep_data_s { #define CRU_PMU_SGRF_RST_HOLD BIT_WITH_WMSK(6) /* reset hold release*/ #define CRU_PMU_SGRF_RST_RLS WMSK_BIT(6) + +#define CRU_PMU_WDTRST_MSK (0x1 << 4) +#define CRU_PMU_WDTRST_EN 0x0 + +#define CRU_PMU_FIRST_SFTRST_MSK (0x3 << 2) +#define CRU_PMU_FIRST_SFTRST_EN 0x0 + /************************************************** * sgrf reg, offset **************************************************/ diff --git a/plat/rockchip/rk3399/rk3399_def.h b/plat/rockchip/rk3399/rk3399_def.h index 4ddb0ddd..6a8be846 100644 --- a/plat/rockchip/rk3399/rk3399_def.h +++ b/plat/rockchip/rk3399/rk3399_def.h @@ -61,6 +61,9 @@ #define PMUSRAM_SIZE SIZE_K(64) #define PMUSRAM_RSIZE SIZE_K(8) +#define PMUGRF_BASE 0xff320000 +#define PMUGRF_SIZE SIZE_K(64) + /* * include i2c pmu/audio, pwm0-3 rkpwm0-3 uart_dbg,mailbox scr * 0xff650000 -0xff6c0000 |