2019-03-29 14:12:17 +08:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2018-10-16 02:05:43 +08:00
|
|
|
From: Pardha Saradhi K <pardha.saradhi.kesapragada@intel.com>
|
|
|
|
Date: Thu, 30 Mar 2017 22:57:48 +0530
|
2019-03-29 14:12:17 +08:00
|
|
|
Subject: [PATCH] ASoC: Intel: common: Provide an interface to send IPCs
|
|
|
|
directly
|
2018-10-16 02:05:43 +08:00
|
|
|
|
|
|
|
This patch adds support for an IPC Tx function that can
|
|
|
|
be called directly rather than adding new Tx messages to the Queue.
|
|
|
|
Hence the new logic to send IPCs will be -
|
|
|
|
If the DSP is not busy, send IPCs directly.
|
|
|
|
Else add to the queue
|
|
|
|
|
|
|
|
Change-Id: I9d58872a051c9d704c60cf25a2e3b69c3b580818
|
|
|
|
Signed-off-by: Pardha Saradhi K <pardha.saradhi.kesapragada@intel.com>
|
|
|
|
Reviewed-on:
|
|
|
|
Reviewed-by: Koul, Vinod <vinod.koul@intel.com>
|
|
|
|
Tested-by: Tr, HarishkumarX <harishkumarx.tr@intel.com>
|
|
|
|
Reviewed-on:
|
|
|
|
Reviewed-by: Shaik, ShahinaX <shahinax.shaik@intel.com>
|
|
|
|
Reviewed-by: Kale, Sanyog R <sanyog.r.kale@intel.com>
|
|
|
|
Tested-by: Madiwalar, MadiwalappaX <madiwalappax.madiwalar@intel.com>
|
|
|
|
---
|
|
|
|
sound/soc/intel/common/sst-ipc.c | 11 +++++++--
|
|
|
|
sound/soc/intel/common/sst-ipc.h | 1 +
|
|
|
|
sound/soc/intel/skylake/skl-sst-ipc.c | 34 +++++++++++++++++++++++++++
|
|
|
|
3 files changed, 44 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
|
2020-10-27 02:14:06 +08:00
|
|
|
index 8a62daa1965b..fd93d58b9033 100644
|
2018-10-16 02:05:43 +08:00
|
|
|
--- a/sound/soc/intel/common/sst-ipc.c
|
|
|
|
+++ b/sound/soc/intel/common/sst-ipc.c
|
|
|
|
@@ -127,8 +127,15 @@ static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
|
|
|
|
ipc->ops.tx_data_copy(msg, tx_data, tx_bytes);
|
|
|
|
|
|
|
|
list_add_tail(&msg->list, &ipc->tx_list);
|
|
|
|
- schedule_work(&ipc->kwork);
|
|
|
|
- spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+
|
|
|
|
+ if ((ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) ||
|
|
|
|
+ (ipc->ops.direct_tx_msg == NULL)) {
|
|
|
|
+ schedule_work(&ipc->kwork);
|
|
|
|
+ spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+ } else {
|
|
|
|
+ spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+ ipc->ops.direct_tx_msg(ipc);
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (wait)
|
|
|
|
return tx_wait_done(ipc, msg, rx_data,
|
|
|
|
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
|
2020-10-27 02:14:06 +08:00
|
|
|
index 4cfa9e37ac28..eae3fa7d1aef 100644
|
2018-10-16 02:05:43 +08:00
|
|
|
--- a/sound/soc/intel/common/sst-ipc.h
|
|
|
|
+++ b/sound/soc/intel/common/sst-ipc.h
|
|
|
|
@@ -47,6 +47,7 @@ struct sst_generic_ipc;
|
|
|
|
|
|
|
|
struct sst_plat_ipc_ops {
|
|
|
|
void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
|
|
|
|
+ void (*direct_tx_msg)(struct sst_generic_ipc *);
|
|
|
|
void (*shim_dbg)(struct sst_generic_ipc *, const char *);
|
|
|
|
void (*tx_data_copy)(struct ipc_message *, char *, size_t);
|
|
|
|
u64 (*reply_msg_match)(u64 header, u64 *mask);
|
|
|
|
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
|
2020-10-27 02:14:06 +08:00
|
|
|
index 6efc9502d06e..9370c474c618 100644
|
2018-10-16 02:05:43 +08:00
|
|
|
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
|
|
|
|
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
|
|
|
|
@@ -343,6 +343,39 @@ static bool skl_ipc_is_dsp_busy(struct sst_dsp *dsp)
|
|
|
|
return (hipci & SKL_ADSP_REG_HIPCI_BUSY);
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void skl_ipc_tx_msgs_direct(struct sst_generic_ipc *ipc)
|
|
|
|
+{
|
|
|
|
+ struct ipc_message *msg;
|
|
|
|
+ unsigned long flags;
|
|
|
|
+
|
|
|
|
+ spin_lock_irqsave(&ipc->dsp->spinlock, flags);
|
|
|
|
+
|
|
|
|
+ if (list_empty(&ipc->tx_list) || ipc->pending) {
|
|
|
|
+ spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* if the DSP is busy, we will TX messages after IRQ.
|
|
|
|
+ * also postpone if we are in the middle of procesing completion irq*/
|
|
|
|
+ if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) {
|
|
|
|
+ dev_dbg(ipc->dev, "skl_ipc_tx_msgs_direct dsp busy\n");
|
|
|
|
+ spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ msg = list_first_entry(&ipc->tx_list, struct ipc_message, list);
|
|
|
|
+ list_move(&msg->list, &ipc->rx_list);
|
|
|
|
+
|
|
|
|
+ dev_dbg(ipc->dev, "skl_ipc_tx_msgs_direct sending message, header - %#.16lx\n",
|
|
|
|
+ (unsigned long)msg->header);
|
|
|
|
+ print_hex_dump_debug("Params:", DUMP_PREFIX_OFFSET, 8, 4,
|
|
|
|
+ msg->tx_data, msg->tx_size, false);
|
|
|
|
+ if (ipc->ops.tx_msg != NULL)
|
|
|
|
+ ipc->ops.tx_msg(ipc, msg);
|
|
|
|
+
|
|
|
|
+ spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Lock to be held by caller */
|
|
|
|
static void skl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
|
|
|
|
{
|
|
|
|
@@ -854,6 +887,7 @@ int skl_ipc_init(struct device *dev, struct skl_sst *skl)
|
|
|
|
|
|
|
|
ipc->ops.tx_msg = skl_ipc_tx_msg;
|
|
|
|
ipc->ops.tx_data_copy = skl_ipc_tx_data_copy;
|
|
|
|
+ ipc->ops.direct_tx_msg = skl_ipc_tx_msgs_direct;
|
|
|
|
ipc->ops.is_dsp_busy = skl_ipc_is_dsp_busy;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
--
|
2019-04-08 18:08:36 +08:00
|
|
|
https://clearlinux.org
|
2018-10-16 02:05:43 +08:00
|
|
|
|