[V3,7/8] soundwire: amd: handle SoundWire wake enable interrupt

Message ID 20230220100418.76754-8-Vijendar.Mukunda@amd.com
State New
Headers
Series [V3,1/8] soundwire: export sdw_compute_slave_ports() function |

Commit Message

Mukunda,Vijendar Feb. 20, 2023, 10:04 a.m. UTC
  Add wake enable interrupt support for both the SoundWire manager
instances.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Mastan Katragadda <Mastan.Katragadda@amd.com>
---
 drivers/soundwire/amd_manager.c | 10 ++++++++++
 drivers/soundwire/amd_manager.h |  1 +
 2 files changed, 11 insertions(+)
  

Comments

Pierre-Louis Bossart Feb. 21, 2023, 4:13 p.m. UTC | #1
On 2/20/23 05:04, Vijendar Mukunda wrote:
> Add wake enable interrupt support for both the SoundWire manager
> instances.
> 
> Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
> Signed-off-by: Mastan Katragadda <Mastan.Katragadda@amd.com>
> ---
>  drivers/soundwire/amd_manager.c | 10 ++++++++++
>  drivers/soundwire/amd_manager.h |  1 +
>  2 files changed, 11 insertions(+)
> 
> diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
> index 3322adeca0d8..a7182aa78652 100644
> --- a/drivers/soundwire/amd_manager.c
> +++ b/drivers/soundwire/amd_manager.c
> @@ -932,6 +932,13 @@ static void amd_sdw_update_slave_status(u32 status_change_0to7, u32 status_chang
>  	}
>  }
>  
> +static void amd_sdw_process_wake_event(struct amd_sdw_manager *amd_manager)
> +{
> +	pm_request_resume(amd_manager->dev);

is this needed?

In the Intel case, the wakes do not necessarily come as in-band wakes,
but they can also be notified by the PCI subsystem, so we do have to use
pm_request_resume.

In the AMD case, what happens if you don't do this? Doesn't the
interrupt trigger a pm_runtime_resume already?

> +	acp_reg_writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
> +	acp_reg_writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
> +}
\
  
Mukunda,Vijendar Feb. 21, 2023, 8:40 p.m. UTC | #2
On 21/02/23 21:43, Pierre-Louis Bossart wrote:
>
> On 2/20/23 05:04, Vijendar Mukunda wrote:
>> Add wake enable interrupt support for both the SoundWire manager
>> instances.
>>
>> Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
>> Signed-off-by: Mastan Katragadda <Mastan.Katragadda@amd.com>
>> ---
>>  drivers/soundwire/amd_manager.c | 10 ++++++++++
>>  drivers/soundwire/amd_manager.h |  1 +
>>  2 files changed, 11 insertions(+)
>>
>> diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
>> index 3322adeca0d8..a7182aa78652 100644
>> --- a/drivers/soundwire/amd_manager.c
>> +++ b/drivers/soundwire/amd_manager.c
>> @@ -932,6 +932,13 @@ static void amd_sdw_update_slave_status(u32 status_change_0to7, u32 status_chang
>>  	}
>>  }
>>  
>> +static void amd_sdw_process_wake_event(struct amd_sdw_manager *amd_manager)
>> +{
>> +	pm_request_resume(amd_manager->dev);
> is this needed?
>
> In the Intel case, the wakes do not necessarily come as in-band wakes,
> but they can also be notified by the PCI subsystem, so we do have to use
> pm_request_resume.
>
> In the AMD case, what happens if you don't do this? Doesn't the
> interrupt trigger a pm_runtime_resume already?
ACP PCI driver receives soundwire interrupt and soundwire manager
interrupt work queue will be scheduled.
In this work queue, wake interrupt status bit is checked.
As still soundwire manager in D3 state, it required to invoke
pm_request_resume(). Without pm_request_resume() call, pm_runtime_resume
won't be triggered in this scenario.
>
>> +	acp_reg_writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
>> +	acp_reg_writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
>> +}
> \
  

Patch

diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
index 3322adeca0d8..a7182aa78652 100644
--- a/drivers/soundwire/amd_manager.c
+++ b/drivers/soundwire/amd_manager.c
@@ -932,6 +932,13 @@  static void amd_sdw_update_slave_status(u32 status_change_0to7, u32 status_chang
 	}
 }
 
+static void amd_sdw_process_wake_event(struct amd_sdw_manager *amd_manager)
+{
+	pm_request_resume(amd_manager->dev);
+	acp_reg_writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance));
+	acp_reg_writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
+}
+
 static void amd_sdw_irq_thread(struct work_struct *work)
 {
 	struct amd_sdw_manager *amd_manager =
@@ -943,6 +950,9 @@  static void amd_sdw_irq_thread(struct work_struct *work)
 	status_change_0to7 = acp_reg_readl(amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_0TO7);
 	dev_dbg(amd_manager->dev, "[SDW%d] SDW INT: 0to7=0x%x, 8to11=0x%x\n",
 		amd_manager->instance, status_change_0to7, status_change_8to11);
+	if (status_change_8to11 & AMD_SDW_WAKE_STAT_MASK)
+		return amd_sdw_process_wake_event(amd_manager);
+
 	if (status_change_8to11 & AMD_SDW_PREQ_INTR_STAT) {
 		amd_sdw_read_and_process_ping_status(amd_manager);
 	} else {
diff --git a/drivers/soundwire/amd_manager.h b/drivers/soundwire/amd_manager.h
index 6ec37612ae4e..86bc6d4f48bf 100644
--- a/drivers/soundwire/amd_manager.h
+++ b/drivers/soundwire/amd_manager.h
@@ -190,6 +190,7 @@ 
 #define AMD_SDW_CLK_STOP_DONE				1
 #define AMD_SDW_CLK_RESUME_REQ				2
 #define AMD_SDW_CLK_RESUME_DONE				3
+#define AMD_SDW_WAKE_STAT_MASK				BIT(16)
 
 enum amd_sdw_cmd_type {
 	AMD_SDW_CMD_PING = 0,