ARM: rockchip: rk3228: implement function rk3228_restart
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk3036.c
index 4daaf979529a3c48b1d166f89aafee4078231be3..89b3850da268bba9d6d8a829800ff05b31dec45b 100755 (executable)
@@ -26,6 +26,7 @@
 #include <linux/wakeup_reason.h>
 #include <linux/rockchip/common.h>
 #include <linux/rockchip/cpu.h>
+#include <linux/rockchip/cpu_axi.h>
 #include <linux/rockchip/cru.h>
 #include <linux/rockchip/dvfs.h>
 #include <linux/rockchip/grf.h>
@@ -35,7 +36,6 @@
 #include <asm/cputype.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include "cpu_axi.h"
 #include "loader.h"
 #define CPU 3036
 #include "sram.h"
@@ -57,6 +57,7 @@ static struct map_desc rk3036_io_desc[] __initdata = {
        RK3036_DEVICE(GRF),
        RK3036_DEVICE(ROM),
        RK3036_DEVICE(EFUSE),
+       RK3036_DEVICE(CPU_AXI_BUS),
        RK_DEVICE(RK_DDR_VIRT, RK3036_DDR_PCTL_PHYS, RK3036_DDR_PCTL_SIZE),
        RK_DEVICE(RK_DDR_VIRT + RK3036_DDR_PCTL_SIZE, RK3036_DDR_PHY_PHYS,
                  RK3036_DDR_PHY_SIZE),
@@ -69,6 +70,7 @@ static struct map_desc rk3036_io_desc[] __initdata = {
                  RK3036_GIC_CPU_SIZE),
        RK_DEVICE(RK3036_IMEM_VIRT, RK3036_IMEM_PHYS, SZ_4K),
        RK_DEVICE(RK_TIMER_VIRT, RK3036_TIMER_PHYS, RK3036_TIMER_SIZE),
+       RK_DEVICE(RK_PWM_VIRT, RK3036_PWM_PHYS, RK3036_PWM_SIZE),
 };
 
 static void __init rk3036_boot_mode_init(void)
@@ -251,6 +253,15 @@ static void rk3036_pm_dump_inten(void)
        DUMP_GPIO_INTEN(2);
 }
 
+static void rkpm_prepare(void)
+{
+       rk3036_pm_dump_inten();
+}
+static void rkpm_finish(void)
+{
+       rk3036_pm_dump_irq();
+}
+
 static u32 clk_ungt_msk[RK3036_CRU_CLKGATES_CON_CNT];
 /*first clk gating setting*/
 
@@ -306,6 +317,8 @@ static void clks_gating_suspend_init(void)
 
 #define RK3036_PLL_BYPASS CRU_W_MSK_SETBITS(1, 0xF, 0x01)
 #define RK3036_PLL_NOBYPASS CRU_W_MSK_SETBITS(0, 0xF, 0x01)
+#define RK3036_PLL_POWERDOWN CRU_W_MSK_SETBITS(1, 0xD, 0x01)
+#define RK3036_PLL_POWERON CRU_W_MSK_SETBITS(0, 0xD, 0x01)
 
 #define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
 #define grf_writel(v, offset) do { writel_relaxed(v, \
@@ -321,8 +334,6 @@ static u32 plls_con2_save[RK3036_END_PLL_ID];
 
 static u32 cru_mode_con;
 static u32 clk_sel0, clk_sel1, clk_sel10;
-static int goio0_pin_iomux, gpio0_pin_data, gpio0_pin_dir;
-
 static void pm_pll_wait_lock(u32 pll_idx)
 {
        u32 delay = 600000U;
@@ -362,7 +373,8 @@ static inline void plls_suspend(u32 pll_id)
        plls_con1_save[pll_id] = cru_readl(RK3036_PLL_CONS((pll_id), 1));
        plls_con2_save[pll_id] = cru_readl(RK3036_PLL_CONS((pll_id), 2));
 
-       cru_writel(RK3036_PLL_BYPASS, RK3036_PLL_CONS((pll_id), 0));
+       /*cru_writel(RK3036_PLL_BYPASS, RK3036_PLL_CONS((pll_id), 0));*/
+       cru_writel(RK3036_PLL_POWERDOWN, RK3036_PLL_CONS((pll_id), 1));
 }
 static inline void plls_resume(u32 pll_id)
 {
@@ -371,11 +383,12 @@ static inline void plls_resume(u32 pll_id)
        pllcon0 = plls_con0_save[pll_id];
        pllcon1 = plls_con1_save[pll_id];
        pllcon2 = plls_con2_save[pll_id];
-
+/*
        cru_writel(pllcon0 | 0xffff0000, RK3036_PLL_CONS(pll_id, 0));
        cru_writel(pllcon1 | 0xf5ff0000, RK3036_PLL_CONS(pll_id, 1));
        cru_writel(pllcon2, RK3036_PLL_CONS(pll_id, 2));
-
+*/
+       cru_writel(RK3036_PLL_POWERON, RK3036_PLL_CONS((pll_id), 1));
 
        pll_udelay(5);
 
@@ -415,39 +428,183 @@ static void pm_plls_suspend(void)
                                         , RK3036_CRU_CLKSELS_CON(1));
 
        plls_suspend(APLL_ID);
