rockchip: avoid change ddr freq before lcd driver is inited
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk3288.c
old mode 100644 (file)
new mode 100755 (executable)
index d1aaeab..100327c
@@ -16,6 +16,8 @@
 
 #include <linux/clk-provider.h>
 #include <linux/clocksource.h>
+#include <linux/cpuidle.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
 #include <linux/rockchip/dvfs.h>
 #include <linux/rockchip/grf.h>
 #include <linux/rockchip/iomap.h>
+#include <linux/rockchip/pmu.h>
+#include <linux/fb.h>
+#include <asm/cpuidle.h>
+#include <asm/cputype.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include "cpu_axi.h"
 #include "loader.h"
-#include "pmu.h"
+#define CPU 3288
 #include "sram.h"
+#include "pm.h"
 
 #define RK3288_DEVICE(name) \
        { \
                .type           = MT_DEVICE, \
        }
 
+#define RK3288_SERVICE_DEVICE(name) \
+       RK_DEVICE(RK3288_SERVICE_##name##_VIRT, RK3288_SERVICE_##name##_PHYS, RK3288_SERVICE_##name##_SIZE)
+
+#define RK3288_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
+#define RK3288_TIMER7_VIRT (RK_TIMER_VIRT + 0x20)
+
 static struct map_desc rk3288_io_desc[] __initdata = {
        RK3288_DEVICE(CRU),
        RK3288_DEVICE(GRF),
@@ -49,6 +62,14 @@ static struct map_desc rk3288_io_desc[] __initdata = {
        RK3288_DEVICE(PMU),
        RK3288_DEVICE(ROM),
        RK3288_DEVICE(EFUSE),
+       RK3288_SERVICE_DEVICE(CORE),
+       RK3288_SERVICE_DEVICE(DMAC),
+       RK3288_SERVICE_DEVICE(GPU),
+       RK3288_SERVICE_DEVICE(PERI),
+       RK3288_SERVICE_DEVICE(VIO),
+       RK3288_SERVICE_DEVICE(VIDEO),
+       RK3288_SERVICE_DEVICE(HEVC),
+       RK3288_SERVICE_DEVICE(BUS),
        RK_DEVICE(RK_DDR_VIRT, RK3288_DDR_PCTL0_PHYS, RK3288_DDR_PCTL_SIZE),
        RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE, RK3288_DDR_PUBL0_PHYS, RK3288_DDR_PUBL_SIZE),
        RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PCTL1_PHYS, RK3288_DDR_PCTL_SIZE),
@@ -63,6 +84,11 @@ static struct map_desc rk3288_io_desc[] __initdata = {
        RK_DEVICE(RK_GPIO_VIRT(7), RK3288_GPIO7_PHYS, RK3288_GPIO_SIZE),
        RK_DEVICE(RK_GPIO_VIRT(8), RK3288_GPIO8_PHYS, RK3288_GPIO_SIZE),
        RK_DEVICE(RK_DEBUG_UART_VIRT, RK3288_UART_DBG_PHYS, RK3288_UART_SIZE),
+       RK_DEVICE(RK_GIC_VIRT, RK3288_GIC_DIST_PHYS, RK3288_GIC_DIST_SIZE),
+       RK_DEVICE(RK_GIC_VIRT + RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_PHYS, RK3288_GIC_CPU_SIZE),
+       RK_DEVICE(RK_BOOTRAM_VIRT, RK3288_BOOTRAM_PHYS, RK3288_BOOTRAM_SIZE),
+       RK_DEVICE(RK3288_IMEM_VIRT, RK3288_IMEM_PHYS, SZ_4K),
+       RK_DEVICE(RK_TIMER_VIRT, RK3288_TIMER6_PHYS, RK3288_TIMER_SIZE),
 };
 
 static void __init rk3288_boot_mode_init(void)
@@ -80,23 +106,63 @@ static void __init rk3288_boot_mode_init(void)
        rockchip_boot_mode_init(flag, mode);
 }
 
