2 * Device Tree support for Rockchip RK3288
4 * Copyright (C) 2014 ROCKCHIP, Inc.
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.
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.
17 #include <linux/clk-provider.h>
18 #include <linux/clocksource.h>
19 #include <linux/init.h>
20 #include <linux/irqchip.h>
21 #include <linux/kernel.h>
22 #include <linux/of_address.h>
23 #include <linux/of_platform.h>
24 #include <linux/rockchip/common.h>
25 #include <linux/rockchip/cpu.h>
26 #include <linux/rockchip/cru.h>
27 #include <linux/rockchip/dvfs.h>
28 #include <linux/rockchip/grf.h>
29 #include <linux/rockchip/iomap.h>
30 #include <asm/mach/arch.h>
31 #include <asm/mach/map.h>
37 #define RK3288_DEVICE(name) \
39 .virtual = (unsigned long) RK_##name##_VIRT, \
40 .pfn = __phys_to_pfn(RK3288_##name##_PHYS), \
41 .length = RK3288_##name##_SIZE, \
45 #define RK3288_SERVICE_DEVICE(name) \
46 RK_DEVICE(RK3288_SERVICE_##name##_VIRT, RK3288_SERVICE_##name##_PHYS, RK3288_SERVICE_##name##_SIZE)
48 static struct map_desc rk3288_io_desc[] __initdata = {
55 RK3288_SERVICE_DEVICE(CORE),
56 RK3288_SERVICE_DEVICE(DMAC),
57 RK3288_SERVICE_DEVICE(GPU),
58 RK3288_SERVICE_DEVICE(PERI),
59 RK3288_SERVICE_DEVICE(VIO),
60 RK3288_SERVICE_DEVICE(VIDEO),
61 RK3288_SERVICE_DEVICE(HEVC),
62 RK_DEVICE(RK_DDR_VIRT, RK3288_DDR_PCTL0_PHYS, RK3288_DDR_PCTL_SIZE),
63 RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE, RK3288_DDR_PUBL0_PHYS, RK3288_DDR_PUBL_SIZE),
64 RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PCTL1_PHYS, RK3288_DDR_PCTL_SIZE),
65 RK_DEVICE(RK_DDR_VIRT + 2 * RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PUBL1_PHYS, RK3288_DDR_PUBL_SIZE),
66 RK_DEVICE(RK_GPIO_VIRT(0), RK3288_GPIO0_PHYS, RK3288_GPIO_SIZE),
67 RK_DEVICE(RK_GPIO_VIRT(1), RK3288_GPIO1_PHYS, RK3288_GPIO_SIZE),
68 RK_DEVICE(RK_GPIO_VIRT(2), RK3288_GPIO2_PHYS, RK3288_GPIO_SIZE),
69 RK_DEVICE(RK_GPIO_VIRT(3), RK3288_GPIO3_PHYS, RK3288_GPIO_SIZE),
70 RK_DEVICE(RK_GPIO_VIRT(4), RK3288_GPIO4_PHYS, RK3288_GPIO_SIZE),
71 RK_DEVICE(RK_GPIO_VIRT(5), RK3288_GPIO5_PHYS, RK3288_GPIO_SIZE),
72 RK_DEVICE(RK_GPIO_VIRT(6), RK3288_GPIO6_PHYS, RK3288_GPIO_SIZE),
73 RK_DEVICE(RK_GPIO_VIRT(7), RK3288_GPIO7_PHYS, RK3288_GPIO_SIZE),
74 RK_DEVICE(RK_GPIO_VIRT(8), RK3288_GPIO8_PHYS, RK3288_GPIO_SIZE),
75 RK_DEVICE(RK_DEBUG_UART_VIRT, RK3288_UART_DBG_PHYS, RK3288_UART_SIZE),
78 static void __init rk3288_boot_mode_init(void)
80 u32 flag = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG0);
81 u32 mode = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG1);
82 u32 rst_st = readl_relaxed(RK_CRU_VIRT + RK3288_CRU_GLB_RST_ST);
84 if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER))
85 mode = BOOT_MODE_RECOVERY;
86 if (rst_st & ((1 << 4) | (1 << 5)))
87 mode = BOOT_MODE_WATCHDOG;
88 else if (rst_st & ((1 << 2) | (1 << 3)))
89 mode = BOOT_MODE_TSADC;
90 rockchip_boot_mode_init(flag, mode);
93 extern void secondary_startup(void);
95 static void usb_uart_init(void)
98 writel_relaxed(0x00c00000, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
99 #ifdef CONFIG_RK_USB_UART
100 soc_status2 = (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2));
101 if(!(soc_status2 & (1<<14)) && (soc_status2 & (1<<17)))
103 writel_relaxed(0x00040004, RK_GRF_VIRT + RK3288_GRF_UOC0_CON2); //software control usb phy enable
104 writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3); //usb phy enter suspend
105 writel_relaxed(0x00c000c0, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
107 #endif // end of CONFIG_RK_USB_UART
110 static void __init rk3288_dt_map_io(void)
112 iotable_init(rk3288_io_desc, ARRAY_SIZE(rk3288_io_desc));
115 rockchip_soc_id = ROCKCHIP_SOC_RK3288;
117 /* rkpwm is used instead of old pwm */
118 //writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2);
120 /* enable fast boot */
121 writel_relaxed(0x01000100, RK_SGRF_VIRT + RK3288_SGRF_SOC_CON0);
122 writel_relaxed(virt_to_phys(secondary_startup), RK_SGRF_VIRT + RK3288_SGRF_FAST_BOOT_ADDR);
124 rk3288_boot_mode_init();
127 static const u8 pmu_st_map[] = {
141 static bool rk3288_pmu_power_domain_is_on(enum pmu_power_domain pd)
143 /* 1'b0: power on, 1'b1: power off */
144 return !(readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_ST) & BIT(pmu_st_map[pd]));
147 static DEFINE_SPINLOCK(pmu_idle_lock);
149 static const u8 pmu_idle_map[] = {
153 [IDLE_REQ_VIDEO] = 3,
156 [IDLE_REQ_ALIVE] = 6,
162 static int rk3288_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
164 u32 bit = pmu_idle_map[req];
165 u32 idle_mask = BIT(bit) | BIT(bit + 16);
166 u32 idle_target = (idle << bit) | (idle << (bit + 16));
171 spin_lock_irqsave(&pmu_idle_lock, flags);
172 val = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_IDLE_REQ);
177 writel_relaxed(val, RK_PMU_VIRT + RK3288_PMU_IDLE_REQ);
180 while ((readl_relaxed(RK_PMU_VIRT + RK3288_PMU_IDLE_ST) & idle_mask) != idle_target)
182 spin_unlock_irqrestore(&pmu_idle_lock, flags);
187 static const u8 pmu_pd_map[] = {
201 static DEFINE_SPINLOCK(pmu_pd_lock);
203 static noinline void rk3288_do_pmu_set_power_domain(enum pmu_power_domain domain, bool on)
205 u8 pd = pmu_pd_map[domain];
206 u32 val = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_CON);
211 writel_relaxed(val, RK_PMU_VIRT + RK3288_PMU_PWRDN_CON);
214 while ((readl_relaxed(RK_PMU_VIRT + RK3288_PMU_PWRDN_ST) & BIT(pmu_st_map[domain])) == on)
218 static u32 gpu_r_qos[CPU_AXI_QOS_NUM_REGS];
219 static u32 gpu_w_qos[CPU_AXI_QOS_NUM_REGS];
220 static u32 vio0_iep_qos[CPU_AXI_QOS_NUM_REGS];
221 static u32 vio0_vip_qos[CPU_AXI_QOS_NUM_REGS];
222 static u32 vio0_vop_qos[CPU_AXI_QOS_NUM_REGS];
223 static u32 vio1_isp_r_qos[CPU_AXI_QOS_NUM_REGS];
224 static u32 vio1_isp_w0_qos[CPU_AXI_QOS_NUM_REGS];
225 static u32 vio1_isp_w1_qos[CPU_AXI_QOS_NUM_REGS];
226 static u32 vio1_vop_qos[CPU_AXI_QOS_NUM_REGS];
227 static u32 vio2_rga_r_qos[CPU_AXI_QOS_NUM_REGS];
228 static u32 vio2_rga_w_qos[CPU_AXI_QOS_NUM_REGS];
229 static u32 video_qos[CPU_AXI_QOS_NUM_REGS];
230 static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS];
231 static u32 hevc_w_qos[CPU_AXI_QOS_NUM_REGS];
233 #define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
234 #define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT)
236 static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
240 spin_lock_irqsave(&pmu_pd_lock, flags);
241 if (rk3288_pmu_power_domain_is_on(pd) == on) {
242 spin_unlock_irqrestore(&pmu_pd_lock, flags);
247 /* if power down, idle request to NIU first */
249 SAVE_QOS(vio0_iep_qos, VIO0_IEP);
250 SAVE_QOS(vio0_vip_qos, VIO0_VIP);
251 SAVE_QOS(vio0_vop_qos, VIO0_VOP);
252 SAVE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
253 SAVE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
254 SAVE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
255 SAVE_QOS(vio1_vop_qos, VIO1_VOP);
256 SAVE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
257 SAVE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
258 rk3288_pmu_set_idle_request(IDLE_REQ_VIO, true);
259 } else if (pd == PD_VIDEO) {
260 SAVE_QOS(video_qos, VIDEO);
261 rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
262 } else if (pd == PD_GPU) {
263 SAVE_QOS(gpu_r_qos, GPU_R);
264 SAVE_QOS(gpu_w_qos, GPU_W);
265 rk3288_pmu_set_idle_request(IDLE_REQ_GPU, true);
266 } else if (pd == PD_HEVC) {
267 SAVE_QOS(hevc_r_qos, HEVC_R);
268 SAVE_QOS(hevc_w_qos, HEVC_W);
269 rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, true);
273 rk3288_do_pmu_set_power_domain(pd, on);
276 /* if power up, idle request release to NIU */
278 rk3288_pmu_set_idle_request(IDLE_REQ_VIO, false);
279 RESTORE_QOS(vio0_iep_qos, VIO0_IEP);
280 RESTORE_QOS(vio0_vip_qos, VIO0_VIP);
281 RESTORE_QOS(vio0_vop_qos, VIO0_VOP);
282 RESTORE_QOS(vio1_isp_r_qos, VIO1_ISP_R);
283 RESTORE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0);
284 RESTORE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1);
285 RESTORE_QOS(vio1_vop_qos, VIO1_VOP);
286 RESTORE_QOS(vio2_rga_r_qos, VIO2_RGA_R);
287 RESTORE_QOS(vio2_rga_w_qos, VIO2_RGA_W);
288 } else if (pd == PD_VIDEO) {
289 rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
290 RESTORE_QOS(video_qos, VIDEO);
291 } else if (pd == PD_GPU) {
292 rk3288_pmu_set_idle_request(IDLE_REQ_GPU, false);
293 RESTORE_QOS(gpu_r_qos, GPU_R);
294 RESTORE_QOS(gpu_w_qos, GPU_W);
295 } else if (pd == PD_HEVC) {
296 rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, false);
297 RESTORE_QOS(hevc_r_qos, HEVC_R);
298 RESTORE_QOS(hevc_w_qos, HEVC_W);
302 spin_unlock_irqrestore(&pmu_pd_lock, flags);
306 static void __init rk3288_dt_init_timer(void)
308 rockchip_pmu_ops.set_power_domain = rk3288_pmu_set_power_domain;
309 rockchip_pmu_ops.power_domain_is_on = rk3288_pmu_power_domain_is_on;
310 rockchip_pmu_ops.set_idle_request = rk3288_pmu_set_idle_request;
312 clocksource_of_init();
316 static void __init rk3288_reserve(void)
318 /* reserve memory for ION */
319 rockchip_ion_reserve();
322 static const char * const rk3288_dt_compat[] __initconst = {
327 static void rk3288_restart(char mode, const char *cmd)
329 u32 boot_flag, boot_mode;
331 rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
333 writel_relaxed(boot_flag, RK_PMU_VIRT + RK3288_PMU_SYS_REG0); // for loader
334 writel_relaxed(boot_mode, RK_PMU_VIRT + RK3288_PMU_SYS_REG1); // for linux
337 writel_relaxed(0xeca8, RK_CRU_VIRT + RK3288_CRU_GLB_SRST_SND_VALUE);
341 DT_MACHINE_START(RK3288_DT, "RK30board")
342 .smp = smp_ops(rockchip_smp_ops),
343 .map_io = rk3288_dt_map_io,
344 .init_time = rk3288_dt_init_timer,
345 .dt_compat = rk3288_dt_compat,
346 .init_late = rockchip_suspend_init,
347 .reserve = rk3288_reserve,
348 .restart = rk3288_restart,
352 char PIE_DATA(sram_stack)[1024];
353 EXPORT_PIE_SYMBOL(DATA(sram_stack));
355 static int __init rk3288_pie_init(void)
359 if (!cpu_is_rk3288())
362 err = rockchip_pie_init();
366 rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3288);
367 if (IS_ERR(rockchip_pie_chunk)) {
368 err = PTR_ERR(rockchip_pie_chunk);
369 pr_err("%s: failed to load section %d\n", __func__, err);
370 rockchip_pie_chunk = NULL;
374 rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
375 rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *) DATA(sram_stack) + sizeof(DATA(sram_stack)));
379 arch_initcall(rk3288_pie_init);