-
-       goio0_pin_iomux = grf_readl(0xa8);
-       grf_writel(0x000c0000, 0xa8);
-
-       gpio0_pin_data = gpio0_readl(0x0);
-       gpio0_pin_dir = gpio0_readl(0x04);
-
-       gpio0_writel(gpio0_pin_dir | 0x2, 0x04);
-       gpio0_writel(gpio0_pin_data | 0x2, 0x00);
 }
 
 static void pm_plls_resume(void)
 {
-       gpio0_writel(gpio0_pin_dir, 0x04);
-       gpio0_writel(gpio0_pin_data, 0x00);
-       grf_writel(0x000c0008, 0xa8);
-
+       plls_resume(APLL_ID);
        cru_writel(clk_sel0 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x1f))
                , RK3036_CRU_CLKSELS_CON(0));
        cru_writel(clk_sel1 | (CRU_W_MSK(0, 0xf) | CRU_W_MSK(4, 0x7)
                |CRU_W_MSK(8, 0x3) | CRU_W_MSK(12, 0x7))
                , RK3036_CRU_CLKSELS_CON(1));
-
-       plls_resume(APLL_ID);
        cru_writel(cru_mode_con | (RK3036_PLL_MODE_MSK(APLL_ID) << 16)
                , RK3036_CRU_MODE_CON);
+
+       plls_resume(GPLL_ID);
        cru_writel(clk_sel10 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x3)
                | CRU_W_MSK(12, 0x3)), RK3036_CRU_CLKSELS_CON(10));
-       plls_resume(GPLL_ID);
        cru_writel(cru_mode_con | (RK3036_PLL_MODE_MSK(GPLL_ID)
                << 16), RK3036_CRU_MODE_CON);
 }
 
