keystone2: add possibility to turn off all dsps

By default all DSPs are turned off, for another case option
to turn off them is added in this commit.
Also add command to turn off itself.

Acked-by: Murali Karicheri <m-maricheri2@ti.com>
Signed-off-by: Hao Zhang <hzhang@ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
diff --git a/arch/arm/cpu/armv7/keystone/keystone.c b/arch/arm/cpu/armv7/keystone/keystone.c
index 48c8690..1c8c038 100644
--- a/arch/arm/cpu/armv7/keystone/keystone.c
+++ b/arch/arm/cpu/armv7/keystone/keystone.c
@@ -9,6 +9,9 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/mon.h>
+#include <asm/arch/psc_defs.h>
+#include <asm/arch/hardware.h>
 #include <asm/arch/hardware.h>
 
 /**
@@ -26,3 +29,59 @@
 
 	return 0;
 }
+
+static int turn_off_myself(void)
+{
+	printf("Turning off ourselves\r\n");
+	mon_power_off(0);
+
+	psc_disable_module(KS2_LPSC_TETRIS);
+	psc_disable_domain(KS2_TETRIS_PWR_DOMAIN);
+
+	asm volatile ("isb\n"
+		      "dsb\n"
+		      "wfi\n");
+
+	printf("What! Should not see that\n");
+	return 0;
+}
+
+static void turn_off_all_dsps(int num_dsps)
+{
+	int i;
+
+	for (i = 0; i < num_dsps; i++) {
+		if (psc_disable_module(i + KS2_LPSC_GEM_0))
+			printf("Cannot disable module for #%d DSP", i);
+
+		if (psc_disable_domain(i + 8))
+			printf("Cannot disable domain for #%d DSP", i);
+	}
+}
+
+int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	return turn_off_myself();
+}
+
+U_BOOT_CMD(
+	killme, 1,      0,      do_killme_cmd,
+	"turn off main ARM core",
+	"turn off main ARM core. Should not live after that :(\n"
+);
+
+int misc_init_r(void)
+{
+	char *env;
+	long ks2_debug = 0;
+
+	env = getenv("ks2_debug");
+
+	if (env)
+		ks2_debug = simple_strtol(env, NULL, 0);
+
+	if ((ks2_debug & DBG_LEAVE_DSPS_ON) == 0)
+		turn_off_all_dsps(KS2_NUM_DSPS);
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
index 2cac633..5e2f659 100644
--- a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
+++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h
@@ -68,7 +68,6 @@
 #define K2HK_LPSC_VUSR0                12
 #define K2HK_LPSC_CHIP_SRSS            13
 #define K2HK_LPSC_MSMC                 14
-#define K2HK_LPSC_GEM_0                15
 #define K2HK_LPSC_GEM_1                16
 #define K2HK_LPSC_GEM_2                17
 #define K2HK_LPSC_GEM_3                18
@@ -105,7 +104,6 @@
 #define K2HK_LPSC_VUSR1                49
 #define K2HK_LPSC_XGE                  50
 #define K2HK_LPSC_ARM_SREFLEX          51
-#define K2HK_LPSC_TETRIS               52
 
 /* DDR3A definitions */
 #define K2HK_DDR3A_EMIF_CTRL_BASE      0x21010000
@@ -137,4 +135,7 @@
 /* MSMC control */
 #define K2HK_MSMC_CTRL_BASE             0x0bc00000
 
+/* Number of DSP cores */
+#define KS2_NUM_DSPS			8
+
 #endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h
index db2d36b..0dcc31a 100644
--- a/arch/arm/include/asm/arch-keystone/hardware.h
+++ b/arch/arm/include/asm/arch-keystone/hardware.h
@@ -87,11 +87,17 @@
 
 /* PSC */
 #define KS2_PSC_BASE			0x02350000
+#define KS2_LPSC_GEM_0			15
+#define KS2_LPSC_TETRIS			52
+#define KS2_TETRIS_PWR_DOMAIN		31
 
 /* AEMIF */
 #define KS2_AEMIF_CNTRL_BASE       	0x21000a00
 #define DAVINCI_ASYNC_EMIF_CNTRL_BASE   KS2_AEMIF_CNTRL_BASE
 
+/* Flag from ks2_debug options to check if DSPs need to stay ON */
+#define DBG_LEAVE_DSPS_ON		0x1
+
 #ifdef CONFIG_SOC_K2HK
 #include <asm/arch/hardware-k2hk.h>
 #endif
diff --git a/arch/arm/include/asm/arch-keystone/mon.h b/arch/arm/include/asm/arch-keystone/mon.h
new file mode 100644
index 0000000..33a2876
--- /dev/null
+++ b/arch/arm/include/asm/arch-keystone/mon.h
@@ -0,0 +1,15 @@
+/*
+ * K2HK: secure kernel command header file
+ *
+ * (C) Copyright 2014
+ *     Texas Instruments Incorporated, <www.ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _MON_H_
+#define _MON_H_
+
+int mon_power_off(int core_id);
+
+#endif