[Sound-open-firmware] [PATCH v3 7/7] host: add HOST_SIDE_BUFFER_CHECK to make host side buffer check configurable
Keyon Jie
yang.jie at linux.intel.com
Wed Mar 1 10:32:05 CET 2017
It is possible that we may don't like check host side buffer
and assume there are always datas/room for playback/capture,
so here we add a config item HOST_SIDE_BUFFER_CHECK to make
it configurable, and disable this buffer check may save about
0.6KB to the firmware binary size.
Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
---
src/audio/host.c | 50 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/src/audio/host.c b/src/audio/host.c
index 195cd6c..80ee3fe 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -50,6 +50,8 @@
#define tracev_host(__e) tracev_event(TRACE_CLASS_HOST, __e)
#define trace_host_error(__e) trace_error(TRACE_CLASS_HOST, __e)
+//#define HOST_SIDE_BUFFER_CHECK
+
struct hc_buf {
/* host buffer info */
struct list_item elem_list;
@@ -65,19 +67,23 @@ struct host_data {
completion_t complete;
struct period_desc *period;
struct comp_buffer *dma_buffer;
- struct work work;
/* local and host DMA buffer info */
struct hc_buf host;
struct hc_buf local;
uint32_t host_size;
+ /* host possition reporting related */
volatile uint32_t *host_pos; /* read/write pos, update to mailbox for host side */
- uint32_t buff_w_off; /* the host side buffer write offset in bytes */
- uint32_t buff_r_off; /* the host side buffer read offset in bytes */
- uint32_t report_period; /* host_pos report/update to host side period, in bytes */
- uint32_t report_pos; /* position in current report period */
- uint32_t buff_avail; /* host side buffer available size */
- uint32_t buff_free; /* host side buffer free size */
+ uint32_t report_period; /* host_pos report/update to host side period, in bytes */
+ uint32_t report_pos; /* position in current report period */
+ uint32_t buff_w_off; /* the host side buffer write offset in bytes */
+ uint32_t buff_r_off; /* the host side buffer read offset in bytes */
+#ifdef HOST_SIDE_BUFFER_CHECK
+ struct work work;
+ /* host side buffer management related */
+ uint32_t buff_avail; /* host side buffer available size */
+ uint32_t buff_free; /* host side buffer free size */
+#endif
/* pointers set during params to host or local above */
struct hc_buf *source;
struct hc_buf *sink;
@@ -89,6 +95,7 @@ struct host_data {
struct comp_position cp;
};
+#ifdef HOST_SIDE_BUFFER_CHECK
static void host_update_buffer(struct host_data *hd, uint32_t produce)
{
if (hd->buff_r_off < hd->buff_w_off)
@@ -99,7 +106,11 @@ static void host_update_buffer(struct host_data *hd, uint32_t produce)
hd->buff_avail = hd->host_size -hd->buff_r_off + hd->buff_w_off;
hd->buff_free = hd->host_size - hd->buff_avail;
}
-
+#else
+static void host_update_buffer(struct host_data *hd, uint32_t produce)
+{
+}
+#endif
static inline struct dma_sg_elem *next_buffer(struct hc_buf *hc)
{
struct dma_sg_elem *elem;
@@ -161,6 +172,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
hd->report_pos += local_elem->size;
if (hd->report_pos >= hd->report_period) {
hd->report_pos = 0;
+#ifdef HOST_SIDE_BUFFER_CHECK
/* for the last bytes/period, send notification later */
if (hd->buff_avail) {
/* update for host side */
@@ -169,6 +181,13 @@ static void host_dma_cb_playback(struct comp_dev *dev,
ipc_stream_send_notification(dev, &hd->cp);
}
}
+#else
+ /* update for host side */
+ if (hd->host_pos) {
+ *hd->host_pos = hd->buff_r_off;
+ ipc_stream_send_notification(dev, &hd->cp);
+ }
+#endif
}
local_elem->src += local_elem->size;
@@ -203,6 +222,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
}
local_elem->size = next_size;
+#ifdef HOST_SIDE_BUFFER_CHECK
/* check if avail is enough, otherwise, drain the last bytes and stop */
if (hd->buff_avail < local_elem->size) {
if (hd->buff_avail == 0) {
@@ -226,6 +246,7 @@ static void host_dma_cb_playback(struct comp_dev *dev,
}
next_copy:
+#endif
if (need_copy) {
next->src = local_elem->src;
next->dest = local_elem->dest;
@@ -347,6 +368,7 @@ static void host_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
host_dma_cb_capture(dev, next);
}
+#ifdef HOST_SIDE_BUFFER_CHECK
/* We need to wait until the last bytes/period is finished in dai, before we
* can notify host side about that, otherwise, host side will trigger stop too
* early, and we will miss rendering them.
@@ -378,8 +400,7 @@ static uint32_t host_finish_work(void *data, uint32_t udelay)
return 0;
}
-
-
+#endif
static struct comp_dev *host_new(uint32_t type, uint32_t index,
uint32_t direction)
@@ -410,8 +431,9 @@ static struct comp_dev *host_new(uint32_t type, uint32_t index,
hd->dma = dma_get(DMA_ID_DMAC0);
if (hd->dma == NULL)
goto error;
+#ifdef HOST_SIDE_BUFFER_CHECK
work_init(&hd->work, host_finish_work, dev, WORK_ASYNC);
-
+#endif
/* init buffer elems */
list_init(&hd->config.elem_list);
list_init(&hd->host.elem_list);
@@ -694,7 +716,9 @@ static int host_cmd(struct comp_dev *dev, int cmd, void *data)
{
struct host_data *hd = comp_get_drvdata(dev);
struct comp_dev *vol_dev = NULL;
+#ifdef HOST_SIDE_BUFFER_CHECK
struct ipc_intel_ipc_stream_set_position *app_pos;
+#endif
int ret = 0;
// TODO: align cmd macros.
@@ -723,6 +747,7 @@ static int host_cmd(struct comp_dev *dev, int cmd, void *data)
case COMP_CMD_IPC_MMAP_RPOS:
hd->host_pos = data;
break;
+#ifdef HOST_SIDE_BUFFER_CHECK
case COMP_CMD_AVAIL_UPDATE:
app_pos = (struct ipc_intel_ipc_stream_set_position *)data;
@@ -735,6 +760,7 @@ static int host_cmd(struct comp_dev *dev, int cmd, void *data)
host_update_buffer(hd, 0); /* consume */
}
break;
+#endif
case COMP_CMD_VOLUME:
vol_dev = host_volume_component(dev);
if (vol_dev != NULL)
@@ -810,6 +836,7 @@ static int host_copy(struct comp_dev *dev)
if (dev->state != COMP_STATE_RUNNING)
return 0;
+#ifdef HOST_SIDE_BUFFER_CHECK
/* don't copy if the host side buffer is not ready */
if ((hd->params.direction == STREAM_DIRECTION_PLAYBACK)
&& (hd->buff_avail == 0))
@@ -817,6 +844,7 @@ static int host_copy(struct comp_dev *dev)
if ((hd->params.direction == STREAM_DIRECTION_CAPTURE)
&& (hd->buff_free == 0))
return 0;
+#endif
/* do DMA transfer */
wait_init(&hd->complete);
--
2.7.4
More information about the Sound-open-firmware
mailing list