Skip to content

Mt8196/v0.3#10785

Open
mtkcyril wants to merge 7 commits into
thesofproject:mainfrom
mtkcyril:mt8196/v0.3
Open

Mt8196/v0.3#10785
mtkcyril wants to merge 7 commits into
thesofproject:mainfrom
mtkcyril:mt8196/v0.3

Conversation

@mtkcyril
Copy link
Copy Markdown

No description provided.

Cyril Chao added 7 commits May 15, 2026 15:15
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>
@sofci
Copy link
Copy Markdown
Collaborator

sofci commented May 18, 2026

Can one of the admins verify this patch?

reply test this please to run this test once

@abonislawski
Copy link
Copy Markdown
Member

test this please

#else
#include "dma-legacy.h"
#endif /* !CONFIG_ZEPHYR_NATIVE_DRIVERS */
#endif /* CONFIG_ZEPHYR_NATIVE_DRIVERS */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't fix any builds, this just changes a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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; \
} \
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preferably no additional empty lines at the end of the file

@lgirdwood lgirdwood requested a review from Copilot May 19, 2026 12:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 populating struct dma_status. SOF's host Zephyr component relies on dma_get_status() fields like free, pending_length, read_position, and write_position to decide how many bytes to copy. Returning 0 with uninitialized status data can cause incorrect copy sizes or undefined behavior. Please either properly fill stat (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() dereferences config->head_block before validating it is non-NULL (e.g. config->head_block->source_address). If a caller passes block_count == 1 with head_block == NULL, this will crash. Please check config and config->head_block for NULL before any dereference, and validate block_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;
	}

Comment thread zephyr/lib/dma.c
Comment on lines +253 to +262
#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)),
},
Comment on lines +231 to +241
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;

Comment on lines +72 to +76
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;
}
Comment on lines +96 to +113
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;
Comment thread src/audio/dai-zephyr.c
break;
case SOF_DAI_MEDIATEK_AFE:
cfg.type = DAI_MEDIATEK_AFE;
cfg_params = spec_config;
Comment on lines +47 to +51
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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants