From 1834169f13cccb1784172aa1ccb85d89f006c254 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 20 Oct 2014 20:15:30 +0200 Subject: [PATCH] tegra: pmc: add support for reset src detection Also activate in defconfig. Signed-off-by: Lucas Stach Signed-off-by: Sascha Hauer --- arch/arm/configs/tegra_v7_defconfig | 1 + .../arm/mach-tegra/include/mach/tegra20-pmc.h | 9 ++++++ arch/arm/mach-tegra/tegra20-pmc.c | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig index ead69edff..1402bd6d0 100644 --- a/arch/arm/configs/tegra_v7_defconfig +++ b/arch/arm/configs/tegra_v7_defconfig @@ -16,6 +16,7 @@ CONFIG_AUTO_COMPLETE=y CONFIG_MENU=y CONFIG_BLSPEC=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_RESET_SOURCE=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y CONFIG_CMD_MEMINFO=y diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h index 30ac06508..c37954475 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 dcd297810..eaa5ac73f 100644 --- a/arch/arm/mach-tegra/tegra20-pmc.c +++ b/arch/arm/mach-tegra/tegra20-pmc.c @@ -28,6 +28,8 @@ #include #include #include +#include + #include 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; }