Merge tag 'v4.1-rockchip-socfixes1' of git://git.kernel.org/pub/scm/linux/kernel...
authorArnd Bergmann <arnd@arndb.de>
Thu, 7 May 2015 16:19:27 +0000 (18:19 +0200)
committerArnd Bergmann <arnd@arndb.de>
Thu, 7 May 2015 16:19:27 +0000 (18:19 +0200)
Merge "ARM: rockchip: some soc-level fixes for 4.1" from Heiko Stübner:

Two fixes from Chris Zhong, fixing some suspend oddities.
And I've given up on the timer7 issue. While I initially thought
devices would either have both the grave mmu issue requiring a uboot
update and the timer7 issue or none, it looks like in all units in the
field the mmu issue got fixed while the timer7 issue stayed on.
So instead of making everybody wanting to use mainline jump through a
hoop just make sure timer7 is on on boot before we init the arch-timer.

* tag 'v4.1-rockchip-socfixes1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip:
  rockchip: make sure timer7 is enabled on rk3288 platforms
  ARM: rockchip: fix undefined instruction of reset_ctrl_regs
  ARM: rockchip: disable dapswjdp during suspend

arch/arm/mach-rockchip/pm.c
arch/arm/mach-rockchip/pm.h
arch/arm/mach-rockchip/rockchip.c

index b07d886..22812fe 100644 (file)
@@ -44,9 +44,11 @@ static void __iomem *rk3288_bootram_base;
 static phys_addr_t rk3288_bootram_phy;
 
 static struct regmap *pmu_regmap;
+static struct regmap *grf_regmap;
 static struct regmap *sgrf_regmap;
 
 static u32 rk3288_pmu_pwr_mode_con;
+static u32 rk3288_grf_soc_con0;
 static u32 rk3288_sgrf_soc_con0;
 
 static inline u32 rk3288_l2_config(void)
@@ -70,11 +72,25 @@ static void rk3288_slp_mode_set(int level)
 {
        u32 mode_set, mode_set1;
 
+       regmap_read(grf_regmap, RK3288_GRF_SOC_CON0, &rk3288_grf_soc_con0);
+
        regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
 
        regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
                    &rk3288_pmu_pwr_mode_con);
 
+       /*
+        * We need set this bit GRF_FORCE_JTAG here, for the debug module,
+        * otherwise, it may become inaccessible after resume.
+        * This creates a potential security issue, as the sdmmc pins may
+        * accept jtag data for a short time during resume if no card is
+        * inserted.
+        * But this is of course also true for the regular boot, before we
+        * turn of the jtag/sdmmc autodetect.
+        */
+       regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, GRF_FORCE_JTAG |
+                    GRF_FORCE_JTAG_WRITE);
+
        /*
         * SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
         * PCLK_WDT_GATE - disable WDT during suspend.
@@ -83,6 +99,13 @@ static void rk3288_slp_mode_set(int level)
                     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,
                     rk3288_bootram_phy);
@@ -128,6 +151,9 @@ static void rk3288_slp_mode_set_resume(void)
        regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
                     rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
                     | SGRF_FAST_BOOT_EN_WRITE);
+
+       regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, rk3288_grf_soc_con0 |
+                    GRF_FORCE_JTAG_WRITE);
 }
 
 static int rockchip_lpmode_enter(unsigned long arg)
@@ -186,6 +212,13 @@ static int rk3288_suspend_init(struct device_node *np)
                return PTR_ERR(pmu_regmap);
        }
 
+       grf_regmap = syscon_regmap_lookup_by_compatible(
+                               "rockchip,rk3288-grf");
+       if (IS_ERR(grf_regmap)) {
+               pr_err("%s: could not find grf regmap\n", __func__);
+               return PTR_ERR(pmu_regmap);
+       }
+
        sram_np = of_find_compatible_node(NULL, NULL,
                                          "rockchip,rk3288-pmu-sram");
        if (!sram_np) {
index 03ff31d..f8a747b 100644 (file)
@@ -48,6 +48,10 @@ static inline void rockchip_suspend_init(void)
 #define RK3288_PMU_WAKEUP_RST_CLR_CNT  0x44
 #define RK3288_PMU_PWRMODE_CON1                0x90
 
+#define RK3288_GRF_SOC_CON0            0x244
+#define GRF_FORCE_JTAG                 BIT(12)
+#define GRF_FORCE_JTAG_WRITE           BIT(28)
+
 #define RK3288_SGRF_SOC_CON0           (0x0000)
 #define RK3288_SGRF_FAST_BOOT_ADDR     (0x0120)
 #define SGRF_PCLK_WDT_GATE             BIT(6)
@@ -55,6 +59,10 @@ static inline void rockchip_suspend_init(void)
 #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
index d360ec0..b6cf3b4 100644 (file)
 #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