From 336602a2f912fd19eb717083306e54804bc92e79 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:24:04 -0500 Subject: [PATCH 01/27] mmc: mtk-sd: enable DMA on mediatek,mt8189-mmc Enable DMA on mediatek,mt8189-mmc compatible. The issue that was preventing DMA from working correctly was fixed by the get_effective_memsize() implementation in commit a7c682565b4b ("arm: mediatek: add support of MT8189 SoC family"). Reviewed-by: Julien Stephan Tested-by: Julien Stephan Link: https://patch.msgid.link/20260421-mmc-mtk-sd-fixes-v1-1-5b840c546af2@baylibre.com Signed-off-by: David Lechner --- drivers/mmc/mtk-sd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index 7a4bdee7496..d2472ae7efe 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -1987,6 +1987,7 @@ static const struct msdc_compatible mt8189_compat = { .busy_check = true, .stop_clk_fix = true, .enhance_rx = true, + .use_dma_mode = true, }; static const struct udevice_id msdc_ids[] = { From 93f67d893b32606cfb723b82be783a013c16fc0c Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:24:05 -0500 Subject: [PATCH 02/27] mmc: mtk-sd: enable async_fifo_crcsts on mt8189 Enable the async_fifo_crcsts option for mediatek,mt8189-mmc compatible. Without this option, writing will fail in HS200 mode. Fixes: b3d16267b509 ("mmc: mtk-sd: add mediatek,mt8189-mmc compatible") Reviewed-by: Julien Stephan Tested-by: Julien Stephan Link: https://patch.msgid.link/20260421-mmc-mtk-sd-fixes-v1-2-5b840c546af2@baylibre.com Signed-off-by: David Lechner --- drivers/mmc/mtk-sd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index d2472ae7efe..616cf3f360f 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -1983,6 +1983,7 @@ static const struct msdc_compatible mt8189_compat = { .clk_div_bits = 12, .pad_tune0 = true, .async_fifo = true, + .async_fifo_crcsts = true, .data_tune = true, .busy_check = true, .stop_clk_fix = true, From 8436dd6b0e7e529fda238edf762076fa436bdfda Mon Sep 17 00:00:00 2001 From: "ht.lin" Date: Tue, 21 Apr 2026 09:24:06 -0500 Subject: [PATCH 03/27] mmc: mtk-sd: fix msdc cmd ready check Correct the check condition in msdc_cmd_is_ready() for MSDC_PS_DAT0 polling. Without this change, it may not be able to detect if the SD controller is busy correctly for issuing the command. Fixes: d24b69395949 ("mmc: mtk-sd: add SD/MMC host controller driver for MT7623 SoC") Signed-off-by: ht.lin Reviewed-by: Julien Stephan Tested-by: Julien Stephan Link: https://patch.msgid.link/20260421-mmc-mtk-sd-fixes-v1-3-5b840c546af2@baylibre.com Signed-off-by: David Lechner --- drivers/mmc/mtk-sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index 616cf3f360f..51c9c0a3fad 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -539,7 +539,7 @@ static bool msdc_cmd_is_ready(struct msdc_host *host) return false; } - if (host->last_resp_type == MMC_RSP_R1b && host->last_data_write) { + if (host->last_resp_type == MMC_RSP_R1b || host->last_data_write) { ret = readl_poll_timeout(&host->base->msdc_ps, reg, reg & MSDC_PS_DAT0, 1000000); From ba97dd5c107a844115b8b6a7f63c5e0b773204fb Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:09:34 -0500 Subject: [PATCH 04/27] configs: mediatek: mt8365_evk: remove CONFIG_IDENT_STRING Remove CONFIG_IDENT_STRING from the mt8365_evk defconfig. This makes it consistent with other mediatek defconfigs and frees the option for use by downstream users. This only affects the version string printed by U-Boot, so it doesn't have any functional impact. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260421-mtk-configs-remove-ident-string-v1-1-66d5fc3d67be@baylibre.com Signed-off-by: David Lechner --- configs/mt8365_evk_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mt8365_evk_defconfig b/configs/mt8365_evk_defconfig index 9b403cd7aab..1a385492547 100644 --- a/configs/mt8365_evk_defconfig +++ b/configs/mt8365_evk_defconfig @@ -8,7 +8,6 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_DEFAULT_DEVICE_TREE="mediatek/mt8365-evk" CONFIG_TARGET_MT8365=y CONFIG_SYS_LOAD_ADDR=0x4c000000 -CONFIG_IDENT_STRING=" mt8365-evk" CONFIG_DEFAULT_FDT_FILE="mt8365-evk" # CONFIG_BOARD_INIT is not set CONFIG_CMD_CLK=y From 4c435a7ffb104ef4f13c6c29d784d6a6be247f1e Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:09:35 -0500 Subject: [PATCH 05/27] configs: mediatek: mt8370_genio_510_evk: remove CONFIG_IDENT_STRING Remove CONFIG_IDENT_STRING from the mt8370_genio_510_evk defconfig. This makes it consistent with other mediatek defconfigs and frees the option for use by downstream users. This only affects the version string printed by U-Boot, so it doesn't have any functional impact. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260421-mtk-configs-remove-ident-string-v1-2-66d5fc3d67be@baylibre.com Signed-off-by: David Lechner --- configs/mt8370_genio_510_evk_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mt8370_genio_510_evk_defconfig b/configs/mt8370_genio_510_evk_defconfig index e3530571cc4..2ddd8d2a36a 100644 --- a/configs/mt8370_genio_510_evk_defconfig +++ b/configs/mt8370_genio_510_evk_defconfig @@ -2,4 +2,3 @@ CONFIG_DEFAULT_DEVICE_TREE="mediatek/mt8370-genio-510-evk" CONFIG_MTK_MEM_MAP_DDR_SIZE=0x100000000 -CONFIG_IDENT_STRING="mt8370-genio-510-evk" From 9b471cb9b2e9c070d27b1ee6c7bd658f5289d31e Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:09:36 -0500 Subject: [PATCH 06/27] configs: mediatek: mt8390_genio_700_evk: remove CONFIG_IDENT_STRING Remove CONFIG_IDENT_STRING from the mt8390_genio_700_evk defconfig. This makes it consistent with other mediatek defconfigs and frees the option for use by downstream users. This only affects the version string printed by U-Boot, so it doesn't have any functional impact. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260421-mtk-configs-remove-ident-string-v1-3-66d5fc3d67be@baylibre.com Signed-off-by: David Lechner --- configs/mt8390_genio_700_evk_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mt8390_genio_700_evk_defconfig b/configs/mt8390_genio_700_evk_defconfig index 0b07e3be2c4..fe4f6ad9016 100644 --- a/configs/mt8390_genio_700_evk_defconfig +++ b/configs/mt8390_genio_700_evk_defconfig @@ -1,4 +1,3 @@ #include CONFIG_DEFAULT_DEVICE_TREE="mediatek/mt8390-genio-700-evk" -CONFIG_IDENT_STRING="mt8390-genio-700-evk" From eb1551fddc6b50e3053c850814d16d95cf542559 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:09:37 -0500 Subject: [PATCH 07/27] configs: mediatek: mt8395_genio_1200_evk: remove CONFIG_IDENT_STRING Remove CONFIG_IDENT_STRING from the mt8395_genio_1200_evk defconfig. This makes it consistent with other mediatek defconfigs and frees the option for use by downstream users. This only affects the version string printed by U-Boot, so it doesn't have any functional impact. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260421-mtk-configs-remove-ident-string-v1-4-66d5fc3d67be@baylibre.com Signed-off-by: David Lechner --- configs/mt8395_genio_1200_evk_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mt8395_genio_1200_evk_defconfig b/configs/mt8395_genio_1200_evk_defconfig index 47c10757c52..e2e5480f55c 100644 --- a/configs/mt8395_genio_1200_evk_defconfig +++ b/configs/mt8395_genio_1200_evk_defconfig @@ -1,4 +1,3 @@ #include CONFIG_DEFAULT_DEVICE_TREE="mediatek/mt8395-genio-1200-evk" -CONFIG_IDENT_STRING="mt8395-genio-1200-evk" From 95c06da44f83f5db523433d04b5518b4fe62f906 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 21 Apr 2026 09:09:38 -0500 Subject: [PATCH 08/27] configs: mediatek: mt8395_genio_1200_evk_ufs: remove CONFIG_IDENT_STRING Remove CONFIG_IDENT_STRING from the mt8395_genio_1200_evk_ufs defconfig. This makes it consistent with other mediatek defconfigs and frees the option for use by downstream users. This only affects the version string printed by U-Boot, so it doesn't have any functional impact. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260421-mtk-configs-remove-ident-string-v1-5-66d5fc3d67be@baylibre.com Signed-off-by: David Lechner --- configs/mt8395_genio_1200_evk_ufs_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/mt8395_genio_1200_evk_ufs_defconfig b/configs/mt8395_genio_1200_evk_ufs_defconfig index e927365a03a..525638f5800 100644 --- a/configs/mt8395_genio_1200_evk_ufs_defconfig +++ b/configs/mt8395_genio_1200_evk_ufs_defconfig @@ -1,7 +1,6 @@ #include CONFIG_DEFAULT_DEVICE_TREE="mediatek/mt8395-genio-1200-evk-ufs" -CONFIG_IDENT_STRING=" mt8395-genio-1200-evk-ufs" CONFIG_CMD_UFS=y CONFIG_PHY=y CONFIG_SCSI=y From 4f9842e4799c6c3c98cc27c723ba223b42d739d8 Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:27 -0500 Subject: [PATCH 09/27] spi: mtk_snor: clean up comments Avoid use of C++-style comments and fix multi-line comment style. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-1-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index f202b2f49f5..eb36c9dd5e8 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -1,10 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 -// -// Mediatek SPI-NOR controller driver -// -// Copyright (C) 2020 SkyLake Huang -// -// Some parts are based on drivers/spi/spi-mtk-nor.c of linux version +/* + * Mediatek SPI-NOR controller driver + * + * Copyright (C) 2020 SkyLake Huang + * + * Some parts are based on drivers/spi/spi-mtk-nor.c of linux version + */ #include #include @@ -89,13 +90,13 @@ #define MTK_NOR_REG_DMA_END_DADR 0x724 #define MTK_NOR_PRG_MAX_SIZE 6 -// Reading DMA src/dst addresses have to be 16-byte aligned +/* Reading DMA src/dst addresses have to be 16-byte aligned */ #define MTK_NOR_DMA_ALIGN 16 #define MTK_NOR_DMA_ALIGN_MASK (MTK_NOR_DMA_ALIGN - 1) -// and we allocate a bounce buffer if destination address isn't aligned. +/* and we allocate a bounce buffer if destination address isn't aligned. */ #define MTK_NOR_BOUNCE_BUF_SIZE PAGE_SIZE -// Buffered page program can do one 128-byte transfer +/* Buffered page program can do one 128-byte transfer */ #define MTK_NOR_PP_SIZE 128 #define CLK_TO_US(priv, clkcnt) DIV_ROUND_UP(clkcnt, (priv)->spi_freq / 1000000) @@ -168,8 +169,8 @@ static int mtk_snor_adjust_op_size(struct spi_slave *slave, return 0; if (op->addr.nbytes == 3 || op->addr.nbytes == 4) { - if (op->data.dir == SPI_MEM_DATA_IN) { //&& - // limit size to prevent timeout calculation overflow + if (op->data.dir == SPI_MEM_DATA_IN) { + /* limit size to prevent timeout calculation overflow */ if (op->data.nbytes > 0x400000) op->data.nbytes = 0x400000; if (op->addr.val & MTK_NOR_DMA_ALIGN_MASK || @@ -496,7 +497,8 @@ static int mtk_snor_probe(struct udevice *bus) priv->spi_freq = clk_get_rate(&priv->spi_clk); printf("spi frequency: %d Hz\n", priv->spi_freq); - /* With this setting, we issue one command at a time to + /* + * With this setting, we issue one command at a time to * accommodate to SPI-mem framework. */ writel(MTK_NOR_ENABLE_SF_CMD, priv->base + MTK_NOR_REG_WP); @@ -504,7 +506,8 @@ static int mtk_snor_probe(struct udevice *bus) mtk_snor_rmw(priv, MTK_NOR_REG_CFG3, MTK_NOR_DISABLE_WREN | MTK_NOR_DISABLE_SR_POLL, 0); - /* Unlock all blocks using write status command. + /* + * Unlock all blocks using write status command. * SPI-MEM hasn't implemented unlock procedure on MXIC devices. * We may remove this later. */ @@ -521,7 +524,8 @@ static int mtk_snor_probe(struct udevice *bus) static int mtk_snor_set_speed(struct udevice *bus, uint speed) { - /* MTK's SNOR controller does not have a bus clock divider. + /* + * MTK's SNOR controller does not have a bus clock divider. * We setup maximum bus clock in dts. */ @@ -530,8 +534,7 @@ static int mtk_snor_set_speed(struct udevice *bus, uint speed) static int mtk_snor_set_mode(struct udevice *bus, uint mode) { - /* We set up mode later for each transmission. - */ + /* We set up mode later for each transmission. */ return 0; } From 4eac47d4eb661c019b84723628bab2f0c826403f Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:28 -0500 Subject: [PATCH 10/27] spi: mtk_snor: avoid alloc in mtk_snor_cmd_program() Rework mtk_snor_cmd_program() to avoid allocating a temporary buffer for tx data. This improves performance a bit by avoiding the need to allocate memory and copy data an extra time. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-2-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 77 ++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index eb36c9dd5e8..0ff4a8b23d5 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -383,50 +383,63 @@ static int mtk_snor_pp_unbuffered(struct mtk_snor_priv *priv, static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, const struct spi_mem_op *op) { - u32 tx_len = 0; - u32 trx_len = 0; + int rx_len = 0; int reg_offset = MTK_NOR_REG_PRGDATA_MAX; + int tx_len, prg_len; + int i; void __iomem *reg; - u8 *txbuf; - int tx_cnt = 0; - u8 *rxbuf = op->data.buf.in; - int i = 0; + u8 val; - tx_len = 1 + op->addr.nbytes + op->dummy.nbytes; - trx_len = tx_len + op->data.nbytes; + tx_len = op->cmd.nbytes + op->addr.nbytes; + + /* count dummy bytes only if we need to write data after it */ if (op->data.dir == SPI_MEM_DATA_OUT) - tx_len += op->data.nbytes; + tx_len += op->dummy.nbytes + op->data.nbytes; + else if (op->data.dir == SPI_MEM_DATA_IN) + rx_len = op->data.nbytes; - txbuf = kmalloc_array(tx_len, sizeof(u8), GFP_KERNEL); - memset(txbuf, 0x0, tx_len * sizeof(u8)); + prg_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes + + op->data.nbytes; - /* Join all bytes to be transferred */ - txbuf[tx_cnt] = op->cmd.opcode; - tx_cnt++; - for (i = op->addr.nbytes; i > 0; i--, tx_cnt++) - txbuf[tx_cnt] = ((u8 *)&op->addr.val)[i - 1]; - for (i = op->dummy.nbytes; i > 0; i--, tx_cnt++) - txbuf[tx_cnt] = 0x0; - if (op->data.dir == SPI_MEM_DATA_OUT) - for (i = op->data.nbytes; i > 0; i--, tx_cnt++) - txbuf[tx_cnt] = ((u8 *)op->data.buf.out)[i - 1]; + /* fill tx data */ - for (i = MTK_NOR_REG_PRGDATA_MAX; i >= 0; i--) - writeb(0, priv->base + MTK_NOR_REG_PRGDATA(i)); + for (i = op->cmd.nbytes; i > 0; i--, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + val = (op->cmd.opcode >> ((i - 1) * BITS_PER_BYTE)) & 0xff; + writeb(val, reg); + } - for (i = 0; i < tx_len; i++, reg_offset--) - writeb(txbuf[i], priv->base + MTK_NOR_REG_PRGDATA(reg_offset)); + for (i = op->addr.nbytes; i > 0; i--, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + val = (op->addr.val >> ((i - 1) * BITS_PER_BYTE)) & 0xff; + writeb(val, reg); + } - kfree(txbuf); + for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + writeb(0, reg); + } - writel(trx_len * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); - - mtk_snor_cmd_exec(priv, MTK_NOR_CMD_PROGRAM, trx_len * BITS_PER_BYTE); - - reg_offset = op->data.nbytes - 1; for (i = 0; i < op->data.nbytes; i++, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + writeb(((const u8 *)(op->data.buf.out))[i], reg); + } + + for (; reg_offset >= 0; reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + writeb(0, reg); + } + + /* trigger op */ + writel(prg_len * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); + + mtk_snor_cmd_exec(priv, MTK_NOR_CMD_PROGRAM, prg_len * BITS_PER_BYTE); + + /* fetch read data */ + reg_offset = 0; + for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) { reg = priv->base + MTK_NOR_REG_SHIFT(reg_offset); - rxbuf[i] = readb(reg); + ((u8 *)(op->data.buf.in))[i] = readb(reg); } return 0; From 3b0a037052a24f8449c9fafd02034307e30a3c97 Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:29 -0500 Subject: [PATCH 11/27] spi: mtk_snor: conditionally copy tx/rx data Only write out data for OUT command and read in data for IN commands. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-3-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index 0ff4a8b23d5..674e723db01 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -415,14 +415,16 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, writeb(val, reg); } - for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) { - reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); - writeb(0, reg); - } + if (op->data.dir == SPI_MEM_DATA_OUT) { + for (i = 0; i < op->dummy.nbytes; i++, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + writeb(0, reg); + } - for (i = 0; i < op->data.nbytes; i++, reg_offset--) { - reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); - writeb(((const u8 *)(op->data.buf.out))[i], reg); + for (i = 0; i < op->data.nbytes; i++, reg_offset--) { + reg = priv->base + MTK_NOR_REG_PRGDATA(reg_offset); + writeb(((const u8 *)(op->data.buf.out))[i], reg); + } } for (; reg_offset >= 0; reg_offset--) { @@ -437,9 +439,11 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, /* fetch read data */ reg_offset = 0; - for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) { - reg = priv->base + MTK_NOR_REG_SHIFT(reg_offset); - ((u8 *)(op->data.buf.in))[i] = readb(reg); + if (op->data.dir == SPI_MEM_DATA_IN) { + for (i = op->data.nbytes - 1; i >= 0; i--, reg_offset++) { + reg = priv->base + MTK_NOR_REG_SHIFT(reg_offset); + ((u8 *)(op->data.buf.in))[i] = readb(reg); + } } return 0; From 55944a68d550d00df494a5c75685f00cbf0998f0 Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:30 -0500 Subject: [PATCH 12/27] spi: mtk_snor: check return value of mtk_snor_cmd_exec() Always check the return value of mtk_snor_cmd_exec() and propagate the error. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-4-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index 674e723db01..babdb4600d5 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -362,8 +362,12 @@ static int mtk_snor_pp_buffered(struct mtk_snor_priv *priv, buf[i]; writel(val, priv->base + MTK_NOR_REG_PP_DATA); } - mtk_snor_cmd_exec(priv, MTK_NOR_CMD_WRITE, - (op->data.nbytes + 5) * BITS_PER_BYTE); + + ret = mtk_snor_cmd_exec(priv, MTK_NOR_CMD_WRITE, + (op->data.nbytes + 5) * BITS_PER_BYTE); + if (ret) + return ret; + return mtk_snor_write_buffer_disable(priv); } @@ -386,7 +390,7 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, int rx_len = 0; int reg_offset = MTK_NOR_REG_PRGDATA_MAX; int tx_len, prg_len; - int i; + int i, ret; void __iomem *reg; u8 val; @@ -435,7 +439,9 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, /* trigger op */ writel(prg_len * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); - mtk_snor_cmd_exec(priv, MTK_NOR_CMD_PROGRAM, prg_len * BITS_PER_BYTE); + ret = mtk_snor_cmd_exec(priv, MTK_NOR_CMD_PROGRAM, prg_len * BITS_PER_BYTE); + if (ret) + return ret; /* fetch read data */ reg_offset = 0; From 78950bb20707417657d9122d50325bda9c9aa8b9 Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:31 -0500 Subject: [PATCH 13/27] spi: mtk-snor: add bounds checking in mtk_snor_cmd_program() Add bounds checking of the various lengths in mtk_snor_cmd_program() to prevent reading or writing registers out of bounds. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-5-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index babdb4600d5..77f94827568 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -90,6 +90,7 @@ #define MTK_NOR_REG_DMA_END_DADR 0x724 #define MTK_NOR_PRG_MAX_SIZE 6 +#define MTK_NOR_PRG_CNT_MAX 56 /* Reading DMA src/dst addresses have to be 16-byte aligned */ #define MTK_NOR_DMA_ALIGN 16 #define MTK_NOR_DMA_ALIGN_MASK (MTK_NOR_DMA_ALIGN - 1) @@ -405,6 +406,16 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, prg_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes + op->data.nbytes; + /* + * An invalid op may reach here if the caller calls exec_op without + * adjust_op_size. return -EINVAL instead of -ENOTSUPP so that + * spi-mem won't try this op again with generic spi transfers. + */ + if ((tx_len > MTK_NOR_REG_PRGDATA_MAX + 1) || + (rx_len > MTK_NOR_REG_SHIFT_MAX + 1) || + (prg_len > MTK_NOR_PRG_CNT_MAX / 8)) + return -EINVAL; + /* fill tx data */ for (i = op->cmd.nbytes; i > 0; i--, reg_offset--) { From 1cfcd7100d54b706b7d4ee17dd016b83e5eb88ff Mon Sep 17 00:00:00 2001 From: "Noah.Shen" Date: Mon, 6 Apr 2026 15:13:32 -0500 Subject: [PATCH 14/27] spi: mtk_snor: support newer SOCs Add support for some newer SOCs. New compatible strings are added to the lookup table. Some SOCs also need a extra bit clocked out as a hardware quirk, so a new capability structure and code is added to support that. Signed-off-by: Noah.Shen Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-6-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index 77f94827568..649bca5716c 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -104,9 +104,19 @@ #define MTK_NOR_UNLOCK_ALL 0x0 +struct mtk_snor_caps { + /* + * Some new SoCs modify the timing of fetching registers' values and IDs + * of NOR flash, they need a extra_bit which can add more clock cycles + * for fetching data. + */ + u8 extra_bit; +}; + struct mtk_snor_priv { struct device *dev; void __iomem *base; + const struct mtk_snor_caps *caps; u8 *buffer; struct clk spi_clk; struct clk ctlr_clk; @@ -448,7 +458,11 @@ static int mtk_snor_cmd_program(struct mtk_snor_priv *priv, } /* trigger op */ - writel(prg_len * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); + if (rx_len) + writel(prg_len * BITS_PER_BYTE + priv->caps->extra_bit, + priv->base + MTK_NOR_REG_PRG_CNT); + else + writel(prg_len * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); ret = mtk_snor_cmd_exec(priv, MTK_NOR_CMD_PROGRAM, prg_len * BITS_PER_BYTE); if (ret) @@ -508,6 +522,8 @@ static int mtk_snor_probe(struct udevice *bus) if (!priv->base) return -EINVAL; + priv->caps = (const void *)dev_get_driver_data(bus); + ret = clk_get_by_name(bus, "spi", &priv->spi_clk); if (ret < 0) return ret; @@ -584,8 +600,19 @@ static const struct dm_spi_ops mtk_snor_ops = { .set_mode = mtk_snor_set_mode, }; +static const struct mtk_snor_caps mtk_snor_caps_default = { + .extra_bit = 0, +}; + +static const struct mtk_snor_caps mtk_snor_caps_extra_bit = { + .extra_bit = 1, +}; + static const struct udevice_id mtk_snor_ids[] = { - { .compatible = "mediatek,mtk-snor" }, + { .compatible = "mediatek,mtk-snor", .data = (ulong)&mtk_snor_caps_default }, + { .compatible = "mediatek,mt8188-nor", .data = (ulong)&mtk_snor_caps_extra_bit }, + { .compatible = "mediatek,mt8189-nor", .data = (ulong)&mtk_snor_caps_extra_bit }, + { .compatible = "mediatek,mt8195-nor", .data = (ulong)&mtk_snor_caps_default }, {} }; From 28bd63967784d1dbeff75289560e71fd1deac902 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Mon, 6 Apr 2026 15:13:33 -0500 Subject: [PATCH 15/27] spi: mtk_snor: fix zeroed data in DMA read bounce path Implement proper bounce buffer handling for the read path to fix zeroed data when using DMA. In the bounce path, map the bounce buffer with dma_map_single(), perform DMA using bounce_dma, then copy data from the bounce buffer to the user buffer, and finally unmap with dma_unmap_single(). Signed-off-by: Macpaul Lin Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-7-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index 649bca5716c..21ac115e3c3 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -274,6 +274,7 @@ static int mtk_snor_read_bounce(struct mtk_snor_priv *priv, { unsigned int rdlen; int ret; + dma_addr_t bounce_dma; if (op->data.nbytes & MTK_NOR_DMA_ALIGN_MASK) rdlen = (op->data.nbytes + MTK_NOR_DMA_ALIGN) & @@ -281,11 +282,21 @@ static int mtk_snor_read_bounce(struct mtk_snor_priv *priv, else rdlen = op->data.nbytes; - ret = mtk_snor_dma_exec(priv, op->addr.val, rdlen, - (dma_addr_t)priv->buffer); + /* Map bounce buffer for DMA */ + bounce_dma = dma_map_single(priv->buffer, rdlen, DMA_FROM_DEVICE); + if (dma_mapping_error(priv->dev, bounce_dma)) { + dev_err(priv->dev, "bounce buffer dma map failed\n"); + return -EINVAL; + } - if (!ret) + ret = mtk_snor_dma_exec(priv, op->addr.val, rdlen, bounce_dma); + /* Ensure DMA writes are visible to CPU and copy the requested bytes */ + if (!ret) { + /* Synchronize cached data to CPU visible memory if needed */ memcpy(op->data.buf.in, priv->buffer, op->data.nbytes); + } + /* Unmap bounce buffer regardless of success/failure */ + dma_unmap_single(bounce_dma, rdlen, DMA_FROM_DEVICE); return ret; } From 6c881e9980594a468e9f875187e5e4d30a22bcbd Mon Sep 17 00:00:00 2001 From: Meiker Gao Date: Mon, 6 Apr 2026 15:13:34 -0500 Subject: [PATCH 16/27] spi: mtk_snor: Remove status register write procedure in probe() Remove status register write procedure in probe(). This is handled in spi-nor-core by the SPI_NOR_HAS_LOCK flag. Signed-off-by: Meiker Gao Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260406-mtk-spi-nor-improvements-v1-8-66f675cbbd3e@baylibre.com Signed-off-by: David Lechner --- drivers/spi/mtk_snor.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/spi/mtk_snor.c b/drivers/spi/mtk_snor.c index 21ac115e3c3..40fc1826db6 100644 --- a/drivers/spi/mtk_snor.c +++ b/drivers/spi/mtk_snor.c @@ -527,7 +527,6 @@ static int mtk_snor_probe(struct udevice *bus) struct mtk_snor_priv *priv = dev_get_priv(bus); u8 *buffer; int ret; - u32 reg; priv->base = devfdt_get_addr_ptr(bus); if (!priv->base) @@ -567,19 +566,6 @@ static int mtk_snor_probe(struct udevice *bus) mtk_snor_rmw(priv, MTK_NOR_REG_CFG3, MTK_NOR_DISABLE_WREN | MTK_NOR_DISABLE_SR_POLL, 0); - /* - * Unlock all blocks using write status command. - * SPI-MEM hasn't implemented unlock procedure on MXIC devices. - * We may remove this later. - */ - writel(2 * BITS_PER_BYTE, priv->base + MTK_NOR_REG_PRG_CNT); - writel(MTK_NOR_UNLOCK_ALL, priv->base + MTK_NOR_REG_PRGDATA(5)); - writel(MTK_NOR_IRQ_WRSR, priv->base + MTK_NOR_REG_IRQ_EN); - writel(MTK_NOR_CMD_WRSR, priv->base + MTK_NOR_REG_CMD); - ret = readl_poll_timeout(priv->base + MTK_NOR_REG_IRQ_STAT, reg, - !(reg & MTK_NOR_IRQ_WRSR), - ((3 * BITS_PER_BYTE) + 1) * 200); - return 0; } From f1b077c512b566a3a7bf1cf89ecb1ff49791ebd1 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 6 Apr 2026 15:37:09 -0500 Subject: [PATCH 17/27] arm: dts: mediatek: add Genio 520/720 SNOR support Add devicetree nodes needed to enable SNOR support on Genio 520 and 720 EVKs. This is copied from the most recent upstream submission [1] of the devicetree for these boards, so there should be minimal differences when we eventually switch to OF_UPSTREAM. Link: https://lore.kernel.org/linux-mediatek/20251111070031.305281-10-jh.hsu@mediatek.com/ [1] Link: https://patch.msgid.link/20260406-mtk-genio-720-snor-v1-1-cbfd5fc4e59a@baylibre.com Signed-off-by: David Lechner --- arch/arm/dts/mt8189.dtsi | 17 +++++++++++++++ arch/arm/dts/mt8371-genio-common.dtsi | 31 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/arch/arm/dts/mt8189.dtsi b/arch/arm/dts/mt8189.dtsi index e550745ac5d..891d3249ecd 100644 --- a/arch/arm/dts/mt8189.dtsi +++ b/arch/arm/dts/mt8189.dtsi @@ -181,6 +181,23 @@ status = "disabled"; }; + nor_flash: spi@11018000 { + compatible = "mediatek,mt8189-nor","mediatek,mt8186-nor"; + reg = <0 0x11018000 0 0x1000>; + clocks = <&topckgen_clk CLK_TOP_SFLASH_SEL>, + <&pericfg_ao_clk CLK_PERAO_SFLASH>, + <&pericfg_ao_clk CLK_PERAO_SFLASH_F>, + <&pericfg_ao_clk CLK_PERAO_SFLASH_H>, + <&pericfg_ao_clk CLK_PERAO_SFLASH_P>; + clock-names = "spi", "sf", "axi_f", "axi_h", "axi_p"; + assigned-clocks = <&topckgen_clk CLK_TOP_SFLASH_SEL>; + assigned-clock-parents = <&topckgen_clk CLK_TOP_UNIVPLL_D6_D8>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + xhci0: usb@11200000 { compatible = "mediatek,mt8189-xhci", "mediatek,mtk-xhci"; reg = <0 0x11200000 0 0x1000>, diff --git a/arch/arm/dts/mt8371-genio-common.dtsi b/arch/arm/dts/mt8371-genio-common.dtsi index 046e9d57752..1d4728e3732 100644 --- a/arch/arm/dts/mt8371-genio-common.dtsi +++ b/arch/arm/dts/mt8371-genio-common.dtsi @@ -162,6 +162,21 @@ regulator-always-on; }; +&nor_flash { + pinctrl-names = "default"; + pinctrl-0 = <&nor_pins>; + + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <2>; + }; +}; + &pio { mmc0_default_pins: mmc0-default-pins { pins-clk { @@ -274,6 +289,22 @@ }; }; + nor_pins: nor-pins { + pins-ck-io { + pinmux = , + , + ; + drive-strength = <8>; + bias-pull-down; + }; + + pins-cs { + pinmux = ; + drive-strength = <8>; + bias-pull-up; + }; + }; + uart0_pins: uart0-pins { pins { pinmux = , From 8c15436fb2191294162deaf2c94fbe030fee9455 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 6 Apr 2026 15:37:10 -0500 Subject: [PATCH 18/27] configs: mediatek: add required config for SNOR on Genio 520/720 EVK Enable options to be able to access the SNOR flash on Genio 520/720 EVK boards. Reviewed-by: Macpaul Lin Link: https://patch.msgid.link/20260406-mtk-genio-720-snor-v1-2-cbfd5fc4e59a@baylibre.com Signed-off-by: David Lechner --- configs/mt8189.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/mt8189.config b/configs/mt8189.config index ecf8c5f4b4b..763f20b1063 100644 --- a/configs/mt8189.config +++ b/configs/mt8189.config @@ -23,6 +23,9 @@ CONFIG_CLK=y # CONFIG_MMC_QUIRKS is not set CONFIG_MMC_HS200_SUPPORT=y CONFIG_MMC_MTK=y +CONFIG_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y CONFIG_PHY=y CONFIG_PHY_MTK_TPHY=y CONFIG_PHY_MTK_XSPHY=y @@ -37,6 +40,9 @@ CONFIG_DM_REGULATOR_MT6359=y CONFIG_BAUDRATE=921600 CONFIG_DM_SERIAL=y CONFIG_MTK_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MTK_SNOR=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MTK=y From 3c14cd8388dad4c93c24fac53a7b6d21bc81765c Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Tue, 28 Apr 2026 11:36:25 +0800 Subject: [PATCH 19/27] configs: mt7622: remove empty header file Remove the empty include/configs/mt7622.h header file as it is not needed. The Kconfig entry that referenced it is also removed. Signed-off-by: Weijie Gao Link: https://patch.msgid.link/20260428033625.109032-1-weijie.gao@mediatek.com Signed-off-by: David Lechner --- arch/arm/mach-mediatek/Kconfig | 1 - board/mediatek/mt7622/MAINTAINERS | 1 - include/configs/mt7622.h | 12 ------------ 3 files changed, 14 deletions(-) delete mode 100644 include/configs/mt7622.h diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index b5b06f4e5b2..80f7185e929 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -195,7 +195,6 @@ config SYS_BOARD be used. config SYS_CONFIG_NAME - default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 default "mt7981" if TARGET_MT7981 diff --git a/board/mediatek/mt7622/MAINTAINERS b/board/mediatek/mt7622/MAINTAINERS index a3e0e75ca07..067f33bb39f 100644 --- a/board/mediatek/mt7622/MAINTAINERS +++ b/board/mediatek/mt7622/MAINTAINERS @@ -2,5 +2,4 @@ MT7622 M: Sam Shih S: Maintained F: board/mediatek/mt7622 -F: include/configs/mt7622.h F: configs/mt7622_rfb_defconfig diff --git a/include/configs/mt7622.h b/include/configs/mt7622.h deleted file mode 100644 index 4a056954bf8..00000000000 --- a/include/configs/mt7622.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Configuration for MediaTek MT7629 SoC - * - * Copyright (C) 2019 MediaTek Inc. - * Author: Sam Shih - */ - -#ifndef __MT7622_H -#define __MT7622_H - -#endif From 98116c0ef88246d41bf1ec218cfbc885cbdf7e53 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:33 -0500 Subject: [PATCH 20/27] power: pmic: mtk-pwrap: fix file description Fix the comment at the start of the file to accurately describe what this file does. The old description was likely copied from the related regulator driver. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-1-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index 3e3a691d9e8..f4dfb48e93b 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * MT6357 regulator driver + * MediaTek PMIC Wrapper driver * * Copyright (c) 2026 BayLibre, SAS. * Author: Julien Masson From 3996c209562bd17ee11672c763b76421ffe917f2 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:34 -0500 Subject: [PATCH 21/27] power: pmic: mtk-pwrap: add PWRAP_CAP_WDT_SRC flag Add a PWRAP_CAP_WDT_SRC flag to indicate if a PMIC wrapper has a WDT_SRC or not. Then use this to conditionally enable the watchdog timer. Prior to this change, since the register was not defined, it defaulted to 0, so the wrong register (DONE2) was being written to. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-2-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index f4dfb48e93b..3ed21dcf2ef 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -60,8 +60,9 @@ static const struct pmic_child_info mt6359_pmic_children_info[] = { /* Group of bits used for shown pwrap capability */ #define PWRAP_CAP_INT1_EN BIT(3) -#define PWRAP_CAP_WDT_SRC1 BIT(4) -#define PWRAP_CAP_ARB BIT(5) +#define PWRAP_CAP_WDT_SRC BIT(4) +#define PWRAP_CAP_WDT_SRC1 BIT(5) +#define PWRAP_CAP_ARB BIT(6) /* defines for slave device wrapper registers */ enum dew_regs { @@ -755,7 +756,8 @@ static int mtk_pwrap_probe(struct udevice *dev) * Since STAUPD was not used on mt8173 platform, * so STAUPD of WDT_SRC which should be turned off */ - pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN); + if (HAS_CAP(wrp->master->caps, PWRAP_CAP_WDT_SRC)) + pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN); if (HAS_CAP(wrp->master->caps, PWRAP_CAP_WDT_SRC1)) pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN_1); From 8c5f5ef2c913209bc9f3f44e4bba30c911570ea6 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:35 -0500 Subject: [PATCH 22/27] power: pmic: mtk-pwrap: add init capability flag Add a PWRAP_CAP_INIT capability flag to specify if it is safe to call pwrap_init() or not. Not all targets define the registers accessed by pwrap_init(). In that case, it is expected that an earlier bootloader has already initialized the PMIC. If not, we now return an error instead of trying to access undefined registers. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-3-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index 3ed21dcf2ef..38ae44f0abf 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -63,6 +63,8 @@ static const struct pmic_child_info mt6359_pmic_children_info[] = { #define PWRAP_CAP_WDT_SRC BIT(4) #define PWRAP_CAP_WDT_SRC1 BIT(5) #define PWRAP_CAP_ARB BIT(6) +/* To implement this capability, the registers used in pwrap_init() must be defined. */ +#define PWRAP_CAP_INIT BIT(7) /* defines for slave device wrapper registers */ enum dew_regs { @@ -735,6 +737,11 @@ static int mtk_pwrap_probe(struct udevice *dev) * Skip initialization here in this case. */ if (!pwrap_readl(wrp, PWRAP_INIT_DONE2)) { + if (!HAS_CAP(wrp->master->caps, PWRAP_CAP_INIT)) { + dev_err(dev, "initialization is required but not supported\n"); + return -EOPNOTSUPP; + } + ret = pwrap_init(wrp); if (ret) { dev_err(dev, "init failed with %d\n", ret); @@ -877,7 +884,7 @@ static const struct pmic_wrapper_type pwrap_mt8365 = { .int1_en_all = 0x0, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, - .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_WDT_SRC1, + .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_WDT_SRC1 | PWRAP_CAP_INIT, }; static const struct udevice_id mtk_pwrap_ids[] = { From b60d1c5262bf7d1a7e6ffbcf7813df5dd3228f98 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:36 -0500 Subject: [PATCH 23/27] power: pmic: mtk-pwrap: drop PWRAP_SLV_CAP_DUALIO on mt6359 Drop the PWRAP_SLV_CAP_DUALIO flag from the mt6359 PMIC definition. The mt6359p variant of the PMIC does support dual I/O. Prior to this change, the driver would attempt to write to the PWRAP_DEW_DIO_EN register, which was not defined, so would write register 0 (DONE2). Reviewed-by: Julien Stephan Reviewed-by: Macpaul Lin Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-4-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index 38ae44f0abf..64c483b2f3b 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -647,7 +647,7 @@ static const struct pwrap_slv_type pmic_mt6357 = { static const struct pwrap_slv_type pmic_mt6359 = { .dew_regs = mt6359_regs, - .caps = PWRAP_SLV_CAP_DUALIO, + .caps = 0, }; static const struct udevice_id mtk_pmic_ids[] = { From 27fdacf4208e30f3ae8f8ee97f268d4a164b7dea Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:37 -0500 Subject: [PATCH 24/27] power: pmic: mtk-pwrap: remove interrupt related code Remove the interrupt related code in mtk-pwrap driver. This was just enabling interrupts without any handler. Even if we did have a handler, the only thing we could do is log a message. Since U-Boot isn't long running, this likely wouldn't be very useful. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-5-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index 64c483b2f3b..d994e0a67c9 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -59,7 +59,6 @@ static const struct pmic_child_info mt6359_pmic_children_info[] = { #define HAS_CAP(_c, _x_val) (((_c) & (_x_val)) == (_x_val)) /* Group of bits used for shown pwrap capability */ -#define PWRAP_CAP_INT1_EN BIT(3) #define PWRAP_CAP_WDT_SRC BIT(4) #define PWRAP_CAP_WDT_SRC1 BIT(5) #define PWRAP_CAP_ARB BIT(6) @@ -367,8 +366,6 @@ struct pmic_wrapper_type { int *regs; enum pwrap_type type; u32 arb_en_all; - u32 int_en_all; - u32 int1_en_all; u32 spi_w; u32 wdt_src; /* Flags indicating the capability for the target pwrap */ @@ -774,15 +771,6 @@ static int mtk_pwrap_probe(struct udevice *dev) else pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN); - pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN); - - /* - * We add INT1 interrupt to handle starvation and request exception - * If we support it, we should enable it here. - */ - if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN)) - pwrap_writel(wrp, wrp->master->int1_en_all, PWRAP_INT1_EN); - return 0; } @@ -859,18 +847,15 @@ static struct pmic_wrapper_type pwrap_mt8188 = { .regs = mt8188_regs, .type = PWRAP_MT8188, .arb_en_all = 0x777f, - .int_en_all = 0x180000, - .int1_en_all = 0x0, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, - .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_ARB, + .caps = PWRAP_CAP_ARB, }; static struct pmic_wrapper_type pwrap_mt8189 = { .regs = mt8189_regs, .type = PWRAP_MT8189, .arb_en_all = 0x777f, - .int_en_all = 0x180000, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, .caps = PWRAP_CAP_ARB, @@ -880,11 +865,9 @@ static const struct pmic_wrapper_type pwrap_mt8365 = { .regs = mt8365_regs, .type = PWRAP_MT8365, .arb_en_all = 0x3ffff, - .int_en_all = 0x7f1fffff, - .int1_en_all = 0x0, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, - .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_WDT_SRC1 | PWRAP_CAP_INIT, + .caps = PWRAP_CAP_WDT_SRC1 | PWRAP_CAP_INIT, }; static const struct udevice_id mtk_pwrap_ids[] = { From df660cc7b26aa4287bb2ae6cd56e58ac59a805f2 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Thu, 9 Apr 2026 15:30:38 -0500 Subject: [PATCH 25/27] power: pmic: mtk-pwrap: use pmic compatible to select child info Change the logic for selecting pmic_children_info to use the compatible string from the devicetree instead of expecting the pwrap (part of the MCU) to correspond to the separate PMIC chip. In addition to being more correct, it also saves a few lines of code for each MCU type that is added by dropping the enum and type field. Reviewed-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-6-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index d994e0a67c9..d41a43c8c95 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -340,12 +340,6 @@ static int mt8365_regs[] = { [PWRAP_WDT_SRC_EN_1] = 0xf8, }; -enum pwrap_type { - PWRAP_MT8188, - PWRAP_MT8189, - PWRAP_MT8365, -}; - struct pwrap_slv_type { const u32 *dew_regs; u32 caps; @@ -364,7 +358,6 @@ struct pmic_wrapper { struct pmic_wrapper_type { int *regs; - enum pwrap_type type; u32 arb_en_all; u32 spi_w; u32 wdt_src; @@ -779,7 +772,6 @@ static int mtk_pwrap_bind(struct udevice *dev) ofnode pmic_node, regulators_node; int children; const struct pmic_child_info *pmic_children_info; - struct pmic_wrapper_type *pw_type = (void *)dev_get_driver_data(dev); pmic_node = dev_read_first_subnode(dev); if (!ofnode_valid(pmic_node)) { @@ -787,16 +779,13 @@ static int mtk_pwrap_bind(struct udevice *dev) return -ENXIO; } - switch (pw_type->type) { - case PWRAP_MT8365: + if (ofnode_device_is_compatible(pmic_node, "mediatek,mt6357")) { pmic_children_info = mt6357_pmic_children_info; - break; - case PWRAP_MT8188: - case PWRAP_MT8189: + } else if (ofnode_device_is_compatible(pmic_node, "mediatek,mt6359")) { pmic_children_info = mt6359_pmic_children_info; - break; - default: - dev_err(dev, "pwrap type %d not supported\n", pw_type->type); + } else { + dev_err(dev, "pmic type %s not supported\n", + ofnode_read_string(pmic_node, "compatible")); return -ENXIO; } @@ -845,7 +834,6 @@ static struct dm_pmic_ops mtk_pwrap_ops = { static struct pmic_wrapper_type pwrap_mt8188 = { .regs = mt8188_regs, - .type = PWRAP_MT8188, .arb_en_all = 0x777f, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, @@ -854,7 +842,6 @@ static struct pmic_wrapper_type pwrap_mt8188 = { static struct pmic_wrapper_type pwrap_mt8189 = { .regs = mt8189_regs, - .type = PWRAP_MT8189, .arb_en_all = 0x777f, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, @@ -863,7 +850,6 @@ static struct pmic_wrapper_type pwrap_mt8189 = { static const struct pmic_wrapper_type pwrap_mt8365 = { .regs = mt8365_regs, - .type = PWRAP_MT8365, .arb_en_all = 0x3ffff, .spi_w = PWRAP_MAN_CMD_SPI_WRITE, .wdt_src = PWRAP_WDT_SRC_MASK_ALL, From e262eb4cfe46a6feef554dfb68d721ab83930711 Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Thu, 9 Apr 2026 15:30:39 -0500 Subject: [PATCH 26/27] power: pmic: mtk-pwrap: use tabs for alignment Fix mt8188_regs definition to use tabs instead of spaces for alignment to be consistent with other definitions. Reviewed-by: Macpaul Lin Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-7-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index d41a43c8c95..9a249c796e7 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -251,20 +251,20 @@ enum pwrap_regs { }; static int mt8188_regs[] = { - [PWRAP_INIT_DONE2] = 0x0, - [PWRAP_STAUPD_CTRL] = 0x4C, - [PWRAP_TIMER_EN] = 0x3E4, - [PWRAP_INT_EN] = 0x420, - [PWRAP_INT_FLG] = 0x428, - [PWRAP_INT_CLR] = 0x42C, - [PWRAP_INT1_EN] = 0x450, - [PWRAP_INT1_FLG] = 0x458, - [PWRAP_INT1_CLR] = 0x45C, - [PWRAP_WACS2_CMD] = 0x880, - [PWRAP_SWINF_2_WDATA_31_0] = 0x884, - [PWRAP_SWINF_2_RDATA_31_0] = 0x894, - [PWRAP_WACS2_VLDCLR] = 0x8A4, - [PWRAP_WACS2_RDATA] = 0x8A8, + [PWRAP_INIT_DONE2] = 0x0, + [PWRAP_STAUPD_CTRL] = 0x4C, + [PWRAP_TIMER_EN] = 0x3E4, + [PWRAP_INT_EN] = 0x420, + [PWRAP_INT_FLG] = 0x428, + [PWRAP_INT_CLR] = 0x42C, + [PWRAP_INT1_EN] = 0x450, + [PWRAP_INT1_FLG] = 0x458, + [PWRAP_INT1_CLR] = 0x45C, + [PWRAP_WACS2_CMD] = 0x880, + [PWRAP_SWINF_2_WDATA_31_0] = 0x884, + [PWRAP_SWINF_2_RDATA_31_0] = 0x894, + [PWRAP_WACS2_VLDCLR] = 0x8A4, + [PWRAP_WACS2_RDATA] = 0x8A8, }; static int mt8189_regs[] = { From a97c82bfdf52aab727ecb4ce3a81ef585e4c55d3 Mon Sep 17 00:00:00 2001 From: Julien Stephan Date: Thu, 9 Apr 2026 15:30:40 -0500 Subject: [PATCH 27/27] power: pmic: mtk-pwrap: add MT8195 support Add mt8195 support. Support comes directly from commit e88edc977b00 ("soc: mediatek: pwrap: add pwrap driver for MT8195 SoC") from the Linux Kernel. Signed-off-by: Julien Stephan Link: https://patch.msgid.link/20260409-mtk-pmic-fixes-v2-8-73e83aa6345b@baylibre.com Signed-off-by: David Lechner --- drivers/power/pmic/mtk-pwrap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/power/pmic/mtk-pwrap.c b/drivers/power/pmic/mtk-pwrap.c index 9a249c796e7..47347785519 100644 --- a/drivers/power/pmic/mtk-pwrap.c +++ b/drivers/power/pmic/mtk-pwrap.c @@ -278,6 +278,23 @@ static int mt8189_regs[] = { [PWRAP_WACS2_RDATA] = 0x8A8, }; +static int mt8195_regs[] = { + [PWRAP_INIT_DONE2] = 0x0, + [PWRAP_STAUPD_CTRL] = 0x4C, + [PWRAP_TIMER_EN] = 0x3E4, + [PWRAP_INT_EN] = 0x420, + [PWRAP_INT_FLG] = 0x428, + [PWRAP_INT_CLR] = 0x42C, + [PWRAP_INT1_EN] = 0x450, + [PWRAP_INT1_FLG] = 0x458, + [PWRAP_INT1_CLR] = 0x45C, + [PWRAP_WACS2_CMD] = 0x880, + [PWRAP_SWINF_2_WDATA_31_0] = 0x884, + [PWRAP_SWINF_2_RDATA_31_0] = 0x894, + [PWRAP_WACS2_VLDCLR] = 0x8A4, + [PWRAP_WACS2_RDATA] = 0x8A8, +}; + static int mt8365_regs[] = { [PWRAP_MUX_SEL] = 0x0, [PWRAP_WRAP_EN] = 0x4, @@ -848,6 +865,14 @@ static struct pmic_wrapper_type pwrap_mt8189 = { .caps = PWRAP_CAP_ARB, }; +static const struct pmic_wrapper_type pwrap_mt8195 = { + .regs = mt8195_regs, + .arb_en_all = 0x777f, /* NEED CONFIRM */ + .spi_w = PWRAP_MAN_CMD_SPI_WRITE, + .wdt_src = PWRAP_WDT_SRC_MASK_ALL, + .caps = PWRAP_CAP_ARB, +}; + static const struct pmic_wrapper_type pwrap_mt8365 = { .regs = mt8365_regs, .arb_en_all = 0x3ffff, @@ -859,6 +884,7 @@ static const struct pmic_wrapper_type pwrap_mt8365 = { static const struct udevice_id mtk_pwrap_ids[] = { { .compatible = "mediatek,mt8188-pwrap", .data = (ulong)&pwrap_mt8188 }, { .compatible = "mediatek,mt8189-pwrap", .data = (ulong)&pwrap_mt8189 }, + { .compatible = "mediatek,mt8195-pwrap", .data = (ulong)&pwrap_mt8195 }, { .compatible = "mediatek,mt8365-pwrap", .data = (ulong)&pwrap_mt8365 }, { } };