+static void usb_uart_init(void)
+{
+       u32 soc_status2;
+
+       writel_relaxed(0x00c00000, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+       soc_status2 = (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2));
+
+#ifdef CONFIG_RK_USB_UART
+       if (!(soc_status2 & (1<<14)) && (soc_status2 & (1<<17))) {
+               /* software control usb phy enable */
+               writel_relaxed(0x00040004, RK_GRF_VIRT + RK3288_GRF_UOC0_CON2);
+               /* usb phy enter suspend */
+               writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+               writel_relaxed(0x00c000c0, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+       }
+#endif
+}
+
 extern void secondary_startup(void);
 
 static void __init rk3288_dt_map_io(void)
 {
+       u32 v;
+
+       rockchip_soc_id = ROCKCHIP_SOC_RK3288;
+
        iotable_init(rk3288_io_desc, ARRAY_SIZE(rk3288_io_desc));
        debug_ll_io_init();
+       usb_uart_init();
 
-       rockchip_soc_id = ROCKCHIP_SOC_RK3288;
+       /* pmu reset by second global soft reset */
+       v = readl_relaxed(RK_CRU_VIRT + RK3288_CRU_GLB_RST_CON);
+       v &= ~(3 << 2);
+       v |= 1 << 2;
+       writel_relaxed(v, RK_CRU_VIRT + RK3288_CRU_GLB_RST_CON);
 
        /* rkpwm is used instead of old pwm */
-       //writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2);
+       writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2);
 
-       /* enable fast boot */
-       writel_relaxed(0x01000100, RK_SGRF_VIRT + RK3288_SGRF_SOC_CON0);
-       writel_relaxed(virt_to_phys(secondary_startup), RK_SGRF_VIRT + RK3288_SGRF_FAST_BOOT_ADDR);
+       /* disable address remap */
+       writel_relaxed(0x08000000, RK_SGRF_VIRT + RK3288_SGRF_SOC_CON0);
+
+       /* enable timer7 for core */
+       writel_relaxed(0, RK3288_TIMER7_VIRT + 0x10);
+       dsb();
+       writel_relaxed(0xFFFFFFFF, RK3288_TIMER7_VIRT + 0x00);
+       writel_relaxed(0xFFFFFFFF, RK3288_TIMER7_VIRT + 0x04);
+       dsb();
+       writel_relaxed(1, RK3288_TIMER7_VIRT + 0x10);
+       dsb();
+
+       /* power up/down GPU domain wait 1us */
+       writel_relaxed(24, RK_PMU_VIRT + RK3288_PMU_GPU_PWRDWN_CNT);
+       writel_relaxed(24, RK_PMU_VIRT + RK3288_PMU_GPU_PWRUP_CNT);
 
        rk3288_boot_mode_init();
+       rockchip_efuse_init();
 }
 
 static const u8 pmu_st_map[] = {
@@ -190,25 +256,176 @@ static noinline void rk3288_do_pmu_set_power_domain(enum pmu_power_domain domain
                ;
 }
 
+static u32 gpu_r_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 gpu_w_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio0_iep_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio0_vip_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio0_vop_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio1_isp_r_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio1_isp_w0_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio1_isp_w1_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio1_vop_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio2_rga_r_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vio2_rga_w_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 video_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 hevc_w_qos[CPU_AXI_QOS_NUM_REGS];
+
+#define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
+#define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
+
 static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&pmu_pd_lock, flags);
-       if (rk3288_pmu_power_domain_is_on(pd) == on) {
-               spin_unlock_irqrestore(&pmu_pd_lock, flags);
-               return 0;
+       if (rk3288_pmu_power_domain_is_on(pd) == on)
+               goto out;
+
+       if (!on) {
+               /* if power down, idle request to NIU first */
+               if (pd == PD_VIO) {
+                       SAVE_QOS(vio0_iep_qos, VIO0_IEP);
+                       SAVE_QOS(vio0_vip_qos, VIO0_VIP);
+                       SAVE_QOS(vio0_vop_qos, VIO0_VOP);
+                       SAVE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
+                       SAVE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
+                       SAVE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
+                       SAVE_QOS(vio1_vop_qos, VIO1_VOP);
+                       SAVE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
+                       SAVE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
+                       rk3288_pmu_set_idle_request(IDLE_REQ_VIO, true);
+               } else if (pd == PD_VIDEO) {
+                       SAVE_QOS(video_qos, VIDEO);
+                       rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
+               } else if (pd == PD_GPU) {
+                       SAVE_QOS(gpu_r_qos, GPU_R);
+                       SAVE_QOS(gpu_w_qos, GPU_W);
+                       rk3288_pmu_set_idle_request(IDLE_REQ_GPU, true);
+               } else if (pd == PD_HEVC) {
+                       SAVE_QOS(hevc_r_qos, HEVC_R);
+                       SAVE_QOS(hevc_w_qos, HEVC_W);
+                       rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, true);
+               } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
+                       writel_relaxed(0x20002 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
+                       dsb();
+               }
+                 else if (pd == PD_PERI) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_PERI, true);
+               }
+        
        }
 
        rk3288_do_pmu_set_power_domain(pd, on);
 
