aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-imx/clock-imx6q.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c35
-rw-r--r--arch/arm/mach-imx/src.c23
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h1
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
29void 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
54soft:
55 /* we'll take a jump through zero as a poor second */
56 soft_restart(0);
57}
58
26static void __init imx6q_init_machine(void) 59static 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,
87MACHINE_END 120MACHINE_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
50void 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
49void __init imx_src_init(void) 63void __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) {}
122extern void imx_enable_cpu(int cpu, bool enable); 122extern void imx_enable_cpu(int cpu, bool enable);
123extern void imx_set_cpu_jump(int cpu, void *jump_addr); 123extern void imx_set_cpu_jump(int cpu, void *jump_addr);
124extern void imx_src_init(void); 124extern void imx_src_init(void);
125extern void imx_src_prepare_restart(void);
125extern void imx_gpc_init(void); 126extern void imx_gpc_init(void);
126extern void imx_gpc_pre_suspend(void); 127extern void imx_gpc_pre_suspend(void);
127extern void imx_gpc_post_resume(void); 128extern void imx_gpc_post_resume(void);