0a768a98ba06a68388b119a3236dedaff66d87ec
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk3288.c
1 /*
2  * Device Tree support for Rockchip RK3288
3  *
4  * Copyright (C) 2014 ROCKCHIP, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <linux/clk-provider.h>
18 #include <linux/clocksource.h>
19 #include <linux/cpuidle.h>
20 #include <linux/delay.h>
21 #include <linux/init.h>
22 #include <linux/irqchip.h>
23 #include <linux/kernel.h>
24 #include <linux/of_address.h>
25 #include <linux/of_platform.h>
26 #include <linux/rockchip/common.h>
27 #include <linux/rockchip/cpu.h>
28 #include <linux/rockchip/cpu_axi.h>
29 #include <linux/rockchip/cru.h>
30 #include <linux/rockchip/dvfs.h>
31 #include <linux/rockchip/grf.h>
32 #include <linux/rockchip/iomap.h>
33 #include <linux/rockchip/pmu.h>
34 #include <linux/fb.h>
35 #include <asm/cpuidle.h>
36 #include <asm/cputype.h>
37 #include <asm/mach/arch.h>
38 #include <asm/mach/map.h>
39 #include "loader.h"
40 #define CPU 3288
41 #include "sram.h"
42 #include "pm.h"
43
44 #define RK3288_DEVICE(name) \
45         { \
46                 .virtual        = (unsigned long) RK_##name##_VIRT, \
47                 .pfn            = __phys_to_pfn(RK3288_##name##_PHYS), \
48                 .length         = RK3288_##name##_SIZE, \
49                 .type           = MT_DEVICE, \
50         }
51
52 #define RK3288_SERVICE_DEVICE(name) \
53         RK_DEVICE(RK3288_SERVICE_##name##_VIRT, RK3288_SERVICE_##name##_PHYS, RK3288_SERVICE_##name##_SIZE)
54
55 #define RK3288_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
56 #define RK3288_TIMER7_VIRT (RK_TIMER_VIRT + 0x20)
57
58 static struct map_desc rk3288_io_desc[] __initdata = {
59         RK3288_DEVICE(CRU),
60         RK3288_DEVICE(GRF),
61         RK3288_DEVICE(SGRF),
62         RK3288_DEVICE(PMU),
63         RK3288_DEVICE(ROM),
64         RK3288_DEVICE(EFUSE),
65         RK3288_SERVICE_DEVICE(CORE),
66         RK3288_SERVICE_DEVICE(DMAC),
67         RK3288_SERVICE_DEVICE(GPU),
68         RK3288_SERVICE_DEVICE(PERI),
69         RK3288_SERVICE_DEVICE(VIO),
70         RK3288_SERVICE_DEVICE(VIDEO),
71         RK3288_SERVICE_DEVICE(HEVC),
72         RK3288_SERVICE_DEVICE(BUS),
73         RK_DEVICE(RK_DDR_VIRT, RK3288_DDR_PCTL0_PHYS, RK3288_DDR_PCTL_SIZE),
74         RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE, RK3288_DDR_PUBL0_PHYS, RK3288_DDR_PUBL_SIZE),
75         RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PCTL1_PHYS, RK3288_DDR_PCTL_SIZE),
76         RK_DEVICE(RK_DDR_VIRT + 2 * RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PUBL1_PHYS, RK3288_DDR_PUBL_SIZE),
77         RK_DEVICE(RK_GPIO_VIRT(0), RK3288_GPIO0_PHYS, RK3288_GPIO_SIZE),
78         RK_DEVICE(RK_GPIO_VIRT(1), RK3288_GPIO1_PHYS, RK3288_GPIO_SIZE),
79         RK_DEVICE(RK_GPIO_VIRT(2), RK3288_GPIO2_PHYS, RK3288_GPIO_SIZE),
80         RK_DEVICE(RK_GPIO_VIRT(3), RK3288_GPIO3_PHYS, RK3288_GPIO_SIZE),
81         RK_DEVICE(RK_GPIO_VIRT(4), RK3288_GPIO4_PHYS, RK3288_GPIO_SIZE),
82         RK_DEVICE(RK_GPIO_VIRT(5), RK3288_GPIO5_PHYS, RK3288_GPIO_SIZE),
83         RK_DEVICE(RK_GPIO_VIRT(6), RK3288_GPIO6_PHYS, RK3288_GPIO_SIZE),
84         RK_DEVICE(RK_GPIO_VIRT(7), RK3288_GPIO7_PHYS, RK3288_GPIO_SIZE),
85         RK_DEVICE(RK_GPIO_VIRT(8), RK3288_GPIO8_PHYS, RK3288_GPIO_SIZE),
86         RK_DEVICE(RK_DEBUG_UART_VIRT, RK3288_UART_DBG_PHYS, RK3288_UART_SIZE),
87         RK_DEVICE(RK_GIC_VIRT, RK3288_GIC_DIST_PHYS, RK3288_GIC_DIST_SIZE),
88         RK_DEVICE(RK_GIC_VIRT + RK3288_GIC_DIST_SIZE, RK3288_GIC_CPU_PHYS, RK3288_GIC_CPU_SIZE),
89         RK_DEVICE(RK_BOOTRAM_VIRT, RK3288_BOOTRAM_PHYS, RK3288_BOOTRAM_SIZE),
90         RK_DEVICE(RK3288_IMEM_VIRT, RK3288_IMEM_PHYS, SZ_4K),
91         RK_DEVICE(RK_TIMER_VIRT, RK3288_TIMER6_PHYS, RK3288_TIMER_SIZE),
92 };
93
94 static void __init rk3288_boot_mode_init(void)
95 {
96         u32 flag = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG0);
97         u32 mode = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG1);
98         u32 rst_st = readl_relaxed(RK_CRU_VIRT + RK3288_CRU_GLB_RST_ST);
99
100         if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER))
101                 mode = BOOT_MODE_RECOVERY;
102         if (rst_st & ((1 << 4) | (1 << 5)))
103                 mode = BOOT_MODE_WATCHDOG;
104         else if (rst_st & ((1 << 2) | (1 << 3)))
105                 mode = BOOT_MODE_TSADC;
106         rockchip_boot_mode_init(flag, mode);
107 }
108
109 static void usb_uart_init(void)
110 {
111         u32 soc_status2;
112
113         writel_relaxed(0x00c00000, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
114         soc_status2 = (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2));
115
116 #ifdef CONFIG_RK_USB_UART
117         if (!(soc_status2 & (1<<14)) && (soc_status2 & (1<<17))) {
118                 /* software control usb phy enable */
119                 writel_relaxed(0x00040004, RK_GRF_VIRT + RK3288_GRF_UOC0_CON2);
120                 /* usb phy enter suspend */
121                 writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
122                 writel_relaxed(0x00c000c0, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
123         }
124 #endif
125 }
126
127 extern void secondary_startup(void);
128
129 static void __init rk3288_dt_map_io(void)
130 {
131         u32 v;
132
133         rockchip_soc_id = ROCKCHIP_SOC_RK3288;
134
135         iotable_init(rk3288_io_desc, ARRAY_SIZE(rk3288_io_desc));
136         debug_ll_io_init();
137         usb_uart_init();
138
139         /* pmu reset by second global soft reset */
140         v = readl_relaxed(RK_CRU_VIRT + RK3288_CRU_GLB_RST_CON);
141         v &= ~(3 << 2);
142         v |= 1 << 2;
143         writel_relaxed(v, RK_CRU_VIRT + RK3288_CRU_GLB_RST_CON);
144
145         /* rkpwm is used instead of old pwm */
146         writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2);
147
148         /* disable address remap */
149 #ifndef CONFIG_ARM_TRUSTZONE
150         writel_relaxed(0x08000000, RK_SGRF_VIRT + RK3288_SGRF_SOC_CON0);
151 #endif
152
153         /* enable timer7 for core */
154         writel_relaxed(0, RK3288_TIMER7_VIRT + 0x10);
155         dsb();
156         writel_relaxed(0xFFFFFFFF, RK3288_TIMER7_VIRT + 0x00);
157         writel_relaxed(0xFFFFFFFF, RK3288_TIMER7_VIRT + 0x04);
158         dsb();
159         writel_relaxed(1, RK3288_TIMER7_VIRT + 0x10);
160         dsb();
161
162         /* power up/down GPU domain wait 1us */
163         writel_relaxed(24, RK_PMU_VIRT + RK3288_PMU_GPU_PWRDWN_CNT);
164         writel_relaxed(24, RK_PMU_VIRT + RK3288_PMU_GPU_PWRUP_CNT);
165
166         rk3288_boot_mode_init();
167 #ifndef CONFIG_ARM_TRUSTZONE
168         rockchip_efuse_init();
169 #endif
170 }
171
172 static const u8 pmu_st_map[] = {
173         [PD_CPU_0] = 0,
174         [PD_CPU_1] = 1,
175         [PD_CPU_2] = 2,
176         [PD_CPU_3] = 3,
177         [PD_BUS] = 5,
178         [PD_PERI] = 6,
179         [PD_VIO] = 7,
180         [PD_VIDEO] = 8,
181         [PD_GPU] = 9,
182         [PD_HEVC] = 10,
183         [PD_SCU] = 11,
184 };
185
186 static bool rk3288_pmu_power_domain_is_on(enum pmu_power_domain pd)
187 {
188         /* 1'b0: power on, 1'b1: power off */
189         return !(readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_ST) & BIT(pmu_st_map[pd]));
190 }
191
192 static DEFINE_SPINLOCK(pmu_idle_lock);
193
194 static const u8 pmu_idle_map[] = {
195         [IDLE_REQ_BUS] = 0,
196         [IDLE_REQ_PERI] = 1,
197         [IDLE_REQ_GPU] = 2,
198         [IDLE_REQ_VIDEO] = 3,
199         [IDLE_REQ_VIO] = 4,
200         [IDLE_REQ_CORE] = 5,
201         [IDLE_REQ_ALIVE] = 6,
202         [IDLE_REQ_DMA] = 7,
203         [IDLE_REQ_CPUP] = 8,
204         [IDLE_REQ_HEVC] = 9,
205 };
206
207 static int rk3288_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
208 {
209         u32 bit = pmu_idle_map[req];
210         u32 idle_mask = BIT(bit) | BIT(bit + 16);
211         u32 idle_target = (idle << bit) | (idle << (bit + 16));
212         u32 mask = BIT(bit);
213         u32 val;
214         unsigned long flags;
215
216         spin_lock_irqsave(&pmu_idle_lock, flags);
217         val = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_IDLE_REQ);
218         if (idle)
219                 val |=  mask;
220         else
221                 val &= ~mask;
222         writel_relaxed(val, RK_PMU_VIRT + RK3288_PMU_IDLE_REQ);
223         dsb();
224
225         while ((readl_relaxed(RK_PMU_VIRT + RK3288_PMU_IDLE_ST) & idle_mask) != idle_target)
226                 ;
227         spin_unlock_irqrestore(&pmu_idle_lock, flags);
228
229         return 0;
230 }
231
232 static const u8 pmu_pd_map[] = {
233         [PD_CPU_0] = 0,
234         [PD_CPU_1] = 1,
235         [PD_CPU_2] = 2,
236         [PD_CPU_3] = 3,
237         [PD_BUS] = 5,
238         [PD_PERI] = 6,
239         [PD_VIO] = 7,
240         [PD_VIDEO] = 8,
241         [PD_GPU] = 9,
242         [PD_SCU] = 11,
243         [PD_HEVC] = 14,
244 };
245
246 static DEFINE_SPINLOCK(pmu_pd_lock);
247
248 static noinline void rk3288_do_pmu_set_power_domain(enum pmu_power_domain domain, bool on)
249 {
250         u8 pd = pmu_pd_map[domain];
251         u32 val = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_CON);
252         if (on)
253                 val &= ~BIT(pd);
254         else
255                 val |=  BIT(pd);
256         writel_relaxed(val, RK_PMU_VIRT + RK3288_PMU_PWRDN_CON);
257         dsb();
258
259         while ((readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_ST) & BIT(pmu_st_map[domain])) == on)
260                 ;
261 }
262
263 static u32 gpu_r_qos[CPU_AXI_QOS_NUM_REGS];
264 static u32 gpu_w_qos[CPU_AXI_QOS_NUM_REGS];
265 static u32 vio0_iep_qos[CPU_AXI_QOS_NUM_REGS];
266 static u32 vio0_vip_qos[CPU_AXI_QOS_NUM_REGS];
267 static u32 vio0_vop_qos[CPU_AXI_QOS_NUM_REGS];
268 static u32 vio1_isp_r_qos[CPU_AXI_QOS_NUM_REGS];
269 static u32 vio1_isp_w0_qos[CPU_AXI_QOS_NUM_REGS];
270 static u32 vio1_isp_w1_qos[CPU_AXI_QOS_NUM_REGS];
271 static u32 vio1_vop_qos[CPU_AXI_QOS_NUM_REGS];
272 static u32 vio2_rga_r_qos[CPU_AXI_QOS_NUM_REGS];
273 static u32 vio2_rga_w_qos[CPU_AXI_QOS_NUM_REGS];
274 static u32 video_qos[CPU_AXI_QOS_NUM_REGS];
275 static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS];
276 static u32 hevc_w_qos[CPU_AXI_QOS_NUM_REGS];
277
278 #define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
279 #define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
280
281 static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
282 {
283         unsigned long flags;
284
285         spin_lock_irqsave(&pmu_pd_lock, flags);
286         if (rk3288_pmu_power_domain_is_on(pd) == on)
287                 goto out;
288
289         if (!on) {
290                 /* if power down, idle request to NIU first */
291                 if (pd == PD_VIO) {
292                         SAVE_QOS(vio0_iep_qos, VIO0_IEP);
293                         SAVE_QOS(vio0_vip_qos, VIO0_VIP);
294                         SAVE_QOS(vio0_vop_qos, VIO0_VOP);
295                         SAVE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
296                         SAVE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
297                         SAVE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
298                         SAVE_QOS(vio1_vop_qos, VIO1_VOP);
299                         SAVE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
300                         SAVE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
301                         rk3288_pmu_set_idle_request(IDLE_REQ_VIO, true);
302                 } else if (pd == PD_VIDEO) {
303                         SAVE_QOS(video_qos, VIDEO);
304                         rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
305                 } else if (pd == PD_GPU) {
306                         SAVE_QOS(gpu_r_qos, GPU_R);
307                         SAVE_QOS(gpu_w_qos, GPU_W);
308                         rk3288_pmu_set_idle_request(IDLE_REQ_GPU, true);
309                 } else if (pd == PD_HEVC) {
310                         SAVE_QOS(hevc_r_qos, HEVC_R);
311                         SAVE_QOS(hevc_w_qos, HEVC_W);
312                         rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, true);
313                 } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
314                         writel_relaxed(0x20002 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
315                         dsb();
316                 }
317                  else if (pd == PD_PERI) {
318                         rk3288_pmu_set_idle_request(IDLE_REQ_PERI, true);
319                 }
320         
321         }
322
323         rk3288_do_pmu_set_power_domain(pd, on);
324
325         if (on) {
326                 /* if power up, idle request release to NIU */
327                 if (pd == PD_VIO) {
328                         rk3288_pmu_set_idle_request(IDLE_REQ_VIO, false);
329                         RESTORE_QOS(vio0_iep_qos, VIO0_IEP);
330                         RESTORE_QOS(vio0_vip_qos, VIO0_VIP);
331                         RESTORE_QOS(vio0_vop_qos, VIO0_VOP);
332                         RESTORE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
333                         RESTORE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
334                         RESTORE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
335                         RESTORE_QOS(vio1_vop_qos, VIO1_VOP);
336                         RESTORE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
337                         RESTORE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
338                 } else if (pd == PD_VIDEO) {
339                         rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
340                         RESTORE_QOS(video_qos, VIDEO);
341                 } else if (pd == PD_GPU) {
342                         rk3288_pmu_set_idle_request(IDLE_REQ_GPU, false);
343                         RESTORE_QOS(gpu_r_qos, GPU_R);
344                         RESTORE_QOS(gpu_w_qos, GPU_W);
345                 } else if (pd == PD_HEVC) {
346                         rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, false);
347                         RESTORE_QOS(hevc_r_qos, HEVC_R);
348                         RESTORE_QOS(hevc_w_qos, HEVC_W);
349                 } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
350 #ifdef CONFIG_SMP
351                         writel_relaxed(0x20000 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
352                         dsb();
353                         udelay(10);
354                         writel_relaxed(virt_to_phys(secondary_startup), RK3288_IMEM_VIRT + 8);
355                         writel_relaxed(0xDEADBEAF, RK3288_IMEM_VIRT + 4);
356                         dsb_sev();
357 #endif
358                 }
359                 else if (pd == PD_PERI) {
360                         rk3288_pmu_set_idle_request(IDLE_REQ_PERI, false);
361                 }
362         }
363
364 out:
365         spin_unlock_irqrestore(&pmu_pd_lock, flags);
366         return 0;
367 }
368
369 static int rk3288_sys_set_power_domain(enum pmu_power_domain pd, bool on)
370 {
371         u32 clks_ungating[RK3288_CRU_CLKGATES_CON_CNT];
372         u32 clks_save[RK3288_CRU_CLKGATES_CON_CNT];
373         u32 i, ret;
374
375         for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
376                 clks_save[i] = cru_readl(RK3288_CRU_CLKGATES_CON(i));
377                 clks_ungating[i] = 0;
378         }
379
380         switch (pd) {
381         case PD_GPU:
382                 /* gpu */
383                 clks_ungating[5] = 1 << 7;
384                 /* aclk_gpu */
385                 clks_ungating[18] = 1 << 0;
386                 break;
387         case PD_VIDEO:
388                 /* aclk_vdpu_src hclk_vpu aclk_vepu_src */
389                 clks_ungating[3] = 1 << 11 | 1 << 10 | 1 << 9;
390                 /* hclk_video aclk_video */
391                 clks_ungating[9] = 1 << 1 | 1 << 0;
392                 break;
393         case PD_VIO:
394                 /* aclk_lcdc0/1_src dclk_lcdc0/1_src rga_core aclk_rga_src */
395                 /* edp_24m edp isp isp_jpeg */
396                 clks_ungating[3] =
397                     1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 1 << 5 |
398                     1 << 12 | 1 << 13 | 1 << 14 | 1 << 15;
399                 clks_ungating[15] = 0xffff;
400                 clks_ungating[16] = 0x0fff;
401                 break;
402         case PD_HEVC:
403                 /* hevc_core hevc_cabac aclk_hevc */
404                 clks_ungating[13] = 1 << 15 | 1 << 14 | 1 << 13;
405                 break;
406 #if 0
407         case PD_CS:
408                 clks_ungating[12] = 1 << 11 | 1 < 10 | 1 << 9 | 1 << 8;
409                 break;
410 #endif
411         default:
412                 break;
413         }
414
415         for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
416                 if (clks_ungating[i])
417                         cru_writel(clks_ungating[i] << 16, RK3288_CRU_CLKGATES_CON(i));
418         }
419
420         ret = rk3288_pmu_set_power_domain(pd, on);
421
422         for (i = 0; i < RK3288_CRU_CLKGATES_CON_CNT; i++) {
423                 if (clks_ungating[i])
424                         cru_writel(clks_save[i] | 0xffff0000, RK3288_CRU_CLKGATES_CON(i));
425         }
426
427         return ret;
428 }
429
430 static void __init rk3288_dt_init_timer(void)
431 {
432         rockchip_pmu_ops.set_power_domain = rk3288_sys_set_power_domain;
433         rockchip_pmu_ops.power_domain_is_on = rk3288_pmu_power_domain_is_on;
434         rockchip_pmu_ops.set_idle_request = rk3288_pmu_set_idle_request;
435         of_clk_init(NULL);
436         clocksource_of_init();
437         of_dvfs_init();
438 }
439
440 static void __init rk3288_reserve(void)
441 {
442         /* reserve memory for uboot */
443         rockchip_uboot_mem_reserve();
444
445         /* reserve memory for ION */
446         rockchip_ion_reserve();
447 }
448
449 static const char * const rk3288_dt_compat[] __initconst = {
450         "rockchip,rk3288",
451         NULL,
452 };
453
454 static void rk3288_restart(char mode, const char *cmd)
455 {
456         u32 boot_flag, boot_mode;
457
458         rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
459
460         writel_relaxed(boot_flag, RK_PMU_VIRT + RK3288_PMU_SYS_REG0);   // for loader
461         writel_relaxed(boot_mode, RK_PMU_VIRT + RK3288_PMU_SYS_REG1);   // for linux
462         dsb();
463
464         /* pll enter slow mode */
465         writel_relaxed(0xf3030000, RK_CRU_VIRT + RK3288_CRU_MODE_CON);
466         dsb();
467         writel_relaxed(0xeca8, RK_CRU_VIRT + RK3288_CRU_GLB_SRST_SND_VALUE);
468         dsb();
469 }
470
471 static struct cpuidle_driver rk3288_cpuidle_driver = {
472         .name = "rk3288_cpuidle",
473         .owner = THIS_MODULE,
474         .states[0] = ARM_CPUIDLE_WFI_STATE,
475         .state_count = 1,
476 };
477
478 static int rk3288_cpuidle_enter(struct cpuidle_device *dev,
479                 struct cpuidle_driver *drv, int index)
480 {
481         void *sel = RK_CRU_VIRT + RK3288_CRU_CLKSELS_CON(36);
482         u32 con = readl_relaxed(sel);
483         u32 cpu = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 0);
484         writel_relaxed(0x70007 << (cpu << 2), sel);
485         cpu_do_idle();
486         writel_relaxed((0x70000 << (cpu << 2)) | con, sel);
487         dsb();
488         return index;
489 }
490
491 static void __init rk3288_init_cpuidle(void)
492 {
493         int ret;
494
495         if (!rockchip_jtag_enabled)
496                 rk3288_cpuidle_driver.states[0].enter = rk3288_cpuidle_enter;
497         ret = cpuidle_register(&rk3288_cpuidle_driver, NULL);
498         if (ret)
499                 pr_err("%s: failed to register cpuidle driver: %d\n", __func__, ret);
500 }
501
502 static int rk3288_pll_early_suspend_notifier_call(struct notifier_block *self,
503                                 unsigned long action, void *data)
504 {
505         struct fb_event *event = data;
506         int blank_mode = *((int *)event->data);
507         static bool enable = false;
508
509         if (action == FB_EARLY_EVENT_BLANK) {
510                 switch (blank_mode) {
511                 case FB_BLANK_UNBLANK:
512                         if (!enable) {
513                                 clk_prepare_enable(clk_get_sys(NULL, "clk_cpll"));
514                                 clk_prepare_enable(clk_get_sys(NULL, "clk_npll"));
515                                 enable = true;
516                         }
517                         break;
518                 default:
519                         break;
520                 }
521         } else if (action == FB_EVENT_BLANK) {
522                 switch (blank_mode) {
523                 case FB_BLANK_POWERDOWN:
524                         if (enable) {
525                                 clk_disable_unprepare(clk_get_sys(NULL, "clk_cpll"));
526                                 clk_disable_unprepare(clk_get_sys(NULL, "clk_npll"));
527                                 enable = false;
528                         }
529                         break;
530                 default:
531                         break;
532                 }
533         }
534
535         return NOTIFY_OK;
536 }
537
538 static struct notifier_block rk3288_pll_early_suspend_notifier = {
539         .notifier_call = rk3288_pll_early_suspend_notifier_call,
540 };
541
542 #ifdef CONFIG_PM
543 static void __init rk3288_init_suspend(void);
544 #endif
545 static void __init rk3288_init_late(void)
546 {
547 #ifdef CONFIG_PM
548         rk3288_init_suspend();
549 #endif
550 #ifdef CONFIG_CPU_IDLE
551         rk3288_init_cpuidle();
552 #endif
553         if (rockchip_jtag_enabled)
554                 clk_prepare_enable(clk_get_sys(NULL, "clk_jtag"));
555 }
556
557 DT_MACHINE_START(RK3288_DT, "Rockchip RK3288 (Flattened Device Tree)")
558         .smp            = smp_ops(rockchip_smp_ops),
559         .map_io         = rk3288_dt_map_io,
560         .init_time      = rk3288_dt_init_timer,
561         .dt_compat      = rk3288_dt_compat,
562         .init_late      = rk3288_init_late,
563         .reserve        = rk3288_reserve,
564         .restart        = rk3288_restart,
565 MACHINE_END
566
567 char PIE_DATA(sram_stack)[1024];
568 EXPORT_PIE_SYMBOL(DATA(sram_stack));
569
570 static int __init rk3288_pie_init(void)
571 {
572         int err;
573         if (!cpu_is_rk3288())
574                 return 0;
575
576         err = rockchip_pie_init();
577         if (err)
578                 return err;
579
580         rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3288);
581         if (IS_ERR(rockchip_pie_chunk)) {
582                 err = PTR_ERR(rockchip_pie_chunk);
583                 pr_err("%s: failed to load section %d\n", __func__, err);
584                 rockchip_pie_chunk = NULL;
585                 return err;
586         }
587
588         rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
589         rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *) DATA(sram_stack) + sizeof(DATA(sram_stack)));
590
591     return 0;
592 }
593 arch_initcall(rk3288_pie_init);
594 #ifdef CONFIG_PM
595 #include "pm-rk3288.c"
596
597 static u32 rk_pmu_pwrdn_st;
598 static inline void rk_pm_soc_pd_suspend(void)
599 {
600     rk_pmu_pwrdn_st = pmu_readl(RK3288_PMU_PWRDN_ST);
601
602     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU])))
603     rk3288_sys_set_power_domain(PD_GPU, false);
604
605     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC])))
606     rk3288_sys_set_power_domain(PD_HEVC, false);
607
608     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO])))
609     rk3288_sys_set_power_domain(PD_VIO, false);
610
611     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO])))
612     rk3288_sys_set_power_domain(PD_VIDEO, false);
613 #if 0
614     rkpm_ddr_printascii("pd state:");
615     rkpm_ddr_printhex(rk_pmu_pwrdn_st);        
616     rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST));        
617     rkpm_ddr_printascii("\n");
618  #endif  
619 }
620 static inline void rk_pm_soc_pd_resume(void)
621 {
622     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_GPU])))
623         rk3288_sys_set_power_domain(PD_GPU, true);
624
625     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_HEVC])))
626         rk3288_sys_set_power_domain(PD_HEVC, true);
627
628     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIO])))
629      rk3288_sys_set_power_domain(PD_VIO, true);
630
631     if(!(rk_pmu_pwrdn_st&BIT(pmu_st_map[PD_VIDEO])))
632         rk3288_sys_set_power_domain(PD_VIDEO, true);
633
634 #if 0
635     rkpm_ddr_printascii("pd state:");
636     rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRDN_ST));        
637     rkpm_ddr_printascii("\n");
638 #endif    
639 }
640 void inline rkpm_periph_pd_dn(bool on)
641 {
642     rk3288_sys_set_power_domain(PD_PERI, on);
643 }
644
645 static void __init rk3288_init_suspend(void)
646 {
647     printk("%s\n",__FUNCTION__);
648     fb_register_client(&rk3288_pll_early_suspend_notifier);
649     rockchip_suspend_init();       
650     rkpm_pie_init();
651     rk3288_suspend_init();
652    rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume);
653 }
654
655 #if 0
656 extern bool console_suspend_enabled;
657
658 static int  __init rk3288_pm_dbg(void)
659 {
660 #if 1    
661         console_suspend_enabled=0;
662         do{
663             pm_suspend(PM_SUSPEND_MEM);
664         }
665         while(1);
666         
667 #endif
668
669 }
670
671 //late_initcall_sync(rk3288_pm_dbg);
672 #endif
673
674
675 #endif
676 #define sram_printascii(s) do {} while (0) /* FIXME */
677 #include "ddr_rk32.c"
678
679 static int __init rk3288_ddr_init(void)
680 {
681     if (cpu_is_rk3288()
682 #ifdef CONFIG_ARM_TRUSTZONE
683         && false
684 #endif
685         )
686     {
687         ddr_change_freq = _ddr_change_freq;
688         ddr_round_rate = _ddr_round_rate;
689         ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
690         ddr_bandwidth_get = _ddr_bandwidth_get;
691
692         ddr_init(DDR3_DEFAULT, 0);
693     }
694
695     return 0;
696 }
697 arch_initcall_sync(rk3288_ddr_init);
698