aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/src.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 14:02:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 14:02:18 -0400
commitfcba914542082b272f31c8e4c40000b88ed3208d (patch)
treefb28069bf571d93420daafd501b4e97f221d526c /arch/arm/mach-imx/src.c
parenta8c4b90e670be3b01e9395c7310639c8109fc77e (diff)
parent5c5f0421a8eea5bdaba9b9313c5bb4833aeb39cd (diff)
Merge tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates (part 3) from Arnd Bergmann: "This is the third and smallest of the SoC specific updates. Changes include: - SMP support for the Xilinx zynq platform - Smaller imx changes - LPAE support for mvebu - Moving the orion5x, kirkwood, dove and mvebu platforms to a common "mbus" driver for their internal devices. It would be good to get feedback on the location of the "mbus" driver. Since this is used on multiple platforms may potentially get shared with other architectures (powerpc and arm64), it was moved to drivers/bus/. We expect other similar drivers to get moved to the same place in order to avoid creating more top-level directories under drivers/ or cluttering up the messy drivers/misc/ even more." * tag 'soc-for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (50 commits) ARM: imx: reset_controller may be disabled ARM: mvebu: Align the internal registers virtual base to support LPAE ARM: mvebu: Limit the DMA zone when LPAE is selected arm: plat-orion: remove addr-map code arm: mach-mv78xx0: convert to use the mvebu-mbus driver arm: mach-orion5x: convert to use mvebu-mbus driver arm: mach-dove: convert to use mvebu-mbus driver arm: mach-kirkwood: convert to use mvebu-mbus driver arm: mach-mvebu: convert to use mvebu-mbus driver ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock ARM i.MX53: tve_di clock is not part of the CCM, but of TVE ARM i.MX53: make tve_ext_sel propagate rate change to PLL ARM i.MX53: Remove unused tve_gate clkdev entry ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree ARM: i.MX5: Add PATA and SRTC clocks ARM: imx: do not bring up unavailable cores ARM: imx: add initial imx6dl support ARM: imx1: mm: add call to mxc_device_init ARM: imx_v4_v5_defconfig: Add CONFIG_GPIO_SYSFS ARM: imx_v6_v7_defconfig: Select CONFIG_PERF_EVENTS ...
Diffstat (limited to 'arch/arm/mach-imx/src.c')
-rw-r--r--arch/arm/mach-imx/src.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c
index 97d086889481..10a6b1a8c5ac 100644
--- a/arch/arm/mach-imx/src.c
+++ b/arch/arm/mach-imx/src.c
@@ -14,6 +14,7 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/reset-controller.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <asm/smp_plat.h> 19#include <asm/smp_plat.h>
19#include "common.h" 20#include "common.h"
@@ -21,10 +22,65 @@
21#define SRC_SCR 0x000 22#define SRC_SCR 0x000
22#define SRC_GPR1 0x020 23#define SRC_GPR1 0x020
23#define BP_SRC_SCR_WARM_RESET_ENABLE 0 24#define BP_SRC_SCR_WARM_RESET_ENABLE 0
25#define BP_SRC_SCR_SW_GPU_RST 1
26#define BP_SRC_SCR_SW_VPU_RST 2
27#define BP_SRC_SCR_SW_IPU1_RST 3
28#define BP_SRC_SCR_SW_OPEN_VG_RST 4
29#define BP_SRC_SCR_SW_IPU2_RST 12
24#define BP_SRC_SCR_CORE1_RST 14 30#define BP_SRC_SCR_CORE1_RST 14
25#define BP_SRC_SCR_CORE1_ENABLE 22 31#define BP_SRC_SCR_CORE1_ENABLE 22
26 32
27static void __iomem *src_base; 33static void __iomem *src_base;
34static DEFINE_SPINLOCK(scr_lock);
35
36static const int sw_reset_bits[5] = {
37 BP_SRC_SCR_SW_GPU_RST,
38 BP_SRC_SCR_SW_VPU_RST,
39 BP_SRC_SCR_SW_IPU1_RST,
40 BP_SRC_SCR_SW_OPEN_VG_RST,
41 BP_SRC_SCR_SW_IPU2_RST
42};
43
44static int imx_src_reset_module(struct reset_controller_dev *rcdev,
45 unsigned long sw_reset_idx)
46{
47 unsigned long timeout;
48 unsigned long flags;
49 int bit;
50 u32 val;
51
52 if (!src_base)
53 return -ENODEV;
54
55 if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits))
56 return -EINVAL;
57
58 bit = 1 << sw_reset_bits[sw_reset_idx];
59
60 spin_lock_irqsave(&scr_lock, flags);
61 val = readl_relaxed(src_base + SRC_SCR);
62 val |= bit;
63 writel_relaxed(val, src_base + SRC_SCR);
64 spin_unlock_irqrestore(&scr_lock, flags);
65
66 timeout = jiffies + msecs_to_jiffies(1000);
67 while (readl(src_base + SRC_SCR) & bit) {
68 if (time_after(jiffies, timeout))
69 return -ETIME;
70 cpu_relax();
71 }
72
73 return 0;
74}
75
76static struct reset_control_ops imx_src_ops = {
77 .reset = imx_src_reset_module,
78};
79
80static struct reset_controller_dev imx_reset_controller = {
81 .ops = &imx_src_ops,
82 .nr_resets = ARRAY_SIZE(sw_reset_bits),
83};
28 84
29void imx_enable_cpu(int cpu, bool enable) 85void imx_enable_cpu(int cpu, bool enable)
30{ 86{
@@ -32,9 +88,11 @@ void imx_enable_cpu(int cpu, bool enable)
32 88
33 cpu = cpu_logical_map(cpu); 89 cpu = cpu_logical_map(cpu);
34 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); 90 mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1);
91 spin_lock(&scr_lock);
35 val = readl_relaxed(src_base + SRC_SCR); 92 val = readl_relaxed(src_base + SRC_SCR);
36 val = enable ? val | mask : val & ~mask; 93 val = enable ? val | mask : val & ~mask;
37 writel_relaxed(val, src_base + SRC_SCR); 94 writel_relaxed(val, src_base + SRC_SCR);
95 spin_unlock(&scr_lock);
38} 96}
39 97
40void imx_set_cpu_jump(int cpu, void *jump_addr) 98void imx_set_cpu_jump(int cpu, void *jump_addr)
@@ -61,9 +119,11 @@ void imx_src_prepare_restart(void)
61 u32 val; 119 u32 val;
62 120
63 /* clear enable bits of secondary cores */ 121 /* clear enable bits of secondary cores */
122 spin_lock(&scr_lock);
64 val = readl_relaxed(src_base + SRC_SCR); 123 val = readl_relaxed(src_base + SRC_SCR);
65 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); 124 val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
66 writel_relaxed(val, src_base + SRC_SCR); 125 writel_relaxed(val, src_base + SRC_SCR);
126 spin_unlock(&scr_lock);
67 127
68 /* clear persistent entry register of primary core */ 128 /* clear persistent entry register of primary core */
69 writel_relaxed(0, src_base + SRC_GPR1); 129 writel_relaxed(0, src_base + SRC_GPR1);
@@ -80,11 +140,17 @@ void __init imx_src_init(void)
80 src_base = of_iomap(np, 0); 140 src_base = of_iomap(np, 0);
81 WARN_ON(!src_base); 141 WARN_ON(!src_base);
82 142
143 imx_reset_controller.of_node = np;
144 if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
145 reset_controller_register(&imx_reset_controller);
146
83 /* 147 /*
84 * force warm reset sources to generate cold reset 148 * force warm reset sources to generate cold reset
85 * for a more reliable restart 149 * for a more reliable restart
86 */ 150 */
151 spin_lock(&scr_lock);
87 val = readl_relaxed(src_base + SRC_SCR); 152 val = readl_relaxed(src_base + SRC_SCR);
88 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); 153 val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
89 writel_relaxed(val, src_base + SRC_SCR); 154 writel_relaxed(val, src_base + SRC_SCR);
155 spin_unlock(&scr_lock);
90} 156}