[Sound-open-firmware] [PATCH 4/4] Add IPC processing code for DMA tracing.
yan.wang at linux.intel.com
yan.wang at linux.intel.com
Mon Sep 18 05:23:55 CEST 2017
From: Yan Wang <yan.wang at 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 at 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);
--
2.7.4
More information about the Sound-open-firmware
mailing list