Lines Matching refs:hd
57 static uint32_t host_dma_get_split(struct host_data *hd, uint32_t bytes) in host_dma_get_split() argument
59 struct dma_sg_elem *local_elem = hd->config.elem_array.elems; in host_dma_get_split()
63 if (local_elem->src + bytes > hd->source->current_end) in host_dma_get_split()
65 (hd->source->current_end - local_elem->src); in host_dma_get_split()
67 if (local_elem->dest + bytes > hd->sink->current_end) in host_dma_get_split()
69 (hd->sink->current_end - local_elem->dest); in host_dma_get_split()
77 static int host_dma_set_config_and_copy(struct host_data *hd, struct comp_dev *dev, uint32_t bytes) in host_dma_set_config_and_copy() argument
79 struct dma_sg_elem *local_elem = hd->config.elem_array.elems; in host_dma_set_config_and_copy()
85 ret = dma_config(hd->chan->dma->z_dev, hd->chan->index, &hd->z_config); in host_dma_set_config_and_copy()
93 .channel = hd->chan, in host_dma_set_config_and_copy()
96 notifier_event(hd->chan, NOTIFIER_ID_DMA_COPY, in host_dma_set_config_and_copy()
98 ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, bytes); in host_dma_set_config_and_copy()
113 static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd) in host_get_copy_bytes_one_shot() argument
115 struct comp_buffer *buffer = hd->local_buffer; in host_get_copy_bytes_one_shot()
122 if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) in host_get_copy_bytes_one_shot()
132 return ALIGN_DOWN(copy_bytes, hd->dma_copy_align); in host_get_copy_bytes_one_shot()
141 static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev) in host_copy_one_shot() argument
149 copy_bytes = host_get_copy_bytes_one_shot(hd); in host_copy_one_shot()
157 split_value = host_dma_get_split(hd, copy_bytes); in host_copy_one_shot()
160 ret = host_dma_set_config_and_copy(hd, dev, copy_bytes); in host_copy_one_shot()
178 static uint32_t host_get_copy_bytes_one_shot(struct host_data *hd) in host_get_copy_bytes_one_shot() argument
180 struct dma_sg_elem *local_elem = hd->config.elem_array.elems; in host_get_copy_bytes_one_shot()
181 struct comp_buffer *buffer = hd->local_buffer; in host_get_copy_bytes_one_shot()
189 if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) in host_get_copy_bytes_one_shot()
199 copy_bytes = ALIGN_DOWN(copy_bytes, hd->dma_copy_align); in host_get_copy_bytes_one_shot()
201 split_value = host_dma_get_split(hd, copy_bytes); in host_get_copy_bytes_one_shot()
216 static int host_copy_one_shot(struct host_data *hd, struct comp_dev *dev) in host_copy_one_shot() argument
223 copy_bytes = host_get_copy_bytes_one_shot(hd); in host_copy_one_shot()
230 ret = dma_config(hd->chan->dma->z_dev, hd->chan->index, &hd->z_config); in host_copy_one_shot()
237 .channel = hd->chan, in host_copy_one_shot()
240 notifier_event(hd->chan, NOTIFIER_ID_DMA_COPY, in host_copy_one_shot()
242 ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, copy_bytes); in host_copy_one_shot()
250 void host_update_position(struct host_data *hd, struct comp_dev *dev, uint32_t bytes) in host_update_position() argument
258 if (hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK) { in host_update_position()
259 source = buffer_acquire(hd->dma_buffer); in host_update_position()
260 sink = buffer_acquire(hd->local_buffer); in host_update_position()
261 ret = dma_buffer_copy_from(source, sink, hd->process, bytes); in host_update_position()
263 source = buffer_acquire(hd->local_buffer); in host_update_position()
264 sink = buffer_acquire(hd->dma_buffer); in host_update_position()
265 ret = dma_buffer_copy_to(source, sink, hd->process, bytes); in host_update_position()
271 hd->ipc_host.direction, bytes, in host_update_position()
283 hd->total_data_processed += bytes; in host_update_position()
288 hd->local_pos += bytes; in host_update_position()
291 if (hd->local_pos >= hd->host_size) in host_update_position()
293 hd->local_pos %= hd->host_size; in host_update_position()
295 hd->local_pos = 0; in host_update_position()
297 if (hd->cont_update_posn) in host_update_position()
301 if (!hd->no_stream_position) { in host_update_position()
302 hd->report_pos += bytes; in host_update_position()
308 if (hd->host_period_bytes != 0 && in host_update_position()
309 hd->report_pos >= hd->host_period_bytes) { in host_update_position()
310 hd->report_pos = 0; in host_update_position()
321 pipeline_get_timestamp(dev->pipeline, dev, &hd->posn); in host_update_position()
323 &hd->posn, sizeof(hd->posn)); in host_update_position()
325 ipc_msg_send(hd->msg, &hd->posn, false); in host_update_position()
334 void host_one_shot_cb(struct host_data *hd, uint32_t bytes) in host_one_shot_cb() argument
336 struct dma_sg_elem *local_elem = hd->config.elem_array.elems; in host_one_shot_cb()
344 if (local_elem->src == hd->source->current_end) { in host_one_shot_cb()
346 source_elem = next_buffer(hd->source); in host_one_shot_cb()
348 hd->source->current_end = source_elem->src + in host_one_shot_cb()
354 if (local_elem->dest == hd->sink->current_end) { in host_one_shot_cb()
356 sink_elem = next_buffer(hd->sink); in host_one_shot_cb()
358 hd->sink->current_end = sink_elem->dest + in host_one_shot_cb()
372 struct host_data *hd = comp_get_drvdata(dev); in host_dma_cb() local
378 host_update_position(hd, dev, bytes); in host_dma_cb()
381 if (hd->copy_type == COMP_COPY_ONE_SHOT) in host_dma_cb()
382 host_one_shot_cb(hd, bytes); in host_dma_cb()
390 static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev *dev) in host_get_copy_bytes_normal() argument
392 struct comp_buffer *buffer = hd->local_buffer; in host_get_copy_bytes_normal()
401 ret = dma_get_status(hd->chan->dma->z_dev, hd->chan->index, &stat); in host_get_copy_bytes_normal()
425 if (!(hd->ipc_host.feature_mask & BIT(IPC4_COPIER_FAST_MODE))) in host_get_copy_bytes_normal()
426 copy_bytes = MIN(hd->period_bytes, copy_bytes); in host_get_copy_bytes_normal()
437 return ALIGN_DOWN(copy_bytes, hd->dma_copy_align); in host_get_copy_bytes_normal()
446 static int host_copy_normal(struct host_data *hd, struct comp_dev *dev) in host_copy_normal() argument
459 copy_bytes = host_get_copy_bytes_normal(hd, dev); in host_copy_normal()
464 .channel = hd->chan, in host_copy_normal()
467 notifier_event(hd->chan, NOTIFIER_ID_DMA_COPY, in host_copy_normal()
470 hd->partial_size += copy_bytes; in host_copy_normal()
471 buffer_c = buffer_acquire(hd->dma_buffer); in host_copy_normal()
480 buffer_c->stream.size < hd->period_bytes << 3 || in host_copy_normal()
481 buffer_c->stream.size - hd->partial_size <= (2 + threshold) * hd->period_bytes) { in host_copy_normal()
482 ret = dma_reload(hd->chan->dma->z_dev, hd->chan->index, 0, 0, hd->partial_size); in host_copy_normal()
486 hd->partial_size = 0; in host_copy_normal()
494 static int create_local_elems(struct host_data *hd, struct comp_dev *dev, uint32_t buffer_count, in create_local_elems() argument
506 if (hd->host.elem_array.count) { in create_local_elems()
507 elem_array = &hd->local.elem_array; in create_local_elems()
510 err = dma_sg_alloc(&hd->config.elem_array, SOF_MEM_ZONE_RUNTIME, in create_local_elems()
517 elem_array = &hd->config.elem_array; in create_local_elems()
520 dma_buf_c = buffer_acquire(hd->dma_buffer); in create_local_elems()
533 int host_zephyr_trigger(struct host_data *hd, struct comp_dev *dev, int cmd) in host_zephyr_trigger() argument
540 if (cmd != COMP_TRIGGER_START && hd->copy_type == COMP_COPY_ONE_SHOT) in host_zephyr_trigger()
543 if (!hd->chan) { in host_zephyr_trigger()
550 hd->partial_size = 0; in host_zephyr_trigger()
551 ret = dma_start(hd->chan->dma->z_dev, hd->chan->index); in host_zephyr_trigger()
559 ret = dma_stop(hd->chan->dma->z_dev, hd->chan->index); in host_zephyr_trigger()
585 struct host_data *hd = comp_get_drvdata(dev); in host_trigger() local
597 return host_zephyr_trigger(hd, dev, cmd); in host_trigger()
600 int host_zephyr_new(struct host_data *hd, struct comp_dev *dev, in host_zephyr_new() argument
605 hd->ipc_host = *ipc_host; in host_zephyr_new()
607 dir = hd->ipc_host.direction == SOF_IPC_STREAM_PLAYBACK ? in host_zephyr_new()
610 hd->dma = dma_get(dir, 0, DMA_DEV_HOST, DMA_ACCESS_SHARED); in host_zephyr_new()
611 if (!hd->dma) { in host_zephyr_new()
617 dma_sg_init(&hd->config.elem_array); in host_zephyr_new()
618 dma_sg_init(&hd->host.elem_array); in host_zephyr_new()
619 dma_sg_init(&hd->local.elem_array); in host_zephyr_new()
621 ipc_build_stream_posn(&hd->posn, SOF_IPC_STREAM_POSITION, config_id); in host_zephyr_new()
623 hd->msg = ipc_msg_init(hd->posn.rhdr.hdr.cmd, sizeof(hd->posn)); in host_zephyr_new()
624 if (!hd->msg) { in host_zephyr_new()
626 dma_put(hd->dma); in host_zephyr_new()
629 hd->chan = NULL; in host_zephyr_new()
630 hd->copy_type = COMP_COPY_NORMAL; in host_zephyr_new()
640 struct host_data *hd; in host_new() local
651 hd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*hd)); in host_new()
652 if (!hd) in host_new()
655 comp_set_drvdata(dev, hd); in host_new()
657 ret = host_zephyr_new(hd, dev, ipc_host, dev->ipc_config.id); in host_new()
666 rfree(hd); in host_new()
672 void host_zephyr_free(struct host_data *hd) in host_zephyr_free() argument
674 dma_put(hd->dma); in host_zephyr_free()
676 ipc_msg_free(hd->msg); in host_zephyr_free()
677 dma_sg_free(&hd->config.elem_array); in host_zephyr_free()
682 struct host_data *hd = comp_get_drvdata(dev); in host_free() local
685 host_zephyr_free(hd); in host_free()
686 rfree(hd); in host_free()
690 static int host_elements_reset(struct host_data *hd, int direction) in host_elements_reset() argument
697 source_elem = hd->source->elem_array.elems; in host_elements_reset()
699 hd->source->current = 0; in host_elements_reset()
700 hd->source->current_end = source_elem->src + source_elem->size; in host_elements_reset()
704 sink_elem = hd->sink->elem_array.elems; in host_elements_reset()
706 hd->sink->current = 0; in host_elements_reset()
707 hd->sink->current_end = sink_elem->dest + sink_elem->size; in host_elements_reset()
712 local_elem = hd->config.elem_array.elems; in host_elements_reset()
739 int host_zephyr_params(struct host_data *hd, struct comp_dev *dev, in host_zephyr_params() argument
742 struct dma_sg_config *config = &hd->config; in host_zephyr_params()
744 struct dma_config *dma_cfg = &hd->z_config; in host_zephyr_params()
757 hd->host_size = params->buffer.size; in host_zephyr_params()
758 hd->stream_tag = params->stream_tag; in host_zephyr_params()
759 hd->no_stream_position = params->no_stream_position; in host_zephyr_params()
760 hd->host_period_bytes = params->host_period_bytes; in host_zephyr_params()
761 hd->cont_update_posn = params->cont_update_posn; in host_zephyr_params()
764 err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_BUFFER_ADDRESS_ALIGNMENT, in host_zephyr_params()
773 err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_BUFFER_SIZE_ALIGNMENT, &align); in host_zephyr_params()
781 period_count = hd->dma->plat_data.period_count; in host_zephyr_params()
788 hd->local_buffer = list_first_item(&dev->bsink_list, in host_zephyr_params()
792 hd->local_buffer = list_first_item(&dev->bsource_list, in host_zephyr_params()
795 host_buf_c = buffer_acquire(hd->local_buffer); in host_zephyr_params()
808 hd->source = &hd->host; in host_zephyr_params()
809 hd->sink = &hd->local; in host_zephyr_params()
812 hd->source = &hd->local; in host_zephyr_params()
813 hd->sink = &hd->host; in host_zephyr_params()
817 if (hd->host.elem_array.count) { in host_zephyr_params()
824 buffer_size = MAX(buffer_size, ALIGN_UP(hd->ipc_host.dma_buffer_size, align)); in host_zephyr_params()
831 if (hd->dma_buffer) { in host_zephyr_params()
832 dma_buf_c = buffer_acquire(hd->dma_buffer); in host_zephyr_params()
841 hd->dma_buffer = buffer_alloc(buffer_size, SOF_MEM_CAPS_DMA, in host_zephyr_params()
843 if (!hd->dma_buffer) { in host_zephyr_params()
849 dma_buf_c = buffer_acquire(hd->dma_buffer); in host_zephyr_params()
854 hd->process = pcm_get_conversion_function(host_buf_c->stream.frame_fmt, in host_zephyr_params()
857 hd->process = pcm_get_conversion_function(dma_buf_c->stream.frame_fmt, in host_zephyr_params()
866 err = create_local_elems(hd, dev, period_count, buffer_size / period_count, in host_zephyr_params()
877 host_elements_reset(hd, params->direction); in host_zephyr_params()
879 hd->stream_tag -= 1; in host_zephyr_params()
880 uint32_t hda_chan = hd->stream_tag; in host_zephyr_params()
884 channel = dma_request_channel(hd->dma->z_dev, &hda_chan); in host_zephyr_params()
890 hd->chan = &hd->dma->chan[channel]; in host_zephyr_params()
896 hd->chan->direction = config->direction; in host_zephyr_params()
897 hd->chan->desc_count = config->elem_array.count; in host_zephyr_params()
898 hd->chan->is_scheduling_source = config->is_scheduling_source; in host_zephyr_params()
899 hd->chan->period = config->period; in host_zephyr_params()
936 err = dma_config(hd->chan->dma->z_dev, hd->chan->index, dma_cfg); in host_zephyr_params()
939 dma_release_channel(hd->dma->z_dev, hd->chan->index); in host_zephyr_params()
940 hd->chan = NULL; in host_zephyr_params()
944 err = dma_get_attribute(hd->dma->z_dev, DMA_ATTR_COPY_ALIGNMENT, in host_zephyr_params()
945 &hd->dma_copy_align); in host_zephyr_params()
954 hd->period_bytes = ALIGN_UP(period_bytes, hd->dma_copy_align); in host_zephyr_params()
957 hd->copy = hd->copy_type == COMP_COPY_ONE_SHOT ? host_copy_one_shot : in host_zephyr_params()
969 struct host_data *hd = comp_get_drvdata(dev); in host_params() local
980 err = host_zephyr_params(hd, dev, params); in host_params()
983 notifier_register(dev, hd->chan, NOTIFIER_ID_DMA_COPY, host_dma_cb, 0); in host_params()
988 int host_zephyr_prepare(struct host_data *hd) in host_zephyr_prepare() argument
990 struct comp_buffer __sparse_cache *buf_c = buffer_acquire(hd->dma_buffer); in host_zephyr_prepare()
1000 struct host_data *hd = comp_get_drvdata(dev); in host_prepare() local
1013 return host_zephyr_prepare(hd); in host_prepare()
1019 struct host_data *hd = comp_get_drvdata(dev); in host_position() local
1022 posn->host_posn = hd->local_pos; in host_position()
1027 void host_zephyr_reset(struct host_data *hd, uint16_t state) in host_zephyr_reset() argument
1029 if (hd->chan) { in host_zephyr_reset()
1031 dma_stop(hd->chan->dma->z_dev, hd->chan->index); in host_zephyr_reset()
1032 dma_release_channel(hd->dma->z_dev, hd->chan->index); in host_zephyr_reset()
1033 hd->chan = NULL; in host_zephyr_reset()
1037 dma_sg_free(&hd->host.elem_array); in host_zephyr_reset()
1038 dma_sg_free(&hd->local.elem_array); in host_zephyr_reset()
1039 dma_sg_free(&hd->config.elem_array); in host_zephyr_reset()
1042 if (hd->dma_buffer) { in host_zephyr_reset()
1043 buffer_free(hd->dma_buffer); in host_zephyr_reset()
1044 hd->dma_buffer = NULL; in host_zephyr_reset()
1048 hd->local_pos = 0; in host_zephyr_reset()
1049 hd->report_pos = 0; in host_zephyr_reset()
1050 hd->total_data_processed = 0; in host_zephyr_reset()
1052 hd->copy_type = COMP_COPY_NORMAL; in host_zephyr_reset()
1053 hd->source = NULL; in host_zephyr_reset()
1054 hd->sink = NULL; in host_zephyr_reset()
1059 struct host_data *hd = comp_get_drvdata(dev); in host_reset() local
1063 if (hd->chan) in host_reset()
1064 notifier_unregister(dev, hd->chan, NOTIFIER_ID_DMA_COPY); in host_reset()
1066 host_zephyr_reset(hd, dev->state); in host_reset()
1073 int host_zephyr_copy(struct host_data *hd, struct comp_dev *dev) in host_zephyr_copy() argument
1075 return hd->copy(hd, dev); in host_zephyr_copy()
1081 struct host_data *hd = comp_get_drvdata(dev); in host_copy() local
1086 return host_zephyr_copy(hd, dev); in host_copy()
1092 struct host_data *hd = comp_get_drvdata(dev); in host_get_attribute() local
1096 *(enum comp_copy_type *)value = hd->copy_type; in host_get_attribute()
1099 *(uint32_t *)value = hd->ipc_host.direction; in host_get_attribute()
1111 struct host_data *hd = comp_get_drvdata(dev); in host_set_attribute() local
1115 hd->copy_type = *(enum comp_copy_type *)value; in host_set_attribute()
1118 hd->host.elem_array = *(struct dma_sg_elem_array *)value; in host_set_attribute()
1129 struct host_data *hd = comp_get_drvdata(dev); in host_get_processed_data() local
1137 ret = hd->total_data_processed; in host_get_processed_data()