Mt8196/v0.3#10785
Conversation
Make sof_dma.h and dma-legacy.h mutually exclusive based on CONFIG_ZEPHYR_NATIVE_DRIVERS, instead of always including sof_dma.h. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Specify the rimage signing schema for the mt8196 ADSP board so the firmware image is signed with the matching mt8196 manifest. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Map Zephyr DMA API operations to AFE MEMIF register accesses. Use chan_filter to enforce fixed channel-to-MEMIF-index mapping. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Software DMA using memcpy + cache ops to copy audio from host DRAM to DSP local SRAM. Transfer executes in config() so data is ready before the pipeline callback fires. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Expose each AFE MEMIF as a Zephyr DAI device via DEVICE_DT_INST_DEFINE. Hardware start/stop is handled by the MEMIF DMA driver; DAI trigger is a no-op. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Add SOF_DAI_MEDIATEK_AFE handling in dai_set_config() and dai_set_device_params(), and expose mediatek_afe devices to dai_get(). Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
Register sof_dma[] entries, allocate dma_chan_data[] arrays in platform_init(), add CONFIG_DMA_MTK_SOF_HOST_DMA Kconfig symbol, guard legacy-only code paths, and enable native drivers for MT8196. Signed-off-by: Cyril Chao <cyril.chao@mediatek.corp-partner.google.com>
|
Can one of the admins verify this patch?
|
|
test this please |
| #else | ||
| #include "dma-legacy.h" | ||
| #endif /* !CONFIG_ZEPHYR_NATIVE_DRIVERS */ | ||
| #endif /* CONFIG_ZEPHYR_NATIVE_DRIVERS */ |
There was a problem hiding this comment.
this doesn't fix any builds, this just changes a comment
There was a problem hiding this comment.
oh yeah, thanks point that out, it looks like the issue mentioned here was already fixed in some version, which is why the cherry-pick had some issues. This commit is no longer needed, so I'll drop it later.
| for (uint32_t i = 0; i < data->ctx.dma_channels; i++) { | ||
| data->channels[i].afe = afe; | ||
| data->channels[i].memif_id = i; | ||
| } |
There was a problem hiding this comment.
This is a global initialisation so it's also ok to keep it if the function fails? Otherwise it looks like it should be possibly to move this block of lines 71-86 to below sanity checks in lines 88-127. Then if any of those checks fail you return from the function without changing anything persistent.
| ret = afe_memif_set_addr(chan->afe, chan->memif_id, | ||
| chan->dma_base, chan->dma_size); | ||
| if (ret < 0) { | ||
| return ret; |
There was a problem hiding this comment.
here you exit the function with a partially successful hardware configuration from the previous function. But maybe there's nothing you can reasonably do about that.
| data->channel_flags = ATOMIC_INIT(0); \ | ||
| data->ctx.atomic = &data->channel_flags; \ | ||
| return 0; \ | ||
| } \ |
There was a problem hiding this comment.
does this function have to be per-instance? Looks like you could just define a single mtk_memif_init() and use it for all instances below?
| } | ||
|
|
||
| memcpy(UINT_TO_POINTER(chan->dest), UINT_TO_POINTER(chan->src), chan->size); | ||
| sys_cache_data_flush_range(UINT_TO_POINTER(chan->dest), chan->size); |
There was a problem hiding this comment.
this looks asymmetric... If you only need to invalidate the source if the direction is host-to-memory, then maybe you also only need to write-back if the direction is memory-to-host?
| CONFIG_ZEPHYR_NATIVE_DRIVERS=y | ||
| CONFIG_DMA=y | ||
| CONFIG_DAI=y | ||
|
|
There was a problem hiding this comment.
preferably no additional empty lines at the end of the file
There was a problem hiding this comment.
Pull request overview
This PR introduces a Zephyr “native drivers” path for MediaTek (MT8196) by adding Zephyr-based DMA/DAI drivers for MTK AFE + host memory transfers and wiring them into the MTK Zephyr platform init/build.
Changes:
- Add MTK Zephyr-native DMA drivers (AFE MEMIF DMA + “host DMA” memcpy/cache driver) and a Zephyr DAI wrapper for MTK AFE.
- Switch MTK Zephyr build to select native vs legacy DMA/DAI sources and update platform init to use
sof_dma_*in native mode. - Extend Zephyr-native DAI/device enumeration and allow MTK host DMA for IPC3 host page-table transfers.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| zephyr/lib/dma.c | Adds new DT-based DMA entries for MTK AFE MEMIF and host DMA |
| zephyr/Kconfig | Adds Kconfig symbol for MTK SOF host DMA driver |
| zephyr/include/sof/lib/dma.h | Fixes #endif comment for native/legacy include |
| zephyr/CMakeLists.txt | Selects MTK native vs legacy DMA/DAI source sets |
| src/platform/mtk/platform.c | Uses sof_dma_get() in native mode; adds SOF-level DMA channel-array allocation |
| src/platform/mtk/dai.c | Gates legacy DAI/DMA info setup on non-native builds |
| src/platform/Kconfig | Avoids selecting SCHEDULE_DMA_MULTI_CHANNEL in native mode |
| src/lib/dai.c | Adds MediaTek AFE devices to Zephyr DAI device list and sets DMA dev mapping |
| src/ipc/ipc3/host-page-table.c | Allows MTK host DMA driver for page-table transfer in native mode |
| src/drivers/mediatek/afe/zephyr_mtk_host_dma.c | New MTK “software host DMA” driver (memcpy + cache mgmt) |
| src/drivers/mediatek/afe/zephyr_mtk_dai.c | New Zephyr DAI driver for MTK AFE that bridges to SOF AFE functions |
| src/drivers/mediatek/afe/zephyr_mtk_afe_memif.c | New Zephyr DMA driver for MTK AFE MEMIF |
| src/audio/dai-zephyr.c | Adds MediaTek AFE case to Zephyr DAI config translation |
| app/boards/mt8196_mt8196_adsp.conf | Enables Zephyr native drivers + DMA/DAI for MT8196 board config |
Comments suppressed due to low confidence (2)
src/drivers/mediatek/afe/zephyr_mtk_host_dma.c:163
mtk_host_dma_get_status()always returns success without populatingstruct dma_status. SOF's host Zephyr component relies ondma_get_status()fields likefree,pending_length,read_position, andwrite_positionto decide how many bytes to copy. Returning 0 with uninitialized status data can cause incorrect copy sizes or undefined behavior. Please either properly fillstat(and track positions/busy state) or return a clear error (e.g.-ENOTSUP) until implemented.
static int mtk_host_dma_get_status(const struct device *dev,
uint32_t chan_id, struct dma_status *stat)
{
return 0;
}
src/drivers/mediatek/afe/zephyr_mtk_host_dma.c:111
mtk_host_dma_config()dereferencesconfig->head_blockbefore validating it is non-NULL (e.g.config->head_block->source_address). If a caller passesblock_count == 1withhead_block == NULL, this will crash. Please checkconfigandconfig->head_blockfor NULL before any dereference, and validateblock_size/addresses afterward.
if (config->block_count != 1) {
LOG_ERR("invalid number of blocks: %d", config->block_count);
return -EINVAL;
}
if (!config->head_block->source_address) {
LOG_ERR("got NULL source address");
return -EINVAL;
}
if (!config->head_block->dest_address) {
LOG_ERR("got NULL destination address");
return -EINVAL;
}
| #if DT_NODE_HAS_STATUS(DT_NODELABEL(host_dma), okay) | ||
| { | ||
| .plat_data = { | ||
| .dir = SOF_DMA_DIR_HMEM_TO_LMEM | SOF_DMA_DIR_LMEM_TO_HMEM, | ||
| .devs = SOF_DMA_DEV_HOST, | ||
| .channels = DT_PROP(DT_NODELABEL(host_dma), dma_channels), | ||
| .period_count = 4, | ||
| }, | ||
| .z_dev = DEVICE_DT_GET(DT_NODELABEL(host_dma)), | ||
| }, |
| for (i = 0; i < sof->dma_info->num_dmas; i++) { | ||
| struct sof_dma *d = &sof->dma_info->dma_array[i]; | ||
|
|
||
| if (!d->plat_data.channels || d->chan) | ||
| continue; | ||
|
|
||
| d->chan = rzalloc(SOF_MEM_FLAG_KERNEL, | ||
| d->plat_data.channels * sizeof(struct dma_chan_data)); | ||
| if (!d->chan) | ||
| continue; | ||
|
|
| static int mtk_host_dma_reload(const struct device *dev, uint32_t chan_id, | ||
| uint32_t src, uint32_t dst, size_t size) | ||
| { | ||
| return 0; | ||
| } |
| dai_id = config->dma_slot & 0xFF; /* AFE_HS_GET_DAI equivalent */ | ||
| irq_id = 0; /* IRQ not used in Zephyr mode */ | ||
|
|
||
| switch (config->channel_direction) { | ||
| case MEMORY_TO_PERIPHERAL: | ||
| if (direction != 1) { | ||
| LOG_ERR("channel %d is not a playback memif", chan_id); | ||
| return -EINVAL; | ||
| } | ||
| dma_addr = config->head_block->source_address; | ||
| break; | ||
| case PERIPHERAL_TO_MEMORY: | ||
| if (direction != 0) { | ||
| LOG_ERR("channel %d is not a capture memif", chan_id); | ||
| return -EINVAL; | ||
| } | ||
| dma_addr = config->head_block->dest_address; | ||
| break; |
| break; | ||
| case SOF_DAI_MEDIATEK_AFE: | ||
| cfg.type = DAI_MEDIATEK_AFE; | ||
| cfg_params = spec_config; |
| const struct dai_mtk_afe_cfg *dev_cfg = dev->config; | ||
| struct dai_mtk_afe_data *data = dev->data; | ||
| const struct sof_ipc_dai_config *sof_cfg = bespoke_cfg; | ||
| struct mtk_base_afe *afe; | ||
| int ret; |
No description provided.