Commit f47a25dd authored by Caesar Wang's avatar Caesar Wang
Browse files

rockchip: support the suspend/resume for rk3399



This patch adds to support the suspend/resume for rk3399 SoCs.
Signed-off-by: default avatarShengfei xu <xsf@rock-chips.com>
Signed-off-by: default avatarCaesar Wang <wxt@rock-chips.com>
parent 32d4f826
...@@ -189,6 +189,7 @@ endfunc plat_crash_console_putc ...@@ -189,6 +189,7 @@ endfunc plat_crash_console_putc
* cpus online or resume enterpoint * cpus online or resume enterpoint
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
.align 16
func platform_cpu_warmboot func platform_cpu_warmboot
mrs x0, MPIDR_EL1 mrs x0, MPIDR_EL1
and x1, x0, #MPIDR_CPU_MASK and x1, x0, #MPIDR_CPU_MASK
...@@ -206,12 +207,6 @@ func platform_cpu_warmboot ...@@ -206,12 +207,6 @@ func platform_cpu_warmboot
adr x4, cpuson_flags adr x4, cpuson_flags
add x4, x4, x0, lsl #2 add x4, x4, x0, lsl #2
ldr w1, [x4] ldr w1, [x4]
/* --------------------------------------------------------------------
* get per cpuup boot addr
* --------------------------------------------------------------------
*/
adr x5, cpuson_entry_point
ldr x2, [x5, x0, lsl #3]
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* check cpuon reason * check cpuon reason
* -------------------------------------------------------------------- * --------------------------------------------------------------------
...@@ -231,8 +226,15 @@ wfe_loop: ...@@ -231,8 +226,15 @@ wfe_loop:
wfe wfe
b wfe_loop b wfe_loop
boot_entry: boot_entry:
mov w0, #0 mov w1, #0
str w0, [x4] str w1, [x4]
/* --------------------------------------------------------------------
* get per cpuup boot addr
* --------------------------------------------------------------------
*/
adr x5, cpuson_entry_point
ldr x2, [x5, x0, lsl #3]
br x2 br x2
endfunc platform_cpu_warmboot endfunc platform_cpu_warmboot
...@@ -248,5 +250,5 @@ cpuson_entry_point: ...@@ -248,5 +250,5 @@ cpuson_entry_point:
.endr .endr
cpuson_flags: cpuson_flags:
.rept PLATFORM_CORE_COUNT .rept PLATFORM_CORE_COUNT
.quad 0 .word 0
.endr .endr
...@@ -27,13 +27,19 @@ ...@@ -27,13 +27,19 @@
#ifndef __PMU_COM_H__ #ifndef __PMU_COM_H__
#define __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); 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_get() bakery_lock_get(&rockchip_pd_lock)
#define rockchip_pd_lock_rls() bakery_lock_release(&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 * power domain on or off
*****************************************************************************/ *****************************************************************************/
......
...@@ -77,7 +77,7 @@ struct rockchip_pm_ops_cb { ...@@ -77,7 +77,7 @@ struct rockchip_pm_ops_cb {
#endif #endif
#ifndef BITS_WITH_WMASK #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))) (BITS_SHIFT(bits, shift) | BITS_SHIFT(msk, (shift + REG_MSK_SHIFT)))
#endif #endif
...@@ -108,6 +108,8 @@ void plat_rockchip_pmu_init(void); ...@@ -108,6 +108,8 @@ void plat_rockchip_pmu_init(void);
void plat_rockchip_soc_init(void); void plat_rockchip_soc_init(void);
void plat_setup_rockchip_pm_ops(struct rockchip_pm_ops_cb *ops); 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 const unsigned char rockchip_power_domain_tree_desc[];
extern void *pmu_cpuson_entrypoint_start; extern void *pmu_cpuson_entrypoint_start;
......
...@@ -52,7 +52,6 @@ static struct rockchip_pm_ops_cb *rockchip_ops; ...@@ -52,7 +52,6 @@ static struct rockchip_pm_ops_cb *rockchip_ops;
static void plat_rockchip_sys_pwr_domain_resume(void) static void plat_rockchip_sys_pwr_domain_resume(void)
{ {
plat_rockchip_gic_init();
if (rockchip_ops && rockchip_ops->sys_pwr_dm_resume) if (rockchip_ops && rockchip_ops->sys_pwr_dm_resume)
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) ...@@ -62,8 +61,6 @@ static void plat_rockchip_cores_pwr_domain_resume(void)
if (rockchip_ops && rockchip_ops->cores_pwr_dm_resume) if (rockchip_ops && rockchip_ops->cores_pwr_dm_resume)
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 */ /* Program the gic per-cpu distributor or re-distributor interface */
plat_rockchip_gic_cpuif_enable(); plat_rockchip_gic_cpuif_enable();
} }
......
...@@ -26,12 +26,6 @@ ...@@ -26,12 +26,6 @@
#ifndef __PMU_SRAM_H__ #ifndef __PMU_SRAM_H__
#define __PMU_SRAM_H__ #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 data offset in struct psram_data
*****************************************************************************/ *****************************************************************************/
...@@ -39,9 +33,8 @@ ...@@ -39,9 +33,8 @@
#define PSRAM_DT_DDR_FUNC 0x8 #define PSRAM_DT_DDR_FUNC 0x8
#define PSRAM_DT_DDR_DATA 0x10 #define PSRAM_DT_DDR_DATA 0x10
#define PSRAM_DT_DDRFLAG 0x18 #define PSRAM_DT_DDRFLAG 0x18
#define PSRAM_DT_SYS_MODE 0x1c #define PSRAM_DT_MPIDR 0x1c
#define PSRAM_DT_MPIDR 0x20 #define PSRAM_DT_END 0x20
#define PSRAM_DT_END 0x24
/****************************************************************************** /******************************************************************************
* Allocate data region for struct psram_data_t in pmusram * Allocate data region for struct psram_data_t in pmusram
******************************************************************************/ ******************************************************************************/
...@@ -67,7 +60,6 @@ struct psram_data_t { ...@@ -67,7 +60,6 @@ struct psram_data_t {
uint64_t ddr_func; uint64_t ddr_func;
uint64_t ddr_data; uint64_t ddr_data;
uint32_t ddr_flag; uint32_t ddr_flag;
uint32_t sys_mode;
uint32_t boot_mpidr; uint32_t boot_mpidr;
}; };
...@@ -81,8 +73,6 @@ CASSERT(__builtin_offsetof(struct psram_data_t, ddr_data) == PSRAM_DT_DDR_DATA, ...@@ -81,8 +73,6 @@ CASSERT(__builtin_offsetof(struct psram_data_t, ddr_data) == PSRAM_DT_DDR_DATA,
assert_psram_dt_ddr_data_offset_mistmatch); assert_psram_dt_ddr_data_offset_mistmatch);
CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG, CASSERT(__builtin_offsetof(struct psram_data_t, ddr_flag) == PSRAM_DT_DDRFLAG,
assert_psram_dt_ddr_flag_offset_mistmatch); 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, CASSERT(__builtin_offsetof(struct psram_data_t, boot_mpidr) == PSRAM_DT_MPIDR,
assert_psram_dt_mpidr_offset_mistmatch); assert_psram_dt_mpidr_offset_mistmatch);
void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes); void u32_align_cpy(uint32_t *dst, const uint32_t *src, size_t bytes);
......
...@@ -35,11 +35,6 @@ ...@@ -35,11 +35,6 @@
func pmu_cpuson_entrypoint func pmu_cpuson_entrypoint
pmu_cpuson_entrypoint_start: pmu_cpuson_entrypoint_start:
ldr x5, psram_data 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: check_wake_cpus:
mrs x0, MPIDR_EL1 mrs x0, MPIDR_EL1
and x1, x0, #MPIDR_CPU_MASK and x1, x0, #MPIDR_CPU_MASK
...@@ -74,8 +69,6 @@ sys_resume: ...@@ -74,8 +69,6 @@ sys_resume:
.align 3 .align 3
psram_data: psram_data:
.quad PSRAM_DT_BASE .quad PSRAM_DT_BASE
warm_boot_func:
.quad platform_cpu_warmboot
sys_wakeup_entry: sys_wakeup_entry:
.quad psci_entrypoint .quad psci_entrypoint
pmu_cpuson_entrypoint_end: pmu_cpuson_entrypoint_end:
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
static struct psram_data_t *psram_sleep_cfg = static struct psram_data_t *psram_sleep_cfg =
(struct psram_data_t *)PSRAM_DT_BASE; (struct psram_data_t *)PSRAM_DT_BASE;
static uint32_t cpu_warm_boot_addr;
void rk3368_flash_l2_b(void) void rk3368_flash_l2_b(void)
{ {
uint32_t wait_cnt = 0; uint32_t wait_cnt = 0;
...@@ -353,7 +355,7 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) ...@@ -353,7 +355,7 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint)
/* Switch boot addr to pmusram */ /* Switch boot addr to pmusram */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1 + cluster), 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); CPU_BOOT_ADDR_WMASK);
dsb(); dsb();
...@@ -368,19 +370,17 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint) ...@@ -368,19 +370,17 @@ static int cores_pwr_domain_on(unsigned long mpidr, uint64_t entrypoint)
static int cores_pwr_domain_on_finish(void) 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; return 0;
} }
static int sys_pwr_domain_resume(void) 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(); pm_plls_resume();
pmu_scu_b_pwrup(); pmu_scu_b_pwrup();
...@@ -392,7 +392,6 @@ static int sys_pwr_domain_suspend(void) ...@@ -392,7 +392,6 @@ static int sys_pwr_domain_suspend(void)
nonboot_cpus_off(); nonboot_cpus_off();
pmu_set_sleep_mode(); pmu_set_sleep_mode();
psram_sleep_cfg->sys_mode = PMU_SYS_SLP_MODE;
psram_sleep_cfg->ddr_flag = 0; psram_sleep_cfg->ddr_flag = 0;
return 0; return 0;
...@@ -412,11 +411,12 @@ void plat_rockchip_pmu_init(void) ...@@ -412,11 +411,12 @@ void plat_rockchip_pmu_init(void)
plat_setup_rockchip_pm_ops(&pm_ops); 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++) for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
cpuson_flags[cpu] = 0; cpuson_flags[cpu] = 0;
psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE;
psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
nonboot_cpus_off(); nonboot_cpus_off();
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
static struct psram_data_t *psram_sleep_cfg = static struct psram_data_t *psram_sleep_cfg =
(struct psram_data_t *)PSRAM_DT_BASE; (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. * 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, * 1) Control it power domain into on or off in PMU_PWRDN_CON reg,
...@@ -63,6 +65,53 @@ __attribute__ ((section("tzfw_coherent_mem"))) ...@@ -63,6 +65,53 @@ __attribute__ ((section("tzfw_coherent_mem")))
#endif #endif
;/* coheront */ ;/* 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) void plat_rockchip_pmusram_prepare(void)
{ {
uint32_t *sram_dst, *sram_src; uint32_t *sram_dst, *sram_src;
...@@ -128,6 +177,7 @@ static int cpus_power_domain_on(uint32_t cpu_id) ...@@ -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), mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id),
BIT(core_pm_sft_wakeup_en)); BIT(core_pm_sft_wakeup_en));
dsb();
} }
return 0; return 0;
...@@ -160,6 +210,7 @@ static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg) ...@@ -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); core_pm_value |= BIT(core_pm_int_wakeup_en);
mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id),
core_pm_value); core_pm_value);
dsb();
} }
return 0; return 0;
...@@ -220,9 +271,6 @@ static int cores_pwr_domain_on_finish(void) ...@@ -220,9 +271,6 @@ static int cores_pwr_domain_on_finish(void)
{ {
uint32_t cpu_id = plat_my_core_pos(); uint32_t cpu_id = plat_my_core_pos();
cpuson_flags[cpu_id] = 0;
cpuson_entry_point[cpu_id] = 0;
/* Disable core_pm */ /* Disable core_pm */
mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); 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) ...@@ -233,9 +281,6 @@ static int cores_pwr_domain_resume(void)
{ {
uint32_t cpu_id = plat_my_core_pos(); uint32_t cpu_id = plat_my_core_pos();
cpuson_flags[cpu_id] = 0;
cpuson_entry_point[cpu_id] = 0;
/* Disable core_pm */ /* Disable core_pm */
mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE);
...@@ -246,33 +291,92 @@ static void sys_slp_config(void) ...@@ -246,33 +291,92 @@ static void sys_slp_config(void)
{ {
uint32_t slp_mode_cfg = 0; uint32_t slp_mode_cfg = 0;
slp_mode_cfg = PMU_PWR_MODE_EN | mmio_write_32(PMU_BASE + PMU_CCI500_CON,
PMU_CPU0_PD_EN | BIT_WITH_WMSK(PMU_CLR_PREQ_CCI500_HW) |
PMU_L2_FLUSH_EN | BIT_WITH_WMSK(PMU_CLR_QREQ_CCI500_HW) |
PMU_L2_IDLE_EN | BIT_WITH_WMSK(PMU_QGATING_CCI500_CFG));
PMU_SCU_PD_EN |
PMU_CLK_CORE_SRC_GATE_EN; 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_L_WKUP_EN);
mmio_setbits_32(PMU_BASE + PMU_WKUP_CFG4, PMU_CLUSTER_B_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_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_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) static int sys_pwr_domain_suspend(void)
{ {
sys_slp_config(); sys_slp_config();
plls_suspend(); plls_suspend();
psram_sleep_cfg->sys_mode = PMU_SYS_SLP_MODE;
pmu_sgrf_rst_hld(); 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; return 0;
} }
static int sys_pwr_domain_resume(void) static int sys_pwr_domain_resume(void)
{ {
pmu_sgrf_rst_hld_release(); pmu_sgrf_rst_hld();
psram_sleep_cfg->sys_mode = PMU_SYS_ON_MODE;
mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1),
(cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) |
CPU_BOOT_ADDR_WMASK);
plls_resume(); 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; return 0;
} }
...@@ -294,19 +398,24 @@ void plat_rockchip_pmu_init(void) ...@@ -294,19 +398,24 @@ void plat_rockchip_pmu_init(void)
rockchip_pd_lock_init(); rockchip_pd_lock_init();
plat_setup_rockchip_pm_ops(&pm_ops); 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++) for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++)
cpuson_flags[cpu] = 0; 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; psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff;
/* cpu boot from pmusram */ /* cpu boot from pmusram */
mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), 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); CPU_BOOT_ADDR_WMASK);
nonboot_cpus_off(); nonboot_cpus_off();
INFO("%s(%d): pd status %x\n", __func__, __LINE__, INFO("%s(%d): pd status %x\n", __func__, __LINE__,
mmio_read_32(PMU_BASE + PMU_PWRDN_ST)); mmio_read_32(PMU_BASE + PMU_PWRDN_ST));
} }
...@@ -341,6 +341,25 @@ enum pmu_sft_con { ...@@ -341,6 +341,25 @@ enum pmu_sft_con {
PMU_DDRCTL1_C_SYSREQ_CFG = 12, PMU_DDRCTL1_C_SYSREQ_CFG = 12,
PMU_DDR1_IO_RET_CFG, 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 { enum pmu_int_con {
...@@ -638,12 +657,100 @@ enum pmu_bus_idle_ack { ...@@ -638,12 +657,100 @@ enum pmu_bus_idle_ack {
PMU_IDLE_ACK_SDIOAUDIO, 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 { enum pmu_pwrdn_con1 {
PMU_VD_SCU_L_PWRDN_EN = 0, PMU_VD_SCU_L_PWRDN_EN = 0,
PMU_VD_SCU_B_PWRDN_EN, PMU_VD_SCU_B_PWRDN_EN,
PMU_VD_CENTER_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_CFG0 0x00
#define PMU_WKUP_CFG1 0x04 #define PMU_WKUP_CFG1 0x04
#define PMU_WKUP_CFG2 0x08 #define PMU_WKUP_CFG2 0x08
...@@ -701,9 +808,12 @@ enum pmu_pwrdn_con1 { ...@@ -701,9 +808,12 @@ enum pmu_pwrdn_con1 {
#define PMU_NOC_AUTO_ENA 0xd8 #define PMU_NOC_AUTO_ENA 0xd8
#define PMU_PWRDN_CON1 0xdc #define PMU_PWRDN_CON1 0xdc
#define PMUGRF_GPIO1A_IOMUX 0x10
#define AP_PWROFF 0x0a
#define CORES_PM_DISABLE 0x0 #define CORES_PM_DISABLE 0x0
#define PD_CTR_LOOP 500 #define PD_CTR_LOOP 500
#define CHK_CPU_LOOP 500 #define CHK_CPU_LOOP 500
#define MAX_WAIT_CONUT 1000
#endif /* __PMU_H__ */ #endif /* __PMU_H__ */
...@@ -55,6 +55,9 @@ const mmap_region_t plat_rk_mmap[] = { ...@@ -55,6 +55,9 @@ const mmap_region_t plat_rk_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE), MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(RK3399_UART2_BASE, RK3399_UART2_SIZE, MAP_REGION_FLAT(RK3399_UART2_BASE, RK3399_UART2_SIZE,
MT_DEVICE | MT_RW | MT_SECURE), MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(PMUGRF_BASE, PMUGRF_SIZE,
MT_DEVICE | MT_RW | MT_SECURE),
{ 0 } { 0 }
}; };
...@@ -313,12 +316,13 @@ void soc_global_soft_reset_init(void) ...@@ -313,12 +316,13 @@ void soc_global_soft_reset_init(void)
{ {
mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1), mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
CRU_PMU_SGRF_RST_RLS); 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) void __dead2 soc_global_soft_reset(void)
{ {
uint32_t temp_val;
set_pll_slow_mode(VPLL_ID); set_pll_slow_mode(VPLL_ID);
set_pll_slow_mode(NPLL_ID); set_pll_slow_mode(NPLL_ID);
set_pll_slow_mode(GPLL_ID); set_pll_slow_mode(GPLL_ID);
...@@ -326,9 +330,9 @@ void __dead2 soc_global_soft_reset(void) ...@@ -326,9 +330,9 @@ void __dead2 soc_global_soft_reset(void)
set_pll_slow_mode(PPLL_ID); set_pll_slow_mode(PPLL_ID);
set_pll_slow_mode(ABPLL_ID); set_pll_slow_mode(ABPLL_ID);
set_pll_slow_mode(ALPLL_ID); set_pll_slow_mode(ALPLL_ID);
temp_val = mmio_read_32(CRU_BASE + CRU_GLB_RST_CON) |
PMU_RST_BY_FIRST_SFT; dsb();
mmio_write_32(CRU_BASE + CRU_GLB_RST_CON, temp_val);
mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL); mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
/* /*
......
...@@ -52,14 +52,16 @@ ...@@ -52,14 +52,16 @@
#define NO_PLL_BYPASS (0x00) #define NO_PLL_BYPASS (0x00)
#define NO_PLL_PWRDN (0x00) #define NO_PLL_PWRDN (0x00)
#define PLL_SLOW_MODE BITS_WITH_WMASK(PLL_MODE_MSK,\ #define PLL_SLOW_MODE BITS_WITH_WMASK(SLOW_MODE,\
SLOW_MODE, PLL_MODE_SHIFT) PLL_MODE_MSK, PLL_MODE_SHIFT)
#define PLL_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS_MSK,\ #define PLL_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS,\
PLL_BYPASS, PLL_BYPASS_SHIFT) PLL_BYPASS_MSK,\
#define PLL_NO_BYPASS_MODE BITS_WITH_WMASK(PLL_BYPASS_MSK,\ PLL_BYPASS_SHIFT)
NO_PLL_BYPASS, PLL_BYPASS_SHIFT) #define PLL_NO_BYPASS_MODE BITS_WITH_WMASK(NO_PLL_BYPASS,\
#define PLL_NOMAL_MODE BITS_WITH_WMASK(PLL_MODE_MSK,\ PLL_BYPASS_MSK,\
NORMAL_MODE, PLL_MODE_SHIFT) PLL_BYPASS_SHIFT)
#define PLL_NOMAL_MODE BITS_WITH_WMASK(NORMAL_MODE,\
PLL_MODE_MSK, PLL_MODE_SHIFT)
#define PLL_CON_COUNT 0x06 #define PLL_CON_COUNT 0x06
#define CRU_CLKSEL_COUNT 0x108 #define CRU_CLKSEL_COUNT 0x108
...@@ -100,6 +102,9 @@ struct deepsleep_data_s { ...@@ -100,6 +102,9 @@ struct deepsleep_data_s {
uint32_t cru_clksel_con[CRU_CLKSEL_COUNT]; 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 * secure timer
**************************************************/ **************************************************/
...@@ -155,6 +160,13 @@ struct deepsleep_data_s { ...@@ -155,6 +160,13 @@ struct deepsleep_data_s {
#define CRU_PMU_SGRF_RST_HOLD BIT_WITH_WMSK(6) #define CRU_PMU_SGRF_RST_HOLD BIT_WITH_WMSK(6)
/* reset hold release*/ /* reset hold release*/
#define CRU_PMU_SGRF_RST_RLS WMSK_BIT(6) #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 * sgrf reg, offset
**************************************************/ **************************************************/
......
...@@ -61,6 +61,9 @@ ...@@ -61,6 +61,9 @@
#define PMUSRAM_SIZE SIZE_K(64) #define PMUSRAM_SIZE SIZE_K(64)
#define PMUSRAM_RSIZE SIZE_K(8) #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 * include i2c pmu/audio, pwm0-3 rkpwm0-3 uart_dbg,mailbox scr
* 0xff650000 -0xff6c0000 * 0xff650000 -0xff6c0000
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment