2 * Device Tree support for Rockchip RK3188
4 * Copyright (C) 2013-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/dvfs.h>
25 #include <linux/rockchip/common.h>
26 #include <linux/rockchip/cpu.h>
27 #include <linux/rockchip/cru.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 RK3188_DEVICE(name) \
39 .virtual = (unsigned long) RK_##name##_VIRT, \
40 .pfn = __phys_to_pfn(RK3188_##name##_PHYS), \
41 .length = RK3188_##name##_SIZE, \
45 static struct map_desc rk3188_io_desc[] __initdata = {
51 RK3188_DEVICE(CPU_AXI_BUS),
52 RK_DEVICE(RK_DDR_VIRT, RK3188_DDR_PCTL_PHYS, RK3188_DDR_PCTL_SIZE),
53 RK_DEVICE(RK_DDR_VIRT + RK3188_DDR_PCTL_SIZE, RK3188_DDR_PUBL_PHYS, RK3188_DDR_PUBL_SIZE),
54 RK_DEVICE(RK_GPIO_VIRT(0), RK3188_GPIO0_PHYS, RK3188_GPIO_SIZE),
55 RK_DEVICE(RK_GPIO_VIRT(1), RK3188_GPIO1_PHYS, RK3188_GPIO_SIZE),
56 RK_DEVICE(RK_GPIO_VIRT(2), RK3188_GPIO2_PHYS, RK3188_GPIO_SIZE),
57 RK_DEVICE(RK_GPIO_VIRT(3), RK3188_GPIO3_PHYS, RK3188_GPIO_SIZE),
58 RK_DEVICE(RK_DEBUG_UART_VIRT, RK3188_UART2_PHYS, RK3188_UART_SIZE),
61 static void __init rk3188_boot_mode_init(void)
63 u32 flag = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_SYS_REG0);
64 u32 mode = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_SYS_REG1);
66 if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER)) {
67 mode = BOOT_MODE_RECOVERY;
69 rockchip_boot_mode_init(flag, mode);
70 #ifdef CONFIG_RK29_WATCHDOG
71 writel_relaxed(BOOT_MODE_WATCHDOG, RK_PMU_VIRT + RK3188_PMU_SYS_REG1);
74 static void usb_uart_init(void)
77 writel_relaxed(0x03100000, RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
78 #ifdef CONFIG_RK_USB_UART
79 soc_status0 = (readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0));
80 if(!(soc_status0 & (1<<10)) && (soc_status0 & (1<<13)))
82 writel_relaxed(0x00040004, RK_GRF_VIRT + RK3188_GRF_UOC0_CON2); //software control usb phy enable
83 writel_relaxed(0x003f002a, RK_GRF_VIRT + RK3188_GRF_UOC0_CON3); //usb phy enter suspend
84 writel_relaxed(0x03000300, RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
86 #endif // end of CONFIG_RK_USB_UART
89 static void __init rk3188_dt_map_io(void)
91 iotable_init(rk3188_io_desc, ARRAY_SIZE(rk3188_io_desc));
95 rockchip_soc_id = ROCKCHIP_SOC_RK3188;
96 if (readl_relaxed(RK_ROM_VIRT + 0x27f0) == 0x33313042
97 && readl_relaxed(RK_ROM_VIRT + 0x27f4) == 0x32303133
98 && readl_relaxed(RK_ROM_VIRT + 0x27f8) == 0x30313331
99 && readl_relaxed(RK_ROM_VIRT + 0x27fc) == 0x56313031)
100 rockchip_soc_id = ROCKCHIP_SOC_RK3188PLUS;
102 /* rki2c is used instead of old i2c */
103 writel_relaxed(0xF800F800, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
105 rk3188_boot_mode_init();
108 static const u8 pmu_pd_map[] = {
122 static bool rk3188_pmu_power_domain_is_on(enum pmu_power_domain pd)
124 /* 1'b0: power on, 1'b1: power off */
125 return !(readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pmu_pd_map[pd]));
128 static noinline void rk3188_do_pmu_set_power_domain(enum pmu_power_domain domain, bool on)
130 u8 pd = pmu_pd_map[domain];
131 u32 val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
136 writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
139 while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pd)) == on)
143 static DEFINE_SPINLOCK(pmu_misc_con1_lock);
145 static const u8 pmu_req_map[] = {
149 [IDLE_REQ_VIDEO] = 4,
153 static const u8 pmu_idle_map[] = {
155 [IDLE_REQ_CORE] = 15,
157 [IDLE_REQ_VIDEO] = 23,
159 [IDLE_REQ_PERI] = 25,
163 static const u8 pmu_ack_map[] = {
165 [IDLE_REQ_CORE] = 18,
167 [IDLE_REQ_VIDEO] = 28,
169 [IDLE_REQ_PERI] = 30,
173 static int rk3188_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
175 u32 idle_mask = BIT(pmu_idle_map[req]);
176 u32 idle_target = idle << pmu_idle_map[req];
177 u32 ack_mask = BIT(pmu_ack_map[req]);
178 u32 ack_target = idle << pmu_ack_map[req];
179 u32 mask = BIT(pmu_req_map[req]);
183 spin_lock_irqsave(&pmu_misc_con1_lock, flags);
184 val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
189 writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
192 while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & ack_mask) != ack_target)
194 while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & idle_mask) != idle_target)
196 spin_unlock_irqrestore(&pmu_misc_con1_lock, flags);
202 * software should power down or power up power domain one by one. Power down or
203 * power up multiple power domains simultaneously will result in chip electric current
204 * change dramatically which will affect the chip function.
206 static DEFINE_SPINLOCK(pmu_pd_lock);
207 static u32 lcdc0_qos[CPU_AXI_QOS_NUM_REGS];
208 static u32 lcdc1_qos[CPU_AXI_QOS_NUM_REGS];
209 static u32 cif0_qos[CPU_AXI_QOS_NUM_REGS];
210 static u32 cif1_qos[CPU_AXI_QOS_NUM_REGS];
211 static u32 ipp_qos[CPU_AXI_QOS_NUM_REGS];
212 static u32 rga_qos[CPU_AXI_QOS_NUM_REGS];
213 static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS];
214 static u32 vpu_qos[CPU_AXI_QOS_NUM_REGS];
216 #define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT)
217 #define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT)
219 static int rk3188_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
223 spin_lock_irqsave(&pmu_pd_lock, flags);
224 if (rk3188_pmu_power_domain_is_on(pd) == on) {
225 spin_unlock_irqrestore(&pmu_pd_lock, flags);
229 /* if power down, idle request to NIU first */
231 SAVE_QOS(lcdc0_qos, LCDC0);
232 SAVE_QOS(lcdc1_qos, LCDC1);
233 SAVE_QOS(cif0_qos, CIF0);
234 SAVE_QOS(cif1_qos, CIF1);
235 SAVE_QOS(ipp_qos, IPP);
236 SAVE_QOS(rga_qos, RGA);
237 rk3188_pmu_set_idle_request(IDLE_REQ_VIO, true);
238 } else if (pd == PD_VIDEO) {
239 SAVE_QOS(vpu_qos, VPU);
240 rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
241 } else if (pd == PD_GPU) {
242 SAVE_QOS(gpu_qos, GPU);
243 rk3188_pmu_set_idle_request(IDLE_REQ_GPU, true);
246 rk3188_do_pmu_set_power_domain(pd, on);
248 /* if power up, idle request release to NIU */
250 rk3188_pmu_set_idle_request(IDLE_REQ_VIO, false);
251 RESTORE_QOS(lcdc0_qos, LCDC0);
252 RESTORE_QOS(lcdc1_qos, LCDC1);
253 RESTORE_QOS(cif0_qos, CIF0);
254 RESTORE_QOS(cif1_qos, CIF1);
255 RESTORE_QOS(ipp_qos, IPP);
256 RESTORE_QOS(rga_qos, RGA);
257 } else if (pd == PD_VIDEO) {
258 rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
259 RESTORE_QOS(vpu_qos, VPU);
260 } else if (pd == PD_GPU) {
261 rk3188_pmu_set_idle_request(IDLE_REQ_GPU, false);
262 RESTORE_QOS(gpu_qos, GPU);
265 spin_unlock_irqrestore(&pmu_pd_lock, flags);
270 static void __init rk3188_dt_init_timer(void)
272 rockchip_pmu_ops.set_power_domain = rk3188_pmu_set_power_domain;
273 rockchip_pmu_ops.power_domain_is_on = rk3188_pmu_power_domain_is_on;
274 rockchip_pmu_ops.set_idle_request = rk3188_pmu_set_idle_request;
276 clocksource_of_init();
280 static void __init rk3188_reserve(void)
282 /* reserve memory for ION */
283 rockchip_ion_reserve();
286 static const char * const rk3188_dt_compat[] __initconst = {
291 static void rk3188_restart(char mode, const char *cmd)
293 u32 boot_flag, boot_mode;
295 rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
297 writel_relaxed(boot_flag, RK_PMU_VIRT + RK3188_PMU_SYS_REG0); // for loader
298 writel_relaxed(boot_mode, RK_PMU_VIRT + RK3188_PMU_SYS_REG1); // for linux
302 writel_relaxed(1 << (12 + 16), RK_GRF_VIRT + RK3188_GRF_SOC_CON0);
303 /* pll enter slow mode */
304 writel_relaxed(RK3188_PLL_MODE_SLOW(RK3188_APLL_ID) |
305 RK3188_PLL_MODE_SLOW(RK3188_CPLL_ID) |
306 RK3188_PLL_MODE_SLOW(RK3188_GPLL_ID),
307 RK_CRU_VIRT + RK3188_CRU_MODE_CON);
309 writel_relaxed(0xeca8, RK_CRU_VIRT + RK3188_CRU_GLB_SRST_SND);
313 DT_MACHINE_START(RK3188_DT, "RK30board")
314 .smp = smp_ops(rockchip_smp_ops),
315 .map_io = rk3188_dt_map_io,
316 .init_time = rk3188_dt_init_timer,
317 .dt_compat = rk3188_dt_compat,
318 .init_late = rockchip_suspend_init,
319 .reserve = rk3188_reserve,
320 .restart = rk3188_restart,
324 char PIE_DATA(sram_stack)[1024];
325 EXPORT_PIE_SYMBOL(DATA(sram_stack));
327 static int __init rk3188_pie_init(void)
331 if (!cpu_is_rk3188())
334 err = rockchip_pie_init();
338 rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3188);
339 if (IS_ERR(rockchip_pie_chunk)) {
340 err = PTR_ERR(rockchip_pie_chunk);
341 pr_err("%s: failed to load section %d\n", __func__, err);
342 rockchip_pie_chunk = NULL;
346 rockchip_sram_virt = kern_to_pie(rockchip_pie_chunk, &__pie_common_start[0]);
347 rockchip_sram_stack = kern_to_pie(rockchip_pie_chunk, (char *) DATA(sram_stack) + sizeof(DATA(sram_stack)));
351 arch_initcall(rk3188_pie_init);
353 #define CONFIG_ARCH_RK3188
354 #define RK30_DDR_PCTL_BASE RK_DDR_VIRT
355 #define RK30_DDR_PUBL_BASE (RK_DDR_VIRT + RK3188_DDR_PCTL_SIZE)
356 #define rk_pll_flag() 0 /* FIXME */
357 #define sram_printascii(s) do {} while (0) /* FIXME */
358 #include "ddr_rk30.c"
360 static int __init rk3188_ddr_init(void)
362 ddr_change_freq = _ddr_change_freq;
363 ddr_round_rate = _ddr_round_rate;
364 ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
367 ddr_init(DDR3_DEFAULT, 300);
371 arch_initcall_sync(rk3188_ddr_init);
373 #include "pm-rk3188.c"