+       if (on) {
+               /* if power up, idle request release to NIU */
+               if (pd == PD_VIO) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_VIO, false);
+                       RESTORE_QOS(vio0_iep_qos, VIO0_IEP);
+                       RESTORE_QOS(vio0_vip_qos, VIO0_VIP);
+                       RESTORE_QOS(vio0_vop_qos, VIO0_VOP);
+                       RESTORE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
+                       RESTORE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
+                       RESTORE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
+                       RESTORE_QOS(vio1_vop_qos, VIO1_VOP);
+                       RESTORE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
+                       RESTORE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
+               } else if (pd == PD_VIDEO) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
+                       RESTORE_QOS(video_qos, VIDEO);
+               } else if (pd == PD_GPU) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_GPU, false);
+                       RESTORE_QOS(gpu_r_qos, GPU_R);
+                       RESTORE_QOS(gpu_w_qos, GPU_W);
+               } else if (pd == PD_HEVC) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, false);
+                       RESTORE_QOS(hevc_r_qos, HEVC_R);
+                       RESTORE_QOS(hevc_w_qos, HEVC_W);
+               } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
+#ifdef CONFIG_SMP
+                       writel_relaxed(0x20000 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
+                       dsb();
+                       udelay(10);
+                       writel_relaxed(virt_to_phys(secondary_startup), RK3288_IMEM_VIRT + 8);
+                       writel_relaxed(0xDEADBEAF, RK3288_IMEM_VIRT + 4);
+                       dsb_sev();
+#endif
+               }
+                else if (pd == PD_PERI) {
+                       rk3288_pmu_set_idle_request(IDLE_REQ_PERI, false);
+               }
+       }
+
+out:
        spin_unlock_irqrestore(&pmu_pd_lock, flags);
        return 0;
 }
 
+static int rk3288_sys_set_power_domain(enum pmu_power_domain pd, bool on)
+{
+       u32 clks_ungating[RK3288_CRU_CLKGATES_CON_CNT];
+       u32 clks_save[RK3288_CRU_CLKGATES_CON_CNT];
+       u32 i, ret;
+
+       for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
+               clks_save[i] = cru_readl(RK3288_CRU_CLKGATES_CON(i));
+               clks_ungating[i] = 0;
+       }
+
+       switch (pd) {
+       case PD_GPU:
+               /* gpu */
+               clks_ungating[5] = 1 << 7;
+               /* aclk_gpu */
+               clks_ungating[18] = 1 << 0;
+               break;
+       case PD_VIDEO:
+               /* aclk_vdpu_src hclk_vpu aclk_vepu_src */
+               clks_ungating[3] = 1 << 11 | 1 << 10 | 1 << 9;
+               /* hclk_video aclk_video */
+               clks_ungating[9] = 1 << 1 | 1 << 0;
+               break;
+       case PD_VIO:
+               /* aclk_lcdc0/1_src dclk_lcdc0/1_src rga_core aclk_rga_src */
+               /* edp_24m edp isp isp_jpeg */
+               clks_ungating[3] =
+                   1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5 |
+                   1 << 12 | 1 << 13 | 1 << 14 | 1 << 15;
+               clks_ungating[15] = 0xffff;
+               clks_ungating[16] = 0x0fff;
+               break;
+       case PD_HEVC:
+               /* hevc_core hevc_cabac aclk_hevc */
+               clks_ungating[13] = 1 << 15 | 1 << 14 | 1 << 13;
+               break;
+#if 0
+       case PD_CS:
+               clks_ungating[12] = 1 << 11 | 1 < 10 | 1 << 9 | 1 << 8;
+               break;
+#endif
+       default:
+               break;
+       }
+
+       for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
+               if (clks_ungating[i])
+                       cru_writel(clks_ungating[i] << 16, RK3288_CRU_CLKGATES_CON(i));
+       }
+
+       ret = rk3288_pmu_set_power_domain(pd, on);
+
+       for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
+               if (clks_ungating[i])
+                       cru_writel(clks_save[i] | 0xffff0000, RK3288_CRU_CLKGATES_CON(i));
+       }
+
+       return ret;
+}
+
 static void __init rk3288_dt_init_timer(void)
 {
-       rockchip_pmu_ops.set_power_domain = rk3288_pmu_set_power_domain;
+       rockchip_pmu_ops.set_power_domain = rk3288_sys_set_power_domain;
        rockchip_pmu_ops.power_domain_is_on = rk3288_pmu_power_domain_is_on;
        rockchip_pmu_ops.set_idle_request = rk3288_pmu_set_idle_request;
        of_clk_init(NULL);
@@ -216,6 +433,12 @@ static void __init rk3288_dt_init_timer(void)
        of_dvfs_init();
 }
 
