From: Vinod Koul <vkoul@kernel.org>
To: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Cc: alsa-devel@alsa-project.org,
pierre-louis.bossart@linux.intel.com,
Basavaraj.Hiregoudar@amd.com, Sunil-kumar.Dommati@amd.com,
Mario.Limonciello@amd.com, amadeuszx.slawinski@linux.intel.com,
Mastan.Katragadda@amd.com, Arungopal.kondaveeti@amd.com,
claudiu.beznea@microchip.com,
Bard Liao <yung-chuan.liao@linux.intel.com>,
Sanyog Kale <sanyog.r.kale@intel.com>,
open list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH V6 5/8] soundwire: amd: add SoundWire manager interrupt handling
Date: Wed, 15 Mar 2023 15:36:49 +0530 [thread overview]
Message-ID: <ZBGYubOYyu7E8ueo@matsya> (raw)
In-Reply-To: <20230307133135.545952-6-Vijendar.Mukunda@amd.com>
On 07-03-23, 19:01, Vijendar Mukunda wrote:
> Add support for handling SoundWire manager interrupts.
>
> Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
> Signed-off-by: Mastan Katragadda <Mastan.Katragadda@amd.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Link: https://lore.kernel.org/lkml/20230227154801.50319-6-Vijendar.Mukunda@amd.com
> ---
> drivers/soundwire/amd_manager.c | 130 ++++++++++++++++++++++++++++++
> drivers/soundwire/amd_manager.h | 1 +
> include/linux/soundwire/sdw_amd.h | 7 ++
> 3 files changed, 138 insertions(+)
>
> diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c
> index dd7fd4036d89..165078beca2e 100644
> --- a/drivers/soundwire/amd_manager.c
> +++ b/drivers/soundwire/amd_manager.c
> @@ -357,6 +357,51 @@ static enum sdw_command_response amd_sdw_xfer_msg(struct sdw_bus *bus, struct sd
> return SDW_CMD_OK;
> }
>
> +static void amd_sdw_fill_slave_status(struct amd_sdw_manager *amd_manager, u16 index, u32 status)
> +{
> + switch (status) {
> + case SDW_SLAVE_ATTACHED:
> + amd_manager->status[index] = SDW_SLAVE_ATTACHED;
> + break;
> + case SDW_SLAVE_UNATTACHED:
> + amd_manager->status[index] = SDW_SLAVE_UNATTACHED;
> + break;
> + case SDW_SLAVE_ALERT:
> + amd_manager->status[index] = SDW_SLAVE_ALERT;
> + break;
why not:
case SDW_SLAVE_ATTACHED:
case SDW_SLAVE_UNATTACHED:
case SDW_SLAVE_ALERT:
amd_manager->status[index] = status;
break;
> + default:
> + amd_manager->status[index] = SDW_SLAVE_RESERVED;
> + break;
> + }
> +}
> +
> +static void amd_sdw_process_ping_status(u64 response, struct amd_sdw_manager *amd_manager)
> +{
> + u64 slave_stat;
> + u32 val;
> + u16 dev_index;
> +
> + /* slave status response */
> + slave_stat = FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_0_3, response);
> + slave_stat |= FIELD_GET(AMD_SDW_MCP_SLAVE_STAT_4_11, response) << 8;
> + dev_dbg(amd_manager->dev, "slave_stat:0x%llx\n", slave_stat);
> + for (dev_index = 0; dev_index <= SDW_MAX_DEVICES; ++dev_index) {
> + val = (slave_stat >> (dev_index * 2)) & AMD_SDW_MCP_SLAVE_STATUS_MASK;
> + dev_dbg(amd_manager->dev, "val:0x%x\n", val);
> + amd_sdw_fill_slave_status(amd_manager, dev_index, val);
> + }
> +}
> +
> +static void amd_sdw_read_and_process_ping_status(struct amd_sdw_manager *amd_manager)
> +{
> + u64 response;
> +
> + mutex_lock(&amd_manager->bus.msg_lock);
> + response = amd_sdw_send_cmd_get_resp(amd_manager, 0, 0);
> + mutex_unlock(&amd_manager->bus.msg_lock);
> + amd_sdw_process_ping_status(response, amd_manager);
> +}
> +
> static u32 amd_sdw_read_ping_status(struct sdw_bus *bus)
> {
> struct amd_sdw_manager *amd_manager = to_amd_sdw(bus);
> @@ -757,6 +802,89 @@ static int amd_sdw_register_dais(struct amd_sdw_manager *amd_manager)
> dais, num_dais);
> }
>
> +static void amd_sdw_update_slave_status_work(struct work_struct *work)
> +{
> + struct amd_sdw_manager *amd_manager =
> + container_of(work, struct amd_sdw_manager, amd_sdw_work);
> + int retry_count = 0;
> +
> + if (amd_manager->status[0] == SDW_SLAVE_ATTACHED) {
> + acp_reg_writel(0, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
> + acp_reg_writel(0, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
> + }
> +
> +update_status:
> + sdw_handle_slave_status(&amd_manager->bus, amd_manager->status);
> + /*
> + * During the peripheral enumeration sequence, the SoundWire manager interrupts
> + * are masked. Once the device number programming is done for all peripherals,
> + * interrupts will be unmasked. Read the peripheral device status from ping command
> + * and process the response. This sequence will ensure all peripheral devices enumerated
> + * and initialized properly.
> + */
> + if (amd_manager->status[0] == SDW_SLAVE_ATTACHED) {
> + if (retry_count++ < SDW_MAX_DEVICES) {
> + acp_reg_writel(AMD_SDW_IRQ_MASK_0TO7, amd_manager->mmio +
> + ACP_SW_STATE_CHANGE_STATUS_MASK_0TO7);
> + acp_reg_writel(AMD_SDW_IRQ_MASK_8TO11,
> + amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_MASK_8TO11);
> + amd_sdw_read_and_process_ping_status(amd_manager);
> + goto update_status;
goto are mostly used for error handling, i dont thing case here deserves
a goto, can you please change this...
> + } else {
> + dev_err_ratelimited(amd_manager->dev,
> + "Device0 detected after %d iterations\n",
> + retry_count);
> + }
> + }
> +}
> +
> +static void amd_sdw_update_slave_status(u32 status_change_0to7, u32 status_change_8to11,
> + struct amd_sdw_manager *amd_manager)
> +{
> + u64 slave_stat;
> + u32 val;
> + int dev_index;
> +
> + if (status_change_0to7 == AMD_SDW_SLAVE_0_ATTACHED)
> + memset(amd_manager->status, 0, sizeof(amd_manager->status));
> + slave_stat = status_change_0to7;
> + slave_stat |= FIELD_GET(AMD_SDW_MCP_SLAVE_STATUS_8TO_11, status_change_8to11) << 32;
> + dev_dbg(amd_manager->dev, "status_change_0to7:0x%x status_change_8to11:0x%x\n",
> + status_change_0to7, status_change_8to11);
> + if (slave_stat) {
> + for (dev_index = 0; dev_index <= SDW_MAX_DEVICES; ++dev_index) {
> + if (slave_stat & AMD_SDW_MCP_SLAVE_STATUS_VALID_MASK(dev_index)) {
> + val = (slave_stat >> AMD_SDW_MCP_SLAVE_STAT_SHIFT_MASK(dev_index)) &
> + AMD_SDW_MCP_SLAVE_STATUS_MASK;
> + amd_sdw_fill_slave_status(amd_manager, dev_index, val);
> + }
> + }
> + }
> +}
> +
> +static void amd_sdw_irq_thread(struct work_struct *work)
> +{
> + struct amd_sdw_manager *amd_manager =
> + container_of(work, struct amd_sdw_manager, amd_sdw_irq_thread);
> + u32 status_change_8to11;
> + u32 status_change_0to7;
> +
> + status_change_8to11 = acp_reg_readl(amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
> + 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_PREQ_INTR_STAT) {
> + amd_sdw_read_and_process_ping_status(amd_manager);
> + } else {
> + /* Check for the updated status on peripheral device */
> + amd_sdw_update_slave_status(status_change_0to7, status_change_8to11, amd_manager);
> + }
> + if (status_change_8to11 || status_change_0to7)
> + schedule_work(&amd_manager->amd_sdw_work);
> + acp_reg_writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_8TO11);
> + acp_reg_writel(0x00, amd_manager->mmio + ACP_SW_STATE_CHANGE_STATUS_0TO7);
> +}
> +
> static void amd_sdw_probe_work(struct work_struct *work)
> {
> struct amd_sdw_manager *amd_manager = container_of(work, struct amd_sdw_manager,
> @@ -847,6 +975,8 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
> return ret;
> }
> dev_set_drvdata(dev, amd_manager);
> + INIT_WORK(&amd_manager->amd_sdw_irq_thread, amd_sdw_irq_thread);
> + INIT_WORK(&amd_manager->amd_sdw_work, amd_sdw_update_slave_status_work);
> INIT_WORK(&amd_manager->probe_work, amd_sdw_probe_work);
> /*
> * Instead of having lengthy probe sequence, use deferred probe.
> diff --git a/drivers/soundwire/amd_manager.h b/drivers/soundwire/amd_manager.h
> index cad26034087b..807bc5a314d8 100644
> --- a/drivers/soundwire/amd_manager.h
> +++ b/drivers/soundwire/amd_manager.h
> @@ -185,6 +185,7 @@
> #define AMD_SDW1_PAD_KEEPER_EN_MASK 0x10
> #define AMD_SDW0_PAD_KEEPER_DISABLE_MASK 0x1E
> #define AMD_SDW1_PAD_KEEPER_DISABLE_MASK 0xF
> +#define AMD_SDW_PREQ_INTR_STAT BIT(19)
>
> enum amd_sdw_cmd_type {
> AMD_SDW_CMD_PING = 0,
> diff --git a/include/linux/soundwire/sdw_amd.h b/include/linux/soundwire/sdw_amd.h
> index ac537419301d..df60bc0de6fc 100644
> --- a/include/linux/soundwire/sdw_amd.h
> +++ b/include/linux/soundwire/sdw_amd.h
> @@ -45,8 +45,11 @@ struct sdw_amd_dai_runtime {
> * @mmio: SoundWire registers mmio base
> * @acp_mmio: acp registers mmio base
> * @reg_mask: register mask structure per manager instance
> + * @amd_sdw_irq_thread: SoundWire manager irq workqueue
> + * @amd_sdw_work: peripheral status work queue
> * @probe_work: SoundWire manager probe workqueue
> * @acp_sdw_lock: mutex to protect acp share register access
> + * @status: peripheral devices status array
> * @num_din_ports: number of input ports
> * @num_dout_ports: number of output ports
> * @cols_index: Column index in frame shape
> @@ -65,10 +68,14 @@ struct amd_sdw_manager {
> void __iomem *acp_mmio;
>
> struct sdw_manager_reg_mask *reg_mask;
> + struct work_struct amd_sdw_irq_thread;
> + struct work_struct amd_sdw_work;
> struct work_struct probe_work;
> /* mutex to protect acp common register access */
> struct mutex *acp_sdw_lock;
>
> + enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
> +
> int num_din_ports;
> int num_dout_ports;
>
> --
> 2.34.1
--
~Vinod
next prev parent reply other threads:[~2023-03-15 10:08 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20230307133135.545952-1-Vijendar.Mukunda@amd.com>
2023-03-07 13:31 ` [PATCH V6 1/8] soundwire: export sdw_compute_slave_ports() function Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` Vijendar Mukunda
2023-03-07 13:31 ` [PATCH V6 2/8] soundwire: amd: Add support for AMD Manager driver Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` Vijendar Mukunda
2023-03-07 15:25 ` Pierre-Louis Bossart
2023-03-07 20:36 ` Mukunda,Vijendar via Alsa-devel
2023-03-07 20:36 ` Mukunda,Vijendar
2023-03-15 9:42 ` Vinod Koul
2023-03-16 13:58 ` Mukunda,Vijendar via Alsa-devel
2023-03-16 13:58 ` Mukunda,Vijendar
2023-03-17 13:34 ` Vinod Koul
2023-03-17 14:04 ` Mukunda,Vijendar via Alsa-devel
2023-03-17 14:04 ` Mukunda,Vijendar
2023-03-07 13:31 ` [PATCH V6 3/8] soundwire: amd: register SoundWire manager dai ops Vijendar Mukunda
2023-03-15 9:58 ` Vinod Koul
2023-03-16 3:32 ` Mukunda,Vijendar via Alsa-devel
2023-03-16 3:32 ` Mukunda,Vijendar
2023-03-07 13:31 ` Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` [PATCH V6 4/8] soundwire: amd: enable build for AMD SoundWire manager driver Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` Vijendar Mukunda
2023-03-15 9:59 ` Vinod Koul
2023-03-16 3:29 ` Mukunda,Vijendar
2023-03-16 3:29 ` Mukunda,Vijendar via Alsa-devel
2023-03-07 13:31 ` [PATCH V6 5/8] soundwire: amd: add SoundWire manager interrupt handling Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` Vijendar Mukunda
2023-03-15 10:06 ` Vinod Koul [this message]
2023-03-16 17:04 ` Mukunda,Vijendar
2023-03-17 13:36 ` Vinod Koul
2023-03-17 14:46 ` Mukunda,Vijendar via Alsa-devel
2023-03-17 14:46 ` Mukunda,Vijendar
2023-03-16 17:04 ` Mukunda,Vijendar via Alsa-devel
2023-03-07 13:31 ` [PATCH V6 6/8] soundwire: amd: add runtime pm ops for AMD SoundWire manager driver Vijendar Mukunda
2023-03-07 13:31 ` Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` [PATCH V6 7/8] soundwire: amd: handle SoundWire wake enable interrupt Vijendar Mukunda
2023-03-07 13:31 ` Vijendar Mukunda via Alsa-devel
2023-03-07 13:31 ` [PATCH V6 8/8] soundwire: amd: add pm_prepare callback and pm ops support Vijendar Mukunda
2023-03-07 15:28 ` Pierre-Louis Bossart
2023-03-07 20:25 ` Mukunda,Vijendar
2023-03-07 21:08 ` Pierre-Louis Bossart
2023-03-08 4:32 ` Mukunda,Vijendar
2023-03-08 13:58 ` Pierre-Louis Bossart
2023-03-08 14:19 ` Mukunda,Vijendar
2023-03-08 14:23 ` Pierre-Louis Bossart
2023-03-08 15:05 ` Mukunda,Vijendar via Alsa-devel
2023-03-08 15:05 ` Mukunda,Vijendar
2023-03-08 14:19 ` Mukunda,Vijendar via Alsa-devel
2023-03-08 4:32 ` Mukunda,Vijendar via Alsa-devel
2023-03-07 20:25 ` Mukunda,Vijendar via Alsa-devel
2023-03-07 13:31 ` Vijendar Mukunda via Alsa-devel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZBGYubOYyu7E8ueo@matsya \
--to=vkoul@kernel.org \
--cc=Arungopal.kondaveeti@amd.com \
--cc=Basavaraj.Hiregoudar@amd.com \
--cc=Mario.Limonciello@amd.com \
--cc=Mastan.Katragadda@amd.com \
--cc=Sunil-kumar.Dommati@amd.com \
--cc=Vijendar.Mukunda@amd.com \
--cc=alsa-devel@alsa-project.org \
--cc=amadeuszx.slawinski@linux.intel.com \
--cc=claudiu.beznea@microchip.com \
--cc=linux-kernel@vger.kernel.org \
--cc=pierre-louis.bossart@linux.intel.com \
--cc=sanyog.r.kale@intel.com \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.