blob: 648634d9b6c39e6e28dc7368535e39b0b4f6626a [file] [log] [blame]
Shawn Guo9fbbe682011-09-06 14:39:44 +08001/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
Will Deaconeaa142c2011-08-09 12:24:07 +010017#include <linux/smp.h>
Will Deaconeb504392012-01-20 12:01:12 +010018#include <asm/smp_plat.h>
Fabio Estevam09898572013-03-25 09:20:43 -030019#include "common.h"
Shawn Guo9fbbe682011-09-06 14:39:44 +080020
21#define SRC_SCR 0x000
22#define SRC_GPR1 0x020
Shawn Guo0575fb72011-12-09 00:51:26 +010023#define BP_SRC_SCR_WARM_RESET_ENABLE 0
Shawn Guo9fbbe682011-09-06 14:39:44 +080024#define BP_SRC_SCR_CORE1_RST 14
25#define BP_SRC_SCR_CORE1_ENABLE 22
26
27static void __iomem *src_base;
28
29void imx_enable_cpu(int cpu, bool enable)
30{
31 u32 mask, val;
32
Will Deaconeaa142c2011-08-09 12:24:07 +010033 cpu = cpu_logical_map(cpu);
Shawn Guo9fbbe682011-09-06 14:39:44 +080034 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
35 val = readl_relaxed(src_base + SRC_SCR);
36 val = enable ? val | mask : val & ~mask;
37 writel_relaxed(val, src_base + SRC_SCR);
38}
39
40void imx_set_cpu_jump(int cpu, void *jump_addr)
41{
Will Deaconeaa142c2011-08-09 12:24:07 +010042 cpu = cpu_logical_map(cpu);
Rob Herring0a60cb12012-01-09 15:41:40 -060043 writel_relaxed(virt_to_phys(jump_addr),
Shawn Guo9fbbe682011-09-06 14:39:44 +080044 src_base + SRC_GPR1 + cpu * 8);
45}
46
Shawn Guo0575fb72011-12-09 00:51:26 +010047void imx_src_prepare_restart(void)
48{
49 u32 val;
50
51 /* clear enable bits of secondary cores */
52 val = readl_relaxed(src_base + SRC_SCR);
53 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
54 writel_relaxed(val, src_base + SRC_SCR);
55
56 /* clear persistent entry register of primary core */
57 writel_relaxed(0, src_base + SRC_GPR1);
58}
59
Shawn Guo9fbbe682011-09-06 14:39:44 +080060void __init imx_src_init(void)
61{
62 struct device_node *np;
Shawn Guo0575fb72011-12-09 00:51:26 +010063 u32 val;
Shawn Guo9fbbe682011-09-06 14:39:44 +080064
65 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
66 src_base = of_iomap(np, 0);
67 WARN_ON(!src_base);
Shawn Guo0575fb72011-12-09 00:51:26 +010068
69 /*
70 * force warm reset sources to generate cold reset
71 * for a more reliable restart
72 */
73 val = readl_relaxed(src_base + SRC_SCR);
74 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
75 writel_relaxed(val, src_base + SRC_SCR);
Shawn Guo9fbbe682011-09-06 14:39:44 +080076}