+static void __init rk3288_reserve(void)
+{
+       /* reserve memory for ION */
+       rockchip_ion_reserve();
+}
+
 static const char * const rk3288_dt_compat[] __initconst = {
        "rockchip,rk3288",
        NULL,
@@ -231,27 +454,108 @@ static void rk3288_restart(char mode, const char *cmd)
        writel_relaxed(boot_mode, RK_PMU_VIRT + RK3288_PMU_SYS_REG1);   // for linux
        dsb();
 
+       /* pll enter slow mode */
+       writel_relaxed(0xf3030000, RK_CRU_VIRT + RK3288_CRU_MODE_CON);
+       dsb();
        writel_relaxed(0xeca8, RK_CRU_VIRT + RK3288_CRU_GLB_SRST_SND_VALUE);
        dsb();
 }
 
-DT_MACHINE_START(RK3288_DT, "RK30board")
+static struct cpuidle_driver rk3288_cpuidle_driver = {
+       .name = "rk3288_cpuidle",
+       .owner = THIS_MODULE,
+       .states[0] = ARM_CPUIDLE_WFI_STATE,
+       .state_count = 1,
+};
+
+static int rk3288_cpuidle_enter(struct cpuidle_device *dev,
+               struct cpuidle_driver *drv, int index)
+{
+       void *sel = RK_CRU_VIRT + RK3288_CRU_CLKSELS_CON(36);
+       u32 con = readl_relaxed(sel);
+       u32 cpu = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 0);
+       writel_relaxed(0x70007 << (cpu << 2), sel);
+       cpu_do_idle();
+       writel_relaxed((0x70000 << (cpu << 2)) | con, sel);
+       dsb();
+       return index;
+}
+
+static void __init rk3288_init_cpuidle(void)
+{
+       int ret;
+
+       if (!rockchip_jtag_enabled)
+               rk3288_cpuidle_driver.states[0].enter = rk3288_cpuidle_enter;
+       ret = cpuidle_register(&rk3288_cpuidle_driver, NULL);
+       if (ret)
+               pr_err("%s: failed to register cpuidle driver: %d\n", __func__, ret);
+}
+
+static int rk3288_pll_early_suspend_notifier_call(struct notifier_block *self,
+                               unsigned long action, void *data)
+{
+       struct fb_event *event = data;
+       int blank_mode = *((int *)event->data);
+
+       if (action == FB_EARLY_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       clk_prepare_enable(clk_get_sys(NULL, "clk_cpll"));
+                       clk_prepare_enable(clk_get_sys(NULL, "clk_npll"));
+                       break;
+               default:
+                       break;
+               }
+       } else if (action == FB_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_POWERDOWN:
+                       clk_disable_unprepare(clk_get_sys(NULL, "clk_cpll"));
+                       clk_disable_unprepare(clk_get_sys(NULL, "clk_npll"));
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block rk3288_pll_early_suspend_notifier = {
+       .notifier_call = rk3288_pll_early_suspend_notifier_call,
+};
+
+#ifdef CONFIG_PM
+static void __init rk3288_init_suspend(void);
+#endif
+static void __init rk3288_init_late(void)
+{
+#ifdef CONFIG_PM
+       rk3288_init_suspend();
+#endif
+#ifdef CONFIG_CPU_IDLE
+       rk3288_init_cpuidle();
+#endif
+       if (rockchip_jtag_enabled)
+               clk_prepare_enable(clk_get_sys(NULL, "clk_jtag"));
+}
+
+DT_MACHINE_START(RK3288_DT, "Rockchip RK3288 (Flattened Device Tree)")
        .smp            = smp_ops(rockchip_smp_ops),
        .map_io         = rk3288_dt_map_io,
        .init_time      = rk3288_dt_init_timer,
        .dt_compat      = rk3288_dt_compat,
-       .init_late      = rockchip_suspend_init,
+       .init_late      = rk3288_init_late,
+       .reserve        = rk3288_reserve,
        .restart        = rk3288_restart,
 MACHINE_END
 
-#define CPU 3288
 char PIE_DATA(sram_stack)[1024];
 EXPORT_PIE_SYMBOL(DATA(sram_stack));
 
 static int __init rk3288_pie_init(void)
 {
        int err;
-
        if (!cpu_is_rk3288())
                return 0;
 
@@ -270,6 +574,107 @@ static int __init rk3288_pie_init(void)
        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;
+    return 0;
 }
 arch_initcall(rk3288_pie_init);
+#ifdef CONFIG_PM
+#include "pm-rk3288.c"
+
+static u32 rk_pmu_pwrdn_st;
+static inline void rk_pm_soc_pd_suspend(void)
+{
+    rk_pmu_pwrdn_st = pmu_readl(RK3288_PMU_PWRDN_ST);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU])))
+    rk3288_sys_set_power_domain(PD_GPU, false);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC])))
+    rk3288_sys_set_power_domain(PD_HEVC, false);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO])))
+    rk3288_sys_set_power_domain(PD_VIO, false);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO])))
+    rk3288_sys_set_power_domain(PD_VIDEO, false);
+#if 0
+    rkpm_ddr_printascii("pd state:");
+    rkpm_ddr_printhex(rk_pmu_pwrdn_st);        
+    rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST));        
+    rkpm_ddr_printascii("\n");
+ #endif  
+}
+static inline void rk_pm_soc_pd_resume(void)
+{
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU])))
+        rk3288_sys_set_power_domain(PD_GPU, true);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC])))
+        rk3288_sys_set_power_domain(PD_HEVC, true);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO])))
+     rk3288_sys_set_power_domain(PD_VIO, true);
+
+    if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO])))
+        rk3288_sys_set_power_domain(PD_VIDEO, true);
+
+#if 0
+    rkpm_ddr_printascii("pd state:");
+    rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST));        
+    rkpm_ddr_printascii("\n");
+#endif    
+}
+void inline rkpm_periph_pd_dn(bool on)
+{
+    rk3288_sys_set_power_domain(PD_PERI, on);
+}
+
+static void __init rk3288_init_suspend(void)
+{
+    printk("%s\n",__FUNCTION__);
+    fb_register_client(&rk3288_pll_early_suspend_notifier);
+    rockchip_suspend_init();       
+    rkpm_pie_init();
+    rk3288_suspend_init();
+   rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume);
+}
+
+#if 0
+extern bool console_suspend_enabled;
+
+static int  __init rk3288_pm_dbg(void)
+{
+#if 1    
+        console_suspend_enabled=0;
+        do{
+            pm_suspend(PM_SUSPEND_MEM);
+        }
+        while(1);
+        
+#endif
+
+}
+
+//late_initcall_sync(rk3288_pm_dbg);
+#endif
+
+
+#endif
+#define sram_printascii(s) do {} while (0) /* FIXME */
+#include "ddr_rk32.c"
+
+static int __init rk3288_ddr_init(void)
+{
+    if (cpu_is_rk3288())
+    {
+       ddr_change_freq = _ddr_change_freq;
+       ddr_round_rate = _ddr_round_rate;
+       ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
+       ddr_bandwidth_get = _ddr_bandwidth_get;
+
+       ddr_init(DDR3_DEFAULT, 0);
+    }
+
+    return 0;
+}
+arch_initcall_sync(rk3288_ddr_init);
+