Merge branch develop-3.10
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk312x.c
index 01ff0f575e0ab0d916dd31d657301fa7a4e18103..91255c901ca1abc4c5c0348b4694df725a095ac9 100755 (executable)
@@ -1,6 +1,4 @@
 /*
- * Device Tree support for Rockchip RK3288
- *
  * Copyright (C) 2014 ROCKCHIP, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,6 +23,7 @@
 #include <linux/of_platform.h>
 #include <linux/rockchip/common.h>
 #include <linux/rockchip/cpu.h>
+#include <linux/rockchip/cpu_axi.h>
 #include <linux/rockchip/cru.h>
 #include <linux/rockchip/dvfs.h>
 #include <linux/rockchip/grf.h>
 #include <asm/cputype.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include "cpu_axi.h"
 #include "loader.h"
+#include "rk3126b.h"
 #define CPU 312x
 #include "sram.h"
 #include "pm.h"
 #include "pm-rk312x.c"
+#include <linux/rockchip/cpu.h>
 #define RK312X_DEVICE(name) \
        { \
                .virtual        = (unsigned long) RK_##name##_VIRT, \
@@ -79,7 +79,23 @@ static struct map_desc rk312x_io_desc[] __initdata = {
        RK_DEVICE(RK_GIC_VIRT, RK312X_GIC_DIST_PHYS, RK312X_GIC_DIST_SIZE),
        RK_DEVICE(RK_GIC_VIRT + RK312X_GIC_DIST_SIZE, RK312X_GIC_CPU_PHYS, RK312X_GIC_CPU_SIZE),
        RK_DEVICE(RK312X_IMEM_VIRT, RK312X_IMEM_PHYS, RK312X_IMEM_SIZE),
+       RK_DEVICE(RK_PWM_VIRT, RK312X_PWM_PHYS, RK312X_PWM_SIZE),
 };
+
+static void __init rk312x_boot_mode_init(void)
+{
+       u32 flag = readl_relaxed(RK_PMU_VIRT + RK312X_PMU_SYS_REG0);
+       u32 mode = readl_relaxed(RK_PMU_VIRT + RK312X_PMU_SYS_REG1);
+       u32 rst_st = readl_relaxed(RK_CRU_VIRT + RK312X_CRU_GLB_RST_ST);
+
+       if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER))
+               mode = BOOT_MODE_RECOVERY;
+       if (rst_st & ((1 << 2) | (1 << 3)))
+               mode = BOOT_MODE_WATCHDOG;
+
+       rockchip_boot_mode_init(flag, mode);
+}
+
 static void usb_uart_init(void)
 {
 #ifdef CONFIG_RK_USB_UART
@@ -104,12 +120,18 @@ static void usb_uart_init(void)
 
 static void __init rk312x_dt_map_io(void)
 {
-       u32 val;
-       
+       u32 v;
+
        iotable_init(rk312x_io_desc, ARRAY_SIZE(rk312x_io_desc));
        debug_ll_io_init();
        usb_uart_init();
 
+       /* pmu reset by second global soft reset */
+       v = readl_relaxed(RK_CRU_VIRT + RK312X_CRU_GLB_CNT_TH);
+       v &= ~(3 << 12);
+       v |= 1 << 12;
+       writel_relaxed(v, RK_CRU_VIRT + RK312X_CRU_GLB_CNT_TH);
+
        /* enable timer5 for core */
        writel_relaxed(0, RK312X_TIMER5_VIRT + 0x10);
        dsb();
@@ -118,11 +140,11 @@ static void __init rk312x_dt_map_io(void)
        dsb();
        writel_relaxed(1, RK312X_TIMER5_VIRT + 0x10);
        dsb();
-       val = readl_relaxed(RK_CRU_VIRT + RK312X_CRU_MISC_CON);
-       val &= (~(1 << 15));
-       writel_relaxed(0x80000000 | val, RK_CRU_VIRT + RK312X_CRU_MISC_CON);
+       writel_relaxed(0x80000000, RK_CRU_VIRT + RK312X_CRU_MISC_CON);
        dsb();
 
+       rk312x_boot_mode_init();
+       rockchip_efuse_init();
 }
 
 static void __init rk3126_dt_map_io(void)
@@ -130,6 +152,9 @@ static void __init rk3126_dt_map_io(void)
        rockchip_soc_id = ROCKCHIP_SOC_RK3126;
 
        rk312x_dt_map_io();
+
+       if (readl_relaxed(RK_GRF_VIRT + RK312X_GRF_CHIP_TAG) == 0x3136)
+               rockchip_soc_id = ROCKCHIP_SOC_RK3126B;
 }
 
 static void __init rk3128_dt_map_io(void)