+#include "ddr_rk3036.c"
+#include "pm-pie.c"
+
+char PIE_DATA(sram_stack)[1024];
+EXPORT_PIE_SYMBOL(DATA(sram_stack));
+
+static int __init rk3036_pie_init(void)
+{
+       int err;
+
+       if (!cpu_is_rk3036())
+               return 0;
+
+       err = rockchip_pie_init();
+       if (err)
+               return err;
+
+       rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3036);
+       if (IS_ERR(rockchip_pie_chunk)) {
+               err = PTR_ERR(rockchip_pie_chunk);
+               pr_err("%s: failed to load section %d\n", __func__, err);
+               rockchip_pie_chunk = NULL;
+               return err;
+       }
+
+       rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk
+               , &__pie_common_start[0]);
+       rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk
+               , (char *)DATA(sram_stack) + sizeof(DATA(sram_stack)));
+
+       return 0;
+}
+arch_initcall(rk3036_pie_init);
+
+static void reg_pread(void)
+{
+       volatile u32 n;
+       int i;
+
+       volatile u32 *temp = (volatile unsigned int *)rockchip_sram_virt;
+
+       flush_cache_all();
+       outer_flush_all();
+       local_flush_tlb_all();
+
+       for (i = 0; i < 2; i++) {
+               n = temp[1024 * i];
+               barrier();
+       }
+
+       n = readl_relaxed(RK_GPIO_VIRT(0));
+       n = readl_relaxed(RK_GPIO_VIRT(1));
+       n = readl_relaxed(RK_GPIO_VIRT(2));
+
+       n = readl_relaxed(RK_DEBUG_UART_VIRT);
+       n = readl_relaxed(RK_CPU_AXI_BUS_VIRT);
+       n = readl_relaxed(RK_DDR_VIRT);
+       n = readl_relaxed(RK_GRF_VIRT);
+       n = readl_relaxed(RK_CRU_VIRT);
+       n = readl_relaxed(RK_PWM_VIRT);
+}
+
+#define RK3036_CRU_UNGATING_OPS(id) cru_writel(\
+       CRU_W_MSK_SETBITS(0,  (id), 0x1), RK3036_CRU_UART_GATE)
+#define RK3036_CRU_GATING_OPS(id) cru_writel(\
+       CRU_W_MSK_SETBITS(1, (id), 0x1), RK3036_CRU_UART_GATE)
+
+static inline void  uart_printch(char bbyte)
+{
+       u32 reg_save;
+       u32 u_clk_id = (RK3036_CLKGATE_UART0_SRC + CONFIG_RK_DEBUG_UART * 2);
+       u32 u_pclk_id = (RK3036_CLKGATE_UART0_PCLK + CONFIG_RK_DEBUG_UART * 2);
+
+       reg_save = cru_readl(RK3036_CRU_UART_GATE);
+       RK3036_CRU_UNGATING_OPS(u_clk_id);
+       RK3036_CRU_UNGATING_OPS(u_pclk_id);
+       rkpm_udelay(1);
+
+
+write_uart:
+       writel_relaxed(bbyte, RK_DEBUG_UART_VIRT);
+       dsb();
+
+       while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
+               barrier();
+
+       if (bbyte == '\n') {
+               bbyte = '\r';
+               goto write_uart;
+       }
+
+       cru_writel(reg_save | CRU_W_MSK(u_clk_id
+               , 0x1), RK3036_CRU_UART_GATE);
+       cru_writel(reg_save | CRU_W_MSK(u_pclk_id
+               , 0x1), RK3036_CRU_UART_GATE);
+
+
+       if (0) {
+write_uart1:
+               writel_relaxed(bbyte, RK_DEBUG_UART_VIRT);
+               dsb();
+
+               while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
+                       barrier();
+       if (bbyte == '\n') {
+               bbyte = '\r';
+               goto write_uart1;
+               }
+       }
+}
+
+
+void PIE_FUNC(sram_printch)(char byte)
+{
+       uart_printch(byte);
+}
+
+static __sramdata u32 rkpm_pwm_duty0;
+static __sramdata u32 rkpm_pwm_duty1;
+static __sramdata u32 rkpm_pwm_duty2;
+#define PWM_VOLTAGE 0x600
+
+void PIE_FUNC(pwm_regulator_suspend)(void)
+{
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM0)) {
+               rkpm_pwm_duty0 = readl_relaxed(RK_PWM_VIRT + 0x08);
+               writel_relaxed(PWM_VOLTAGE, RK_PWM_VIRT + 0x08);
+       }
+
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM1)) {
+               rkpm_pwm_duty1 = readl_relaxed(RK_PWM_VIRT + 0x18);
+               writel_relaxed(PWM_VOLTAGE, RK_PWM_VIRT + 0x18);
+       }
+
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM2)) {
+               rkpm_pwm_duty2 = readl_relaxed(RK_PWM_VIRT + 0x28);
+               writel_relaxed(PWM_VOLTAGE, RK_PWM_VIRT + 0x28);
+       }
+       //rkpm_udelay(30);
+}
+
+void PIE_FUNC(pwm_regulator_resume)(void)
+{
+       rkpm_udelay(30);
+
+
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM0))
+               writel_relaxed(rkpm_pwm_duty0, RK_PWM_VIRT + 0x08);
+
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM1))
+               writel_relaxed(rkpm_pwm_duty1, RK_PWM_VIRT + 0x18);
+
+       if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM2))
+               writel_relaxed(rkpm_pwm_duty2, RK_PWM_VIRT + 0x28);
+       rkpm_udelay(30);
+}
+
 static void __init rk3036_suspend_init(void)
 {
        struct device_node *parent;
@@ -471,18 +628,37 @@ static void __init rk3036_suspend_init(void)
        rkpm_set_ctrbits(pm_ctrbits);
 
        clks_gating_suspend_init();
+       rkpm_set_ops_prepare_finish(rkpm_prepare, rkpm_finish);
        rkpm_set_ops_plls(pm_plls_suspend, pm_plls_resume);
-       rkpm_set_ops_prepare_finish(rk3036_pm_dump_inten
-               , rk3036_pm_dump_irq);
+
+       rkpm_set_ops_regs_pread(reg_pread);
+       rkpm_set_sram_ops_ddr(fn_to_pie(rockchip_pie_chunk
+               , &FUNC(ddr_suspend))
+               , fn_to_pie(rockchip_pie_chunk, &FUNC(ddr_resume)));
+
+       rkpm_set_sram_ops_volt(fn_to_pie(rockchip_pie_chunk
+               , &FUNC(pwm_regulator_suspend))
+               , fn_to_pie(rockchip_pie_chunk, &FUNC(pwm_regulator_resume)));
+
+
+       rkpm_set_sram_ops_printch(fn_to_pie(rockchip_pie_chunk
+               , &FUNC(sram_printch)));
        rkpm_set_ops_printch(rk3036_ddr_printch);
-       rockchip_suspend_init();
 }
 #endif
 
+static void __init rk3036_init_suspend(void)
+{
+       pr_info("%s\n", __func__);
+       rockchip_suspend_init();
+       rkpm_pie_init();
+       rk3036_suspend_init();
+}
+
 static void __init rk3036_init_late(void)
 {
 #ifdef CONFIG_PM
-       rk3036_suspend_init();
+       rk3036_init_suspend();
 #endif
 }