[alsa-devel] [PATCH 0/8] ASoC: Intel: refactor common SST IPC handling
This series refactors the common SST IPC code to remove some hardcoded assumption which are no longer valid for future platforms like Skylake, These are made configurable and right configuration applied for respective drivers. The changes are mailbox sizes and dsp busy checks.
Subhransu S. Prusty (8): ASoC: Intel: Create an ops to check for DSP busy ASoC: Intel: Move the busy check to ops for Baytrail ASoC: Intel: Move the busy check to ops for HSW ASoC: Intel: Remove the direct register reference from common ipc ASoC: Intel: Allow to configure max size for mailbox data ASoC: Intel: Initialize max mailbox size for baytrail ASoC: Intel: Initialize max mailbox size for haswell ASoC: Intel: Allocate for the mailbox with max size
sound/soc/intel/baytrail/sst-baytrail-ipc.c | 11 +++++++++++ sound/soc/intel/common/sst-ipc.c | 20 +++++++++++++++++--- sound/soc/intel/common/sst-ipc.h | 7 +++++-- sound/soc/intel/haswell/sst-haswell-ipc.c | 12 ++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-)
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Created an ops to check if DSP busy, to avoid using platform specific registers in common IPC.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/common/sst-ipc.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h index 125ea451a373..77a3befd16b0 100644 --- a/sound/soc/intel/common/sst-ipc.h +++ b/sound/soc/intel/common/sst-ipc.h @@ -51,6 +51,7 @@ struct sst_plat_ipc_ops { 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); + bool (*is_dsp_busy)(struct sst_dsp *dsp); };
/* SST generic IPC data */
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/baytrail/sst-baytrail-ipc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c index 1efb33b36303..799b804f3e34 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c +++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c @@ -679,6 +679,14 @@ static u64 byt_reply_msg_match(u64 header, u64 *mask) return header; }
+static bool byt_is_dsp_busy(struct sst_dsp *dsp) +{ + u64 ipcx; + + ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX); + return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)); +} + int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) { struct sst_byt *byt; @@ -699,6 +707,7 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) ipc->ops.shim_dbg = byt_shim_dbg; ipc->ops.tx_data_copy = byt_tx_data_copy; ipc->ops.reply_msg_match = byt_reply_msg_match; + ipc->ops.is_dsp_busy = byt_is_dsp_busy;
err = sst_ipc_init(ipc); if (err != 0)
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/haswell/sst-haswell-ipc.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c index 324eceb07b25..6304e4bfccd6 100644 --- a/sound/soc/intel/haswell/sst-haswell-ipc.c +++ b/sound/soc/intel/haswell/sst-haswell-ipc.c @@ -2098,6 +2098,14 @@ static u64 hsw_reply_msg_match(u64 header, u64 *mask) return header; }
+static bool hsw_is_dsp_busy(struct sst_dsp *dsp) +{ + u64 ipcx; + + ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX); + return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)); +} + int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) { struct sst_hsw_ipc_fw_version version; @@ -2117,6 +2125,7 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) ipc->ops.shim_dbg = hsw_shim_dbg; ipc->ops.tx_data_copy = hsw_tx_data_copy; ipc->ops.reply_msg_match = hsw_reply_msg_match; + ipc->ops.is_dsp_busy = hsw_is_dsp_busy;
ret = sst_ipc_init(ipc); if (ret != 0)
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/common/sst-ipc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c index 4b62a553823c..a7699f35a8d2 100644 --- a/sound/soc/intel/common/sst-ipc.c +++ b/sound/soc/intel/common/sst-ipc.c @@ -142,7 +142,6 @@ static void ipc_tx_msgs(struct kthread_work *work) container_of(work, struct sst_generic_ipc, kwork); struct ipc_message *msg; unsigned long flags; - u64 ipcx;
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
@@ -153,8 +152,8 @@ static void ipc_tx_msgs(struct kthread_work *work)
/* if the DSP is busy, we will TX messages after IRQ. * also postpone if we are in the middle of procesing completion irq*/ - ipcx = sst_dsp_shim_read_unlocked(ipc->dsp, SST_IPCX); - if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) { + if (ipc->ops.is_dsp_busy && ipc->ops.is_dsp_busy(ipc->dsp)) { + dev_dbg(ipc->dev, "ipc_tx_msgs dsp busy\n"); spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); return; }
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Mailbox size can be different for different platforms. So allow the drivers to configure the size.
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/common/sst-ipc.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h index 77a3befd16b0..7139afd2547f 100644 --- a/sound/soc/intel/common/sst-ipc.h +++ b/sound/soc/intel/common/sst-ipc.h @@ -69,6 +69,8 @@ struct sst_generic_ipc { struct kthread_work kwork; bool pending; struct ipc_message *msg; + int tx_data_max_size; + int rx_data_max_size;
struct sst_plat_ipc_ops ops; };
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/baytrail/sst-baytrail-ipc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/intel/baytrail/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c index 799b804f3e34..773a47552bdf 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-ipc.c +++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c @@ -708,6 +708,8 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) ipc->ops.tx_data_copy = byt_tx_data_copy; ipc->ops.reply_msg_match = byt_reply_msg_match; ipc->ops.is_dsp_busy = byt_is_dsp_busy; + ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES; + ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES;
err = sst_ipc_init(ipc); if (err != 0)
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/haswell/sst-haswell-ipc.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c index 6304e4bfccd6..f95f271aab0c 100644 --- a/sound/soc/intel/haswell/sst-haswell-ipc.c +++ b/sound/soc/intel/haswell/sst-haswell-ipc.c @@ -2127,6 +2127,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) ipc->ops.reply_msg_match = hsw_reply_msg_match; ipc->ops.is_dsp_busy = hsw_is_dsp_busy;
+ ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES; + ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES; + ret = sst_ipc_init(ipc); if (ret != 0) goto ipc_init_err;
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/common/sst-ipc.c | 15 +++++++++++++++ sound/soc/intel/common/sst-ipc.h | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c index a7699f35a8d2..137bdfc35063 100644 --- a/sound/soc/intel/common/sst-ipc.c +++ b/sound/soc/intel/common/sst-ipc.c @@ -128,6 +128,21 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) if (ipc->msg == NULL) return -ENOMEM;
+ ipc->msg->tx_data = devm_kzalloc(ipc->dev, + sizeof(ipc->tx_data_max_size), GFP_KERNEL); + if (ipc->msg->tx_data == NULL) { + kfree(ipc->msg); + return -ENOMEM; + } + + ipc->msg->rx_data = devm_kzalloc(ipc->dev, + sizeof(ipc->rx_data_max_size), GFP_KERNEL); + if (ipc->msg->rx_data == NULL) { + kfree(ipc->msg->tx_data); + kfree(ipc->msg); + return -ENOMEM; + } + for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { init_waitqueue_head(&ipc->msg[i].waitq); list_add(&ipc->msg[i].list, &ipc->empty_list); diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h index 7139afd2547f..ceb7e468a3fa 100644 --- a/sound/soc/intel/common/sst-ipc.h +++ b/sound/soc/intel/common/sst-ipc.h @@ -32,9 +32,9 @@ struct ipc_message { u64 header;
/* direction wrt host CPU */ - char tx_data[IPC_MAX_MAILBOX_BYTES]; + char *tx_data; size_t tx_size; - char rx_data[IPC_MAX_MAILBOX_BYTES]; + char *rx_data; size_t rx_size;
wait_queue_head_t waitq;
On Mon, May 18, 2015 at 04:56:01PM +0530, Vinod Koul wrote:
From: "Subhransu S. Prusty" subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com
sound/soc/intel/common/sst-ipc.c | 15 +++++++++++++++ sound/soc/intel/common/sst-ipc.h | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c index a7699f35a8d2..137bdfc35063 100644 --- a/sound/soc/intel/common/sst-ipc.c +++ b/sound/soc/intel/common/sst-ipc.c @@ -128,6 +128,21 @@ static int msg_empty_list_init(struct sst_generic_ipc *ipc) if (ipc->msg == NULL) return -ENOMEM;
- ipc->msg->tx_data = devm_kzalloc(ipc->dev,
sizeof(ipc->tx_data_max_size), GFP_KERNEL);
- if (ipc->msg->tx_data == NULL) {
kfree(ipc->msg);
return -ENOMEM;
- }
- ipc->msg->rx_data = devm_kzalloc(ipc->dev,
sizeof(ipc->rx_data_max_size), GFP_KERNEL);
- if (ipc->msg->rx_data == NULL) {
kfree(ipc->msg->tx_data);
kfree(ipc->msg);
return -ENOMEM;
- }
- for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
we need to allocate the memory for each message in the queue, i will send updated series now
participants (1)
-
Vinod Koul