diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2011-12-08 18:51:26 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-05 07:57:22 -0500 |
commit | 0575fb754dbfc32a01f297e778533340a533ec68 (patch) | |
tree | 1b416ae6fca7d905003e64c928c7d37032acfd15 /arch/arm | |
parent | f88b8979d26615ce68772cebc85c3b556571afca (diff) |
ARM: 7198/1: arm/imx6: add restart support for imx6q
The restart support was missed from the initial imx6q submission.
The mxc_restart() does not work for imx6q. Instead, this patch adds
the restart for imx6q.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-imx/clock-imx6q.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 35 | ||||
-rw-r--r-- | arch/arm/mach-imx/src.c | 23 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/common.h | 1 |
4 files changed, 58 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c index 039a7abb165a..9273c2a24b54 100644 --- a/arch/arm/mach-imx/clock-imx6q.c +++ b/arch/arm/mach-imx/clock-imx6q.c | |||
@@ -1931,14 +1931,12 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) | |||
1931 | val |= 0x1 << BP_CLPCR_LPM; | 1931 | val |= 0x1 << BP_CLPCR_LPM; |
1932 | val &= ~BM_CLPCR_VSTBY; | 1932 | val &= ~BM_CLPCR_VSTBY; |
1933 | val &= ~BM_CLPCR_SBYOS; | 1933 | val &= ~BM_CLPCR_SBYOS; |
1934 | val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; | ||
1935 | break; | 1934 | break; |
1936 | case STOP_POWER_OFF: | 1935 | case STOP_POWER_OFF: |
1937 | val |= 0x2 << BP_CLPCR_LPM; | 1936 | val |= 0x2 << BP_CLPCR_LPM; |
1938 | val |= 0x3 << BP_CLPCR_STBY_COUNT; | 1937 | val |= 0x3 << BP_CLPCR_STBY_COUNT; |
1939 | val |= BM_CLPCR_VSTBY; | 1938 | val |= BM_CLPCR_VSTBY; |
1940 | val |= BM_CLPCR_SBYOS; | 1939 | val |= BM_CLPCR_SBYOS; |
1941 | val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; | ||
1942 | break; | 1940 | break; |
1943 | default: | 1941 | default: |
1944 | return -EINVAL; | 1942 | return -EINVAL; |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7c6f9ecf7588..05b49bb5d677 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -10,10 +10,13 @@ | |||
10 | * http://www.gnu.org/copyleft/gpl.html | 10 | * http://www.gnu.org/copyleft/gpl.html |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/io.h> | ||
14 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
15 | #include <linux/irqdomain.h> | 17 | #include <linux/irqdomain.h> |
16 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
18 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
19 | #include <asm/hardware/cache-l2x0.h> | 22 | #include <asm/hardware/cache-l2x0.h> |
@@ -23,6 +26,36 @@ | |||
23 | #include <mach/common.h> | 26 | #include <mach/common.h> |
24 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
25 | 28 | ||
29 | void imx6q_restart(char mode, const char *cmd) | ||
30 | { | ||
31 | struct device_node *np; | ||
32 | void __iomem *wdog_base; | ||
33 | |||
34 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); | ||
35 | wdog_base = of_iomap(np, 0); | ||
36 | if (!wdog_base) | ||
37 | goto soft; | ||
38 | |||
39 | imx_src_prepare_restart(); | ||
40 | |||
41 | /* enable wdog */ | ||
42 | writew_relaxed(1 << 2, wdog_base); | ||
43 | /* write twice to ensure the request will not get ignored */ | ||
44 | writew_relaxed(1 << 2, wdog_base); | ||
45 | |||
46 | /* wait for reset to assert ... */ | ||
47 | mdelay(500); | ||
48 | |||
49 | pr_err("Watchdog reset failed to assert reset\n"); | ||
50 | |||
51 | /* delay to allow the serial port to show the message */ | ||
52 | mdelay(50); | ||
53 | |||
54 | soft: | ||
55 | /* we'll take a jump through zero as a poor second */ | ||
56 | soft_restart(0); | ||
57 | } | ||
58 | |||
26 | static void __init imx6q_init_machine(void) | 59 | static void __init imx6q_init_machine(void) |
27 | { | 60 | { |
28 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 61 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
@@ -83,5 +116,5 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") | |||
83 | .timer = &imx6q_timer, | 116 | .timer = &imx6q_timer, |
84 | .init_machine = imx6q_init_machine, | 117 | .init_machine = imx6q_init_machine, |
85 | .dt_compat = imx6q_dt_compat, | 118 | .dt_compat = imx6q_dt_compat, |
86 | .restart = mxc_restart, | 119 | .restart = imx6q_restart, |
87 | MACHINE_END | 120 | MACHINE_END |
diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index a8e33681b732..4bde04f99e38 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #define SRC_SCR 0x000 | 20 | #define SRC_SCR 0x000 |
21 | #define SRC_GPR1 0x020 | 21 | #define SRC_GPR1 0x020 |
22 | #define BP_SRC_SCR_WARM_RESET_ENABLE 0 | ||
22 | #define BP_SRC_SCR_CORE1_RST 14 | 23 | #define BP_SRC_SCR_CORE1_RST 14 |
23 | #define BP_SRC_SCR_CORE1_ENABLE 22 | 24 | #define BP_SRC_SCR_CORE1_ENABLE 22 |
24 | 25 | ||
@@ -46,11 +47,33 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) | |||
46 | src_base + SRC_GPR1 + cpu * 8); | 47 | src_base + SRC_GPR1 + cpu * 8); |
47 | } | 48 | } |
48 | 49 | ||
50 | void imx_src_prepare_restart(void) | ||
51 | { | ||
52 | u32 val; | ||
53 | |||
54 | /* clear enable bits of secondary cores */ | ||
55 | val = readl_relaxed(src_base + SRC_SCR); | ||
56 | val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); | ||
57 | writel_relaxed(val, src_base + SRC_SCR); | ||
58 | |||
59 | /* clear persistent entry register of primary core */ | ||
60 | writel_relaxed(0, src_base + SRC_GPR1); | ||
61 | } | ||
62 | |||
49 | void __init imx_src_init(void) | 63 | void __init imx_src_init(void) |
50 | { | 64 | { |
51 | struct device_node *np; | 65 | struct device_node *np; |
66 | u32 val; | ||
52 | 67 | ||
53 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src"); | 68 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src"); |
54 | src_base = of_iomap(np, 0); | 69 | src_base = of_iomap(np, 0); |
55 | WARN_ON(!src_base); | 70 | WARN_ON(!src_base); |
71 | |||
72 | /* | ||
73 | * force warm reset sources to generate cold reset | ||
74 | * for a more reliable restart | ||
75 | */ | ||
76 | val = readl_relaxed(src_base + SRC_SCR); | ||
77 | val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); | ||
78 | writel_relaxed(val, src_base + SRC_SCR); | ||
56 | } | 79 | } |
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index e519446cc41f..18e5065df3c5 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
@@ -122,6 +122,7 @@ static inline void imx_smp_prepare(void) {} | |||
122 | extern void imx_enable_cpu(int cpu, bool enable); | 122 | extern void imx_enable_cpu(int cpu, bool enable); |
123 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); | 123 | extern void imx_set_cpu_jump(int cpu, void *jump_addr); |
124 | extern void imx_src_init(void); | 124 | extern void imx_src_init(void); |
125 | extern void imx_src_prepare_restart(void); | ||
125 | extern void imx_gpc_init(void); | 126 | extern void imx_gpc_init(void); |
126 | extern void imx_gpc_pre_suspend(void); | 127 | extern void imx_gpc_pre_suspend(void); |
127 | extern void imx_gpc_post_resume(void); | 128 | extern void imx_gpc_post_resume(void); |