summaryrefslogtreecommitdiff
path: root/arch/arm/mach-rockchip
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-rockchip')
-rw-r--r--arch/arm/mach-rockchip/platsmp.c4
-rw-r--r--arch/arm/mach-rockchip/pm.c21
-rw-r--r--arch/arm/mach-rockchip/pm.h10
-rw-r--r--arch/arm/mach-rockchip/rockchip.c19
4 files changed, 49 insertions, 5 deletions
diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index f26fcdca2445..5b4ca3c3c879 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -55,7 +55,7 @@ static int pmu_power_domain_is_on(int pd)
return !(val & BIT(pd));
}
-struct reset_control *rockchip_get_core_reset(int cpu)
+static struct reset_control *rockchip_get_core_reset(int cpu)
{
struct device *dev = get_cpu_device(cpu);
struct device_node *np;
@@ -201,7 +201,7 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node)
return 0;
}
-static struct regmap_config rockchip_pmu_regmap_config = {
+static const struct regmap_config rockchip_pmu_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index 50cb781aaa36..b0dcbe28f78c 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -75,9 +75,20 @@ static void rk3288_slp_mode_set(int level)
regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
&rk3288_pmu_pwr_mode_con);
- /* set bit 8 so that system will resume to FAST_BOOT_ADDR */
+ /*
+ * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
+ * PCLK_WDT_GATE - disable WDT during suspend.
+ */
regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
- SGRF_FAST_BOOT_EN | SGRF_FAST_BOOT_EN_WRITE);
+ SGRF_PCLK_WDT_GATE | SGRF_FAST_BOOT_EN
+ | SGRF_PCLK_WDT_GATE_WRITE | SGRF_FAST_BOOT_EN_WRITE);
+
+ /*
+ * The dapswjdp can not auto reset before resume, that cause it may
+ * access some illegal address during resume. Let's disable it before
+ * suspend, and the MASKROM will enable it back.
+ */
+ regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, SGRF_DAPDEVICEEN_WRITE);
/* booting address of resuming system is from this register value */
regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
@@ -122,7 +133,8 @@ static void rk3288_slp_mode_set_resume(void)
rk3288_pmu_pwr_mode_con);
regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
- rk3288_sgrf_soc_con0 | SGRF_FAST_BOOT_EN_WRITE);
+ rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
+ | SGRF_FAST_BOOT_EN_WRITE);
}
static int rockchip_lpmode_enter(unsigned long arg)
@@ -209,6 +221,9 @@ static int rk3288_suspend_init(struct device_node *np)
memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
rk3288_bootram_sz);
+ regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH);
+ regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH);
+
return 0;
}
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
index 7c889c04604b..3e8d39c0c3d5 100644
--- a/arch/arm/mach-rockchip/pm.h
+++ b/arch/arm/mach-rockchip/pm.h
@@ -50,9 +50,15 @@ static inline void rockchip_suspend_init(void)
#define RK3288_SGRF_SOC_CON0 (0x0000)
#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
+#define SGRF_PCLK_WDT_GATE BIT(6)
+#define SGRF_PCLK_WDT_GATE_WRITE BIT(22)
#define SGRF_FAST_BOOT_EN BIT(8)
#define SGRF_FAST_BOOT_EN_WRITE BIT(24)
+#define RK3288_SGRF_CPU_CON0 (0x40)
+#define SGRF_DAPDEVICEEN BIT(0)
+#define SGRF_DAPDEVICEEN_WRITE BIT(16)
+
#define RK3288_CRU_MODE_CON 0x50
#define RK3288_CRU_SEL0_CON 0x60
#define RK3288_CRU_SEL1_CON 0x64
@@ -63,6 +69,10 @@ static inline void rockchip_suspend_init(void)
/* PMU_WAKEUP_CFG1 bits */
#define PMU_ARMINT_WAKEUP_EN BIT(0)
+/* wait 30ms for OSC stable and 30ms for pmic stable */
+#define OSC_STABL_CNT_THRESH (32 * 30)
+#define PMU_STABL_CNT_THRESH (32 * 30)
+
enum rk3288_pwr_mode_con {
PMU_PWR_MODE_EN = 0,
PMU_CLK_CORE_SRC_GATE_EN,
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index d360ec044b66..b6cf3b449428 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -30,11 +30,30 @@
#include "pm.h"
#define RK3288_GRF_SOC_CON0 0x244
+#define RK3288_TIMER6_7_PHYS 0xff810000
static void __init rockchip_timer_init(void)
{
if (of_machine_is_compatible("rockchip,rk3288")) {
struct regmap *grf;
+ void __iomem *reg_base;
+
+ /*
+ * Most/all uboot versions for rk3288 don't enable timer7
+ * which is needed for the architected timer to work.
+ * So make sure it is running during early boot.
+ */
+ reg_base = ioremap(RK3288_TIMER6_7_PHYS, SZ_16K);
+ if (reg_base) {
+ writel(0, reg_base + 0x30);
+ writel(0xffffffff, reg_base + 0x20);
+ writel(0xffffffff, reg_base + 0x24);
+ writel(1, reg_base + 0x30);
+ dsb();
+ iounmap(reg_base);
+ } else {
+ pr_err("rockchip: could not map timer7 registers\n");
+ }
/*
* Disable auto jtag/sdmmc switching that causes issues