ipc: replace ipc position update with memory window

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@linux.intel.com>
This commit is contained in:
Pan Xiuli 2018-03-02 17:20:27 +08:00 committed by Liam Girdwood
parent aa562f81ba
commit e92ef97834
5 changed files with 72 additions and 11 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -230,7 +230,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");
@ -301,13 +301,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;
@ -371,15 +375,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;
}
@ -387,24 +394,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)

View File

@ -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;
@ -347,6 +368,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 */
@ -355,6 +377,9 @@ int ipc_init(struct reef *reef)
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);