/*
- * Copyright (C) 2013 ROCKCHIP, Inc.
+ * Copyright (C) 2013-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
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <asm/hardware/cache-l2x0.h>
+#include "common.h"
#include "cpu_axi.h"
+#include "loader.h"
+#include "pmu.h"
#include "sram.h"
static int __init rockchip_cpu_axi_init(void)
return 0;
}
+
+static bool is_panic = false;
+
+static int panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ is_panic = true;
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+ .notifier_call = panic_event,
+};
+
+static int boot_mode;
+
+int rockchip_boot_mode(void)
+{
+ return boot_mode;
+}
+EXPORT_SYMBOL(rockchip_boot_mode);
+
+static inline const char *boot_flag_name(u32 flag)
+{
+ flag -= SYS_KERNRL_REBOOT_FLAG;
+ switch (flag) {
+ case BOOT_NORMAL: return "NORMAL";
+ case BOOT_LOADER: return "LOADER";
+ case BOOT_MASKROM: return "MASKROM";
+ case BOOT_RECOVER: return "RECOVER";
+ case BOOT_NORECOVER: return "NORECOVER";
+ case BOOT_SECONDOS: return "SECONDOS";
+ case BOOT_WIPEDATA: return "WIPEDATA";
+ case BOOT_WIPEALL: return "WIPEALL";
+ case BOOT_CHECKIMG: return "CHECKIMG";
+ case BOOT_FASTBOOT: return "FASTBOOT";
+ default: return "";
+ }
+}
+
+static inline const char *boot_mode_name(u32 mode)
+{
+ switch (mode) {
+ case BOOT_MODE_NORMAL: return "NORMAL";
+ case BOOT_MODE_FACTORY2: return "FACTORY2";
+ case BOOT_MODE_RECOVERY: return "RECOVERY";
+ case BOOT_MODE_CHARGE: return "CHARGE";
+ case BOOT_MODE_POWER_TEST: return "POWER_TEST";
+ case BOOT_MODE_OFFMODE_CHARGING: return "OFFMODE_CHARGING";
+ case BOOT_MODE_REBOOT: return "REBOOT";
+ case BOOT_MODE_PANIC: return "PANIC";
+ case BOOT_MODE_WATCHDOG: return "WATCHDOG";
+ default: return "";
+ }
+}
+
+void __init rockchip_boot_mode_init(u32 flag, u32 mode)
+{
+ boot_mode = mode;
+ if (mode || ((flag & 0xff) && ((flag & 0xffffff00) == SYS_KERNRL_REBOOT_FLAG)))
+ printk("Boot mode: %s (%d) flag: %s (0x%08x)\n", boot_mode_name(mode), mode, boot_flag_name(flag), flag);
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+}
+
+void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode)
+{
+ *flag = 0;
+ *mode = BOOT_MODE_REBOOT;
+
+ if (cmd) {
+ if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
+ *flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
+ else if(!strcmp(cmd, "recovery"))
+ *flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
+ else if (!strcmp(cmd, "charge"))
+ *mode = BOOT_MODE_CHARGE;
+ } else {
+ if (is_panic)
+ *mode = BOOT_MODE_PANIC;
+ }
+}
+
+struct rockchip_pmu_operations rockchip_pmu_ops;
--- /dev/null
+#ifndef __MACH_ROCKCHIP_COMMON_H
+#define __MACH_ROCKCHIP_COMMON_H
+
+extern unsigned long rockchip_boot_fn;
+extern struct smp_operations rockchip_smp_ops;
+
+#define BOOT_MODE_NORMAL 0
+#define BOOT_MODE_FACTORY2 1
+#define BOOT_MODE_RECOVERY 2
+#define BOOT_MODE_CHARGE 3
+#define BOOT_MODE_POWER_TEST 4
+#define BOOT_MODE_OFFMODE_CHARGING 5
+#define BOOT_MODE_REBOOT 6
+#define BOOT_MODE_PANIC 7
+#define BOOT_MODE_WATCHDOG 8
+
+extern int rockchip_boot_mode(void);
+extern void __init rockchip_boot_mode_init(u32 flag, u32 mode);
+extern void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode);
+
+#endif
+++ /dev/null
-/*
- * Copyright (C) 2013 ROCKCHIP, Inc.
- * Copyright (c) 2013 MundoReader S.L.
- * Author: Heiko Stuebner <heiko@sntech.de>
- *
- * 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.
- */
-
-#ifndef __MACH_CORE_H
-#define __MACH_CORE_H
-
-extern unsigned long rockchip_boot_fn;
-
-extern struct smp_operations rockchip_smp_ops;
-
-#endif
writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \
} while (0)
+#define RK3188_CPU_AXI_DMAC_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x1000)
+#define RK3188_CPU_AXI_CPU0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2000)
+#define RK3188_CPU_AXI_CPU1R_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2080)
+#define RK3188_CPU_AXI_CPU1W_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2100)
+#define RK3188_CPU_AXI_PERI_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x4000)
+#define RK3188_CPU_AXI_GPU_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x5000)
+#define RK3188_CPU_AXI_VPU_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x6000)
+#define RK3188_CPU_AXI_LCDC0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7000)
+#define RK3188_CPU_AXI_CIF0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7080)
+#define RK3188_CPU_AXI_IPP_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7100)
+#define RK3188_CPU_AXI_LCDC1_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7180)
+#define RK3188_CPU_AXI_CIF1_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7200)
+#define RK3188_CPU_AXI_RGA_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7280)
+
#endif
--- /dev/null
+#ifndef __MACH_ROCKCHIP_CRU_H
+#define __MACH_ROCKCHIP_CRU_H
+
+enum {
+ RK3188_APLL_ID = 0,
+ RK3188_DPLL_ID,
+ RK3188_CPLL_ID,
+ RK3188_GPLL_ID,
+ RK3188_END_PLL_ID,
+};
+
+#define RK3188_CRU_MODE_CON 0x40
+#define RK3188_CRU_CLKSEL_CON 0x44
+#define RK3188_CRU_CLKGATE_CON 0xd0
+#define RK3188_CRU_GLB_SRST_FST 0x100
+#define RK3188_CRU_GLB_SRST_SND 0x104
+#define RK3188_CRU_SOFTRST_CON 0x110
+
+#define RK3188_PLL_CONS(id, i) ((id) * 0x10 + ((i) * 4))
+
+#define RK3188_CRU_CLKSELS_CON_CNT (35)
+#define RK3188_CRU_CLKSELS_CON(i) (RK3188_CRU_CLKSEL_CON + ((i) * 4))
+
+#define RK3188_CRU_CLKGATES_CON_CNT (10)
+#define RK3188_CRU_CLKGATES_CON(i) (RK3188_CRU_CLKGATE_CON + ((i) * 4))
+
+#define RK3188_CRU_SOFTRSTS_CON_CNT (9)
+#define RK3188_CRU_SOFTRSTS_CON(i) (RK3188_CRU_SOFTRST_CON + ((i) * 4))
+
+#define RK3188_CRU_MISC_CON (0x134)
+#define RK3188_CRU_GLB_CNT_TH (0x140)
+
+/*******************MODE BITS***************************/
+
+#define RK3188_PLL_MODE_MSK(id) (0x3 << ((id) * 4))
+#define RK3188_PLL_MODE_SLOW(id) ((0x0<<((id)*4))|(0x3<<(16+(id)*4)))
+#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)))
+
+#endif
--- /dev/null
+#ifndef __MACH_ROCKCHIP_LOADER_H
+#define __MACH_ROCKCHIP_LOADER_H
+
+#define SYS_LOADER_REBOOT_FLAG 0x5242C300 //high 24 bits is tag, low 8 bits is type
+#define SYS_KERNRL_REBOOT_FLAG 0xC3524200 //high 24 bits is tag, low 8 bits is type
+
+enum {
+ BOOT_NORMAL = 0, /* normal boot */
+ BOOT_LOADER, /* enter loader rockusb mode */
+ BOOT_MASKROM, /* enter maskrom rockusb mode (not support now) */
+ BOOT_RECOVER, /* enter recover */
+ BOOT_NORECOVER, /* do not enter recover */
+ BOOT_SECONDOS, /* boot second OS (not support now)*/
+ BOOT_WIPEDATA, /* enter recover and wipe data. */
+ BOOT_WIPEALL, /* enter recover and wipe all data. */
+ BOOT_CHECKIMG, /* check firmware img with backup part(in loader mode)*/
+ BOOT_FASTBOOT, /* enter fast boot mode (not support now) */
+ BOOT_MAX /* MAX VALID BOOT TYPE.*/
+};
+
+#endif
/*
- * Copyright (C) 2013 ROCKCHIP, Inc.
+ * Copyright (C) 2013-2014 ROCKCHIP, Inc.
* Copyright (c) 2013 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
#include <asm/smp_plat.h>
#include <asm/mach/map.h>
-#include "core.h"
+#include "common.h"
+#include "pmu.h"
#define SCU_CTRL 0x00
#define SCU_STANDBY_EN (1 << 5)
static int ncores;
-/*
- * temporary PMU handling
- */
-
-#define PMU_PWRDN_CON 0x08
-#define PMU_PWRDN_ST 0x0c
-
-static void __iomem *pmu_base_addr;
-
extern void secondary_startup(void);
extern void v7_invalidate_l1(void);
);
}
-static inline bool pmu_power_domain_is_on(int pd)
-{
- return !(readl_relaxed(pmu_base_addr + PMU_PWRDN_ST) & BIT(pd));
-}
-
-static void pmu_set_power_domain(int pd, bool on)
-{
- u32 val = readl_relaxed(pmu_base_addr + PMU_PWRDN_CON);
- if (on)
- val &= ~BIT(pd);
- else
- val |= BIT(pd);
- writel(val, pmu_base_addr + PMU_PWRDN_CON);
-
- while (pmu_power_domain_is_on(pd) != on) { }
-}
-
/*
* Handling of CPU cores
*/
}
/* start the core */
- pmu_set_power_domain(0 + cpu, true);
+ rockchip_pmu_ops.set_power_domain(PD_CPU_0 + cpu, true);
return 0;
}
return;
}
- pmu_base_addr = of_iomap(node, 0);
-
/*
* While the number of cpus is gathered from dt, also get the number
* of cores from the scu to verify this value when booting the cores.
for (i = 0; i < ncores; i++) {
if (i == cpu)
continue;
- pmu_set_power_domain(i, false);
+ rockchip_pmu_ops.set_power_domain(PD_CPU_0 + i, false);
}
iounmap(scu_base_addr);
--- /dev/null
+#ifndef __MACH_ROCKCHIP_PMU_H
+#define __MACH_ROCKCHIP_PMU_H
+
+#define RK3188_PMU_WAKEUP_CFG0 0x00
+#define RK3188_PMU_WAKEUP_CFG1 0x04
+#define RK3188_PMU_PWRDN_CON 0x08
+#define RK3188_PMU_PWRDN_ST 0x0c
+#define RK3188_PMU_INT_CON 0x10
+#define RK3188_PMU_INT_ST 0x14
+#define RK3188_PMU_MISC_CON 0x18
+#define RK3188_PMU_OSC_CNT 0x1c
+#define RK3188_PMU_PLL_CNT 0x20
+#define RK3188_PMU_PMU_CNT 0x24
+#define RK3188_PMU_DDRIO_PWRON_CNT 0x28
+#define RK3188_PMU_WAKEUP_RST_CLR_CNT 0x2c
+#define RK3188_PMU_SCU_PWRDWN_CNT 0x30
+#define RK3188_PMU_SCU_PWRUP_CNT 0x34
+#define RK3188_PMU_MISC_CON1 0x38
+#define RK3188_PMU_GPIO0_CON 0x3c
+#define RK3188_PMU_SYS_REG0 0x40
+#define RK3188_PMU_SYS_REG1 0x44
+#define RK3188_PMU_SYS_REG2 0x48
+#define RK3188_PMU_SYS_REG3 0x4c
+#define RK3188_PMU_STOP_INT_DLY 0x60
+#define RK3188_PMU_GPIO0A_PULL 0x64
+#define RK3188_PMU_GPIO0B_PULL 0x68
+
+enum pmu_power_domain {
+ PD_BCPU,
+ PD_BDSP,
+ PD_BUS,
+ PD_CPU_0,
+ PD_CPU_1,
+ PD_CPU_2,
+ PD_CPU_3,
+ PD_CS,
+ PD_GPU,
+ PD_PERI,
+ PD_SCU,
+ PD_VIDEO,
+ PD_VIO,
+};
+
+enum pmu_idle_req {
+ IDLE_REQ_ALIVE,
+ IDLE_REQ_AP2BP,
+ IDLE_REQ_BP2AP,
+ IDLE_REQ_BUS,
+ IDLE_REQ_CORE,
+ IDLE_REQ_DMA,
+ IDLE_REQ_GPU,
+ IDLE_REQ_PERI,
+ IDLE_REQ_VIDEO,
+ IDLE_REQ_VIO,
+};
+
+struct rockchip_pmu_operations {
+ int (*set_power_domain)(enum pmu_power_domain pd, bool on);
+ bool (*power_domain_is_on)(enum pmu_power_domain pd);
+ int (*set_idle_request)(enum pmu_idle_req req, bool idle);
+};
+
+extern struct rockchip_pmu_operations rockchip_pmu_ops;
+
+#endif
/*
* Device Tree support for Rockchip RK3188
*
- * Copyright (C) 2013 ROCKCHIP, Inc.
+ * Copyright (C) 2013-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
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include "core.h"
+#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"
#define RK3188_DEVICE(name) \
},
};
+static void __init rk3188_boot_mode_init(void)
+{
+ u32 flag = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_SYS_REG0);
+ u32 mode = readl_relaxed(RK_PMU_VIRT + RK3188_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 + RK3188_PMU_SYS_REG1);
+#endif
+}
+
static void __init rk3188_dt_map_io(void)
{
preset_lpj = 11996091ULL / 2;
/* rki2c is used instead of old i2c */
writel_relaxed(0xF800F800, RK_GRF_VIRT + RK3188_GRF_SOC_CON1);
+
+ rk3188_boot_mode_init();
+}
+
+static const u8 pmu_pd_map[] = {
+ [PD_CPU_0] = 0,
+ [PD_CPU_1] = 1,
+ [PD_CPU_2] = 2,
+ [PD_CPU_3] = 3,
+ [PD_SCU] = 4,
+ [PD_BUS] = 5,
+ [PD_PERI] = 6,
+ [PD_VIO] = 7,
+ [PD_VIDEO] = 8,
+ [PD_GPU] = 9,
+ [PD_CS] = 10,
+};
+
+static bool rk3188_pmu_power_domain_is_on(enum pmu_power_domain pd)
+{
+ /* 1'b0: power on, 1'b1: power off */
+ return !(readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pmu_pd_map[pd]));
+}
+
+static noinline void do_pmu_set_power_domain(enum pmu_power_domain domain, bool on)
+{
+ u8 pd = pmu_pd_map[domain];
+ u32 val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
+ if (on)
+ val &= ~BIT(pd);
+ else
+ val |= BIT(pd);
+ writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_PWRDN_CON);
+ dsb();
+
+ while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & BIT(pd)) == on)
+ ;
+}
+
+static DEFINE_SPINLOCK(pmu_misc_con1_lock);
+
+static const u8 pmu_req_map[] = {
+ [IDLE_REQ_BUS] = 1,
+ [IDLE_REQ_PERI] = 2,
+ [IDLE_REQ_GPU] = 3,
+ [IDLE_REQ_VIDEO] = 4,
+ [IDLE_REQ_VIO] = 5,
+};
+
+static const u8 pmu_idle_map[] = {
+ [IDLE_REQ_DMA] = 14,
+ [IDLE_REQ_CORE] = 15,
+ [IDLE_REQ_VIO] = 22,
+ [IDLE_REQ_VIDEO] = 23,
+ [IDLE_REQ_GPU] = 24,
+ [IDLE_REQ_PERI] = 25,
+ [IDLE_REQ_BUS] = 26,
+};
+
+static const u8 pmu_ack_map[] = {
+ [IDLE_REQ_DMA] = 17,
+ [IDLE_REQ_CORE] = 18,
+ [IDLE_REQ_VIO] = 27,
+ [IDLE_REQ_VIDEO] = 28,
+ [IDLE_REQ_GPU] = 29,
+ [IDLE_REQ_PERI] = 30,
+ [IDLE_REQ_BUS] = 31,
+};
+
+static int rk3188_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
+{
+ u32 idle_mask = BIT(pmu_idle_map[req]);
+ u32 idle_target = idle << pmu_idle_map[req];
+ u32 ack_mask = BIT(pmu_ack_map[req]);
+ u32 ack_target = idle << pmu_ack_map[req];
+ u32 mask = BIT(pmu_req_map[req]);
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pmu_misc_con1_lock, flags);
+ val = readl_relaxed(RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
+ if (idle)
+ val |= mask;
+ else
+ val &= ~mask;
+ writel_relaxed(val, RK_PMU_VIRT + RK3188_PMU_MISC_CON1);
+ dsb();
+
+ while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & ack_mask) != ack_target)
+ ;
+ while ((readl_relaxed(RK_PMU_VIRT + RK3188_PMU_PWRDN_ST) & idle_mask) != idle_target)
+ ;
+ spin_unlock_irqrestore(&pmu_misc_con1_lock, flags);
+
+ return 0;
+}
+
+/*
+ * software should power down or power up power domain one by one. Power down or
+ * power up multiple power domains simultaneously will result in chip electric current
+ * change dramatically which will affect the chip function.
+ */
+static DEFINE_SPINLOCK(pmu_pd_lock);
+static u32 lcdc0_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 lcdc1_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 cif0_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 cif1_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 ipp_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 rga_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS];
+static u32 vpu_qos[CPU_AXI_QOS_NUM_REGS];
+
+#define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_BASE)
+#define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_BASE)
+
+static int rk3188_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pmu_pd_lock, flags);
+ if (rk3188_pmu_power_domain_is_on(pd) == on) {
+ spin_unlock_irqrestore(&pmu_pd_lock, flags);
+ return 0;
+ }
+ if (!on) {
+ /* if power down, idle request to NIU first */
+ if (pd == PD_VIO) {
+ SAVE_QOS(lcdc0_qos, LCDC0);
+ SAVE_QOS(lcdc1_qos, LCDC1);
+ SAVE_QOS(cif0_qos, CIF0);
+ SAVE_QOS(cif1_qos, CIF1);
+ SAVE_QOS(ipp_qos, IPP);
+ SAVE_QOS(rga_qos, RGA);
+ rk3188_pmu_set_idle_request(IDLE_REQ_VIO, true);
+ } else if (pd == PD_VIDEO) {
+ SAVE_QOS(vpu_qos, VPU);
+ rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
+ } else if (pd == PD_GPU) {
+ SAVE_QOS(gpu_qos, GPU);
+ rk3188_pmu_set_idle_request(IDLE_REQ_GPU, true);
+ }
+ }
+ do_pmu_set_power_domain(pd, on);
+ if (on) {
+ /* if power up, idle request release to NIU */
+ if (pd == PD_VIO) {
+ rk3188_pmu_set_idle_request(IDLE_REQ_VIO, false);
+ RESTORE_QOS(lcdc0_qos, LCDC0);
+ RESTORE_QOS(lcdc1_qos, LCDC1);
+ RESTORE_QOS(cif0_qos, CIF0);
+ RESTORE_QOS(cif1_qos, CIF1);
+ RESTORE_QOS(ipp_qos, IPP);
+ RESTORE_QOS(rga_qos, RGA);
+ } else if (pd == PD_VIDEO) {
+ rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
+ RESTORE_QOS(vpu_qos, VPU);
+ } else if (pd == PD_GPU) {
+ rk3188_pmu_set_idle_request(IDLE_REQ_GPU, false);
+ RESTORE_QOS(gpu_qos, GPU);
+ }
+ }
+ spin_unlock_irqrestore(&pmu_pd_lock, flags);
+
+ return 0;
}
static void __init rk3188_dt_init_timer(void)
{
+ rockchip_pmu_ops.set_power_domain = rk3188_pmu_set_power_domain;
+ rockchip_pmu_ops.power_domain_is_on = rk3188_pmu_power_domain_is_on;
+ rockchip_pmu_ops.set_idle_request = rk3188_pmu_set_idle_request;
of_clk_init(NULL);
clocksource_of_init();
}
-static const char * const rk3188_dt_compat[] = {
+static const char * const rk3188_dt_compat[] __initconst = {
"rockchip,rk3188",
NULL,
};
+static void rk3188_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 + RK3188_PMU_SYS_REG0); // for loader
+ writel_relaxed(boot_mode, RK_PMU_VIRT + RK3188_PMU_SYS_REG1); // for linux
+ dsb();
+
+ /* disable remap */
+ writel_relaxed(1 << (12 + 16), RK_GRF_VIRT + RK3188_GRF_SOC_CON0);
+ /* pll enter slow mode */
+ writel_relaxed(RK3188_PLL_MODE_SLOW(RK3188_APLL_ID) |
+ RK3188_PLL_MODE_SLOW(RK3188_CPLL_ID) |
+ RK3188_PLL_MODE_SLOW(RK3188_GPLL_ID),
+ RK_CRU_VIRT + RK3188_CRU_MODE_CON);
+ dsb();
+ writel_relaxed(0xeca8, RK_CRU_VIRT + RK3188_CRU_GLB_SRST_SND);
+ dsb();
+}
+
DT_MACHINE_START(RK3188_DT, "Rockchip RK3188 (Flattened Device Tree)")
.smp = smp_ops(rockchip_smp_ops),
.map_io = rk3188_dt_map_io,
.init_time = rk3188_dt_init_timer,
.dt_compat = rk3188_dt_compat,
+ .restart = rk3188_restart,
MACHINE_END
#define CPU 3188
#define sram_printascii(s) do {} while (0) /* FIXME */
#include "ddr_rk30.c"
-static int rk3188_ddr_init(void)
+static int __init rk3188_ddr_init(void)
{
if (cpu_is_rk3188())
ddr_init(DDR3_DEFAULT, 300);