Commit 0575fb75 authored by Shawn Guo's avatar Shawn Guo Committed by Russell King

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: default avatarShawn Guo <shawn.guo@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f88b8979
...@@ -1931,14 +1931,12 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) ...@@ -1931,14 +1931,12 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x1 << BP_CLPCR_LPM; val |= 0x1 << BP_CLPCR_LPM;
val &= ~BM_CLPCR_VSTBY; val &= ~BM_CLPCR_VSTBY;
val &= ~BM_CLPCR_SBYOS; val &= ~BM_CLPCR_SBYOS;
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break; break;
case STOP_POWER_OFF: case STOP_POWER_OFF:
val |= 0x2 << BP_CLPCR_LPM; val |= 0x2 << BP_CLPCR_LPM;
val |= 0x3 << BP_CLPCR_STBY_COUNT; val |= 0x3 << BP_CLPCR_STBY_COUNT;
val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_VSTBY;
val |= BM_CLPCR_SBYOS; val |= BM_CLPCR_SBYOS;
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -10,10 +10,13 @@ ...@@ -10,10 +10,13 @@
* http://www.gnu.org/copyleft/gpl.html * http://www.gnu.org/copyleft/gpl.html
*/ */
#include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/cache-l2x0.h>
...@@ -23,6 +26,36 @@ ...@@ -23,6 +26,36 @@
#include <mach/common.h> #include <mach/common.h>
#include <mach/hardware.h> #include <mach/hardware.h>
void imx6q_restart(char mode, const char *cmd)
{
struct device_node *np;
void __iomem *wdog_base;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt");
wdog_base = of_iomap(np, 0);
if (!wdog_base)
goto soft;
imx_src_prepare_restart();
/* enable wdog */
writew_relaxed(1 << 2, wdog_base);
/* write twice to ensure the request will not get ignored */
writew_relaxed(1 << 2, wdog_base);
/* wait for reset to assert ... */
mdelay(500);
pr_err("Watchdog reset failed to assert reset\n");
/* delay to allow the serial port to show the message */
mdelay(50);
soft:
/* we'll take a jump through zero as a poor second */
soft_restart(0);
}
static void __init imx6q_init_machine(void) static void __init imx6q_init_machine(void)
{ {
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 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,5 +116,5 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
.timer = &imx6q_timer, .timer = &imx6q_timer,
.init_machine = imx6q_init_machine, .init_machine = imx6q_init_machine,
.dt_compat = imx6q_dt_compat, .dt_compat = imx6q_dt_compat,
.restart = mxc_restart, .restart = imx6q_restart,
MACHINE_END MACHINE_END
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define SRC_SCR 0x000 #define SRC_SCR 0x000
#define SRC_GPR1 0x020 #define SRC_GPR1 0x020
#define BP_SRC_SCR_WARM_RESET_ENABLE 0
#define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_RST 14
#define BP_SRC_SCR_CORE1_ENABLE 22 #define BP_SRC_SCR_CORE1_ENABLE 22
...@@ -46,11 +47,33 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) ...@@ -46,11 +47,33 @@ void imx_set_cpu_jump(int cpu, void *jump_addr)
src_base + SRC_GPR1 + cpu * 8); src_base + SRC_GPR1 + cpu * 8);
} }
void imx_src_prepare_restart(void)
{
u32 val;
/* clear enable bits of secondary cores */
val = readl_relaxed(src_base + SRC_SCR);
val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE);
writel_relaxed(val, src_base + SRC_SCR);
/* clear persistent entry register of primary core */
writel_relaxed(0, src_base + SRC_GPR1);
}
void __init imx_src_init(void) void __init imx_src_init(void)
{ {
struct device_node *np; struct device_node *np;
u32 val;
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src"); np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-src");
src_base = of_iomap(np, 0); src_base = of_iomap(np, 0);
WARN_ON(!src_base); WARN_ON(!src_base);
/*
* force warm reset sources to generate cold reset
* for a more reliable restart
*/
val = readl_relaxed(src_base + SRC_SCR);
val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE);
writel_relaxed(val, src_base + SRC_SCR);
} }
...@@ -122,6 +122,7 @@ static inline void imx_smp_prepare(void) {} ...@@ -122,6 +122,7 @@ static inline void imx_smp_prepare(void) {}
extern void imx_enable_cpu(int cpu, bool enable); extern void imx_enable_cpu(int cpu, bool enable);
extern void imx_set_cpu_jump(int cpu, void *jump_addr); extern void imx_set_cpu_jump(int cpu, void *jump_addr);
extern void imx_src_init(void); extern void imx_src_init(void);
extern void imx_src_prepare_restart(void);
extern void imx_gpc_init(void); extern void imx_gpc_init(void);
extern void imx_gpc_pre_suspend(void); extern void imx_gpc_pre_suspend(void);
extern void imx_gpc_post_resume(void); extern void imx_gpc_post_resume(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment