[Sound-open-firmware] [PATCH 4/4] Add IPC processing code for DMA tracing.
From: Yan Wang yan.wang@linux.intel.com
1. Add processing case branch of SOF_IPC_GLB_TRACE_MSG. 2. Add processing functions for SOF_IPC_TRACE_DMA_INIT and SOF_IPC_TRACE_DMA_PARAMS for initlizing DMA for Trace and reply host. 3. Modify page table parsing fucntion for using in both PCM streaming and DMA tracing case.
Signed-off-by: Yan Wang yan.wang@linux.intel.com --- src/include/reef/ipc.h | 4 ++ src/ipc/intel-ipc.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/src/include/reef/ipc.h b/src/include/reef/ipc.h index 3eb94d8..84a1dc1 100644 --- a/src/include/reef/ipc.h +++ b/src/include/reef/ipc.h @@ -40,6 +40,7 @@ #include <uapi/ipc.h> #include <reef/audio/pipeline.h> #include <reef/audio/component.h> +#include <reef/audio/dma-trace.h>
struct reef; struct dai_config; @@ -99,6 +100,9 @@ struct ipc { /* pipelines, components and buffers */ struct list_item comp_list; /* list of component devices */
+ /* DMA for Trace*/ + struct dma_trace_data dmat; + void *private; };
diff --git a/src/ipc/intel-ipc.c b/src/ipc/intel-ipc.c index 01c83b6..dbd9ec7 100644 --- a/src/ipc/intel-ipc.c +++ b/src/ipc/intel-ipc.c @@ -155,14 +155,22 @@ out: * page table entry and adding each elem to a list in struct dma_sg_config. */ static int parse_page_descriptors(struct intel_ipc_data *iipc, - struct sof_ipc_host_buffer *ring, struct comp_dev *cd) + struct sof_ipc_host_buffer *ring, void *data, uint32_t is_trace) { - struct sof_ipc_comp_host *host = (struct sof_ipc_comp_host *)&cd->comp; + struct comp_dev* cd = NULL; + struct sof_ipc_comp_host *host = NULL; + struct dma_trace_data *d = NULL; struct dma_sg_elem elem; int i, err; uint32_t idx, phy_addr;
elem.size = HOST_PAGE_SIZE; + if (is_trace) + d = (struct dma_trace_data *)data; + else { + cd = (struct comp_dev *)data; + host = (struct sof_ipc_comp_host *)&cd->comp; + }
for (i = 0; i < ring->pages; i++) {
@@ -176,12 +184,15 @@ static int parse_page_descriptors(struct intel_ipc_data *iipc, phy_addr <<= 12; phy_addr &= 0xfffff000;
- if (host->direction == SOF_IPC_STREAM_PLAYBACK) + if (!is_trace && host->direction == SOF_IPC_STREAM_PLAYBACK) elem.src = phy_addr; else elem.dest = phy_addr;
- err = comp_host_buffer(cd, &elem, ring->size); + if (is_trace) + err = dma_trace_host_buffer(d, &elem, ring->size); + else + err = comp_host_buffer(cd, &elem, ring->size); if (err < 0) { trace_ipc_error("ePb"); return err; @@ -235,7 +246,7 @@ static int ipc_stream_pcm_params(uint32_t stream)
/* Parse host tables */ err = parse_page_descriptors(iipc, &pcm_params->params.buffer, - pcm_dev->cd); + pcm_dev->cd, 0); if (err < 0) { trace_ipc_error("eAP"); goto error; @@ -551,6 +562,98 @@ static int ipc_glb_pm_message(uint32_t header) }
/* + * Debug IPC Operations. + */ + +static int ipc_dma_trace_init(uint32_t header) +{ + struct sof_ipc_reply reply; + int err; + + trace_ipc("Dti"); + + /* Initialize DMA for Trace*/ + err = dma_trace_init(&_ipc->dmat); + if (err < 0) { + trace_ipc_error("eIP"); + goto error; + } + + /* write component values to the outbox */ + reply.hdr.size = sizeof(reply); + reply.hdr.cmd = header; + reply.error = 0; + mailbox_hostbox_write(0, &reply, sizeof(reply)); + return 0; + +error: + if (err < 0) + trace_ipc_error("eA!"); + return -EINVAL; +} + +static int ipc_dma_trace_config(uint32_t header) +{ + struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc); + struct sof_ipc_dma_trace_params *params = _ipc->comp_data; + struct sof_ipc_reply reply; + int err; + + trace_ipc("DAl"); + + /* use DMA to read in compressed page table ringbuffer from host */ + err = get_page_descriptors(iipc, ¶ms->buffer); + if (err < 0) { + trace_ipc_error("eCp"); + goto error; + } + + trace_ipc("DAg"); + + /* Parse host tables */ + err = parse_page_descriptors(iipc, ¶ms->buffer, + &_ipc->dmat, 1); + if (err < 0) { + trace_ipc_error("ePP"); + goto error; + } + + trace_ipc("DAp"); + + dma_trace_config_ready(&_ipc->dmat); + + /* write component values to the outbox */ + reply.hdr.size = sizeof(reply); + reply.hdr.cmd = header; + reply.error = 0; + mailbox_hostbox_write(0, &reply, sizeof(reply)); + return 0; + +error: + if (err < 0) + trace_ipc_error("eA!"); + return -EINVAL; +} + +static int ipc_glb_debug_message(uint32_t header) +{ + uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT; + + trace_ipc("Idn"); + + switch (cmd) { + case iCS(SOF_IPC_TRACE_DMA_INIT): + return ipc_dma_trace_init(header); + case iCS(SOF_IPC_TRACE_DMA_PARAMS): + return ipc_dma_trace_config(header); + default: + trace_ipc_error("eDc"); + trace_value(header); + return -EINVAL; + } +} + +/* * Topology IPC Operations. */
@@ -766,6 +869,8 @@ int ipc_cmd(void) return ipc_glb_stream_message(hdr->cmd); case iGS(SOF_IPC_GLB_DAI_MSG): return ipc_glb_dai_message(hdr->cmd); + case iGS(SOF_IPC_GLB_TRACE_MSG): + return ipc_glb_debug_message(hdr->cmd); default: trace_ipc_error("eGc"); trace_value(type);
participants (1)
-
yan.wang@linux.intel.com