summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorLucas Stach <dev@lynxeye.de>2014-10-20 20:15:30 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-11-04 12:16:40 +0100
commit1834169f13cccb1784172aa1ccb85d89f006c254 (patch)
tree565fef85697814e91039e6d36dfd44b40de517bd /arch/arm/mach-tegra
parentf63a42a9991164fd938ec2f37f0ed1d1caf9ef32 (diff)
downloadbarebox-1834169f13cccb1784172aa1ccb85d89f006c254.tar.gz
barebox-1834169f13cccb1784172aa1ccb85d89f006c254.tar.xz
tegra: pmc: add support for reset src detection
Also activate in defconfig. Signed-off-by: Lucas Stach <dev@lynxeye.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra20-pmc.h9
-rw-r--r--arch/arm/mach-tegra/tegra20-pmc.c32
2 files changed, 41 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
index 30ac06508c..c379544755 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
@@ -71,3 +71,12 @@
#define PMC_PARTID_C0NC 15
#define PMC_SCRATCH(i) (0x050 + 0x4*i)
+
+#define PMC_RST_STATUS 0x1b4
+#define PMC_RST_STATUS_RST_SRC_SHIFT 0
+#define PMC_RST_STATUS_RST_SRC_MASK (0x7 << PMC_RST_STATUS_RST_SRC_SHIFT)
+#define PMC_RST_STATUS_RST_SRC_POR 0
+#define PMC_RST_STATUS_RST_SRC_WATCHDOG 1
+#define PMC_RST_STATUS_RST_SRC_SENSOR 2
+#define PMC_RST_STATUS_RST_SRC_SW_MAIN 3
+#define PMC_RST_STATUS_RST_SRC_LP0 4
diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
index dcd2978109..eaa5ac73ff 100644
--- a/arch/arm/mach-tegra/tegra20-pmc.c
+++ b/arch/arm/mach-tegra/tegra20-pmc.c
@@ -28,6 +28,8 @@
#include <linux/reset.h>
#include <mach/lowlevel.h>
#include <mach/tegra-powergate.h>
+#include <reset_source.h>
+
#include <mach/tegra20-pmc.h>
static void __iomem *pmc_base;
@@ -171,6 +173,33 @@ static int tegra_powergate_init(void)
return 0;
}
+static void tegra20_pmc_detect_reset_cause(void)
+{
+ u32 reg = readl(pmc_base + PMC_RST_STATUS);
+
+ switch ((reg & PMC_RST_STATUS_RST_SRC_MASK) >>
+ PMC_RST_STATUS_RST_SRC_SHIFT) {
+ case PMC_RST_STATUS_RST_SRC_POR:
+ reset_source_set(RESET_POR);
+ break;
+ case PMC_RST_STATUS_RST_SRC_WATCHDOG:
+ reset_source_set(RESET_WDG);
+ break;
+ case PMC_RST_STATUS_RST_SRC_LP0:
+ reset_source_set(RESET_WKE);
+ break;
+ case PMC_RST_STATUS_RST_SRC_SW_MAIN:
+ reset_source_set(RESET_RST);
+ break;
+ case PMC_RST_STATUS_RST_SRC_SENSOR:
+ reset_source_set(RESET_THERM);
+ break;
+ default:
+ reset_source_set(RESET_UKWN);
+ break;
+ }
+}
+
static int tegra20_pmc_probe(struct device_d *dev)
{
pmc_base = dev_request_mem_region(dev, 0);
@@ -181,6 +210,9 @@ static int tegra20_pmc_probe(struct device_d *dev)
tegra_powergate_init();
+ if (IS_ENABLED(CONFIG_RESET_SOURCE))
+ tegra20_pmc_detect_reset_cause();
+
return 0;
}