[Sound-open-firmware] [PATCH V3 3/3] ipc: replace ipc position update with memory window
Xiuli Pan
xiuli.pan at linux.intel.com
Fri Mar 2 10:20:27 CET 2018
From: Pan Xiuli <xiuli.pan at linux.intel.com>
Add memeory window for stream region. And position offset binding for
component. Replace IPC position update with memory window update.
Signed-off-by: Pan Xiuli <xiuli.pan at linux.intel.com>
---
Test with:
Mininow max rt5651 GP-MRB nocodec
SOF master: 1693b66bb1d804ded975767cc1e5911e6ff9c93c
SOF-Tool master: a02abb799405d0e4ad0d6bb46eacf6fbe958c06e
https://github.com/plbossart/sound/tree/topic/sof-v4.14:
9513a73b981bc1917705671ec54402a7e21672eb
---
src/include/reef/audio/pipeline.h | 3 +++
src/include/reef/ipc.h | 5 +++++
src/include/reef/mailbox.h | 7 +++++++
src/ipc/intel-ipc.c | 43 +++++++++++++++++++++++++++++----------
src/ipc/ipc.c | 25 +++++++++++++++++++++++
5 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/src/include/reef/audio/pipeline.h b/src/include/reef/audio/pipeline.h
index 08a3f30..dca9413 100644
--- a/src/include/reef/audio/pipeline.h
+++ b/src/include/reef/audio/pipeline.h
@@ -69,6 +69,9 @@ struct pipeline {
struct task pipe_task; /* pipeline processing task */
struct comp_dev *sched_comp; /* component that drives scheduling in this pipe */
struct comp_dev *source_comp; /* source component for this pipe */
+
+ /* position update */
+ uint32_t posn_offset; /* position update array offset*/
};
/* static pipeline */
diff --git a/src/include/reef/ipc.h b/src/include/reef/ipc.h
index 9261add..58d1f29 100644
--- a/src/include/reef/ipc.h
+++ b/src/include/reef/ipc.h
@@ -103,6 +103,9 @@ struct ipc {
/* DMA for Trace*/
struct dma_trace_data *dmat;
+ /* mmap for posn_offset */
+ struct pipeline *posn_map[PLATFORM_MAX_STREAMS];
+
void *private;
};
@@ -169,4 +172,6 @@ int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config);
/* send DMA trace host buffer position to host */
int ipc_dma_trace_send_position(void);
+/* get posn offset by pipeline. */
+int ipc_get_posn_offset(struct ipc *ipc, struct pipeline *pipe);
#endif
diff --git a/src/include/reef/mailbox.h b/src/include/reef/mailbox.h
index c0580a9..f134548 100644
--- a/src/include/reef/mailbox.h
+++ b/src/include/reef/mailbox.h
@@ -78,4 +78,11 @@
dcache_invalidate_region((void*)(MAILBOX_HOSTBOX_BASE + src), bytes); \
rmemcpy(dest, (void*)(MAILBOX_HOSTBOX_BASE + src), bytes);
+#define mailbox_stream_write(dest, src, bytes) \
+ do { \
+ rmemcpy((void *)(MAILBOX_STREAM_BASE + dest), src, bytes); \
+ dcache_writeback_region((void *)(MAILBOX_STREAM_BASE + dest), \
+ bytes); \
+ } while (0)
+
#endif
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c
index 04e8c1b..8b77219 100644
--- a/src/ipc/intel-ipc.c
+++ b/src/ipc/intel-ipc.c
@@ -237,7 +237,7 @@ static int ipc_stream_pcm_params(uint32_t stream)
struct sof_ipc_pcm_params_reply reply;
struct ipc_comp_dev *pcm_dev;
struct comp_dev *cd;
- int err;
+ int err, posn_offset;
trace_ipc("SAl");
@@ -291,13 +291,17 @@ static int ipc_stream_pcm_params(uint32_t stream)
goto error;
}
-
+ posn_offset = ipc_get_posn_offset(_ipc, pcm_dev->cd->pipeline);
+ if (posn_offset < 0) {
+ trace_ipc_error("eAo");
+ goto error;
+ }
/* write component values to the outbox */
reply.rhdr.hdr.size = sizeof(reply);
reply.rhdr.hdr.cmd = stream;
reply.rhdr.error = 0;
reply.comp_id = pcm_params->comp_id;
- reply.posn_offset = 0; /* TODO: set this up for mmaped components */
+ reply.posn_offset = posn_offset;
mailbox_hostbox_write(0, &reply, sizeof(reply));
return 1;
@@ -353,15 +357,18 @@ static int ipc_stream_position(uint32_t header)
}
/* set message fields - TODO; get others */
- posn.rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION;
+ posn.rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION |
+ stream->comp_id;
posn.rhdr.hdr.size = sizeof(posn);
posn.comp_id = stream->comp_id;
/* get the stream positions and timestamps */
pipeline_get_timestamp(pcm_dev->cd->pipeline, pcm_dev->cd, &posn);
- /* copy positions to outbox */
- mailbox_hostbox_write(0, &posn, sizeof(posn));
+ /* copy positions to stream region */
+ mailbox_stream_write(pcm_dev->cd->pipeline->posn_offset,
+ &posn, sizeof(posn));
+
return 1;
}
@@ -369,24 +376,38 @@ static int ipc_stream_position(uint32_t header)
int ipc_stream_send_position(struct comp_dev *cdev,
struct sof_ipc_stream_posn *posn)
{
- posn->rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION;
+ struct sof_ipc_hdr hdr;
+
+ tracev_ipc("Pos");
+ posn->rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION |
+ cdev->comp.id;
posn->rhdr.hdr.size = sizeof(*posn);
posn->comp_id = cdev->comp.id;
- return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, posn,
- sizeof(*posn), NULL, 0, NULL, NULL, 1);
+ hdr.cmd = posn->rhdr.hdr.cmd;
+ hdr.size = sizeof(hdr);
+
+ mailbox_stream_write(cdev->pipeline->posn_offset, posn, sizeof(*posn));
+ return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, &hdr,
+ sizeof(hdr), NULL, 0, NULL, NULL, 0);
}
/* send stream position TODO: send compound message */
int ipc_stream_send_xrun(struct comp_dev *cdev,
struct sof_ipc_stream_posn *posn)
{
+ struct sof_ipc_hdr hdr;
+
posn->rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_TRIG_XRUN;
posn->rhdr.hdr.size = sizeof(*posn);
posn->comp_id = cdev->comp.id;
- return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, posn,
- sizeof(*posn), NULL, 0, NULL, NULL, 1);
+ hdr.cmd = posn->rhdr.hdr.cmd;
+ hdr.size = sizeof(hdr);
+
+ mailbox_stream_write(cdev->pipeline->posn_offset, posn, sizeof(*posn));
+ return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, &hdr,
+ sizeof(hdr), NULL, 0, NULL, NULL, 0);
}
static int ipc_stream_trigger(uint32_t header)
diff --git a/src/ipc/ipc.c b/src/ipc/ipc.c
index b753efd..898a69e 100644
--- a/src/ipc/ipc.c
+++ b/src/ipc/ipc.c
@@ -77,6 +77,27 @@ struct ipc_comp_dev *ipc_get_comp(struct ipc *ipc, uint32_t id)
return NULL;
}
+int ipc_get_posn_offset(struct ipc *ipc, struct pipeline *pipe)
+{
+ int i;
+ uint32_t posn_size = sizeof(struct sof_ipc_stream_posn);
+
+ for (i = 0; i < PLATFORM_MAX_STREAMS; i++) {
+ if (ipc->posn_map[i] == pipe)
+ return pipe->posn_offset;
+ }
+
+ for (i = 0; i < PLATFORM_MAX_STREAMS; i++) {
+ if (ipc->posn_map[i] == NULL) {
+ ipc->posn_map[i] = pipe;
+ pipe->posn_offset = i * posn_size;
+ return pipe->posn_offset;
+ }
+ }
+
+ return -EINVAL;
+}
+
int ipc_comp_new(struct ipc *ipc, struct sof_ipc_comp *comp)
{
struct comp_dev *cd;
@@ -345,6 +366,7 @@ int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config)
int ipc_init(struct reef *reef)
{
+ int i;
trace_ipc("IPI");
/* init ipc data */
@@ -352,6 +374,9 @@ int ipc_init(struct reef *reef)
reef->ipc->comp_data = rzalloc(RZONE_SYS, RFLAGS_NONE, SOF_IPC_MSG_MAX_SIZE);
reef->ipc->dmat = reef->dmat;
+ for (i = 0; i < PLATFORM_MAX_STREAMS; i++)
+ reef->ipc->posn_map[i] = NULL;
+
list_init(&reef->ipc->comp_list);
return platform_ipc_init(reef->ipc);
--
2.7.4
More information about the Sound-open-firmware
mailing list