[PATCH] soc/tegra: pmc: Support software wake-up for SPE

From: Petlozu Pravareshwar
Date: Mon Sep 19 2022 - 23:55:54 EST


The Sensor Processing Engine(SPE) can trigger a software wake-up of
the device. To support this wake-up for the SPE, set SR_CAPTURE_EN
bit in WAKE_AOWAKE_CNTRL register associated with the wake-up for
the SPE. This SR capturing logic is expected to be enabled for wakes
with short pulse signalling requirements.

Signed-off-by: Viswanath L <viswanathl@xxxxxxxxxx>
Signed-off-by: Petlozu Pravareshwar <petlozup@xxxxxxxxxx>
---
drivers/soc/tegra/pmc.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index f275af15f2d0..02878ea2632c 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -176,6 +176,7 @@
/* Tegra186 and later */
#define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
#define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
+#define WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN (1 << 1)
#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
#define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
@@ -198,6 +199,8 @@
#define WAKE_NR_EVENTS 96
#define WAKE_NR_VECTORS (WAKE_NR_EVENTS / 32)

+#define SW_WAKE_ID 83 /* wake83 */
+
DECLARE_BITMAP(wake_level_map, WAKE_NR_EVENTS);
DECLARE_BITMAP(wake_dual_edge_map, WAKE_NR_EVENTS);

@@ -375,6 +378,7 @@ struct tegra_pmc_soc {
void (*setup_irq_polarity)(struct tegra_pmc *pmc,
struct device_node *np,
bool invert);
+ void (*set_wake_filters)(struct tegra_pmc *pmc);
int (*irq_set_wake)(struct irq_data *data, unsigned int on);
int (*irq_set_type)(struct irq_data *data, unsigned int type);
int (*powergate_set)(struct tegra_pmc *pmc, unsigned int id,
@@ -2447,6 +2451,17 @@ static int tegra210_pmc_irq_set_type(struct irq_data *data, unsigned int type)
return 0;
}

+static void tegra186_pmc_set_wake_filters(struct tegra_pmc *pmc)
+{
+ u32 value;
+
+ /* SW Wake (wake83) needs SR_CAPTURE filter to be enabled */
+ value = readl(pmc->wake + WAKE_AOWAKE_CNTRL(SW_WAKE_ID));
+ value |= WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN;
+ writel(value, pmc->wake + WAKE_AOWAKE_CNTRL(SW_WAKE_ID));
+ dev_dbg(pmc->dev, "WAKE_AOWAKE_CNTRL_83 = 0x%x\n", value);
+}
+
static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
@@ -3078,6 +3093,10 @@ static int tegra_pmc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pmc);
tegra_pm_init_suspend();

+ /* Some wakes require specific filter configuration */
+ if (pmc->soc->set_wake_filters)
+ pmc->soc->set_wake_filters(pmc);
+
return 0;

cleanup_powergates:
@@ -3889,6 +3908,7 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.regs = &tegra186_pmc_regs,
.init = NULL,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+ .set_wake_filters = tegra186_pmc_set_wake_filters,
.irq_set_wake = tegra186_pmc_irq_set_wake,
.irq_set_type = tegra186_pmc_irq_set_type,
.reset_sources = tegra186_reset_sources,
@@ -4024,6 +4044,7 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.regs = &tegra194_pmc_regs,
.init = NULL,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+ .set_wake_filters = tegra186_pmc_set_wake_filters,
.irq_set_wake = tegra186_pmc_irq_set_wake,
.irq_set_type = tegra186_pmc_irq_set_type,
.reset_sources = tegra194_reset_sources,
@@ -4182,6 +4203,7 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
.regs = &tegra234_pmc_regs,
.init = NULL,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+ .set_wake_filters = tegra186_pmc_set_wake_filters,
.irq_set_wake = tegra186_pmc_irq_set_wake,
.irq_set_type = tegra186_pmc_irq_set_type,
.reset_sources = tegra234_reset_sources,
--
2.17.1