mirror of https://github.com/thesofproject/sof.git
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:
parent
aa562f81ba
commit
e92ef97834
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue