rockchip: support the suspend/resume for rk3399
authorCaesar Wang <wxt@rock-chips.com>
Sun, 10 Apr 2016 06:11:07 +0000 (14:11 +0800)
committerCaesar Wang <wxt@rock-chips.com>
Wed, 4 May 2016 11:39:21 +0000 (19:39 +0800)
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>
12 files changed:
plat/rockchip/common/aarch64/plat_helpers.S
plat/rockchip/common/drivers/pmu/pmu_com.h
plat/rockchip/common/include/plat_private.h
plat/rockchip/common/plat_pm.c
plat/rockchip/common/pmusram/pmu_sram.h
plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
plat/rockchip/rk3368/drivers/pmu/pmu.c
plat/rockchip/rk3399/drivers/pmu/pmu.c
plat/rockchip/rk3399/drivers/pmu/pmu.h
plat/rockchip/rk3399/drivers/soc/soc.c
plat/rockchip/rk3399/drivers/soc/soc.h
plat/rockchip/rk3399/rk3399_def.h

index a90dcd7e3f9f409d92bd8c6509f7b9219433e455..1bbb614560de50b702e6d4b438f91e2b1232c49d 100644 (file)
@@ -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
@@ -206,12 +207,6 @@ func platform_cpu_warmboot
        adr     x4, cpuson_flags
        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
index 0cab53c93a89ad69089dca7051474de0a43fa222..4cffb61434a8d80a18183aae812c2fa0f361d20d 100644 (file)
 #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
  *****************************************************************************/
index 67fb82768444a60be57833a3c7436234379736cf..e05bda41dc5134630e1444465435449e1cfbebbe 100644 (file)
@@ -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;
index fcd47a8c9fe1db75e5e148808607008c5a2cc23f..43558b65afd10de065ce9892785ded1de68390b8 100644 (file)
@@ -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();
 }
index a2ab460b8b4f2c2afe36972683b74dd919165cb7..f29046123989ea8f90a6a41e4db8537c7cdce8c1 100644 (file)
 #ifndef __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
  *****************************************************************************/
@@ -39,9 +33,8 @@
 #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);
index 33a4646dd74d9bc32eb08017f7b4dfbc79935153..9f94b0c13ae564fb2913b10a0e729a59be1da549 100644 (file)
 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:
index e99063481d5497fce99251691b949d39cc57af2a..50e2bf87c85c6c771489e432913118f9862e832f 100644 (file)
@@ -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();
index 351de7dfd942e59b2f5ce1de7a2902fb27288014..1493a4dd8acc2f98df30886f6781352d1d93a216 100644 (file)
@@ -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));
 }
index 053b6ee5d6f814e439335838d931b7f1237a6a29..d5ff8ce095a286a812c02c39dec27daa1fe6004d 100644 (file)
@@ -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__ */
index f8d66c2c1d8c6dad1d5581fdea0c70a5d715a029..5b7613d75b0b69295c17e0e4722407b34f8c6043 100644 (file)
@@ -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);
 
        /*
index 9100d02b323f383a3d504a6e7caf1086626ad3d3..e48f2f03369940d5995f742f35cf0faaab3fdff6 100644 (file)
 #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
  **************************************************/
index 4ddb0ddd73cea2b70cf0d07f7b1af01437eeb2ec..6a8be8466aac9d35b29f26588f4b965fa1cb8950 100644 (file)
@@ -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