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