diff --git a/src/audio/kpb.c b/src/audio/kpb.c index 8a912a307a65..9c29c10b96de 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -350,7 +350,6 @@ static int kpb_prepare(struct comp_dev *dev) /* Init private data */ cd->kpb_no_of_clients = 0; cd->buffered_data = 0; - cd->state = KPB_STATE_BUFFERING; /* Init history buffer */ kpb_clear_history_buffer(cd->history_buffer); @@ -437,16 +436,12 @@ static int kpb_reset(struct comp_dev *dev) /* Reset history buffer */ kpb->is_internal_buffer_full = false; kpb_clear_history_buffer(kpb->history_buffer); - /* Reset amount of buffered data */ kpb->buffered_data = 0; /* Unregister KPB for async notification */ notifier_unregister(&kpb->kpb_events); - /* Reset KPB state to initial buffering state */ - kpb->state = KPB_STATE_BUFFERING; - return comp_set_state(dev, COMP_TRIGGER_RESET); } @@ -474,17 +469,15 @@ static int kpb_copy(struct comp_dev *dev) /* Get source and sink buffers */ source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - sink = (kpb->state == KPB_STATE_BUFFERING) ? kpb->rt_sink - : kpb->cli_sink; - /* Pause selector copy during draining and/or draining on demand. - * We keep selector in this "paused" state as long as draining - * is going and later during direct copy to client's/host sink, - * in so called "draining on demand" state. In order to rearm - * detection algorithm kpb_reset is needed. - */ - if (kpb->state != KPB_STATE_BUFFERING) + /* Stop copying downstream if in draining */ + if (kpb->state == KPB_STATE_DRAINING_ON_DEMAND) { + comp_update_buffer_consume(source, source->avail); return PPL_STATUS_PATH_STOP; + } + + sink = (kpb->state == KPB_STATE_BUFFERING) ? kpb->rt_sink + : kpb->cli_sink; /* Process source data */ /* Check if there are valid pointers */ @@ -795,6 +788,7 @@ static void kpb_init_draining(struct comp_data *kpb, struct kpb_client *cli) comp_set_attribute(kpb->cli_sink->sink, COMP_ATTR_COPY_BLOCKING, 1); + kpb->state = KPB_STATE_DRAINING_ON_DEMAND; /* Schedule draining task */ schedule_task(&kpb->draining_task, 0, 0, SOF_SCHEDULE_FLAG_IDLE); @@ -855,7 +849,7 @@ static uint64_t kpb_draining_task(void *arg) /* Draining is done. Now switch KPB to copy real time stream * to client's sink */ - *draining_data->state = KPB_STATE_DRAINING_ON_DEMAND; + *draining_data->state = KPB_STATE_REALTIME; /* Reset host-sink copy mode back to unblocking */ comp_set_attribute(sink->sink, COMP_ATTR_COPY_BLOCKING, 0); diff --git a/src/audio/selector.c b/src/audio/selector.c index 19d02344acb8..de6d61260478 100644 --- a/src/audio/selector.c +++ b/src/audio/selector.c @@ -183,7 +183,7 @@ static int selector_params(struct comp_dev *dev) else dev->params.channels = cd->config.in_channels_count; - return 0; + return PPL_STATUS_PATH_STOP; } @@ -303,9 +303,11 @@ static int selector_cmd(struct comp_dev *dev, int cmd, void *data, */ static int selector_trigger(struct comp_dev *dev, int cmd) { + int ret; trace_selector("selector_trigger()"); - return comp_set_state(dev, cmd); + ret = comp_set_state(dev, cmd); + return ret == 0 ? PPL_STATUS_PATH_STOP : ret; } @@ -454,7 +456,7 @@ static int selector_prepare(struct comp_dev *dev) goto err; } - return 0; + return PPL_STATUS_PATH_STOP; err: comp_set_state(dev, COMP_TRIGGER_RESET); @@ -468,9 +470,11 @@ static int selector_prepare(struct comp_dev *dev) */ static int selector_reset(struct comp_dev *dev) { + int ret; trace_selector("selector_reset()"); - return comp_set_state(dev, COMP_TRIGGER_RESET); + ret = comp_set_state(dev, COMP_TRIGGER_RESET); + return ret == 0 ? PPL_STATUS_PATH_STOP : ret; } /** diff --git a/src/drivers/intel/cavs/hda-dma.c b/src/drivers/intel/cavs/hda-dma.c index 24e435a678c7..d075799471f0 100644 --- a/src/drivers/intel/cavs/hda-dma.c +++ b/src/drivers/intel/cavs/hda-dma.c @@ -275,6 +275,11 @@ static int hda_dma_wait_for_buffer_full(struct dma *dma, while (!(host_dma_reg_read(dma, chan->index, DGCS) & DGCS_BF)) { if (deadline < platform_timer_get(platform_timer)) { + /* safe check in case we've got preempted after read */ + if (host_dma_reg_read(dma, chan->index, DGCS) & + DGCS_BF) + return 0; + trace_hddma_error("hda-dmac: %d wait for buffer full " "timeout", dma->plat_data.id); return -ETIME; @@ -293,6 +298,11 @@ static int hda_dma_wait_for_buffer_empty(struct dma *dma, while (host_dma_reg_read(dma, chan->index, DGCS) & DGCS_BNE) { if (deadline < platform_timer_get(platform_timer)) { + /* safe check in case we've got preempted after read */ + if (!(host_dma_reg_read(dma, chan->index, DGCS) & + DGCS_BNE)) + return 0; + trace_hddma_error("hda-dmac: %d wait for buffer empty " "timeout", dma->plat_data.id); return -ETIME; diff --git a/src/include/sof/audio/kpb.h b/src/include/sof/audio/kpb.h index 382a1ed919b6..938b2a354d79 100644 --- a/src/include/sof/audio/kpb.h +++ b/src/include/sof/audio/kpb.h @@ -60,6 +60,7 @@ enum kpb_state { KPB_STATE_BUFFERING = 0, KPB_STATE_DRAINING_ON_DEMAND, + KPB_STATE_REALTIME, }; enum kpb_event { diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h index 64fa0ed2c34c..1b6fcf21266e 100644 --- a/src/platform/apollolake/include/platform/platform.h +++ b/src/platform/apollolake/include/platform/platform.h @@ -155,7 +155,7 @@ struct sof; #define PLATFORM_DEFAULT_DELAY 12 /* minimal L1 exit time in cycles */ -#define PLATFORM_FORCE_L1_EXIT_TIME 585 +#define PLATFORM_FORCE_L1_EXIT_TIME 800 /* the SSP port fifo depth */ #define SSP_FIFO_DEPTH 16 diff --git a/tools/topology/m4/detect_test_coef.m4 b/tools/topology/m4/detect_test_coef.m4 index 77f027c664b2..6358be7ad8ec 100644 --- a/tools/topology/m4/detect_test_coef.m4 +++ b/tools/topology/m4/detect_test_coef.m4 @@ -4,8 +4,8 @@ CONTROLBYTES_PRIV(DETECTOR_priv, ` 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x03,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x20,0x00,0x00,0x00,0x05,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,' -` 0x03,0x00,0x00,0x80,0x00,0x00,0x00,0x00,' +` 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x00,' +` 0x03,0x00,0xff,0x3f,0x00,0x00,0x00,0x00,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"' ) diff --git a/tools/topology/sof-glk-da7219-kwd.m4 b/tools/topology/sof-glk-da7219-kwd.m4 index 7ee3a21dd5da..10d14096778d 100644 --- a/tools/topology/sof-glk-da7219-kwd.m4 +++ b/tools/topology/sof-glk-da7219-kwd.m4 @@ -77,14 +77,6 @@ PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, 7, 7, 2, s32le, 48, 1000, 0, 0) -# Passthrough capture pipeline 8 on PCM 8 using max 2 channels. -# Schedule 320 frames per 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-kfbm-capture.m4, - 8, 8, 2, s16le, - KWD_PERIOD_FRAMES, - KWD_PIPE_SCH_DEADLINE_US, - 0, 0) - # # DAIs configuration # @@ -122,24 +114,36 @@ DAI_ADD(sof/pipe-dai-capture.m4, DAI_ADD(sof/pipe-dai-playback.m4, 5, HDA, 3, iDisp1, PIPELINE_SOURCE_5, 2, s32le, - 48, 1000, 0, 0) + 48, 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # playback DAI is iDisp2 using 2 periods # Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 DAI_ADD(sof/pipe-dai-playback.m4, 6, HDA, 4, iDisp2, PIPELINE_SOURCE_6, 2, s32le, - 48, 1000, 0, 0) + 48, 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) # playback DAI is iDisp3 using 2 periods # Buffers use s32le format, with 48 frame per 1000us on core 0 with priority 0 DAI_ADD(sof/pipe-dai-playback.m4, 7, HDA, 5, iDisp3, PIPELINE_SOURCE_7, 2, s32le, - 48, 1000, 0, 0) + 48, 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# +# KWD configuration +# + +# Passthrough capture pipeline 8 on PCM 8 using max 2 channels. +# Schedule 320 frames per 20000us deadline on core 0 with priority 0 +PIPELINE_PCM_ADD(sof/pipe-kfbm-capture.m4, + 8, 8, 2, s16le, + KWD_PERIOD_FRAMES, + KWD_PIPE_SCH_DEADLINE_US, + 0, 0) # capture DAI is DMIC 1 using 2 periods -# Buffers use s16le format, with 320 frame per 1000us on core 0 with priority 0 +# Buffers use s16le format, with 320 frame per 20000us on core 0 with priority 0 DAI_ADD(sof/pipe-dai-capture.m4, 8, DMIC, 1, dmic16k, PIPELINE_SINK_8, 2, s16le,