@@ -232,7 +257,8 @@ static int rk312x_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
                        rk312x_pmu_set_idle_request(IDLE_REQ_GPU, true);
                } else if (pd == PD_VIO) {
                        SAVE_QOS(rga_qos, VIO_RGA);
-                       SAVE_QOS(ebc_qos, VIO_EBC);
+                       if (!soc_is_rk3126b())
+                               SAVE_QOS(ebc_qos, VIO_EBC);
                        SAVE_QOS(iep_qos, VIO_IEP);
                        SAVE_QOS(lcdc0_qos, VIO_LCDC0);
                        SAVE_QOS(vip0_qos, VIO_VIP0);
@@ -252,7 +278,8 @@ static int rk312x_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
                } else if (pd == PD_VIO) {
                        rk312x_pmu_set_idle_request(IDLE_REQ_VIO, false);
                        RESTORE_QOS(rga_qos, VIO_RGA);
-                       RESTORE_QOS(ebc_qos, VIO_EBC);
+                       if (!soc_is_rk3126b())
+                               RESTORE_QOS(ebc_qos, VIO_EBC);
                        RESTORE_QOS(iep_qos, VIO_IEP);
                        RESTORE_QOS(lcdc0_qos, VIO_LCDC0);
                        RESTORE_QOS(vip0_qos, VIO_VIP0);
@@ -326,17 +353,61 @@ static void __init rk312x_dt_init_timer(void)
 
 static void __init rk312x_reserve(void)
 {
+       /* reserve memory for uboot */
+       rockchip_uboot_mem_reserve();
+
        /* reserve memory for ION */
        rockchip_ion_reserve();
 }
+
 #ifdef CONFIG_PM
-static void __init rk321x_init_suspend(void);
+static u32 rk_pmu_pwrdn_st;
+
+static void rk_pm_soc_pd_suspend(void)
+{
+       rk_pmu_pwrdn_st = pmu_readl(RK312X_PMU_PWRDN_ST);
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
+               rk312x_sys_set_power_domain(PD_GPU, false);
+
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
+               rk312x_sys_set_power_domain(PD_VIO, false);
+
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
+               rk312x_sys_set_power_domain(PD_VIDEO, false);
+}
+
+static void rk_pm_soc_pd_resume(void)
+{
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
+               rk312x_sys_set_power_domain(PD_VIDEO, true);
+
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
+               rk312x_sys_set_power_domain(PD_VIO, true);
+
+       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
+               rk312x_sys_set_power_domain(PD_GPU, true);
+}
+
+static void __init rk312x_init_suspend(void)
+{
+       pr_info("%s\n", __func__);
+       rkpm_pie_init();
+       rk312x_suspend_init();
+}
 #endif
+
 static void __init rk312x_init_late(void)
 {
 #ifdef CONFIG_PM
-       rk321x_init_suspend();
+       rockchip_suspend_init();
+       if (soc_is_rk3126b())
+               rk3126b_init_suspend();
+       else
+               rk312x_init_suspend();
+       rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend, rk_pm_soc_pd_resume);
 #endif
+       if (rockchip_jtag_enabled)
+               clk_prepare_enable(clk_get_sys(NULL, "clk_jtag"));
 }
 
 static void rk312x_restart(char mode, const char *cmd)
@@ -353,7 +424,7 @@ static void rk312x_restart(char mode, const char *cmd)
        dsb();
 
        /* pll enter slow mode */
-       writel_relaxed(0x30110000, RK_CRU_VIRT + RK312X_CRU_MODE_CON);
+       writel_relaxed(0x11010000, RK_CRU_VIRT + RK312X_CRU_MODE_CON);
        dsb();
        writel_relaxed(0xeca8, RK_CRU_VIRT + RK312X_CRU_GLB_SRST_SND_VALUE);
        dsb();
@@ -389,6 +460,8 @@ static int __init rk312x_pie_init(void)
 
        if (!cpu_is_rk312x())
                return 0;
+       if (soc_is_rk3126b())
+               return 0;
 
        err = rockchip_pie_init();
        if (err)
@@ -412,47 +485,14 @@ arch_initcall(rk312x_pie_init);
 #include "ddr_rk3126.c"
 static int __init rk312x_ddr_init(void)
 {
-       if (cpu_is_rk312x()) {
+       if (soc_is_rk3128() || soc_is_rk3126()) {
                ddr_change_freq = _ddr_change_freq;
                ddr_round_rate = _ddr_round_rate;
                ddr_set_auto_self_refresh = _ddr_set_auto_self_refresh;
                ddr_bandwidth_get = _ddr_bandwidth_get;
-               ddr_init(DDR3_DEFAULT, 300);
-               }
+               ddr_init(DDR3_DEFAULT, 0);
+       }
+
        return 0;
 }
 arch_initcall_sync(rk312x_ddr_init);
-
-#ifdef CONFIG_PM
-static u32 rk_pmu_pwrdn_st;
-static inline void rk_pm_soc_pd_suspend(void)
-{
-       rk_pmu_pwrdn_st = pmu_readl(RK312X_PMU_PWRDN_ST);
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
-               rk312x_sys_set_power_domain(PD_GPU, false);
-
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
-               rk312x_sys_set_power_domain(PD_VIO, false);
-
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
-               rk312x_sys_set_power_domain(PD_VIDEO, false);
-}
-static inline void rk_pm_soc_pd_resume(void)
-{
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
-               rk312x_sys_set_power_domain(PD_VIDEO, true);
-
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
-               rk312x_sys_set_power_domain(PD_VIO, true);
-
-       if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
-               rk312x_sys_set_power_domain(PD_GPU, true);
-}
-static void __init rk321x_init_suspend(void)
-{
-       pr_info("%s\n", __func__);
-       rockchip_suspend_init();
-       rk312x_suspend_init();
-       rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend, rk_pm_soc_pd_resume);
-}
-#endif