-
Notifications
You must be signed in to change notification settings - Fork 356
audio: dai-zephyr: enable user-space use of DAI, part 1 #10801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c0a3bb0
ff0bc0c
e6d1761
37702da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| #include <sof/lib/notifier.h> | ||
| #include <sof/lib/uuid.h> | ||
| #include <sof/lib/dma.h> | ||
| #include <sof/schedule/ll_schedule_domain.h> /* zephyr_ll_user_heap() */ | ||
| #include <sof/list.h> | ||
| #include <rtos/spinlock.h> | ||
| #include <rtos/string.h> | ||
|
|
@@ -529,6 +530,17 @@ __cold int dai_common_new(struct dai_data *dd, struct comp_dev *dev, | |
| dma_sg_init(&dd->config.elem_array); | ||
| dd->xrun = 0; | ||
|
|
||
| #ifdef CONFIG_SOF_USERSPACE_LL | ||
| /* | ||
| * copier_dai_create() uses mod_zalloc() to allocate | ||
| * the 'dd' dai data object and does not set dd->alloc_ctx. | ||
| * If LL is run in user-space, assign the 'heap' here. | ||
| */ | ||
| dd->alloc_ctx.heap = zephyr_ll_user_heap(); | ||
| #else | ||
| dd->alloc_ctx.heap = NULL; | ||
| #endif | ||
|
|
||
| /* I/O performance init, keep it last so the function does not reach this in case | ||
| * of return on error, so that we do not waste a slot | ||
| */ | ||
|
|
@@ -581,6 +593,7 @@ __cold static struct comp_dev *dai_new(const struct comp_driver *drv, | |
| struct comp_dev *dev; | ||
| const struct ipc_config_dai *dai_cfg = spec; | ||
| struct dai_data *dd; | ||
| struct k_heap *heap = NULL; | ||
| int ret; | ||
|
|
||
| assert_can_be_cold(); | ||
|
|
@@ -593,10 +606,12 @@ __cold static struct comp_dev *dai_new(const struct comp_driver *drv, | |
|
|
||
| dev->ipc_config = *config; | ||
|
|
||
| dd = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*dd)); | ||
| dd = sof_heap_alloc(heap, SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT, sizeof(*dd), 0); | ||
| if (!dd) | ||
| goto e_data; | ||
|
|
||
| memset(dd, 0, sizeof(*dd)); | ||
|
|
||
| comp_set_drvdata(dev, dd); | ||
|
|
||
| ret = dai_common_new(dd, dev, dai_cfg); | ||
|
|
@@ -610,7 +625,7 @@ __cold static struct comp_dev *dai_new(const struct comp_driver *drv, | |
| return dev; | ||
|
|
||
| error: | ||
| rfree(dd); | ||
| sof_heap_free(heap, dd); | ||
| e_data: | ||
| comp_free_device(dev); | ||
| return NULL; | ||
|
|
@@ -638,7 +653,7 @@ __cold void dai_common_free(struct dai_data *dd) | |
|
|
||
| dai_put(dd->dai); | ||
|
|
||
| rfree(dd->dai_spec_config); | ||
| sof_heap_free(dd->alloc_ctx.heap, dd->dai_spec_config); | ||
| } | ||
|
|
||
| __cold static void dai_free(struct comp_dev *dev) | ||
|
|
@@ -652,7 +667,8 @@ __cold static void dai_free(struct comp_dev *dev) | |
|
|
||
| dai_common_free(dd); | ||
|
|
||
| rfree(dd); | ||
| /* heap is NULL to match what is passed in dai_new() */ | ||
| sof_heap_free(NULL, dd); | ||
| comp_free_device(dev); | ||
| } | ||
|
|
||
|
|
@@ -847,7 +863,7 @@ static int dai_set_sg_config(struct dai_data *dd, struct comp_dev *dev, uint32_t | |
| } while (--max_block_count > 0); | ||
| } | ||
|
|
||
| err = dma_sg_alloc(NULL, &config->elem_array, SOF_MEM_FLAG_USER, | ||
| err = dma_sg_alloc(dd->alloc_ctx.heap, &config->elem_array, SOF_MEM_FLAG_USER, | ||
| config->direction, | ||
| period_count, | ||
| period_bytes, | ||
|
|
@@ -873,8 +889,9 @@ static int dai_set_dma_config(struct dai_data *dd, struct comp_dev *dev) | |
|
|
||
| comp_dbg(dev, "entry"); | ||
|
|
||
| dma_cfg = rmalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, | ||
| sizeof(struct dma_config)); | ||
| dma_cfg = sof_heap_alloc(dd->alloc_ctx.heap, | ||
| SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, | ||
| sizeof(struct dma_config), 0); | ||
| if (!dma_cfg) { | ||
| comp_err(dev, "dma_cfg allocation failed"); | ||
| return -ENOMEM; | ||
|
|
@@ -903,10 +920,11 @@ static int dai_set_dma_config(struct dai_data *dd, struct comp_dev *dev) | |
| else | ||
| dma_cfg->dma_slot = config->src_dev; | ||
|
|
||
| dma_block_cfg = rballoc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, | ||
| sizeof(struct dma_block_config) * dma_cfg->block_count); | ||
| dma_block_cfg = sof_heap_alloc(dd->alloc_ctx.heap, | ||
| SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT | SOF_MEM_FLAG_DMA, | ||
| sizeof(struct dma_block_config) * dma_cfg->block_count, 0); | ||
| if (!dma_block_cfg) { | ||
| rfree(dma_cfg); | ||
| sof_heap_free(dd->alloc_ctx.heap, dma_cfg); | ||
| comp_err(dev, "dma_block_config allocation failed"); | ||
| return -ENOMEM; | ||
| } | ||
|
|
@@ -1040,7 +1058,7 @@ static int dai_set_dma_buffer(struct dai_data *dd, struct comp_dev *dev, | |
| return err; | ||
| } | ||
| } else { | ||
| dd->dma_buffer = buffer_alloc_range(NULL, buffer_size_preferred, buffer_size, | ||
| dd->dma_buffer = buffer_alloc_range(&dd->alloc_ctx, buffer_size_preferred, buffer_size, | ||
| SOF_MEM_FLAG_USER | SOF_MEM_FLAG_DMA, | ||
| addr_align, BUFFER_USAGE_NOT_SHARED); | ||
| if (!dd->dma_buffer) { | ||
|
|
@@ -1128,8 +1146,8 @@ int dai_common_params(struct dai_data *dd, struct comp_dev *dev, | |
| if (err < 0) { | ||
| buffer_free(dd->dma_buffer); | ||
| dd->dma_buffer = NULL; | ||
| dma_sg_free(NULL, &config->elem_array); | ||
| rfree(dd->z_config); | ||
| dma_sg_free(dd->alloc_ctx.heap, &config->elem_array); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a valid problem, but problem exists in existing code, so I prefer to handle this case in a follow-up PR. If I need to revise this series, I will add a new commit to address this. |
||
| sof_heap_free(dd->alloc_ctx.heap, dd->z_config); | ||
| dd->z_config = NULL; | ||
| } | ||
|
|
||
|
|
@@ -1255,10 +1273,10 @@ void dai_common_reset(struct dai_data *dd, struct comp_dev *dev) | |
| if (!dd->delayed_dma_stop) | ||
| dai_dma_release(dd, dev); | ||
|
|
||
| dma_sg_free(NULL, &config->elem_array); | ||
| dma_sg_free(dd->alloc_ctx.heap, &config->elem_array); | ||
| if (dd->z_config) { | ||
| rfree(dd->z_config->head_block); | ||
| rfree(dd->z_config); | ||
| sof_heap_free(dd->alloc_ctx.heap, dd->z_config->head_block); | ||
| sof_heap_free(dd->alloc_ctx.heap, dd->z_config); | ||
| dd->z_config = NULL; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just
NULLThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went back and forth between "heap" variable and just putting NULL, but in the end I think this is more readable and makes it explicit same value needs to be passed to alloc and free in this function. Compilation output should be the same in both cases.