From 9208a0dfcee434de73808f062e69c3a0ffa507c9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 27 Feb 2014 21:46:31 +0800 Subject: [PATCH] ARM: rockchip: add rk3288.c, pie support rk3288 --- arch/arm/kernel/pie.lds.S | 1 + arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/cru.h | 15 +++ arch/arm/mach-rockchip/pmu.h | 42 ++++++++ arch/arm/mach-rockchip/rk3288.c | 176 ++++++++++++++++++++++++++++++++ pie/Makefile | 1 + 6 files changed, 236 insertions(+) create mode 100644 arch/arm/mach-rockchip/rk3288.c diff --git a/arch/arm/kernel/pie.lds.S b/arch/arm/kernel/pie.lds.S index e843d323da91..1122abd48ea2 100644 --- a/arch/arm/kernel/pie.lds.S +++ b/arch/arm/kernel/pie.lds.S @@ -34,6 +34,7 @@ SECTIONS PIE_OVERLAY_START OVERLAY : NOCROSSREFS { PIE_OVERLAY_SECTION(rk3188) + PIE_OVERLAY_SECTION(rk3288) } PIE_OVERLAY_END diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index ef6b797b6a20..b28b0d6fe6fb 100755 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1,6 +1,7 @@ obj-y += common.o obj-y += cpu.o obj-y += rk3188.o +obj-y += rk3288.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_RK_FPGA) += fpga.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-rockchip/cru.h b/arch/arm/mach-rockchip/cru.h index 15092a2c9a1f..959671ff3c5c 100644 --- a/arch/arm/mach-rockchip/cru.h +++ b/arch/arm/mach-rockchip/cru.h @@ -37,4 +37,19 @@ enum { #define RK3188_PLL_MODE_NORM(id) ((0x1<<((id)*4))|(0x3<<(16+(id)*4))) #define RK3188_PLL_MODE_DEEP(id) ((0x2<<((id)*4))|(0x3<<(16+(id)*4))) +#define RK3288_CRU_GLB_SRST_FST_VALUE 0x1b0 +#define RK3288_CRU_GLB_SRST_SND_VALUE 0x1b4 +#define RK3288_CRU_MISC_CON 0x1e8 +#define RK3288_CRU_GLB_CNT_TH 0x1ec +#define RK3288_CRU_GLB_RST_CON 0x1f0 +#define RK3288_CRU_GLB_RST_ST 0x1f8 +#define RK3288_CRU_SDMMC_CON0 0x200 +#define RK3288_CRU_SDMMC_CON1 0x204 +#define RK3288_CRU_SDIO0_CON0 0x208 +#define RK3288_CRU_SDIO0_CON1 0x20c +#define RK3288_CRU_SDIO1_CON0 0x210 +#define RK3288_CRU_SDIO1_CON1 0x214 +#define RK3288_CRU_EMMC_CON0 0x218 +#define RK3288_CRU_EMMC_CON1 0x21c + #endif diff --git a/arch/arm/mach-rockchip/pmu.h b/arch/arm/mach-rockchip/pmu.h index 2224faec112e..3e03a974130f 100644 --- a/arch/arm/mach-rockchip/pmu.h +++ b/arch/arm/mach-rockchip/pmu.h @@ -25,6 +25,48 @@ #define RK3188_PMU_GPIO0A_PULL 0x64 #define RK3188_PMU_GPIO0B_PULL 0x68 +#define RK3288_PMU_WAKEUP_CFG0 0x00 +#define RK3288_PMU_WAKEUP_CFG1 0x04 +#define RK3288_PMU_PWRDN_CON 0x08 +#define RK3288_PMU_PWRDN_ST 0x0c +#define RK3288_PMU_IDLE_REQ 0x10 +#define RK3288_PMU_IDLE_ST 0x14 +#define RK3288_PMU_PWRMODE_CON 0x18 +#define RK3288_PMU_PWR_STATE 0x1c +#define RK3288_PMU_OSC_CNT 0x20 +#define RK3288_PMU_PLL_CNT 0x24 +#define RK3288_PMU_STABL_CNT 0x28 +#define RK3288_PMU_DDR0IO_PWRON_CNT 0x2c +#define RK3288_PMU_DDR1IO_PWRON_CNT 0x30 +#define RK3288_PMU_CORE_PWRDWN_CNT 0x34 +#define RK3288_PMU_CORE_PWRUP_CNT 0x38 +#define RK3288_PMU_GPU_PWRDWN_CNT 0x3c +#define RK3288_PMU_GPU_PWRUP_CNT 0x40 +#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44 +#define RK3288_PMU_SFT_CON 0x48 +#define RK3288_PMU_DDR_SREF_ST 0x4c +#define RK3288_PMU_INT_CON 0x50 +#define RK3288_PMU_INT_ST 0x54 +#define RK3288_PMU_BOOT_ADDR_SEL 0x58 +#define RK3288_PMU_GRF_CON 0x5c +#define RK3288_PMU_GPIO_SR 0x60 +#define RK3288_PMU_GPIO0_A_PULL 0x64 +#define RK3288_PMU_GPIO0_B_PULL 0x68 +#define RK3288_PMU_GPIO0_C_PULL 0x6c +#define RK3288_PMU_GPIO0_A_DRV 0x70 +#define RK3288_PMU_GPIO0_B_DRV 0x74 +#define RK3288_PMU_GPIO0_C_DRV 0x78 +#define RK3288_PMU_GPIO_OP 0x7c +#define RK3288_PMU_GPIO0_SEL18 0x80 +#define RK3288_PMU_GPIO0_A_IOMUX 0x84 +#define RK3288_PMU_GPIO0_B_IOMUX 0x88 +#define RK3288_PMU_GPIO0_C_IOMUX 0x8c +#define RK3288_PMU_GPIO0_D_IOMUX 0x90 +#define RK3288_PMU_SYS_REG0 0x94 +#define RK3288_PMU_SYS_REG1 0x98 +#define RK3288_PMU_SYS_REG2 0x9c +#define RK3288_PMU_SYS_REG3 0xa0 + enum pmu_power_domain { PD_BCPU, PD_BDSP, diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c new file mode 100644 index 000000000000..efdccf114736 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3288.c @@ -0,0 +1,176 @@ +/* + * Device Tree support for Rockchip RK3288 + * + * Copyright (C) 2014 ROCKCHIP, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "cpu.h" +#include "cpu_axi.h" +#include "cru.h" +#include "grf.h" +#include "iomap.h" +#include "loader.h" +#include "pmu.h" +#include "sram.h" +#include "dvfs.h" + +#define RK3288_DEVICE(name) \ + { \ + .virtual = (unsigned long) RK_##name##_VIRT, \ + .pfn = __phys_to_pfn(RK3288_##name##_PHYS), \ + .length = RK3288_##name##_SIZE, \ + .type = MT_DEVICE, \ + } + +static struct map_desc rk3288_io_desc[] __initdata = { + RK3288_DEVICE(CRU), + RK3288_DEVICE(GRF), + RK_DEVICE(RK_GRF_VIRT + RK3288_GRF_SIZE, RK3288_SGRF_PHYS, RK3288_SGRF_SIZE), + RK3288_DEVICE(PMU), + RK3288_DEVICE(ROM), + RK3288_DEVICE(EFUSE), + 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), + RK_DEVICE(RK_DDR_VIRT + 2 * RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PUBL1_PHYS, RK3288_DDR_PUBL_SIZE), + RK_DEVICE(RK_GPIO_VIRT(0), RK3288_GPIO0_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(1), RK3288_GPIO1_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(2), RK3288_GPIO2_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(3), RK3288_GPIO3_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(4), RK3288_GPIO4_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(5), RK3288_GPIO5_PHYS, RK3288_GPIO_SIZE), + RK_DEVICE(RK_GPIO_VIRT(6), RK3288_GPIO6_PHYS, RK3288_GPIO_SIZE), + 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), +}; + +static void __init rk3288_boot_mode_init(void) +{ + u32 flag = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG0); + u32 mode = readl_relaxed(RK_PMU_VIRT + RK3288_PMU_SYS_REG1); + + if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER)) { + mode = BOOT_MODE_RECOVERY; + } + rockchip_boot_mode_init(flag, mode); +#ifdef CONFIG_RK29_WATCHDOG + writel_relaxed(BOOT_MODE_WATCHDOG, RK_PMU_VIRT + RK3288_PMU_SYS_REG1); +#endif +} + +static void __init rk3288_dt_map_io(void) +{ + iotable_init(rk3288_io_desc, ARRAY_SIZE(rk3288_io_desc)); + debug_ll_io_init(); + + rockchip_soc_id = ROCKCHIP_SOC_RK3288; + + /* rkpwm is used instead of old pwm */ + //writel_relaxed(0x00010001, RK_GRF_VIRT + RK3288_GRF_SOC_CON2); + + rk3288_boot_mode_init(); +} + +static bool rk3288_pmu_power_domain_is_on(enum pmu_power_domain pd) +{ + return true; +} + +static int rk3288_pmu_set_idle_request(enum pmu_idle_req req, bool idle) +{ + return 0; +} + +static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on) +{ + return 0; +} + +static void __init rk3288_dt_init_timer(void) +{ + rockchip_pmu_ops.set_power_domain = rk3288_pmu_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); + clocksource_of_init(); + of_dvfs_init(); +} + +static const char * const rk3288_dt_compat[] __initconst = { + "rockchip,rk3288", + NULL, +}; + +static void rk3288_restart(char mode, const char *cmd) +{ + u32 boot_flag, boot_mode; + + rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode); + + writel_relaxed(boot_flag, RK_PMU_VIRT + RK3288_PMU_SYS_REG0); // for loader + writel_relaxed(boot_mode, RK_PMU_VIRT + RK3288_PMU_SYS_REG1); // for linux + dsb(); + + writel_relaxed(0xeca8, RK_CRU_VIRT + RK3288_CRU_GLB_SRST_SND_VALUE); + dsb(); +} + +DT_MACHINE_START(RK3288_DT, "RK30board") + .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, + .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; + + err = rockchip_pie_init(); + if (err) + return err; + + rockchip_pie_chunk = pie_load_sections(rockchip_sram_pool, rk3288); + if (IS_ERR(rockchip_pie_chunk)) { + err = PTR_ERR(rockchip_pie_chunk); + pr_err("%s: failed to load section %d\n", __func__, err); + rockchip_pie_chunk = NULL; + return err; + } + + 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; +} +arch_initcall(rk3288_pie_init); diff --git a/pie/Makefile b/pie/Makefile index 2d0541899c41..39a4c3f95956 100644 --- a/pie/Makefile +++ b/pie/Makefile @@ -64,6 +64,7 @@ $(obj)/pie_stage2.o: $(obj)/pie_stage1.o $(obj)/libpie_stage2.o OBJCOPYFLAGS_pie_stage3.o += -j ".pie.*" OBJCOPYFLAGS_pie_stage3.o += -j ".pie.text" OBJCOPYFLAGS_pie_stage3.o += -j ".pie.rk3188.text" -j ".pie.rk3188.data" +OBJCOPYFLAGS_pie_stage3.o += -j ".pie.rk3288.text" -j ".pie.rk3288.data" $(obj)/pie_stage3.o: $(obj)/pie_stage2.o $(call if_changed,objcopy) -- 2.34.1