For wake event, SoundWire host wake interrupt will be asserted based on below pre-conditions for ACP7.0 & ACP7.1 platforms. - ACP device should be in D0 state. - SoundWire manager instance should be in D3 state. - SoundWire manager device state should be set to D3. - ACP_PME_EN should be set to 1. Implement code changes to enable/disable SoundWire host wake interrupt mask during suspend and resume as per design flow for ACP7.0 & ACP7.1 platforms. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx> --- drivers/soundwire/amd_manager.c | 58 +++++++++++++++++++++++++++++++++ drivers/soundwire/amd_manager.h | 2 ++ 2 files changed, 60 insertions(+) diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 03c9e15dce5b..161d963c80e6 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -166,6 +166,34 @@ static int amd_sdw_set_device_state(struct amd_sdw_manager *amd_manager, u32 tar return 0; } +static int amd_sdw_host_wake_enable(struct amd_sdw_manager *amd_manager, bool enable) +{ + u32 intr_cntl1; + u32 sdw_host_wake_irq_mask; + + if (!amd_manager->wake_en_mask) + return 0; + + switch (amd_manager->instance) { + case ACP_SDW0: + sdw_host_wake_irq_mask = AMD_SDW0_HOST_WAKE_INTR_MASK; + break; + case ACP_SDW1: + sdw_host_wake_irq_mask = AMD_SDW1_HOST_WAKE_INTR_MASK; + break; + default: + return -EINVAL; + } + + intr_cntl1 = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1)); + if (enable) + intr_cntl1 |= sdw_host_wake_irq_mask; + else + intr_cntl1 &= ~sdw_host_wake_irq_mask; + writel(intr_cntl1, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1)); + return 0; +} + static void amd_sdw_ctl_word_prep(u32 *lower_word, u32 *upper_word, struct sdw_msg *msg, int cmd_offset) { @@ -1186,11 +1214,21 @@ static int __maybe_unused amd_suspend(struct device *dev) if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) { amd_sdw_wake_enable(amd_manager, false); + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, false); + if (ret) + return ret; + } ret = amd_sdw_clock_stop(amd_manager); if (ret) return ret; } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { amd_sdw_wake_enable(amd_manager, false); + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, false); + if (ret) + return ret; + } /* * As per hardware programming sequence on AMD platforms, * clock stop should be invoked first before powering-off @@ -1224,11 +1262,21 @@ static int __maybe_unused amd_suspend_runtime(struct device *dev) } if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) { amd_sdw_wake_enable(amd_manager, true); + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, true); + if (ret) + return ret; + } ret = amd_sdw_clock_stop(amd_manager); if (ret) return ret; } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { amd_sdw_wake_enable(amd_manager, true); + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, true); + if (ret) + return ret; + } ret = amd_sdw_clock_stop(amd_manager); if (ret) return ret; @@ -1269,8 +1317,18 @@ static int __maybe_unused amd_resume_runtime(struct device *dev) ret = amd_sdw_clock_stop_exit(amd_manager); if (ret) return ret; + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, false); + if (ret) + return ret; + } } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance)); + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { + ret = amd_sdw_host_wake_enable(amd_manager, false); + if (ret) + return ret; + } val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL); if (val) { val |= AMD_SDW_CLK_RESUME_REQ; diff --git a/drivers/soundwire/amd_manager.h b/drivers/soundwire/amd_manager.h index 1d5e94371f81..6cc916b0c820 100644 --- a/drivers/soundwire/amd_manager.h +++ b/drivers/soundwire/amd_manager.h @@ -194,6 +194,8 @@ #define AMD_SDW_CLK_RESUME_DONE 3 #define AMD_SDW_WAKE_STAT_MASK BIT(16) #define AMD_SDW_WAKE_INTR_MASK BIT(16) +#define AMD_SDW0_HOST_WAKE_INTR_MASK BIT(22) +#define AMD_SDW1_HOST_WAKE_INTR_MASK BIT(23) #define AMD_SDW_DEVICE_STATE 0x1430 #define AMD_SDW0_DEVICE_STATE_MASK GENMASK(1, 0) #define AMD_SDW1_DEVICE_STATE_MASK GENMASK(3, 2) -- 2.34.1