From 4db11bb51fc79c5a2d83d0dc735f310a99855e2a Mon Sep 17 00:00:00 2001 From: akku Date: Fri, 2 Jan 2026 22:50:30 +0900 Subject: [PATCH 01/78] pmdomain: mediatek: scpsys: init mt6589 support --- .../bindings/soc/mediatek/scpsys.txt | 2 + arch/arm/boot/dts/mediatek/mt6589.dtsi | 11 +++ arch/arm/configs/lenovo-blade_defconfig | 3 + drivers/pmdomain/mediatek/mtk-scpsys.c | 90 +++++++++++++++++++ include/dt-bindings/power/mt6589-power.h | 29 ++++++ 5 files changed, 135 insertions(+) create mode 100644 include/dt-bindings/power/mt6589-power.h diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt index 3530a6668b4868..4dc10acae474e5 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -20,6 +20,7 @@ Required properties: - compatible: Should be one of: - "mediatek,mt2701-scpsys" - "mediatek,mt2712-scpsys" + - "mediatek,mt6589-scpsys" - "mediatek,mt6735-scpsys" - "mediatek,mt6765-scpsys" - "mediatek,mt6797-scpsys" @@ -36,6 +37,7 @@ Required properties: enabled before enabling certain power domains. Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif" Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec" + Required clocks for MT6589: "disp", "venc", "vdec" Required clocks for MT6765: MUX: "mm", "mfg" CG: "mm-0", "mm-1", "mm-2", "mm-3", "isp-0", "isp-1", "cam-0", "cam-1", "cam-2", diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index deeb1494f15a3a..73dca57cbd669d 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -101,6 +101,17 @@ #reset-cells = <1>; }; + scpsys: power-controller@10006000 { + compatible = "mediatek,mt6589-scpsys", "syscon"; + #power-domain-cells = <1>; + reg = <0 0x10006000 0 0x1000>; + infracfg = <&infracfg>; + clocks = <&topckgen CLK_TOP_MUX_DISP>, + <&topckgen CLK_TOP_MUX_VENC>, + <&topckgen CLK_TOP_MUX_VDEC>; + clock-names = "disp", "venc", "vdec"; + }; + mfgsys: syscon@10206000 { compatible = "mediatek,mt6589-mfgsys", "syscon"; reg = <0x10206000 0x1000>; diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index a563b5de9b32fb..29a2750522fc3b 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -113,6 +113,9 @@ CONFIG_MMC_MTK=y ## Reset #CONFIG_RESET_CONTROLLER +## Power Management +CONFIG_MTK_SCPSYS=y + ## Battery ## Audio diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c index 1a80c1537a43d2..2eac61cd00c88a 100644 --- a/drivers/pmdomain/mediatek/mtk-scpsys.c +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -31,8 +32,11 @@ #define SPM_MFG_PWR_CON 0x0214 #define SPM_VEN_PWR_CON 0x0230 #define SPM_ISP_PWR_CON 0x0238 +#define SPM_IFR_PWR_CON 0x0234 /* MT6589 */ #define SPM_DIS_PWR_CON 0x023c +#define SPM_DPY_PWR_CON 0x0240 /* MT6589 */ #define SPM_CONN_PWR_CON 0x0280 +#define SPM_CONN2_PWR_CON 0x0284 /* MT6589 */ #define SPM_VEN2_PWR_CON 0x0298 #define SPM_AUDIO_PWR_CON 0x029c /* MT8173, MT2712 */ #define SPM_BDP_PWR_CON 0x029c /* MT2701 */ @@ -58,9 +62,11 @@ #define PWR_CLK_DIS_BIT BIT(4) #define PWR_STATUS_CONN BIT(1) +#define PWR_STATUS_DPY BIT(2) /* MT6589 */ #define PWR_STATUS_DISP BIT(3) #define PWR_STATUS_MFG BIT(4) #define PWR_STATUS_ISP BIT(5) +#define PWR_STATUS_IFR BIT(6) /* MT6589 */ #define PWR_STATUS_VDEC BIT(7) #define PWR_STATUS_BDP BIT(14) #define PWR_STATUS_ETH BIT(15) @@ -89,6 +95,7 @@ enum clk_id { CLK_HIFSEL, CLK_JPGDEC, CLK_AUDIO, + CLK_DISP, CLK_MAX, }; @@ -103,6 +110,7 @@ static const char * const clk_names[] = { "hif_sel", "jpgdec", "audio", + "disp", NULL, }; @@ -748,6 +756,73 @@ static const struct scp_subdomain scp_subdomain_mt2712[] = { {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3}, }; +/* + * MT6589 power domain support + */ +static const struct scp_domain_data scp_domain_data_mt6589[] = { + [MT6589_POWER_DOMAIN_MD1] = { + .name = "md1", + .sta_mask = PWR_STATUS_CONN, + .ctl_offs = SPM_CONN2_PWR_CON, /* not miss */ + .clk_id = {CLK_NONE}, + .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ + }, + [MT6589_POWER_DOMAIN_MD2] = { + .name = "md2", + .sta_mask = PWR_STATUS_CONN, + .ctl_offs = SPM_CONN_PWR_CON, + .clk_id = {CLK_NONE}, + .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ + }, + [MT6589_POWER_DOMAIN_DPY] = { + .name = "dpy", + .sta_mask = PWR_STATUS_DPY, + .ctl_offs = SPM_DPY_PWR_CON, + .clk_id = {CLK_NONE}, + .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ + }, + [MT6589_POWER_DOMAIN_DIS] = { + .name = "disp", + .sta_mask = PWR_STATUS_DISP, + .ctl_offs = SPM_DIS_PWR_CON, + .clk_id = {CLK_DISP}, + }, + [MT6589_POWER_DOMAIN_MFG] = { + .name = "mfg", + .sta_mask = PWR_STATUS_MFG, + .ctl_offs = SPM_MFG_PWR_CON, + .clk_id = {CLK_NONE}, + }, + [MT6589_POWER_DOMAIN_ISP] = { + .name = "isp", + .sta_mask = PWR_STATUS_ISP, + .ctl_offs = SPM_ISP_PWR_CON, + .clk_id = {CLK_NONE}, + }, + [MT6589_POWER_DOMAIN_IFR] = { + .name = "ifr", + .sta_mask = PWR_STATUS_IFR, + .ctl_offs = SPM_IFR_PWR_CON, + .clk_id = {CLK_NONE}, + .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ + }, + [MT6589_POWER_DOMAIN_VEN] = { + .name = "venc", + .sta_mask = BIT(7), + .ctl_offs = SPM_VEN_PWR_CON, + .clk_id = {CLK_VENC}, + }, + [MT6589_POWER_DOMAIN_VDE] = { + .name = "vdec", + .sta_mask = BIT(8), + .ctl_offs = SPM_VDE_PWR_CON, + .clk_id = {CLK_VDEC}, + }, +}; + +static const struct scp_subdomain scp_subdomain_mt6589[] = { +}; + /* * MT6797 power domain support */ @@ -1031,6 +1106,18 @@ static const struct scp_soc_data mt2712_data = { .bus_prot_reg_update = false, }; +static const struct scp_soc_data mt6589_data = { + .domains = scp_domain_data_mt6589, + .num_domains = ARRAY_SIZE(scp_domain_data_mt6589), + .subdomains = scp_subdomain_mt6589, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6589), + .regs = { +// .pwr_sta_offs = SPM_PWR_STATUS, +// .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + }, +// .bus_prot_reg_update = false, +}; + static const struct scp_soc_data mt6797_data = { .domains = scp_domain_data_mt6797, .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), @@ -1086,6 +1173,9 @@ static const struct of_device_id of_scpsys_match_tbl[] = { }, { .compatible = "mediatek,mt2712-scpsys", .data = &mt2712_data, + }, { + .compatible = "mediatek,mt6589-scpsys", + .data = &mt6589_data, }, { .compatible = "mediatek,mt6797-scpsys", .data = &mt6797_data, diff --git a/include/dt-bindings/power/mt6589-power.h b/include/dt-bindings/power/mt6589-power.h new file mode 100644 index 00000000000000..39649b4805572f --- /dev/null +++ b/include/dt-bindings/power/mt6589-power.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 akku + */ + +#ifndef _DT_BINDINGS_POWER_MT6589_POWER_H +#define _DT_BINDINGS_POWER_MT6589_POWER_H + +/* + * FC0 + * DBG + * CPU + * FC1 + * FC2 + * FC3 + * IFR_FH + */ + +#define MT6589_POWER_DOMAIN_MD1 0 +#define MT6589_POWER_DOMAIN_MD2 1 +#define MT6589_POWER_DOMAIN_DPY 2 +#define MT6589_POWER_DOMAIN_DIS 3 +#define MT6589_POWER_DOMAIN_MFG 4 +#define MT6589_POWER_DOMAIN_ISP 5 +#define MT6589_POWER_DOMAIN_IFR 6 +#define MT6589_POWER_DOMAIN_VEN 7 +#define MT6589_POWER_DOMAIN_VDE 8 + +#endif /* _DT_BINDINGS_POWER_MT6589_POWER_H */ From f295374a0f69d4f9512da72f48f452c641033961 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Thu, 5 Mar 2026 00:21:42 +0900 Subject: [PATCH 02/78] arm: dts: mediatek: mt6589: fix scpsys address --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 73dca57cbd669d..815ffa9186a8c8 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -104,7 +104,7 @@ scpsys: power-controller@10006000 { compatible = "mediatek,mt6589-scpsys", "syscon"; #power-domain-cells = <1>; - reg = <0 0x10006000 0 0x1000>; + reg = <0x10006000 0x1000>; infracfg = <&infracfg>; clocks = <&topckgen CLK_TOP_MUX_DISP>, <&topckgen CLK_TOP_MUX_VENC>, From b4d11b7e92a60d62d94fe412c34172951bba7ceb Mon Sep 17 00:00:00 2001 From: rva3 Date: Tue, 3 Mar 2026 17:31:00 +0200 Subject: [PATCH 03/78] memory: mtk-smi: add support for mt65xx smi common The mt65xx SoC family uses an earlier version of the SMI, which we refer to as gen 0. Unlike gen 1 or gen 2, gen 0 requires simultaneous access to two distinct MMIO ranges: an AO base for IOMMU configuration and ext base for OSTD, FIFO, and bandwidth limiter setup. Remove the union in struct mtk_smi to allow simultaneous use of smi_ao_base and base. Refactor the probe function into a switch statement to handle the different generation requirements cleanly. Signed-off-by: rva3 --- drivers/memory/mtk-smi.c | 74 +++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index c086c22511f7f6..f590c3f9107b0d 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -100,6 +100,7 @@ struct mtk_smi_reg_pair { }; enum mtk_smi_type { + MTK_SMI_GEN0, MTK_SMI_GEN1, MTK_SMI_GEN2, /* gen2 smi common */ MTK_SMI_GEN2_SUB_COMM, /* gen2 smi sub common */ @@ -141,10 +142,8 @@ struct mtk_smi { unsigned int clk_num; struct clk_bulk_data clks[MTK_SMI_CLK_NR_MAX]; struct clk *clk_async; /*only needed by mt2701*/ - union { - void __iomem *smi_ao_base; /* only for gen1 */ - void __iomem *base; /* only for gen2 */ - }; + void __iomem *smi_ao_base; + void __iomem *base; struct device *smi_common_dev; /* for sub common */ const struct mtk_smi_common_plat *plat; }; @@ -845,31 +844,42 @@ static int mtk_smi_common_probe(struct platform_device *pdev) if (ret) return ret; - /* - * for mtk smi gen 1, we need to get the ao(always on) base to config - * m4u port, and we need to enable the aync clock for transform the smi - * clock into emi clock domain, but for mtk smi gen2, there's no smi ao - * base. - */ - if (common->plat->type == MTK_SMI_GEN1) { - common->smi_ao_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(common->smi_ao_base)) - return PTR_ERR(common->smi_ao_base); - - common->clk_async = devm_clk_get_enabled(dev, "async"); - if (IS_ERR(common->clk_async)) - return PTR_ERR(common->clk_async); - } else { - common->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(common->base)) - return PTR_ERR(common->base); - } - - /* link its smi-common if this is smi-sub-common */ - if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) { - ret = mtk_smi_device_link_common(dev, &common->smi_common_dev); - if (ret < 0) - return ret; + switch (common->plat->type) { + case MTK_SMI_GEN0: + /* + * gen 0 uses 2 mmio ranges: ao base for iommu configuration, + * and ext base for ostd, fifo and bw limiter setup + */ + common->smi_ao_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(common->smi_ao_base)) + return PTR_ERR(common->smi_ao_base); + common->base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(common->base)) + return PTR_ERR(common->base); + break; + case MTK_SMI_GEN1: + /* + * gen 1 needs async clock to transform the smi clock to the + * emi clock domain + */ + common->smi_ao_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(common->smi_ao_base)) + return PTR_ERR(common->smi_ao_base); + common->clk_async = devm_clk_get_enabled(dev, "async"); + if (IS_ERR(common->clk_async)) + return PTR_ERR(common->clk_async); + break; + case MTK_SMI_GEN2: + common->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(common->base)) + return PTR_ERR(common->base); + break; + case MTK_SMI_GEN2_SUB_COMM: + /* link its smi-common if this is smi-sub-common */ + ret = mtk_smi_device_link_common(dev, &common->smi_common_dev); + if (ret < 0) + return ret; + break; } pm_runtime_enable(dev); @@ -897,13 +907,15 @@ static int __maybe_unused mtk_smi_common_resume(struct device *dev) if (ret) return ret; - if (common->plat->type != MTK_SMI_GEN2) + if (common->plat->type != MTK_SMI_GEN0 && common->plat->type != MTK_SMI_GEN2) return 0; for (i = 0; i < SMI_COMMON_INIT_REGS_NR && init && init[i].offset; i++) writel_relaxed(init[i].value, common->base + init[i].offset); - writel(bus_sel, common->base + SMI_BUS_SEL); + if (common->plat->type == MTK_SMI_GEN2) + writel(bus_sel, common->base + SMI_BUS_SEL); + return 0; } From 16ca6555333b6804ddea71e51b67ef8c2634d40d Mon Sep 17 00:00:00 2001 From: rva3 Date: Wed, 4 Mar 2026 03:55:31 +0200 Subject: [PATCH 04/78] memory: mtk-smi: add support for mt65xx smi larb The mt65xx SoC family utilizes a larb design that incorporates features from both gen 1 and gen 2 architectures. Introduce a specific configuration callback for this generation, which implements the port security configuration typical for gen 1 while including the ostd settings found in gen 2. Additionally, add a bandwidth calibration flag for some of the gen 0 SoCs. Signed-off-by: rva3 --- drivers/memory/mtk-smi.c | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index f590c3f9107b0d..57f83836709961 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -37,6 +37,7 @@ #define SMI_DUMMY 0x444 /* SMI LARB */ +#define SMI_LARB_STAT 0x0 #define SMI_LARB_SLP_CON 0xc #define SLP_PROT_EN BIT(0) #define SLP_PROT_RDY BIT(16) @@ -48,9 +49,14 @@ #define SMI_LARB_SW_FLAG 0x40 #define SMI_LARB_SW_FLAG_1 0x1 +#define SMI_LARB_BWFILTER_EN 0x60 +#define SMI_LARB_OSTD_CTRL_EN 0x64 + #define SMI_LARB_OSTDL_PORT 0x200 #define SMI_LARB_OSTDL_PORTx(id) (SMI_LARB_OSTDL_PORT + (((id) & 0x1f) << 2)) +#define SMI_LARB_FIFO_STAT0 0x600 + /* Below are about mmu enable registers, they are different in SoCs */ /* gen1: mt2701 */ #define REG_SMI_SECUR_CON_BASE 0x5c0 @@ -92,6 +98,7 @@ #define MTK_SMI_FLAG_SW_FLAG BIT(1) #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) #define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) +#define MTK_SMI_FLAG_BW_CALIBRATE BIT(4) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) struct mtk_smi_reg_pair { @@ -187,6 +194,65 @@ static const struct component_ops mtk_smi_larb_component_ops = { .unbind = mtk_smi_larb_unbind, }; +static int mtk_smi_larb_config_port_gen0(struct device *dev) +{ + struct mtk_smi_larb *larb = dev_get_drvdata(dev); + const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen; + struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev); + const u8 *larbostd = larb_gen->ostd ? larb_gen->ostd[larb->larbid] : + NULL; + int i, m4u_port_id, larb_port_num; + u32 sec_con_val, reg_val, tmp; + int ret; + + m4u_port_id = larb_gen->port_in_larb[larb->larbid]; + larb_port_num = larb_gen->port_in_larb[larb->larbid + 1] - m4u_port_id; + + /* gen 1 part */ + for (i = 0; i < larb_port_num; i++, m4u_port_id++) { + if (*larb->mmu & BIT(i)) { + sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id); + } else { + continue; + } + + reg_val = readl(common->smi_ao_base + + REG_SMI_SECUR_CON_ADDR(m4u_port_id)); + reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id); + reg_val |= sec_con_val; + reg_val |= SMI_SECUR_CON_VAL_DOMAIN(m4u_port_id); + writel(reg_val, common->smi_ao_base + + REG_SMI_SECUR_CON_ADDR(m4u_port_id)); + } + + /* gen 2 part */ + for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) + writel_relaxed(larbostd[i], + larb->base + SMI_LARB_OSTDL_PORTx(i)); + + /* some gen 0 SoCs need BW calibration */ + if (MTK_SMI_CAPS(larb_gen->flags_general, MTK_SMI_FLAG_BW_CALIBRATE)) { + reg_val = readl_relaxed(larb->base + SMI_LARB_STAT); + if (!reg_val) { + writel_relaxed(0xffffffff, + larb->base + SMI_LARB_BWFILTER_EN); + + ret = readl_poll_timeout( + larb->base + SMI_LARB_FIFO_STAT0, tmp, + tmp == 0xaaaa, 500, 64 * 500); + if (ret) + dev_warn(dev, + "BW limiter calibration timeout\n"); + + writel_relaxed(0, larb->base + SMI_LARB_BWFILTER_EN); + writel_relaxed(0xffffffff, + larb->base + SMI_LARB_OSTD_CTRL_EN); + } + } + + return 0; +} + static int mtk_smi_larb_config_port_gen1(struct device *dev) { struct mtk_smi_larb *larb = dev_get_drvdata(dev); From fd3a5e6e24e0d7d5951ef773d3e5f35840e06279 Mon Sep 17 00:00:00 2001 From: rva3 Date: Fri, 6 Mar 2026 04:43:43 +0200 Subject: [PATCH 05/78] iommu: mtk_iommu_v1: add mt65xx support The mt65xx SoC family utilizes an earlier version of the IOMMU which shares the same v1 architecture but has minor hardware differences compared to mt2701. Introduce mtk_iommu_type to distinguish between mt2701 and mt65xx variants and apply the necessary logic. Signed-off-by: rva3 --- drivers/iommu/mtk_iommu_v1.c | 67 +++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 66824982e05fbf..88ae00fbf78ba8 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -85,6 +85,13 @@ struct dma_iommu_mapping { #define F_DESC_NONSEC BIT(3) #define MT2701_M4U_TF_LARB(TF) (6 - (((TF) >> 13) & 0x7)) #define MT2701_M4U_TF_PORT(TF) (((TF) >> 8) & 0xF) + +#define MT65XX_MMU_INT_ID_PORT_ID GENMASK(12, 8) +#define MT65XX_MMU_INT_ID_LARB_ID GENMASK(14, 13) + +#define MT65XX_M4U_TF_PORT(TF) FIELD_GET(MT65XX_MMU_INT_ID_PORT_ID, TF) +#define MT65XX_M4U_TF_LARB(TF) (FIELD_GET(MT65XX_MMU_INT_ID_LARB_ID, TF) - 1) + /* MTK generation one iommu HW only support 4K size mapping */ #define MT2701_IOMMU_PAGE_SHIFT 12 #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) @@ -96,6 +103,11 @@ struct dma_iommu_mapping { */ #define M2701_IOMMU_PGT_SIZE SZ_4M +enum mtk_iommu_type { + MTK_IOMMU_MT65XX, + MTK_IOMMU_V1, +}; + struct mtk_iommu_v1_suspend_reg { u32 standard_axi_mode; u32 dcm_dis; @@ -116,6 +128,8 @@ struct mtk_iommu_v1_data { struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; struct mtk_iommu_v1_suspend_reg reg; + + enum mtk_iommu_type type; }; struct mtk_iommu_v1_domain { @@ -170,8 +184,11 @@ static inline int mt2701_m4u_to_port(int id) static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) { - writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, - data->base + REG_MMU_INV_SEL); + u32 val = F_INVLD_EN0; + if (data->type == MTK_IOMMU_V1) + val |= F_INVLD_EN1; + + writel_relaxed(val, data->base + REG_MMU_INV_SEL); writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); wmb(); /* Make sure the tlb flush all done */ } @@ -180,25 +197,31 @@ static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, unsigned long iova, size_t size) { int ret; - u32 tmp; + u32 tmp, val = F_INVLD_EN0; + if (data->type == MTK_IOMMU_V1) + val |= F_INVLD_EN1; - writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, - data->base + REG_MMU_INV_SEL); + writel_relaxed(val, data->base + REG_MMU_INV_SEL); writel_relaxed(iova & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_START_A); writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_END_A); writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); - ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, - tmp, tmp != 0, 10, 100000); - if (ret) { - dev_warn(data->dev, - "Partial TLB flush timed out, falling back to full flush\n"); - mtk_iommu_v1_tlb_flush_all(data); + if (data->type == MTK_IOMMU_V1) { + ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, + tmp, tmp != 0, 10, 100000); + if (ret) { + dev_warn(data->dev, + "Partial TLB flush timed out, falling back to full flush\n"); + mtk_iommu_v1_tlb_flush_all(data); + } + + /* Clear the CPE status */ + writel_relaxed(0, data->base + REG_MMU_CPE_DONE); + } else { + wmb(); } - /* Clear the CPE status */ - writel_relaxed(0, data->base + REG_MMU_CPE_DONE); } static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) @@ -215,8 +238,14 @@ static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) fault_iova &= F_MMU_FAULT_VA_MSK; fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); regval = readl_relaxed(data->base + REG_MMU_INT_ID); - fault_larb = MT2701_M4U_TF_LARB(regval); - fault_port = MT2701_M4U_TF_PORT(regval); + + if (data->type == MTK_IOMMU_V1) { + fault_larb = MT2701_M4U_TF_LARB(regval); + fault_port = MT2701_M4U_TF_PORT(regval); + } else { + fault_larb = MT65XX_M4U_TF_LARB(regval); + fault_port = MT65XX_M4U_TF_PORT(regval); + } /* * MTK v1 iommu HW could not determine whether the fault is read or @@ -545,7 +574,10 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) return ret; } - regval = F_MMU_CTRL_COHERENT_EN | F_MMU_TF_PROTECT_SEL(2); + regval = F_MMU_TF_PROTECT_SEL(2); + if (data->type == MTK_IOMMU_V1) + regval |= F_MMU_CTRL_COHERENT_EN; + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); regval = F_INT_TRANSLATION_FAULT | @@ -594,7 +626,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = { }; static const struct of_device_id mtk_iommu_v1_of_ids[] = { - { .compatible = "mediatek,mt2701-m4u", }, + { .compatible = "mediatek,mt2701-m4u", .data = (void *)MTK_IOMMU_V1 }, {} }; MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); @@ -618,6 +650,7 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) return -ENOMEM; data->dev = dev; + data->type = (enum mtk_iommu_type)of_device_get_match_data(dev); /* Protect memory. HW will access here while translation fault.*/ protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, From d692232274fe87de86d0cc67b7c1f472206f8473 Mon Sep 17 00:00:00 2001 From: rva3 Date: Wed, 11 Mar 2026 15:04:46 +0200 Subject: [PATCH 06/78] drm: mediatek: ovl: attach errors for the interrupt XXX: maybe we should drop this?.. Signed-off-by: rva3 --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 ++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index e0236353d4997e..32cee6f4c9e9d4 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -20,9 +20,21 @@ #include "mtk_disp_drv.h" #include "mtk_drm_drv.h" -#define DISP_REG_OVL_INTEN 0x0004 -#define OVL_FME_CPL_INT BIT(1) +#define DISP_REG_OVL_INTEN 0x0004 +#define OVL_FME_CPL_INT BIT(1) +#define OVL_FME_UND_INT BIT(2) +#define OVL_RDMA0_EOF_ABNORMAL_INT BIT(5) +#define OVL_RDMA1_EOF_ABNORMAL_INT BIT(6) +#define OVL_RDMA0_FIFO_UND_INT BIT(9) +#define OVL_RDMA1_FIFO_UND_INT BIT(10) + #define DISP_REG_OVL_INTSTA 0x0008 +#define OVL_FME_UND BIT(2) +#define OVL_RDMA0_EOF_ABNORMAL BIT(5) +#define OVL_RDMA1_EOF_ABNORMAL BIT(6) +#define OVL_RDMA0_FIFO_UND BIT(9) +#define OVL_RDMA1_FIFO_UND BIT(10) + #define DISP_REG_OVL_EN 0x000c #define DISP_REG_OVL_RST 0x0014 #define DISP_REG_OVL_ROI_SIZE 0x0020 @@ -170,6 +182,18 @@ struct mtk_disp_ovl { static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) { struct mtk_disp_ovl *priv = dev_id; + u32 reg = readl(priv->regs + DISP_REG_OVL_INTSTA); + + if (reg & OVL_FME_UND) + pr_err("OVL: OVL frame underflow\n"); + if (reg & OVL_RDMA0_EOF_ABNORMAL) + pr_err("OVL: RDMA0 didn't complete frame\n"); + if (reg & OVL_RDMA1_EOF_ABNORMAL) + pr_err("OVL: RDMA1 didn't complete frame\n"); + if (reg & OVL_RDMA0_FIFO_UND) + pr_err("OVL: RDMA0 FIFO underflow\n"); + if (reg & OVL_RDMA1_FIFO_UND) + pr_err("OVL: RDMA1 FIFO underflow\n"); /* Clear frame completion interrupt */ writel(0x0, priv->regs + DISP_REG_OVL_INTSTA); @@ -205,7 +229,10 @@ void mtk_ovl_enable_vblank(struct device *dev) struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); - writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); + writel_relaxed(OVL_FME_CPL_INT | OVL_FME_UND_INT | + OVL_RDMA0_EOF_ABNORMAL_INT | OVL_RDMA1_EOF_ABNORMAL_INT | + OVL_RDMA0_FIFO_UND_INT | OVL_RDMA1_FIFO_UND_INT, + ovl->regs + DISP_REG_OVL_INTEN); } void mtk_ovl_disable_vblank(struct device *dev) From ecd5e209209e0b9e88ff6ffb9b7380e74776da18 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 15:13:58 +0900 Subject: [PATCH 07/78] dt-bindings: panel-simple-dsi: add blade10 panels Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/display/panel/panel-simple-dsi.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml index 9b92a05791ccf9..352322fbacc871 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml @@ -28,8 +28,12 @@ properties: # AU Optronics Corporation 8.0" WUXGA TFT LCD panel - auo,b080uan01 + # BOE Technology 10.1" WXGA panel with Himax HX8896-A01 TCON + - boe,hx8896-a01 # Boe Corporation 8.0" WUXGA TFT LCD panel - boe,tv080wum-nl0 + # CMI 10.1" WXGA panel with Himax HX8896-A01 TCON + - innolux,hx8896-a01 # Innolux P079ZCA 7.85" 768x1024 TFT LCD panel - innolux,p079zca # JDI FHD_R63452 1080x1920 5.2" IPS LCD Panel From 95713dee5fb409fc45d5f26a18ce32e111b279df Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 15:56:54 +0900 Subject: [PATCH 08/78] drm/panel: simple: add blade10 HX8896-A01 panels Signed-off-by: Akari Tsuyukusa --- drivers/gpu/drm/panel/panel-simple.c | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 9f81fa960b4602..f66690a97591eb 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -5482,6 +5482,31 @@ static const struct panel_desc_dsi auo_b080uan01 = { .lanes = 4, }; +static const struct drm_display_mode boe_hx8896a_01_mode = { + .clock = 69837, /* 1416 * 822 * 60 / 1000 kHz */ + .hdisplay = 1280, + .hsync_start = 1280 + 100, + .hsync_end = 1280 + 100 + 4, + .htotal = 1280 + 100 + 4 + 32, + .vdisplay = 800, + .vsync_start = 800 + 10, + .vsync_end = 800 + 10 + 2, + .vtotal = 800 + 10 + 2 + 10, +}; + +static const struct panel_desc_dsi boe_hx8896_a01 = { + .desc = { + .modes = &boe_hx8896_a01_mode, + .num_modes = 1, + .bpc = 8, + .size = { .width = 217, .height = 136 }, /* TODO */ + .connector_type = DRM_MODE_CONNECTOR_DSI, + }, + .flags = MIPI_DSI_MODE_VIDEO, + .format = MIPI_DSI_FMT_RGB888, + .lanes = 4, +}; + static const struct drm_display_mode boe_tv080wum_nl0_mode = { .clock = 160000, .hdisplay = 1200, @@ -5512,6 +5537,31 @@ static const struct panel_desc_dsi boe_tv080wum_nl0 = { .lanes = 4, }; +static const struct drm_display_mode innolux_hx8896_a01_mode = { + .clock = 76019, /* 1521 * 833 * 60 / 1000 kHz */ + .hdisplay = 1280, + .hsync_start = 1280 + 186, /* + HFP */ + .hsync_end = 1280 + 186 + 5, /* + HSW */ + .htotal = 1280 + 186 + 5 + 50, /* + HBP */ + .vdisplay = 800, + .vsync_start = 800 + 21, /* + VFP */ + .vsync_end = 800 + 21 + 2, /* + VSW */ + .vtotal = 800 + 21 + 2 + 10, /* + VBP */ +}; + +static const struct panel_desc_dsi innolux_hx8896_a01 = { + .desc = { + .modes = &innolux_hx8896_a01_mode, + .num_modes = 1, + .bpc = 8, + .size = { .width = 217, .height = 136 }, /* TODO */ + .connector_type = DRM_MODE_CONNECTOR_DSI, + }, + .flags = MIPI_DSI_MODE_VIDEO, + .format = MIPI_DSI_FMT_RGB888, + .lanes = 4, +}; + static const struct drm_display_mode lg_ld070wx3_sl01_mode = { .clock = 71000, .hdisplay = 800, @@ -5660,9 +5710,15 @@ static const struct of_device_id dsi_of_match[] = { { .compatible = "auo,b080uan01", .data = &auo_b080uan01 + }, { + .compatible = "boe,hx8896-a01", + .data = &boe_hx8896_a01 }, { .compatible = "boe,tv080wum-nl0", .data = &boe_tv080wum_nl0 + }, { + .compatible = "innolux,hx8896-a01", + .data = &innolux_hx8896_a01 }, { .compatible = "lg,ld070wx3-sl01", .data = &lg_ld070wx3_sl01 From bbe679100c220141acc4017021cc924676842061 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 16:00:34 +0900 Subject: [PATCH 09/78] arm: dts: mediatek: blade refactor Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000-f.dts | 2 +- arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000-f.dts b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000-f.dts index 3410e1b8c1bb2a..b3a45d87e8ae64 100644 --- a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000-f.dts +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000-f.dts @@ -3,7 +3,7 @@ * Copyright (c) 2025 akku */ -#include "mt6589-lenovo-blade.dtsi" +#include "mt6589-lenovo-b8000.dtsi" #include / { diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi new file mode 100644 index 00000000000000..e0578ae9fce23d --- /dev/null +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) 2026 Akari Tsuyukusa + */ + +#include "mt6589-lenovo-blade.dtsi" + +/ { + /* TODO: panel */ +} From 2e8043fce155429c3efadeac73e4c5f9d8a7cdc8 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 16:25:45 +0900 Subject: [PATCH 10/78] dt-bindings: memory: Add MT6589 Add a header for the IOMMU ports on the MediaTek MT6589 SoC. Signed-off-by: Akari Tsuyukusa --- include/dt-bindings/memory/mt6589-larb-port.h | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 include/dt-bindings/memory/mt6589-larb-port.h diff --git a/include/dt-bindings/memory/mt6589-larb-port.h b/include/dt-bindings/memory/mt6589-larb-port.h new file mode 100644 index 00000000000000..2b5a0da3bac7b6 --- /dev/null +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026 Akari Tsuyukusa + */ + +#ifndef _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ +#define _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ + +#include + +#define M4U_LARB0_ID 0 +#define M4U_LARB1_ID 1 +#define M4U_LARB2_ID 2 +#define M4U_LARB3_ID 3 +#define M4U_LARB4_ID 4 +#define M4U_LARB5_ID 5 + +/* larb0 */ +#define M4U_PORT_VENC_RCPU MTK_M4U_ID(M4U_LARB0_ID, 0) +#define M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB0_ID, 1) +#define M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) +#define M4U_PORT_VENC_DB_READ MTK_M4U_ID(M4U_LARB0_ID, 3) +#define M4U_PORT_VENC_DB_WRITE MTK_M4U_ID(M4U_LARB0_ID, 4) +#define M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB0_ID, 5) +#define M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) +#define M4U_PORT_VENC_RD_COMV MTK_M4U_ID(M4U_LARB0_ID, 7) +#define M4U_PORT_VENC_SV_COMV MTK_M4U_ID(M4U_LARB0_ID, 8) +#define M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB0_ID, 9) + +/* larb1 */ +#define M4U_PORT_HW_VDEC_MC_EXT MTK_M4U_ID(M4U_LARB1_ID, 0) +#define M4U_PORT_HW_VDEC_PP_EXT MTK_M4U_ID(M4U_LARB1_ID, 1) +#define M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB1_ID, 2) +#define M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB1_ID, 3) +#define M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB1_ID, 4) +#define M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) +#define M4U_PORT_HW_VDEC_VLD2_EXT MTK_M4U_ID(M4U_LARB1_ID, 6) + +/* larb2 */ +#define M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) +#define M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) +#define M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) +#define M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) +#define M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) +#define M4U_PORT_WDMA0 MTK_M4U_ID(M4U_LARB2_ID, 5) +#define M4U_PORT_WDMA1 MTK_M4U_ID(M4U_LARB2_ID, 6) +#define M4U_PORT_RDMA0 MTK_M4U_ID(M4U_LARB2_ID, 7) +#define M4U_PORT_RDMA1 MTK_M4U_ID(M4U_LARB2_ID, 8) +#define M4U_PORT_CMDQ MTK_M4U_ID(M4U_LARB2_ID, 9) +#define M4U_PORT_DBI MTK_M4U_ID(M4U_LARB2_ID, 10) +#define M4U_PORT_G2D MTK_M4U_ID(M4U_LARB2_ID, 11) + +/* larb3 */ +#define M4U_PORT_JPGDEC_WDMA MTK_M4U_ID(M4U_LARB3_ID, 0) +#define M4U_PORT_JPGENC_RDMA MTK_M4U_ID(M4U_LARB3_ID, 1) +#define M4U_PORT_VIPI MTK_M4U_ID(M4U_LARB3_ID, 2) +#define M4U_PORT_IMGI MTK_M4U_ID(M4U_LARB3_ID, 3) +#define M4U_PORT_DISPO MTK_M4U_ID(M4U_LARB3_ID, 4) +#define M4U_PORT_DISPCO MTK_M4U_ID(M4U_LARB3_ID, 5) +#define M4U_PORT_DISPVO MTK_M4U_ID(M4U_LARB3_ID, 6) +#define M4U_PORT_VIDO MTK_M4U_ID(M4U_LARB3_ID, 7) +#define M4U_PORT_VIDCO MTK_M4U_ID(M4U_LARB3_ID, 8) +#define M4U_PORT_VIDVO MTK_M4U_ID(M4U_LARB3_ID, 9) +#define M4U_PORT_VIP2I MTK_M4U_ID(M4U_LARB3_ID, 10) +#define M4U_PORT_GDMA_SMI_WR MTK_M4U_ID(M4U_LARB3_ID, 11) +#define M4U_PORT_JPGDEC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 12) +#define M4U_PORT_JPGENC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 13) + +/* larb4 */ +#define M4U_PORT_GDMA_SMI_RD MTK_M4U_ID(M4U_LARB4_ID, 0) +#define M4U_PORT_IMGCI MTK_M4U_ID(M4U_LARB4_ID, 1) +#define M4U_PORT_IMGO MTK_M4U_ID(M4U_LARB4_ID, 2) +#define M4U_PORT_IMG2O MTK_M4U_ID(M4U_LARB4_ID, 3) +#define M4U_PORT_LSCI MTK_M4U_ID(M4U_LARB4_ID, 4) +#define M4U_PORT_FLKI MTK_M4U_ID(M4U_LARB4_ID, 5) +#define M4U_PORT_LCEI MTK_M4U_ID(M4U_LARB4_ID, 6) +#define M4U_PORT_LCSO MTK_M4U_ID(M4U_LARB4_ID, 7) +#define M4U_PORT_ESFKO MTK_M4U_ID(M4U_LARB4_ID, 8) +#define M4U_PORT_AAO MTK_M4U_ID(M4U_LARB4_ID, 9) + +/* larb5 */ +#define M4U_PORT_AUDIO MTK_M4U_ID(M4U_LARB5_ID, 0) + +#endif From a1514b1c30c961daa1ecaf8703000275200b1b44 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 17:38:42 +0900 Subject: [PATCH 11/78] memory: mtk-smi: Add MT6572 support Add platform data for the SMI common on the MT6589 SoC. Signed-off-by: Akari Tsuyukusa --- drivers/memory/mtk-smi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 57f83836709961..6a72afe5175fbe 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -766,6 +766,10 @@ static struct platform_driver mtk_smi_larb_driver = { } }; +static const struct mtk_smi_reg_pair mtk_smi_common_mt6589_init[SMI_COMMON_INIT_REGS_NR] = { + {0x200, 0x24}, /* SMI_L1LEN */ +}; + static const struct mtk_smi_reg_pair mtk_smi_common_mt6795_init[SMI_COMMON_INIT_REGS_NR] = { {SMI_L1_ARB, 0x1b}, {SMI_M4U_TH, 0xce810c85}, @@ -790,6 +794,11 @@ static const struct mtk_smi_common_plat mtk_smi_common_gen2 = { .type = MTK_SMI_GEN2, }; +static const struct mtk_smi_common_plat mtk_smi_common_mt6589 = { + .type = MTK_SMI_GEN0, + .init = mtk_smi_common_mt6589_init, +}; + static const struct mtk_smi_common_plat mtk_smi_common_mt6779 = { .type = MTK_SMI_GEN2, .has_gals = true, @@ -870,6 +879,7 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8365 = { static const struct of_device_id mtk_smi_common_of_ids[] = { {.compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1}, {.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2}, + {.compatible = "mediatek,mt6572-smi-common", .data = &mtk_smi_common_mt6589}, {.compatible = "mediatek,mt6779-smi-common", .data = &mtk_smi_common_mt6779}, {.compatible = "mediatek,mt6795-smi-common", .data = &mtk_smi_common_mt6795}, {.compatible = "mediatek,mt6893-smi-common", .data = &mtk_smi_common_mt6893}, From 338e81491242448fd0c2ffce226ccb1b1c422dc6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Nov 2025 17:46:22 +0100 Subject: [PATCH 12/78] memory: mtk-smi: fix device leaks on common probe Make sure to drop the reference taken when looking up the SMI device during common probe on late probe failure (e.g. probe deferral) and on driver unbind. Fixes: 47404757702e ("memory: mtk-smi: Add device link for smi-sub-common") Fixes: 038ae37c510f ("memory: mtk-smi: add missing put_device() call in mtk_smi_device_link_common") Cc: stable@vger.kernel.org # 5.16: 038ae37c510f Cc: stable@vger.kernel.org # 5.16 Cc: Yong Wu Cc: Miaoqian Lin Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251121164624.13685-2-johan@kernel.org Signed-off-by: Krzysztof Kozlowski --- drivers/memory/mtk-smi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 6a72afe5175fbe..82281558fc4eea 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -706,6 +706,7 @@ static int mtk_smi_larb_probe(struct platform_device *pdev) err_pm_disable: pm_runtime_disable(dev); device_link_remove(dev, larb->smi_common_dev); + put_device(larb->smi_common_dev); return ret; } @@ -970,6 +971,7 @@ static void mtk_smi_common_remove(struct platform_device *pdev) if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) device_link_remove(&pdev->dev, common->smi_common_dev); pm_runtime_disable(&pdev->dev); + put_device(common->smi_common_dev); } static int __maybe_unused mtk_smi_common_resume(struct device *dev) From 70f743bc3dd6e77a8473a79a5af18064dcc2bbf9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Nov 2025 17:46:23 +0100 Subject: [PATCH 13/78] memory: mtk-smi: fix device leak on larb probe Make sure to drop the reference taken when looking up the SMI device during larb probe on late probe failure (e.g. probe deferral) and on driver unbind. Fixes: cc8bbe1a8312 ("memory: mediatek: Add SMI driver") Fixes: 038ae37c510f ("memory: mtk-smi: add missing put_device() call in mtk_smi_device_link_common") Cc: stable@vger.kernel.org # 4.6: 038ae37c510f Cc: stable@vger.kernel.org # 4.6 Cc: Yong Wu Cc: Miaoqian Lin Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251121164624.13685-3-johan@kernel.org Signed-off-by: Krzysztof Kozlowski --- drivers/memory/mtk-smi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 82281558fc4eea..782e561480c382 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -717,6 +717,7 @@ static void mtk_smi_larb_remove(struct platform_device *pdev) device_link_remove(&pdev->dev, larb->smi_common_dev); pm_runtime_disable(&pdev->dev); component_del(&pdev->dev, &mtk_smi_larb_component_ops); + put_device(larb->smi_common_dev); } static int __maybe_unused mtk_smi_larb_resume(struct device *dev) From 3f574163161265b2be6fa0d1cdfbb2827f9a4e61 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 21 Nov 2025 17:46:24 +0100 Subject: [PATCH 14/78] memory: mtk-smi: clean up device link creation Clean up device link creation by bailing out early in case the SMI platform device lookup fails. Signed-off-by: Johan Hovold Link: https://patch.msgid.link/20251121164624.13685-4-johan@kernel.org Signed-off-by: Krzysztof Kozlowski --- drivers/memory/mtk-smi.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 782e561480c382..e54436eb5cb538 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -627,25 +627,28 @@ static int mtk_smi_device_link_common(struct device *dev, struct device **com_de smi_com_pdev = of_find_device_by_node(smi_com_node); of_node_put(smi_com_node); - if (smi_com_pdev) { - /* smi common is the supplier, Make sure it is ready before */ - if (!platform_get_drvdata(smi_com_pdev)) { - put_device(&smi_com_pdev->dev); - return -EPROBE_DEFER; - } - smi_com_dev = &smi_com_pdev->dev; - link = device_link_add(dev, smi_com_dev, - DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); - if (!link) { - dev_err(dev, "Unable to link smi-common dev\n"); - put_device(&smi_com_pdev->dev); - return -ENODEV; - } - *com_dev = smi_com_dev; - } else { + if (!smi_com_pdev) { dev_err(dev, "Failed to get the smi_common device\n"); return -EINVAL; } + + /* smi common is the supplier, Make sure it is ready before */ + if (!platform_get_drvdata(smi_com_pdev)) { + put_device(&smi_com_pdev->dev); + return -EPROBE_DEFER; + } + + smi_com_dev = &smi_com_pdev->dev; + link = device_link_add(dev, smi_com_dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); + if (!link) { + dev_err(dev, "Unable to link smi-common dev\n"); + put_device(&smi_com_pdev->dev); + return -ENODEV; + } + + *com_dev = smi_com_dev; + return 0; } From 4b13f54cb20aeadd962f9a7cfe232f768c042e12 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 21:24:38 +0900 Subject: [PATCH 15/78] memory: mtk-smi: Add MT6589 larb support Signed-off-by: Akari Tsuyukusa --- drivers/memory/mtk-smi.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index e54436eb5cb538..ed92a16425ac3f 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -49,8 +49,13 @@ #define SMI_LARB_SW_FLAG 0x40 #define SMI_LARB_SW_FLAG_1 0x1 -#define SMI_LARB_BWFILTER_EN 0x60 -#define SMI_LARB_OSTD_CTRL_EN 0x64 +/* mt6589, mt8135 */ +#define SMI_LARB_BWFILTER_EN_V1 0x2c + +/* mt2601, mt6572, mt6571, mt6582, mt6592, mt8127 */ +#define SMI_LARB_BWFILTER_EN_V2 0x60 + +#define SMI_LARB_OSTD_CTRL_EN 0x64 #define SMI_LARB_OSTDL_PORT 0x200 #define SMI_LARB_OSTDL_PORTx(id) (SMI_LARB_OSTDL_PORT + (((id) & 0x1f) << 2)) @@ -98,7 +103,8 @@ #define MTK_SMI_FLAG_SW_FLAG BIT(1) #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) #define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) -#define MTK_SMI_FLAG_BW_CALIBRATE BIT(4) +#define MTK_SMI_FLAG_BW_CALIBRATE BIT(4) +#define MTK_SMI_FLAG_BWFILTER_REG_V2 BIT(5) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) struct mtk_smi_reg_pair { @@ -201,7 +207,7 @@ static int mtk_smi_larb_config_port_gen0(struct device *dev) struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev); const u8 *larbostd = larb_gen->ostd ? larb_gen->ostd[larb->larbid] : NULL; - int i, m4u_port_id, larb_port_num; + int i, m4u_port_id, larb_port_num, offset; u32 sec_con_val, reg_val, tmp; int ret; @@ -232,10 +238,16 @@ static int mtk_smi_larb_config_port_gen0(struct device *dev) /* some gen 0 SoCs need BW calibration */ if (MTK_SMI_CAPS(larb_gen->flags_general, MTK_SMI_FLAG_BW_CALIBRATE)) { + if (MTK_SMI_CAPS(larb_gen->flags_general, + MTK_SMI_FLAG_BWFILTER_REG_V2)) + offset = SMI_LARB_BWFILTER_EN_V2; + else + offset = SMI_LARB_BWFILTER_EN_V1; + reg_val = readl_relaxed(larb->base + SMI_LARB_STAT); if (!reg_val) { writel_relaxed(0xffffffff, - larb->base + SMI_LARB_BWFILTER_EN); + larb->base + offset); ret = readl_poll_timeout( larb->base + SMI_LARB_FIFO_STAT0, tmp, @@ -244,9 +256,9 @@ static int mtk_smi_larb_config_port_gen0(struct device *dev) dev_warn(dev, "BW limiter calibration timeout\n"); - writel_relaxed(0, larb->base + SMI_LARB_BWFILTER_EN); + writel_relaxed(0, larb->base + offset); writel_relaxed(0xffffffff, - larb->base + SMI_LARB_OSTD_CTRL_EN); + larb->base + offset); } } @@ -348,6 +360,8 @@ static int mtk_smi_larb_config_port_gen2_general(struct device *dev) return 0; } + + static const u8 mtk_smi_larb_mt6893_ostd[][SMI_LARB_PORT_NR_MAX] = { [0] = {0x2, 0x6, 0x2, 0x2, 0x2, 0x28, 0x18, 0x18, 0x1, 0x1, 0x1, 0x8, 0x8, 0x1, 0x3f}, @@ -524,6 +538,12 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = { .larb_direct_to_common_mask = BIT(8) | BIT(9), /* bdpsys */ }; +static const struct mtk_smi_larb_gen mtk_smi_larb_mt6589 = { + .port_in_larb = { 0, 10, 17, 29, 43, 53, 54, 54 }, + .config_port = mtk_smi_larb_config_port_gen0, + .flags_general = MTK_SMI_FLAG_BW_CALIBRATE, +}; + static const struct mtk_smi_larb_gen mtk_smi_larb_mt6779 = { .config_port = mtk_smi_larb_config_port_gen2_general, .larb_direct_to_common_mask = @@ -580,6 +600,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = { static const struct of_device_id mtk_smi_larb_of_ids[] = { {.compatible = "mediatek,mt2701-smi-larb", .data = &mtk_smi_larb_mt2701}, {.compatible = "mediatek,mt2712-smi-larb", .data = &mtk_smi_larb_mt2712}, + {.compatible = "mediatek,mt6589-smi-larb", .data = &mtk_smi_larb_mt6589}, {.compatible = "mediatek,mt6779-smi-larb", .data = &mtk_smi_larb_mt6779}, {.compatible = "mediatek,mt6795-smi-larb", .data = &mtk_smi_larb_mt8173}, {.compatible = "mediatek,mt6893-smi-larb", .data = &mtk_smi_larb_mt6893}, From 59153f6bf8cfe24f6f86cfd4ac4d4c71a0ee3474 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 21:32:48 +0900 Subject: [PATCH 16/78] dt-bindings: memory: mtk-smi: Add support for MT6589 Signed-off-by: Akari Tsuyukusa --- .../bindings/memory-controllers/mediatek,smi-common.yaml | 1 + .../bindings/memory-controllers/mediatek,smi-larb.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml index 0762e0ff66ef02..c7ecd9b0d5ccb0 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml @@ -31,6 +31,7 @@ properties: - enum: - mediatek,mt2701-smi-common - mediatek,mt2712-smi-common + - mediatek,mt6589-smi-common - mediatek,mt6779-smi-common - mediatek,mt6795-smi-common - mediatek,mt6893-smi-common diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml index 2e7fac4b50945d..0a4ea1865c2f64 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml @@ -19,6 +19,7 @@ properties: - enum: - mediatek,mt2701-smi-larb - mediatek,mt2712-smi-larb + - mediatek,mt6589-smi-larb - mediatek,mt6779-smi-larb - mediatek,mt6795-smi-larb - mediatek,mt6893-smi-larb From 1000ec858c7ec018184cb02909ea158d1527b1d4 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 21:35:50 +0900 Subject: [PATCH 17/78] dt-bindings: iommu: mediatek: Add binding for MT6589 M4U Signed-off-by: Akari Tsuyukusa --- Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml index 75750c64157c86..9f46549d17e4b5 100644 --- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml @@ -72,6 +72,7 @@ properties: - enum: - mediatek,mt2701-m4u # generation one - mediatek,mt2712-m4u # generation two + - mediatek,mt6589-m4u - mediatek,mt6779-m4u # generation two - mediatek,mt6795-m4u # generation two - mediatek,mt6893-iommu-mm # generation two From 5b7d09f0a88526bd43886cba5d7b07a572e3a98e Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 21:36:34 +0900 Subject: [PATCH 18/78] iommu: mtk_iommu_v1: add support for mt6589 Signed-off-by: Akari Tsuyukusa --- drivers/iommu/mtk_iommu_v1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 88ae00fbf78ba8..5fb334074f680a 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -627,6 +627,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = { static const struct of_device_id mtk_iommu_v1_of_ids[] = { { .compatible = "mediatek,mt2701-m4u", .data = (void *)MTK_IOMMU_V1 }, + { .compatible = "mediatek,mt6589-m4u", .data = (void *)MTK_IOMMU_MT65XX }, {} }; MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); From 8a8979447ce30f56fdfd36374a2b7ec5ba369bda Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 22:53:29 +0900 Subject: [PATCH 19/78] dt-bindings: arm: mediatek: mmsys: Add mt6589-dispsys compatible In MT6589, this IP is called "dispsys" for some reason. I don't know more than that. Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml index 3f4262e93c789c..5a57e918d65411 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml @@ -23,6 +23,7 @@ properties: - enum: - mediatek,mt2701-mmsys - mediatek,mt2712-mmsys + - mediatek,mt6589-dispsys - mediatek,mt6765-mmsys - mediatek,mt6779-mmsys - mediatek,mt6795-mmsys From 9a86b5f8ae146fa963a811e1ac39543d326b461c Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 22:57:35 +0900 Subject: [PATCH 20/78] dt-bindings: clock: mediatek: drop mediatek,mt6589-dispsys It's in Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml now. Signed-off-by: Akari Tsuyukusa --- Documentation/devicetree/bindings/clock/mediatek,syscon.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml b/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml index 38c107ca301c6b..03e0f69d30633a 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml @@ -28,7 +28,6 @@ properties: - mediatek,mt2712-mfgcfg - mediatek,mt2712-vdecsys - mediatek,mt2712-vencsys - - mediatek,mt6589-dispsys - mediatek,mt6589-imgsys - mediatek,mt6589-mfgsys - mediatek,mt6589-vdecsys From 8577ea9619d9b394769fbbdee0470b7f5da827c3 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sat, 14 Mar 2026 23:07:02 +0900 Subject: [PATCH 21/78] soc: mediatek: mmsys: init mt6589 support everyone will say "fixme" Signed-off-by: Akari Tsuyukusa --- drivers/soc/mediatek/mt6589-dispsys.h | 15 +++++++++++++++ drivers/soc/mediatek/mtk-mmsys.c | 8 ++++++++ 2 files changed, 23 insertions(+) create mode 100644 drivers/soc/mediatek/mt6589-dispsys.h diff --git a/drivers/soc/mediatek/mt6589-dispsys.h b/drivers/soc/mediatek/mt6589-dispsys.h new file mode 100644 index 00000000000000..581bd15116aa68 --- /dev/null +++ b/drivers/soc/mediatek/mt6589-dispsys.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2026 Akari Tsuyukusa + */ + +#ifndef __SOC_MEDIATEK_MT6589_DISPSYS_H +#define __SOC_MEDIATEK_MT6589_DISPSYS_H + +#include "mtk-mmsys.h" + +static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { + /* TODO */ +}; + +#endif /* __SOC_MEDIATEK_MT6589_DISPSYS_H */ diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index bb4639ca0b8cdc..c7695c5b963bf4 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -14,6 +14,7 @@ #include #include "mtk-mmsys.h" +#include "mt6589-dispsys.h" #include "mt8167-mmsys.h" #include "mt8173-mmsys.h" #include "mt8183-mmsys.h" @@ -37,6 +38,12 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = { .num_routes = ARRAY_SIZE(mmsys_default_routing_table), }; +static const struct mtk_mmsys_driver_data mt6572_dispsys_driver_data = { + .clk_driver = "clk-mt6589-disp", + .routes = mt6589_dispsys_routing_table, + //.num_routes = ARRAY_SIZE(mt6589_dispsys_routing_table), +}; + static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = { .clk_driver = "clk-mt6779-mm", }; @@ -458,6 +465,7 @@ static void mtk_mmsys_remove(struct platform_device *pdev) static const struct of_device_id of_match_mtk_mmsys[] = { { .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data }, { .compatible = "mediatek,mt2712-mmsys", .data = &mt2712_mmsys_driver_data }, + { .compatible = "mediatek,mt6589-dispsys", .data = &mt6572_dispsys_driver_data }, { .compatible = "mediatek,mt6779-mmsys", .data = &mt6779_mmsys_driver_data }, { .compatible = "mediatek,mt6795-mmsys", .data = &mt6795_mmsys_driver_data }, { .compatible = "mediatek,mt6797-mmsys", .data = &mt6797_mmsys_driver_data }, From 1c847498a5ff416c5e7288940e9305943854c2e5 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 00:44:13 +0900 Subject: [PATCH 22/78] drm: mediatek: dsi: add mt6589 support Signed-off-by: Akari Tsuyukusa --- drivers/gpu/drm/mediatek/mtk_dsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 4fe1f38a3c4b7f..ca88b3e9412a6d 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -1273,6 +1273,11 @@ static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = { .reg_shadow_dbg_off = 0x190 }; +static const struct mtk_dsi_driver_data mt6589_dsi_driver_data = { + .reg_cmdq_off = 0x180, + .reg_vm_cmd_off = 0x130, +}; + static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = { .reg_cmdq_off = 0x200, .reg_vm_cmd_off = 0x130, @@ -1301,6 +1306,7 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = { static const struct of_device_id mtk_dsi_of_match[] = { { .compatible = "mediatek,mt2701-dsi", .data = &mt2701_dsi_driver_data }, + { .compatible = "mediatek,mt6589-dsi", .data = &mt6589_dsi_driver_data }, { .compatible = "mediatek,mt8173-dsi", .data = &mt8173_dsi_driver_data }, { .compatible = "mediatek,mt8183-dsi", .data = &mt8183_dsi_driver_data }, { .compatible = "mediatek,mt8186-dsi", .data = &mt8186_dsi_driver_data }, From ee18d10735d8e227409e5c72644231119defca50 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 00:46:24 +0900 Subject: [PATCH 23/78] dt-bindings: display: mediatek: dsi: add mt6589 Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/display/mediatek/mediatek,dsi.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml index 27ffbccc2a082e..046b2d331c5c8a 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml @@ -24,6 +24,7 @@ properties: oneOf: - enum: - mediatek,mt2701-dsi + - mediatek,mt6589-dsi - mediatek,mt7623-dsi - mediatek,mt8167-dsi - mediatek,mt8173-dsi From a14c9a36f3bc54852fd038ab887c3344dcd6e6e7 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:14:22 +0900 Subject: [PATCH 24/78] drm: mediatek: ovl: add mt6589 support Signed-off-by: Akari Tsuyukusa --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 32cee6f4c9e9d4..931994e7e9e196 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -698,6 +698,18 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { .num_formats = ARRAY_SIZE(mt8173_formats), }; +static const struct mtk_disp_ovl_data mt6589_ovl_driver_data = { + .addr = DISP_REG_OVL_ADDR_MT2701, + .gmc_bits = 10, + .layer_nr = 4, + .fmt_rgb565_is_0 = false, + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | + BIT(DRM_MODE_BLEND_COVERAGE) | + BIT(DRM_MODE_BLEND_PIXEL_NONE), + .formats = mt8173_formats, + .num_formats = ARRAY_SIZE(mt8173_formats), +}; + static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { .addr = DISP_REG_OVL_ADDR_MT8173, .gmc_bits = 8, From 884d1bdfc725755d1dd44fec7a2fc0872c64ca15 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:20:04 +0900 Subject: [PATCH 25/78] drm: mediatek: ovl: add mt6589 of_device_id Signed-off-by: Akari Tsuyukusa --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 931994e7e9e196..99544a3e7ffd36 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -781,6 +781,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-ovl", .data = &mt2701_ovl_driver_data}, + { .compatible = "mediatek,mt6589-disp-ovl", + .data = &mt6589_ovl_driver_data}, { .compatible = "mediatek,mt8173-disp-ovl", .data = &mt8173_ovl_driver_data}, { .compatible = "mediatek,mt8183-disp-ovl", From 2126d785e59b62a429ace369829308c53767d737 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:21:30 +0900 Subject: [PATCH 26/78] dt-bindings: display: mediatek: ovl: add mt6589 Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/display/mediatek/mediatek,ovl.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml index 4f110635afb6a0..86f7799223f235 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml @@ -23,6 +23,7 @@ properties: oneOf: - enum: - mediatek,mt2701-disp-ovl + - mediatek,mt6589-disp-ovl - mediatek,mt8173-disp-ovl - mediatek,mt8183-disp-ovl - mediatek,mt8192-disp-ovl From 85f8fd80937f985e29704c728f228859d0d864ff Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:24:50 +0900 Subject: [PATCH 27/78] dt-bindings: soc: mediatek: mutex: add mt6589 Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/soc/mediatek/mediatek,mutex.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml index a10326a9683d62..11eff4cf0556d2 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml @@ -26,6 +26,7 @@ properties: enum: - mediatek,mt2701-disp-mutex - mediatek,mt2712-disp-mutex + - mediatek,mt6589-disp-mutex - mediatek,mt6795-disp-mutex - mediatek,mt8167-disp-mutex - mediatek,mt8173-disp-mutex From ae8d7b47fe1240129f7a6988d81f4714a6bc0d1b Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:35:19 +0900 Subject: [PATCH 28/78] WIP: soc: mediatek: mtk-mutex: add mt6589 support Signed-off-by: Akari Tsuyukusa --- drivers/soc/mediatek/mtk-mutex.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index aaa965d4b050a7..d8adca4d93c74d 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -377,6 +377,22 @@ static const u8 mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1, }; +static const u8 mt6589_mutex_mod[DDP_COMPONENT_ID_MAX] = { +/* +Bit 0: ROT +Bit 1: SCL +Bit 2: OVL +Bit 3: Color engine +Bit 4: 2D sharpness +Bit 5: WDMA0 +Bit 6: WDMA1 +Bit 7: RDMA0 +Bit 8: RDMA1 +Bit 9: BLS +Bit 10: GAMMA +*/ +}; + static const u8 mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = { [DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL, [DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR, @@ -724,6 +740,13 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = { .mutex_sof_reg = MT2701_MUTEX0_SOF0, }; +static const struct mtk_mutex_data mt6589_mutex_driver_data = { + .mutex_mod = mt6589_mutex_mod, + .mutex_sof = mt8167_mutex_sof, + .mutex_mod_reg = MT2701_MUTEX0_MOD0, + .mutex_sof_reg = MT2701_MUTEX0_SOF0, +}; + static const struct mtk_mutex_data mt6795_mutex_driver_data = { .mutex_mod = mt8173_mutex_mod, .mutex_sof = mt6795_mutex_sof, @@ -1129,6 +1152,7 @@ static int mtk_mutex_probe(struct platform_device *pdev) static const struct of_device_id mutex_driver_dt_match[] = { { .compatible = "mediatek,mt2701-disp-mutex", .data = &mt2701_mutex_driver_data }, { .compatible = "mediatek,mt2712-disp-mutex", .data = &mt2712_mutex_driver_data }, + { .compatible = "mediatek,mt6589-disp-mutex", .data = &mt6589_mutex_driver_data }, { .compatible = "mediatek,mt6795-disp-mutex", .data = &mt6795_mutex_driver_data }, { .compatible = "mediatek,mt8167-disp-mutex", .data = &mt8167_mutex_driver_data }, { .compatible = "mediatek,mt8173-disp-mutex", .data = &mt8173_mutex_driver_data }, From a98c1f1a3029c6d15a0e620755a9370b462b1497 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 01:54:35 +0900 Subject: [PATCH 29/78] soc: mediatek: mtk-mutex: add mt6589 support reviewer: Why didn't you #define it like other SoCs? Signed-off-by: Akari Tsuyukusa --- drivers/soc/mediatek/mtk-mutex.c | 24 +++++++++++------------- include/linux/soc/mediatek/mtk-mmsys.h | 3 +++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index d8adca4d93c74d..a8e65bfd543389 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -378,19 +378,17 @@ static const u8 mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { }; static const u8 mt6589_mutex_mod[DDP_COMPONENT_ID_MAX] = { -/* -Bit 0: ROT -Bit 1: SCL -Bit 2: OVL -Bit 3: Color engine -Bit 4: 2D sharpness -Bit 5: WDMA0 -Bit 6: WDMA1 -Bit 7: RDMA0 -Bit 8: RDMA1 -Bit 9: BLS -Bit 10: GAMMA -*/ + [DDP_COMPONENT_ROT] = 0, + [DDP_COMPONENT_SCL] = 1, + [DDP_COMPONENT_OVL0] = 2, + [DDP_COMPONENT_COLOR0] = 3, + [DDP_COMPONENT_2DSHARP] = 4, + [DDP_COMPONENT_WDMA0] = 5, + [DDP_COMPONENT_WDMA1] = 6, + [DDP_COMPONENT_RDMA0] = 7, + [DDP_COMPONENT_RDMA1] = 8, + [DDP_COMPONENT_BLS] = 9, + [DDP_COMPONENT_GAMMA] = 10, }; static const u8 mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = { diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 4885b065b849fb..7d32c37add14af 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -21,6 +21,7 @@ enum mtk_dpi_out_format_con { }; enum mtk_ddp_comp_id { + DDP_COMPONENT_2DSHARP, DDP_COMPONENT_AAL0, DDP_COMPONENT_AAL1, DDP_COMPONENT_BLS, @@ -78,6 +79,8 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_RDMA1, DDP_COMPONENT_RDMA2, DDP_COMPONENT_RDMA4, + DDP_COMPONENT_ROT, + DDP_COMPONENT_SCL, DDP_COMPONENT_UFOE, DDP_COMPONENT_WDMA0, DDP_COMPONENT_WDMA1, From f9252c215fa5f46ac3c516a2e7cb01719cca8d1c Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 21:51:06 +0900 Subject: [PATCH 30/78] Revert "arm: dts: mediatek: mt6589: fix scpsys address" This reverts commit f295374a0f69d4f9512da72f48f452c641033961. --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 83131c5548e1ae..62aef7c38718d5 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -116,7 +116,7 @@ scpsys: power-controller@10006000 { compatible = "mediatek,mt6589-scpsys", "syscon"; #power-domain-cells = <1>; - reg = <0x10006000 0x1000>; + reg = <0 0x10006000 0 0x1000>; infracfg = <&infracfg>; clocks = <&topckgen CLK_TOP_MUX_DISP>, <&topckgen CLK_TOP_MUX_VENC>, From 49fd4cb1efa67da2afa3324db11f9d38f998868e Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 21:51:10 +0900 Subject: [PATCH 31/78] Revert "pmdomain: mediatek: scpsys: init mt6589 support" This reverts commit 4db11bb51fc79c5a2d83d0dc735f310a99855e2a. --- .../bindings/soc/mediatek/scpsys.txt | 2 - arch/arm/boot/dts/mediatek/mt6589.dtsi | 11 --- arch/arm/configs/lenovo-blade_defconfig | 3 - drivers/pmdomain/mediatek/mtk-scpsys.c | 90 ------------------- include/dt-bindings/power/mt6589-power.h | 29 ------ 5 files changed, 135 deletions(-) delete mode 100644 include/dt-bindings/power/mt6589-power.h diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt index 4dc10acae474e5..3530a6668b4868 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -20,7 +20,6 @@ Required properties: - compatible: Should be one of: - "mediatek,mt2701-scpsys" - "mediatek,mt2712-scpsys" - - "mediatek,mt6589-scpsys" - "mediatek,mt6735-scpsys" - "mediatek,mt6765-scpsys" - "mediatek,mt6797-scpsys" @@ -37,7 +36,6 @@ Required properties: enabled before enabling certain power domains. Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif" Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec" - Required clocks for MT6589: "disp", "venc", "vdec" Required clocks for MT6765: MUX: "mm", "mfg" CG: "mm-0", "mm-1", "mm-2", "mm-3", "isp-0", "isp-1", "cam-0", "cam-1", "cam-2", diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 62aef7c38718d5..ce940c302fa618 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -113,17 +113,6 @@ #reset-cells = <1>; }; - scpsys: power-controller@10006000 { - compatible = "mediatek,mt6589-scpsys", "syscon"; - #power-domain-cells = <1>; - reg = <0 0x10006000 0 0x1000>; - infracfg = <&infracfg>; - clocks = <&topckgen CLK_TOP_MUX_DISP>, - <&topckgen CLK_TOP_MUX_VENC>, - <&topckgen CLK_TOP_MUX_VDEC>; - clock-names = "disp", "venc", "vdec"; - }; - mfgsys: syscon@10206000 { compatible = "mediatek,mt6589-mfgsys", "syscon"; reg = <0x10206000 0x1000>; diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index 341538ea4151fd..845e9dbdb7da12 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -119,9 +119,6 @@ CONFIG_BMC150_MAGN_I2C=y ## Reset #CONFIG_RESET_CONTROLLER -## Power Management -CONFIG_MTK_SCPSYS=y - ## Battery ## Regulator diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c index 2eac61cd00c88a..1a80c1537a43d2 100644 --- a/drivers/pmdomain/mediatek/mtk-scpsys.c +++ b/drivers/pmdomain/mediatek/mtk-scpsys.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -32,11 +31,8 @@ #define SPM_MFG_PWR_CON 0x0214 #define SPM_VEN_PWR_CON 0x0230 #define SPM_ISP_PWR_CON 0x0238 -#define SPM_IFR_PWR_CON 0x0234 /* MT6589 */ #define SPM_DIS_PWR_CON 0x023c -#define SPM_DPY_PWR_CON 0x0240 /* MT6589 */ #define SPM_CONN_PWR_CON 0x0280 -#define SPM_CONN2_PWR_CON 0x0284 /* MT6589 */ #define SPM_VEN2_PWR_CON 0x0298 #define SPM_AUDIO_PWR_CON 0x029c /* MT8173, MT2712 */ #define SPM_BDP_PWR_CON 0x029c /* MT2701 */ @@ -62,11 +58,9 @@ #define PWR_CLK_DIS_BIT BIT(4) #define PWR_STATUS_CONN BIT(1) -#define PWR_STATUS_DPY BIT(2) /* MT6589 */ #define PWR_STATUS_DISP BIT(3) #define PWR_STATUS_MFG BIT(4) #define PWR_STATUS_ISP BIT(5) -#define PWR_STATUS_IFR BIT(6) /* MT6589 */ #define PWR_STATUS_VDEC BIT(7) #define PWR_STATUS_BDP BIT(14) #define PWR_STATUS_ETH BIT(15) @@ -95,7 +89,6 @@ enum clk_id { CLK_HIFSEL, CLK_JPGDEC, CLK_AUDIO, - CLK_DISP, CLK_MAX, }; @@ -110,7 +103,6 @@ static const char * const clk_names[] = { "hif_sel", "jpgdec", "audio", - "disp", NULL, }; @@ -756,73 +748,6 @@ static const struct scp_subdomain scp_subdomain_mt2712[] = { {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3}, }; -/* - * MT6589 power domain support - */ -static const struct scp_domain_data scp_domain_data_mt6589[] = { - [MT6589_POWER_DOMAIN_MD1] = { - .name = "md1", - .sta_mask = PWR_STATUS_CONN, - .ctl_offs = SPM_CONN2_PWR_CON, /* not miss */ - .clk_id = {CLK_NONE}, - .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ - }, - [MT6589_POWER_DOMAIN_MD2] = { - .name = "md2", - .sta_mask = PWR_STATUS_CONN, - .ctl_offs = SPM_CONN_PWR_CON, - .clk_id = {CLK_NONE}, - .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ - }, - [MT6589_POWER_DOMAIN_DPY] = { - .name = "dpy", - .sta_mask = PWR_STATUS_DPY, - .ctl_offs = SPM_DPY_PWR_CON, - .clk_id = {CLK_NONE}, - .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ - }, - [MT6589_POWER_DOMAIN_DIS] = { - .name = "disp", - .sta_mask = PWR_STATUS_DISP, - .ctl_offs = SPM_DIS_PWR_CON, - .clk_id = {CLK_DISP}, - }, - [MT6589_POWER_DOMAIN_MFG] = { - .name = "mfg", - .sta_mask = PWR_STATUS_MFG, - .ctl_offs = SPM_MFG_PWR_CON, - .clk_id = {CLK_NONE}, - }, - [MT6589_POWER_DOMAIN_ISP] = { - .name = "isp", - .sta_mask = PWR_STATUS_ISP, - .ctl_offs = SPM_ISP_PWR_CON, - .clk_id = {CLK_NONE}, - }, - [MT6589_POWER_DOMAIN_IFR] = { - .name = "ifr", - .sta_mask = PWR_STATUS_IFR, - .ctl_offs = SPM_IFR_PWR_CON, - .clk_id = {CLK_NONE}, - .caps = MTK_SCPD_ACTIVE_WAKEUP, /* maybe */ - }, - [MT6589_POWER_DOMAIN_VEN] = { - .name = "venc", - .sta_mask = BIT(7), - .ctl_offs = SPM_VEN_PWR_CON, - .clk_id = {CLK_VENC}, - }, - [MT6589_POWER_DOMAIN_VDE] = { - .name = "vdec", - .sta_mask = BIT(8), - .ctl_offs = SPM_VDE_PWR_CON, - .clk_id = {CLK_VDEC}, - }, -}; - -static const struct scp_subdomain scp_subdomain_mt6589[] = { -}; - /* * MT6797 power domain support */ @@ -1106,18 +1031,6 @@ static const struct scp_soc_data mt2712_data = { .bus_prot_reg_update = false, }; -static const struct scp_soc_data mt6589_data = { - .domains = scp_domain_data_mt6589, - .num_domains = ARRAY_SIZE(scp_domain_data_mt6589), - .subdomains = scp_subdomain_mt6589, - .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6589), - .regs = { -// .pwr_sta_offs = SPM_PWR_STATUS, -// .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND - }, -// .bus_prot_reg_update = false, -}; - static const struct scp_soc_data mt6797_data = { .domains = scp_domain_data_mt6797, .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), @@ -1173,9 +1086,6 @@ static const struct of_device_id of_scpsys_match_tbl[] = { }, { .compatible = "mediatek,mt2712-scpsys", .data = &mt2712_data, - }, { - .compatible = "mediatek,mt6589-scpsys", - .data = &mt6589_data, }, { .compatible = "mediatek,mt6797-scpsys", .data = &mt6797_data, diff --git a/include/dt-bindings/power/mt6589-power.h b/include/dt-bindings/power/mt6589-power.h deleted file mode 100644 index 39649b4805572f..00000000000000 --- a/include/dt-bindings/power/mt6589-power.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2026 akku - */ - -#ifndef _DT_BINDINGS_POWER_MT6589_POWER_H -#define _DT_BINDINGS_POWER_MT6589_POWER_H - -/* - * FC0 - * DBG - * CPU - * FC1 - * FC2 - * FC3 - * IFR_FH - */ - -#define MT6589_POWER_DOMAIN_MD1 0 -#define MT6589_POWER_DOMAIN_MD2 1 -#define MT6589_POWER_DOMAIN_DPY 2 -#define MT6589_POWER_DOMAIN_DIS 3 -#define MT6589_POWER_DOMAIN_MFG 4 -#define MT6589_POWER_DOMAIN_ISP 5 -#define MT6589_POWER_DOMAIN_IFR 6 -#define MT6589_POWER_DOMAIN_VEN 7 -#define MT6589_POWER_DOMAIN_VDE 8 - -#endif /* _DT_BINDINGS_POWER_MT6589_POWER_H */ From b743c8864b3a70aa6c10676250761d748b7917f3 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 21:55:55 +0900 Subject: [PATCH 32/78] dt-bindings: power: mediatek: add mt6589 scpsys Signed-off-by: Akari Tsuyukusa --- .../devicetree/bindings/power/mediatek,power-controller.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml index 9c7cc632abee25..b73d05000acc05 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -23,6 +23,7 @@ properties: compatible: enum: + - mediatek,mt6589-power-controller - mediatek,mt6735-power-controller - mediatek,mt6795-power-controller - mediatek,mt6893-power-controller From 38192bb41a8f835ecb3925961587f1bead915f2f Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 22:18:08 +0900 Subject: [PATCH 33/78] arm: defconfig: lenovo-blade: add CONFIG_MTK_SCPSYS_PM_DOMAINS Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index 845e9dbdb7da12..a676f3adacf808 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -119,6 +119,9 @@ CONFIG_BMC150_MAGN_I2C=y ## Reset #CONFIG_RESET_CONTROLLER +## Power Management +CONFIG_MTK_SCPSYS_PM_DOMAINS=y + ## Battery ## Regulator From 6fa87541a6673034113ab7ab9166d1875873ad76 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Sun, 15 Mar 2026 23:03:51 +0900 Subject: [PATCH 34/78] dt-bindings: power: add mt6589 header Signed-off-by: Akari Tsuyukusa --- include/dt-bindings/power/mt6589-power.h | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/dt-bindings/power/mt6589-power.h diff --git a/include/dt-bindings/power/mt6589-power.h b/include/dt-bindings/power/mt6589-power.h new file mode 100644 index 00000000000000..c08efb8724f11c --- /dev/null +++ b/include/dt-bindings/power/mt6589-power.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DT_BINDINGS_POWER_MT6589_POWER_H +#define _DT_BINDINGS_POWER_MT6589_POWER_H + +/* + * FC0 + * DBG + * CPU + * FC1 + * FC2 + * FC3 + * IFR_FH + */ + +#define MT6589_POWER_DOMAIN_MD1 0 +#define MT6589_POWER_DOMAIN_MD2 1 +#define MT6589_POWER_DOMAIN_DPY 2 +#define MT6589_POWER_DOMAIN_DIS 3 +#define MT6589_POWER_DOMAIN_MFG 4 +#define MT6589_POWER_DOMAIN_ISP 5 +#define MT6589_POWER_DOMAIN_IFR 6 +#define MT6589_POWER_DOMAIN_VEN 7 +#define MT6589_POWER_DOMAIN_VDE 8 + +#endif /* _DT_BINDINGS_POWER_MT6589_POWER_H */ From 344f792563054e7a65ad3caf1fab0d883fff0a61 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 00:36:06 +0900 Subject: [PATCH 35/78] dt-bindings: power: mt6589 fix Signed-off-by: Akari Tsuyukusa --- include/dt-bindings/power/mt6589-power.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/include/dt-bindings/power/mt6589-power.h b/include/dt-bindings/power/mt6589-power.h index c08efb8724f11c..14d2c941015543 100644 --- a/include/dt-bindings/power/mt6589-power.h +++ b/include/dt-bindings/power/mt6589-power.h @@ -1,18 +1,8 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ #ifndef _DT_BINDINGS_POWER_MT6589_POWER_H #define _DT_BINDINGS_POWER_MT6589_POWER_H -/* - * FC0 - * DBG - * CPU - * FC1 - * FC2 - * FC3 - * IFR_FH - */ - #define MT6589_POWER_DOMAIN_MD1 0 #define MT6589_POWER_DOMAIN_MD2 1 #define MT6589_POWER_DOMAIN_DPY 2 From 2226da6d1d797591d7780a8852d5ba2d8bc32367 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 00:39:47 +0900 Subject: [PATCH 36/78] pmdomain: mediatek: Add MT6589 support (wip?) because bp_cfg are not configured Signed-off-by: Akari Tsuyukusa --- drivers/pmdomain/mediatek/mt6589-pm-domains.h | 131 ++++++++++++++++++ drivers/pmdomain/mediatek/mtk-pm-domains.c | 24 +++- drivers/pmdomain/mediatek/mtk-pm-domains.h | 3 + 3 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 drivers/pmdomain/mediatek/mt6589-pm-domains.h diff --git a/drivers/pmdomain/mediatek/mt6589-pm-domains.h b/drivers/pmdomain/mediatek/mt6589-pm-domains.h new file mode 100644 index 00000000000000..6d0f9b14049ddb --- /dev/null +++ b/drivers/pmdomain/mediatek/mt6589-pm-domains.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT6589_PM_DOMAINS_H +#define __SOC_MEDIATEK_MT6589_PM_DOMAINS_H + +#include "mtk-pm-domains.h" +#include + +/* + * MT6589 power domain support + */ + +static const struct scpsys_domain_data scpsys_domain_data_mt6589[] = { + [MT6589_POWER_DOMAIN_MD1] = { + .name = "md1", + .sta_mask = PWR_STATUS_MD1, + .ctl_offs = SPM_MD1_PWR_CON, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = 0, /* don't have */ + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + /* + .bp_cfg = { + BUS_PROT_INFRA_UPDATE_TOPAXI(MT6589_TOP_AXI_PROT_EN_MD1), + }, + */ + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_MD2] = { + .name = "md2", + .sta_mask = PWR_STATUS_CONN, + .ctl_offs = SPM_CONN_PWR_CON, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = 0, /* don't have */ + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + /* + .bp_cfg = { + BUS_PROT_INFRA_UPDATE_TOPAXI(MT6589_TOP_AXI_PROT_EN_MD2), + }, + */ + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_DPY] = { + .name = "dpy", + .sta_mask = PWR_STATUS_DDRPHY, + .ctl_offs = 0x0240, + .caps = MTK_SCPD_ALWAYS_ON | MTK_SCPD_NO_SRAM, + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_DIS] = { + .name = "dis", + .sta_mask = PWR_STATUS_DISP, + .ctl_offs = SPM_DIS_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + /* + .bp_cfg = { + BUS_PROT_INFRA_UPDATE_TOPAXI(MT6589_TOP_AXI_PROT_EN_DIS), + }, + */ + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_MFG] = { + .name = "mfg", + .sta_mask = PWR_STATUS_MFG, + .ctl_offs = SPM_MFG_PWR_CON, + .sram_pdn_bits = BIT(8), + .sram_pdn_ack_bits = BIT(12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + /* + .bp_cfg = { + BUS_PROT_INFRA_UPDATE_TOPAXI(TODO), + }, + */ + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_ISP] = { + .name = "isp", + .sta_mask = PWR_STATUS_ISP, + .ctl_offs = SPM_ISP_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + /* + .bp_cfg = BUS_PROT_INFRA_UPDATE_TOPAXI(TODO), img_s_prot_en?, + */ + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_IFR] = { + .name = "ifr", + .sta_mask = PWR_STATUS_INFRASYS, + .ctl_offs = 0x0234, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .caps = MTK_SCPD_ALWAYS_ON, + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_VEN] = { + .name = "ven", + .sta_mask = BIT(7), + .ctl_offs = SPM_VEN_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, + [MT6589_POWER_DOMAIN_VDE] = { + .name = "vde", + .sta_mask = BIT(8), + .ctl_offs = SPM_VDE_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .caps = MTK_SCPD_KEEP_DEFAULT_OFF, + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, + }, +}; + +static const struct scpsys_soc_data mt6589_scpsys_data = { + .domains_data = scpsys_domain_data_mt6589, + .num_domains = ARRAY_SIZE(scpsys_domain_data_mt6589), +}; + +#endif /* __SOC_MEDIATEK_MT6589_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c index a58ed7e2d9a479..803ff168651927 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -16,6 +16,7 @@ #include #include +#include "mt6589-pm-domains.h" #include "mt6735-pm-domains.h" #include "mt6795-pm-domains.h" #include "mt6893-pm-domains.h" @@ -277,9 +278,11 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) goto err_pwr_ack; } - ret = scpsys_sram_enable(pd); - if (ret < 0) - goto err_disable_subsys_clks; + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_NO_SRAM)) { + ret = scpsys_sram_enable(pd); + if (ret < 0) + goto err_disable_subsys_clks; + } ret = scpsys_bus_protect_disable(pd); if (ret < 0) @@ -297,7 +300,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) err_enable_bus_protect: scpsys_bus_protect_enable(pd); err_disable_sram: - scpsys_sram_disable(pd); + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_NO_SRAM)) + scpsys_sram_disable(pd); err_disable_subsys_clks: if (!MTK_SCPD_CAPS(pd, MTK_SCPD_STRICT_BUS_PROTECTION)) clk_bulk_disable_unprepare(pd->num_subsys_clks, @@ -320,9 +324,11 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) if (ret < 0) return ret; - ret = scpsys_sram_disable(pd); - if (ret < 0) - return ret; + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_NO_SRAM)) { + ret = scpsys_sram_disable(pd); + if (ret < 0) + return ret; + } if (pd->data->ext_buck_iso_offs && MTK_SCPD_CAPS(pd, MTK_SCPD_EXT_BUCK_ISO)) regmap_set_bits(scpsys->base, pd->data->ext_buck_iso_offs, @@ -616,6 +622,10 @@ static void scpsys_domain_cleanup(struct scpsys *scpsys) } static const struct of_device_id scpsys_of_match[] = { + { + .compatible = "mediatek,mt6589-power-controller", + .data = &mt6589_scpsys_data, + }, { .compatible = "mediatek,mt6735-power-controller", .data = &mt6735_scpsys_data, diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h index 7085fa2976e98b..8679302c10217f 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.h +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h @@ -13,6 +13,7 @@ #define MTK_SCPD_EXT_BUCK_ISO BIT(6) #define MTK_SCPD_HAS_INFRA_NAO BIT(7) #define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8) +#define MTK_SCPD_NO_SRAM BIT(10) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) #define SPM_VDE_PWR_CON 0x0210 @@ -33,9 +34,11 @@ #define PWR_STATUS_MD1 BIT(0) #define PWR_STATUS_CONN BIT(1) +#define PWR_STATUS_DDRPHY BIT(2) #define PWR_STATUS_DISP BIT(3) #define PWR_STATUS_MFG BIT(4) #define PWR_STATUS_ISP BIT(5) +#define PWR_STATUS_INFRASYS BIT(6) #define PWR_STATUS_VDEC BIT(7) #define PWR_STATUS_VENC_LT BIT(20) #define PWR_STATUS_VENC BIT(21) From 45fe3ad2d9cc2791ee3e23d157a8f8280f3fd349 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 01:05:00 +0900 Subject: [PATCH 37/78] arm: dts: mediatek: mt6589: add scpsys Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 68 ++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index ce940c302fa618..60da1f25c9f2dc 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -113,6 +114,73 @@ #reset-cells = <1>; }; + scpsys: syscon@10006000 { + compatible = "syscon", "simple-mfd"; + reg = <0x10006000 0x1000>; + #power-domain-cells = <1>; + + spm: power-controller { + compatible = "mediatek,mt6589-power-controller"; + #address-cells = <1>; + #size-cells = <0>; + #power-domain-cells = <1>; + + power-domain@MT6589_POWER_DOMAIN_MD1 { + reg = ; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_MD2 { + reg = ; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_DPY { + reg = ; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_DIS { + reg = ; + clocks = <&topckgen CLK_TOP_MUX_DISP>; + clock-names = "disp"; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_MFG { + reg = ; + clocks = <&topckgen CLK_TOP_MUX_MFG>, + <&topckgen CLK_TOP_MUX_SMI_MFG_AS>; + clock-names = "mfg", "mfg_as"; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_ISP { + reg = ; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_IFR { + reg = ; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_VEN { + reg = ; + clocks = <&topckgen CLK_TOP_MUX_VENC>; + clock-names = "venc"; + #power-domain-cells = <0>; + }; + + power-domain@MT6589_POWER_DOMAIN_VDE { + reg = ; + clocks = <&topckgen CLK_TOP_MUX_VDEC>; + clock-names = "vdec"; + #power-domain-cells = <0>; + }; + }; + }; + mfgsys: syscon@10206000 { compatible = "mediatek,mt6589-mfgsys", "syscon"; reg = <0x10206000 0x1000>; From 47de86775790b97154c7831607778c4f9f31cf19 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 10:02:34 +0900 Subject: [PATCH 38/78] dt-bindings: display: mediatek: rdma: add mt6589 --- .../devicetree/bindings/display/mediatek/mediatek,rdma.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml index 878f676b581f95..8150655a0d2b41 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml @@ -25,6 +25,7 @@ properties: oneOf: - enum: - mediatek,mt2701-disp-rdma + - mediatek,mt6589-disp-rdma - mediatek,mt8173-disp-rdma - mediatek,mt8183-disp-rdma - mediatek,mt8195-disp-rdma From c7048f2247d73834311189be2c7bb59327d54bab Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 10:44:07 +0900 Subject: [PATCH 39/78] soc: mediatek: mmsys: fix mt6589 --- drivers/soc/mediatek/mtk-mmsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index c7695c5b963bf4..5597fceb26ace1 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -41,7 +41,7 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = { static const struct mtk_mmsys_driver_data mt6572_dispsys_driver_data = { .clk_driver = "clk-mt6589-disp", .routes = mt6589_dispsys_routing_table, - //.num_routes = ARRAY_SIZE(mt6589_dispsys_routing_table), + .num_routes = ARRAY_SIZE(mt6589_dispsys_routing_table), }; static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = { From 0df3f803602a538c9fda42c714da4d1a8373d538 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 10:48:24 +0900 Subject: [PATCH 40/78] soc: mediatek: mt6589-dispsys: add routing table thanks to Claude --- drivers/soc/mediatek/mt6589-dispsys.h | 163 +++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/drivers/soc/mediatek/mt6589-dispsys.h b/drivers/soc/mediatek/mt6589-dispsys.h index 581bd15116aa68..5adffcd7e41d2e 100644 --- a/drivers/soc/mediatek/mt6589-dispsys.h +++ b/drivers/soc/mediatek/mt6589-dispsys.h @@ -8,8 +8,169 @@ #include "mtk-mmsys.h" +/* + * MT6589 display pipeline overview: + * + * Main path (OVL → LCD): + * OVL → COLOR → BLS → RDMA0 → DSI0 + * OVL → COLOR → BLS → RDMA0 → DBI + * OVL → COLOR → BLS → RDMA0 → DPI0 + * + * Memory-out path (concurrent with main path): + * OVL → WDMA1 + * + * Direct RDMA1 paths (bypass OVL/COLOR/BLS): + * RDMA1 → DPI0 + * RDMA1 → DPI1 + * + * MDP path: + * SCL → WDMA0 + * + * Routing register bit/value summary (from vendor disp_path_config_()): + * + * OVL_MOUT_EN GENMASK(2,0) bit[0]=WDMA1, bit[2]=COLOR + * COLOR_MOUT_EN GENMASK(3,0) bit[3]=BLS + * COLOR_SEL 0x1 0x1=from OVL + * BLS_SEL 0x1 0x1=from COLOR + * RDMA0_OUT_SEL 0x3 0x0=DSI0, 0x1=DBI, 0x2=DPI0 + * RDMA1_OUT_SEL 0x3 0x1=DPI0, 0x2=DPI1 + * DPI0_SEL 0x1 0x0=RDMA0, 0x1=RDMA1 + * DBI_SEL 0x1 0x0=RDMA0 + * SCL_MOUT_EN BIT(0) bit[0]=WDMA0 + * WDMA0_SEL 0x1 0x0=SCL + * + * NOTE: Register offsets below are placeholders (0x000). + * Fill them in from the MT6589 MMSYS (DISP_REG_CONFIG_*) register map. + */ + +/* TODO: replace each 0x000 with the real MMSYS register offset */ +#define MT6589_DISP_OVL_MOUT_EN 0x000 /* TODO */ +#define MT6589_DISP_COLOR_MOUT_EN 0x000 /* TODO */ +#define MT6589_DISP_COLOR_SEL_IN 0x000 /* TODO */ +#define MT6589_DISP_BLS_SEL_IN 0x000 /* TODO */ +#define MT6589_DISP_RDMA0_SOUT_SEL 0x000 /* TODO */ +#define MT6589_DISP_RDMA1_SOUT_SEL 0x000 /* TODO */ +#define MT6589_DISP_DPI0_SEL_IN 0x000 /* TODO */ +#define MT6589_DISP_DBI_SEL_IN 0x000 /* TODO */ +#define MT6589_DISP_SCL_MOUT_EN 0x000 /* TODO */ +#define MT6589_DISP_WDMA0_SEL_IN 0x000 /* TODO */ + +/* OVL_MOUT_EN */ +#define MT6589_OVL_MOUT_EN_WDMA1 BIT(0) +#define MT6589_OVL_MOUT_EN_COLOR BIT(2) +#define MT6589_OVL_MOUT_EN_MASK GENMASK(2, 0) + +/* COLOR_MOUT_EN */ +#define MT6589_COLOR_MOUT_EN_BLS BIT(3) +#define MT6589_COLOR_MOUT_EN_MASK GENMASK(3, 0) + +/* COLOR_SEL_IN */ +#define MT6589_COLOR_SEL_IN_OVL 0x1 +#define MT6589_COLOR_SEL_IN_MASK 0x1 + +/* BLS_SEL_IN */ +#define MT6589_BLS_SEL_IN_COLOR 0x1 +#define MT6589_BLS_SEL_IN_MASK 0x1 + +/* RDMA0_SOUT_SEL */ +#define MT6589_RDMA0_SOUT_DBI 0x1 +#define MT6589_RDMA0_SOUT_DPI0 0x2 +#define MT6589_RDMA0_SOUT_MASK 0x3 + +/* RDMA1_SOUT_SEL */ +#define MT6589_RDMA1_SOUT_DPI0 0x1 +#define MT6589_RDMA1_SOUT_DPI1 0x2 +#define MT6589_RDMA1_SOUT_MASK 0x3 + +/* DPI0_SEL_IN */ +#define MT6589_DPI0_SEL_IN_RDMA1 0x1 +#define MT6589_DPI0_SEL_IN_MASK 0x1 + +/* SCL_MOUT_EN */ +#define MT6589_SCL_MOUT_EN_WDMA0 BIT(0) +#define MT6589_SCL_MOUT_EN_MASK BIT(0) + static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { - /* TODO */ + /* + * Main path step 1: OVL output → COLOR + * OVL_MOUT_EN selects COLOR as the downstream engine. + * COLOR_SEL_IN confirms OVL as the upstream source. + */ + MMSYS_ROUTE(OVL0, COLOR0, + MT6589_DISP_OVL_MOUT_EN, + MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_COLOR), + MMSYS_ROUTE(OVL0, COLOR0, + MT6589_DISP_COLOR_SEL_IN, + MT6589_COLOR_SEL_IN_MASK, MT6589_COLOR_SEL_IN_OVL), + + /* + * Main path step 2: COLOR output → BLS + * COLOR_MOUT_EN selects BLS as the downstream engine. + * BLS_SEL_IN confirms COLOR as the upstream source. + */ + MMSYS_ROUTE(COLOR0, BLS, + MT6589_DISP_COLOR_MOUT_EN, + MT6589_COLOR_MOUT_EN_MASK, MT6589_COLOR_MOUT_EN_BLS), + MMSYS_ROUTE(COLOR0, BLS, + MT6589_DISP_BLS_SEL_IN, + MT6589_BLS_SEL_IN_MASK, MT6589_BLS_SEL_IN_COLOR), + + /* + * Main path step 3: RDMA0 output → DSI0 / DBI / DPI0 + * BLS feeds RDMA0 via direct-link (no SEL register needed). + * RDMA0_SOUT_SEL steers RDMA0's output to the target interface. + * + * DSI0: default output selection (val=0x0); no SOUT entry needed + * as the hardware resets to DSI0. Only the MOUT/SEL entries for + * the OVL→COLOR and COLOR→BLS hops are required for this path. + */ + + /* RDMA0 → DBI */ + MMSYS_ROUTE(RDMA0, DBI, + MT6589_DISP_RDMA0_SOUT_SEL, + MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DBI), + + /* RDMA0 → DPI0 (OVL-sourced) */ + MMSYS_ROUTE(RDMA0, DPI0, + MT6589_DISP_RDMA0_SOUT_SEL, + MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DPI0), + + /* + * Memory-out path: OVL → WDMA1 + * Allows screen-capture concurrently with the main LCD path. + * Enabled by setting bit[0] of OVL_MOUT_EN alongside bit[2]. + */ + MMSYS_ROUTE(OVL0, WDMA1, + MT6589_DISP_OVL_MOUT_EN, + MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_WDMA1), + + /* + * Direct RDMA1 paths: bypass OVL/COLOR/BLS entirely. + * Used for external display (e.g. HDMI via bridge chip). + */ + + /* RDMA1 → DPI0 */ + MMSYS_ROUTE(RDMA1, DPI0, + MT6589_DISP_RDMA1_SOUT_SEL, + MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI0), + MMSYS_ROUTE(RDMA1, DPI0, + MT6589_DISP_DPI0_SEL_IN, + MT6589_DPI0_SEL_IN_MASK, MT6589_DPI0_SEL_IN_RDMA1), + + /* RDMA1 → DPI1 */ + MMSYS_ROUTE(RDMA1, DPI1, + MT6589_DISP_RDMA1_SOUT_SEL, + MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI1), + + /* + * MDP path: SCL → WDMA0 + * Used for MDP (Media Data Path) scaling + write-back. + * ROT feeds SCL; SCL_MOUT_EN routes the output to WDMA0. + * WDMA0_SEL_IN defaults to SCL (val=0x0); no SEL entry needed. + */ + MMSYS_ROUTE(SCL, WDMA0, + MT6589_DISP_SCL_MOUT_EN, + MT6589_SCL_MOUT_EN_MASK, MT6589_SCL_MOUT_EN_WDMA0), }; #endif /* __SOC_MEDIATEK_MT6589_DISPSYS_H */ From c196931261ec343e18bc683b144b79aeede6cdfd Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 11:10:48 +0900 Subject: [PATCH 41/78] soc: mediatek: mt6589-dispsys: fill out register address --- drivers/soc/mediatek/mt6589-dispsys.h | 34 ++++++++++++--------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/soc/mediatek/mt6589-dispsys.h b/drivers/soc/mediatek/mt6589-dispsys.h index 5adffcd7e41d2e..cf1d0c9e6ec110 100644 --- a/drivers/soc/mediatek/mt6589-dispsys.h +++ b/drivers/soc/mediatek/mt6589-dispsys.h @@ -38,22 +38,18 @@ * DBI_SEL 0x1 0x0=RDMA0 * SCL_MOUT_EN BIT(0) bit[0]=WDMA0 * WDMA0_SEL 0x1 0x0=SCL - * - * NOTE: Register offsets below are placeholders (0x000). - * Fill them in from the MT6589 MMSYS (DISP_REG_CONFIG_*) register map. */ -/* TODO: replace each 0x000 with the real MMSYS register offset */ -#define MT6589_DISP_OVL_MOUT_EN 0x000 /* TODO */ -#define MT6589_DISP_COLOR_MOUT_EN 0x000 /* TODO */ -#define MT6589_DISP_COLOR_SEL_IN 0x000 /* TODO */ -#define MT6589_DISP_BLS_SEL_IN 0x000 /* TODO */ -#define MT6589_DISP_RDMA0_SOUT_SEL 0x000 /* TODO */ -#define MT6589_DISP_RDMA1_SOUT_SEL 0x000 /* TODO */ -#define MT6589_DISP_DPI0_SEL_IN 0x000 /* TODO */ -#define MT6589_DISP_DBI_SEL_IN 0x000 /* TODO */ -#define MT6589_DISP_SCL_MOUT_EN 0x000 /* TODO */ -#define MT6589_DISP_WDMA0_SEL_IN 0x000 /* TODO */ +#define MT6589_DISP_SCL_MOUT_EN 0x020 +#define MT6589_DISP_OVL_MOUT_EN 0x024 +#define MT6589_DISP_COLOR_MOUT_EN 0x028 +#define MT6589_DISP_RDMA0_OUT_SEL 0x034 +#define MT6589_DISP_RDMA1_OUT_SEL 0x038 +#define MT6589_DISP_WDMA0_SEL_IN 0x040 +#define MT6589_DISP_COLOR_SEL_IN 0x04c +#define MT6589_DISP_BLS_SEL_IN 0x054 +#define MT6589_DISP_DPI0_SEL_IN 0x05c +#define MT6589_DISP_DBI_SEL_IN 0x058 /* OVL_MOUT_EN */ #define MT6589_OVL_MOUT_EN_WDMA1 BIT(0) @@ -101,7 +97,7 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_COLOR), MMSYS_ROUTE(OVL0, COLOR0, MT6589_DISP_COLOR_SEL_IN, - MT6589_COLOR_SEL_IN_MASK, MT6589_COLOR_SEL_IN_OVL), + MT6589_COLOR_SEL_IN_MASK, MT6589_COLOR_SEL_IN_OVL), /* * Main path step 2: COLOR output → BLS @@ -127,12 +123,12 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { /* RDMA0 → DBI */ MMSYS_ROUTE(RDMA0, DBI, - MT6589_DISP_RDMA0_SOUT_SEL, + MT6589_DISP_RDMA0_OUT_SEL, MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DBI), /* RDMA0 → DPI0 (OVL-sourced) */ MMSYS_ROUTE(RDMA0, DPI0, - MT6589_DISP_RDMA0_SOUT_SEL, + MT6589_DISP_RDMA0_OUT_SEL, MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DPI0), /* @@ -151,7 +147,7 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { /* RDMA1 → DPI0 */ MMSYS_ROUTE(RDMA1, DPI0, - MT6589_DISP_RDMA1_SOUT_SEL, + MT6589_DISP_RDMA1_OUT_SEL , MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI0), MMSYS_ROUTE(RDMA1, DPI0, MT6589_DISP_DPI0_SEL_IN, @@ -159,7 +155,7 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { /* RDMA1 → DPI1 */ MMSYS_ROUTE(RDMA1, DPI1, - MT6589_DISP_RDMA1_SOUT_SEL, + MT6589_DISP_RDMA1_OUT_SEL , MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI1), /* From b0f7fd343c784bbb4eee947c608cf062aff62932 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 11:21:31 +0900 Subject: [PATCH 42/78] drm: mediatek: mtk_drm_drv: add mt6589 support TODO: remove TODO --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 7c0c12dde48859..93bf8267c12c84 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -334,6 +334,8 @@ static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = { static const struct of_device_id mtk_drm_of_ids[] = { { .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data}, + { .compatible = "mediatek,mt6589-dispsys", + .data = &mt2701_mmsys_driver_data}, /* TODO */ { .compatible = "mediatek,mt7623-mmsys", .data = &mt7623_mmsys_driver_data}, { .compatible = "mediatek,mt2712-mmsys", @@ -761,6 +763,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt2712-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, + { .compatible = "mediatek,mt6589-disp-mutex", + .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8167-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8173-disp-mutex", @@ -781,6 +785,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_OD }, { .compatible = "mediatek,mt2701-disp-ovl", .data = (void *)MTK_DISP_OVL }, + { .compatible = "mediatek,mt6589-disp-ovl", + .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8167-disp-ovl", .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8173-disp-ovl", @@ -805,6 +811,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DISP_PWM }, { .compatible = "mediatek,mt2701-disp-rdma", .data = (void *)MTK_DISP_RDMA }, + { .compatible = "mediatek,mt6589-disp-rdma", + .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8167-disp-rdma", .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8173-disp-rdma", @@ -837,6 +845,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DPI }, { .compatible = "mediatek,mt2701-dsi", .data = (void *)MTK_DSI }, + { .compatible = "mediatek,mt6589-dsi", + .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8173-dsi", .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8183-dsi", From 9a0a3d7337abb9dea675e7314bfe7920be3e7bf1 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 11:33:42 +0900 Subject: [PATCH 43/78] dt-bindings: memory: mt6589-larb-port: add MT6589_ prefix --- include/dt-bindings/memory/mt6589-larb-port.h | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/include/dt-bindings/memory/mt6589-larb-port.h b/include/dt-bindings/memory/mt6589-larb-port.h index 2b5a0da3bac7b6..deceae8d94f6a1 100644 --- a/include/dt-bindings/memory/mt6589-larb-port.h +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -16,69 +16,69 @@ #define M4U_LARB5_ID 5 /* larb0 */ -#define M4U_PORT_VENC_RCPU MTK_M4U_ID(M4U_LARB0_ID, 0) -#define M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB0_ID, 1) -#define M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) -#define M4U_PORT_VENC_DB_READ MTK_M4U_ID(M4U_LARB0_ID, 3) -#define M4U_PORT_VENC_DB_WRITE MTK_M4U_ID(M4U_LARB0_ID, 4) -#define M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB0_ID, 5) -#define M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) -#define M4U_PORT_VENC_RD_COMV MTK_M4U_ID(M4U_LARB0_ID, 7) -#define M4U_PORT_VENC_SV_COMV MTK_M4U_ID(M4U_LARB0_ID, 8) -#define M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB0_ID, 9) +#define MT6589_M4U_PORT_VENC_RCPU MTK_M4U_ID(M4U_LARB0_ID, 0) +#define MT6589_M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB0_ID, 1) +#define MT6589_M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) +#define MT6589_M4U_PORT_VENC_DB_READ MTK_M4U_ID(M4U_LARB0_ID, 3) +#define MT6589_M4U_PORT_VENC_DB_WRITE MTK_M4U_ID(M4U_LARB0_ID, 4) +#define MT6589_M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB0_ID, 5) +#define MT6589_M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) +#define MT6589_M4U_PORT_VENC_RD_COMV MTK_M4U_ID(M4U_LARB0_ID, 7) +#define MT6589_M4U_PORT_VENC_SV_COMV MTK_M4U_ID(M4U_LARB0_ID, 8) +#define MT6589_M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB0_ID, 9) /* larb1 */ -#define M4U_PORT_HW_VDEC_MC_EXT MTK_M4U_ID(M4U_LARB1_ID, 0) -#define M4U_PORT_HW_VDEC_PP_EXT MTK_M4U_ID(M4U_LARB1_ID, 1) -#define M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB1_ID, 2) -#define M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB1_ID, 3) -#define M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB1_ID, 4) -#define M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) -#define M4U_PORT_HW_VDEC_VLD2_EXT MTK_M4U_ID(M4U_LARB1_ID, 6) +#define MT6589_M4U_PORT_HW_VDEC_MC_EXT MTK_M4U_ID(M4U_LARB1_ID, 0) +#define MT6589_M4U_PORT_HW_VDEC_PP_EXT MTK_M4U_ID(M4U_LARB1_ID, 1) +#define MT6589_M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB1_ID, 2) +#define MT6589_M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB1_ID, 3) +#define MT6589_M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB1_ID, 4) +#define MT6589_M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) +#define MT6589_M4U_PORT_HW_VDEC_VLD2_EXT MTK_M4U_ID(M4U_LARB1_ID, 6) /* larb2 */ -#define M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) -#define M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) -#define M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) -#define M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) -#define M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) -#define M4U_PORT_WDMA0 MTK_M4U_ID(M4U_LARB2_ID, 5) -#define M4U_PORT_WDMA1 MTK_M4U_ID(M4U_LARB2_ID, 6) -#define M4U_PORT_RDMA0 MTK_M4U_ID(M4U_LARB2_ID, 7) -#define M4U_PORT_RDMA1 MTK_M4U_ID(M4U_LARB2_ID, 8) -#define M4U_PORT_CMDQ MTK_M4U_ID(M4U_LARB2_ID, 9) -#define M4U_PORT_DBI MTK_M4U_ID(M4U_LARB2_ID, 10) -#define M4U_PORT_G2D MTK_M4U_ID(M4U_LARB2_ID, 11) +#define MT6589_M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) +#define MT6589_M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) +#define MT6589_M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) +#define MT6589_M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) +#define MT6589_M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) +#define MT6589_M4U_PORT_WDMA0 MTK_M4U_ID(M4U_LARB2_ID, 5) +#define MT6589_M4U_PORT_WDMA1 MTK_M4U_ID(M4U_LARB2_ID, 6) +#define MT6589_M4U_PORT_RDMA0 MTK_M4U_ID(M4U_LARB2_ID, 7) +#define MT6589_M4U_PORT_RDMA1 MTK_M4U_ID(M4U_LARB2_ID, 8) +#define MT6589_M4U_PORT_CMDQ MTK_M4U_ID(M4U_LARB2_ID, 9) +#define MT6589_M4U_PORT_DBI MTK_M4U_ID(M4U_LARB2_ID, 10) +#define MT6589_M4U_PORT_G2D MTK_M4U_ID(M4U_LARB2_ID, 11) /* larb3 */ -#define M4U_PORT_JPGDEC_WDMA MTK_M4U_ID(M4U_LARB3_ID, 0) -#define M4U_PORT_JPGENC_RDMA MTK_M4U_ID(M4U_LARB3_ID, 1) -#define M4U_PORT_VIPI MTK_M4U_ID(M4U_LARB3_ID, 2) -#define M4U_PORT_IMGI MTK_M4U_ID(M4U_LARB3_ID, 3) -#define M4U_PORT_DISPO MTK_M4U_ID(M4U_LARB3_ID, 4) -#define M4U_PORT_DISPCO MTK_M4U_ID(M4U_LARB3_ID, 5) -#define M4U_PORT_DISPVO MTK_M4U_ID(M4U_LARB3_ID, 6) -#define M4U_PORT_VIDO MTK_M4U_ID(M4U_LARB3_ID, 7) -#define M4U_PORT_VIDCO MTK_M4U_ID(M4U_LARB3_ID, 8) -#define M4U_PORT_VIDVO MTK_M4U_ID(M4U_LARB3_ID, 9) -#define M4U_PORT_VIP2I MTK_M4U_ID(M4U_LARB3_ID, 10) -#define M4U_PORT_GDMA_SMI_WR MTK_M4U_ID(M4U_LARB3_ID, 11) -#define M4U_PORT_JPGDEC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 12) -#define M4U_PORT_JPGENC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 13) +#define MT6589_M4U_PORT_JPGDEC_WDMA MTK_M4U_ID(M4U_LARB3_ID, 0) +#define MT6589_M4U_PORT_JPGENC_RDMA MTK_M4U_ID(M4U_LARB3_ID, 1) +#define MT6589_M4U_PORT_VIPI MTK_M4U_ID(M4U_LARB3_ID, 2) +#define MT6589_M4U_PORT_IMGI MTK_M4U_ID(M4U_LARB3_ID, 3) +#define MT6589_M4U_PORT_DISPO MTK_M4U_ID(M4U_LARB3_ID, 4) +#define MT6589_M4U_PORT_DISPCO MTK_M4U_ID(M4U_LARB3_ID, 5) +#define MT6589_M4U_PORT_DISPVO MTK_M4U_ID(M4U_LARB3_ID, 6) +#define MT6589_M4U_PORT_VIDO MTK_M4U_ID(M4U_LARB3_ID, 7) +#define MT6589_M4U_PORT_VIDCO MTK_M4U_ID(M4U_LARB3_ID, 8) +#define MT6589_M4U_PORT_VIDVO MTK_M4U_ID(M4U_LARB3_ID, 9) +#define MT6589_M4U_PORT_VIP2I MTK_M4U_ID(M4U_LARB3_ID, 10) +#define MT6589_M4U_PORT_GDMA_SMI_WR MTK_M4U_ID(M4U_LARB3_ID, 11) +#define MT6589_M4U_PORT_JPGDEC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 12) +#define MT6589_M4U_PORT_JPGENC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 13) /* larb4 */ -#define M4U_PORT_GDMA_SMI_RD MTK_M4U_ID(M4U_LARB4_ID, 0) -#define M4U_PORT_IMGCI MTK_M4U_ID(M4U_LARB4_ID, 1) -#define M4U_PORT_IMGO MTK_M4U_ID(M4U_LARB4_ID, 2) -#define M4U_PORT_IMG2O MTK_M4U_ID(M4U_LARB4_ID, 3) -#define M4U_PORT_LSCI MTK_M4U_ID(M4U_LARB4_ID, 4) -#define M4U_PORT_FLKI MTK_M4U_ID(M4U_LARB4_ID, 5) -#define M4U_PORT_LCEI MTK_M4U_ID(M4U_LARB4_ID, 6) -#define M4U_PORT_LCSO MTK_M4U_ID(M4U_LARB4_ID, 7) -#define M4U_PORT_ESFKO MTK_M4U_ID(M4U_LARB4_ID, 8) -#define M4U_PORT_AAO MTK_M4U_ID(M4U_LARB4_ID, 9) +#define MT6589_M4U_PORT_GDMA_SMI_RD MTK_M4U_ID(M4U_LARB4_ID, 0) +#define MT6589_M4U_PORT_IMGCI MTK_M4U_ID(M4U_LARB4_ID, 1) +#define MT6589_M4U_PORT_IMGO MTK_M4U_ID(M4U_LARB4_ID, 2) +#define MT6589_M4U_PORT_IMG2O MTK_M4U_ID(M4U_LARB4_ID, 3) +#define MT6589_M4U_PORT_LSCI MTK_M4U_ID(M4U_LARB4_ID, 4) +#define MT6589_M4U_PORT_FLKI MTK_M4U_ID(M4U_LARB4_ID, 5) +#define MT6589_M4U_PORT_LCEI MTK_M4U_ID(M4U_LARB4_ID, 6) +#define MT6589_M4U_PORT_LCSO MTK_M4U_ID(M4U_LARB4_ID, 7) +#define MT6589_M4U_PORT_ESFKO MTK_M4U_ID(M4U_LARB4_ID, 8) +#define MT6589_M4U_PORT_AAO MTK_M4U_ID(M4U_LARB4_ID, 9) /* larb5 */ -#define M4U_PORT_AUDIO MTK_M4U_ID(M4U_LARB5_ID, 0) +#define MT6589_M4U_PORT_AUDIO MTK_M4U_ID(M4U_LARB5_ID, 0) #endif From 4773abf4e4f34d661bf25b1128d7c04a151f5b16 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 11:34:45 +0900 Subject: [PATCH 44/78] dt-bindings: memory: mt6589-larb-port: fix indent --- include/dt-bindings/memory/mt6589-larb-port.h | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/dt-bindings/memory/mt6589-larb-port.h b/include/dt-bindings/memory/mt6589-larb-port.h index deceae8d94f6a1..1f1b8cb208646a 100644 --- a/include/dt-bindings/memory/mt6589-larb-port.h +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -8,21 +8,21 @@ #include -#define M4U_LARB0_ID 0 -#define M4U_LARB1_ID 1 -#define M4U_LARB2_ID 2 -#define M4U_LARB3_ID 3 -#define M4U_LARB4_ID 4 -#define M4U_LARB5_ID 5 +#define M4U_LARB0_ID 0 +#define M4U_LARB1_ID 1 +#define M4U_LARB2_ID 2 +#define M4U_LARB3_ID 3 +#define M4U_LARB4_ID 4 +#define M4U_LARB5_ID 5 /* larb0 */ #define MT6589_M4U_PORT_VENC_RCPU MTK_M4U_ID(M4U_LARB0_ID, 0) #define MT6589_M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB0_ID, 1) -#define MT6589_M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) +#define MT6589_M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) #define MT6589_M4U_PORT_VENC_DB_READ MTK_M4U_ID(M4U_LARB0_ID, 3) #define MT6589_M4U_PORT_VENC_DB_WRITE MTK_M4U_ID(M4U_LARB0_ID, 4) #define MT6589_M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB0_ID, 5) -#define MT6589_M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) +#define MT6589_M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) #define MT6589_M4U_PORT_VENC_RD_COMV MTK_M4U_ID(M4U_LARB0_ID, 7) #define MT6589_M4U_PORT_VENC_SV_COMV MTK_M4U_ID(M4U_LARB0_ID, 8) #define MT6589_M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB0_ID, 9) @@ -33,15 +33,15 @@ #define MT6589_M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB1_ID, 2) #define MT6589_M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB1_ID, 3) #define MT6589_M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB1_ID, 4) -#define MT6589_M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) +#define MT6589_M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) #define MT6589_M4U_PORT_HW_VDEC_VLD2_EXT MTK_M4U_ID(M4U_LARB1_ID, 6) /* larb2 */ -#define MT6589_M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) -#define MT6589_M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) -#define MT6589_M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) -#define MT6589_M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) -#define MT6589_M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) +#define MT6589_M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) +#define MT6589_M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) +#define MT6589_M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) +#define MT6589_M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) +#define MT6589_M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) #define MT6589_M4U_PORT_WDMA0 MTK_M4U_ID(M4U_LARB2_ID, 5) #define MT6589_M4U_PORT_WDMA1 MTK_M4U_ID(M4U_LARB2_ID, 6) #define MT6589_M4U_PORT_RDMA0 MTK_M4U_ID(M4U_LARB2_ID, 7) From 43736a73dbde6da8fcf1ce493e954874e575f662 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 12:31:20 +0900 Subject: [PATCH 45/78] wip: arm: dts: mediatek: mt6589: add display related nodes --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 142 +++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index ce940c302fa618..6236d6c8e73c2c 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { #address-cells = <1>; @@ -305,6 +306,16 @@ clock-names = "system-clk", "rtc-clk"; }; + mipi_tx0: dsi-phy@10012000 { + compatible = "mediatek,mt7623-mipi-tx", + "mediatek,mt2701-mipi-tx"; + reg = <0x10012000 0x90>; + clocks = <&dispsys CLK_DISP1_DSI_DIGITAL_LANE>; // uart_clk + clock-output-names = "mipi_tx0_pll"; + #clock-cells = <0>; + #phy-cells = <0>; + }; + sysirq: interrupt-controller@10200100 { compatible = "mediatek,mt6589-sysirq", "mediatek,mt6577-sysirq"; @@ -314,6 +325,26 @@ reg = <0x10200100 0x1c>; }; + smi_common: smi@10202000 { + compatible = "mediatek,mt6589-smi-common"; + reg = <0x10202000 0x1000>; + clocks = <&>, + <&infracfg CLK_INFRA_SMI>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; + + iommu: iommu@10205000 { + compatible = "mediatek,mt6589-m4u"; + reg = <0x10205000 0x1000>; + interrupts = ; + clocks = <&infrasys CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; + #iommu-cells = <1>; + power-domains = TODO; + }; + gic: interrupt-controller@10211000 { compatible = "arm,cortex-a7-gic"; interrupt-controller; @@ -443,6 +474,117 @@ clock-names = "source", "hclk"; status = "disabled"; }; + + ovl: ovl@14003000 { + compatible = "mediatek,mt6589-disp-ovl"; + reg = <0x14003000 0x1000>; + interrupts = ; + clocks = <&dispsys CLK_DISP0_OVL_ENGINE> + <&dispsys CLK_DISP0_OVL_SMI>; + iommus = <&iommu MT6589_M4U_PORT_OVL_CH0>, + <&iommu MT6589_M4U_PORT_OVL_CH1>, + <&iommu MT6589_M4U_PORT_OVL_CH2>, + <&iommu MT6589_M4U_PORT_OVL_CH3>; + power-domains = TODO; + }; + + rdma0: rdma@14006000 { + compatible = "mediatek,mt6589-disp-rdma"; + reg = <0x14006000 0x1000>; + interrupts = ; + clocks = <&dispsys CLK_DISP0_RDMA0_ENGINE>, + <&dispsys CLK_DISP0_RDMA0_SMI>, + <&dispsys CLK_DISP0_RDMA0_OUTPUT>; + iommus = <&iommu MT6589_M4U_PORT_RDMA0>; + power-domains = TODO; + }; + + rdma1: rdma@14007000 { + compatible = "mediatek,mt6589-disp-rdma"; + reg = <0x14007000 0x1000>; + interrupts = ; + clocks = <&dispsys CLK_DISP0_RDMA1_ENGINE>, + <&dispsys CLK_DISP0_RDMA1_SMI>, + <&dispsys CLK_DISP0_RDMA1_OUTPUT>; + iommus = <&iommu MT6589_M4U_PORT_RDMA1>; + power-domains = TODO; + }; + + mutex: mutex@14011000 { + compatible = "mediatek,mt6589-disp-mutex"; + reg = <0x14011000 0x1000>; + interrupts = ; + power-domains = TODO; + }; + + dsi: dsi@1400d000 { + compatible = "mediatek,mt6589-dsi"; + reg = <0x1400d000 0x1000>; + interrupts = ; + clocks = <&dispsys CLK_DISP1_DSI_ENGINE>, + <&dispsys CLK_DISP1_DSI_DIGITAL>, + <&mipi_tx0>; + clock-names = "engine", "digital", "hs"; + phys = <&mipi_tx0>; + phy-names = "dphy"; + power-domains = TODO; + status = "disabled"; + }; + + larb0: larb@17001000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x17001000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&>, + <&>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; + + larb1: larb@16010000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x16010000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <1>; + clocks = <&>, + <&>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; + + larb2: larb@14010000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x14010000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <2>; + clocks = <&>, + <&dispsys CLK_DISP0_LARB2_SMI>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; + + larb3: larb@15001000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x15001000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <3>; + clocks = <&>, + <&imgsys CLK_IMAGE_LARB3_SMI>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; + + larb4: larb@15002000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x15002000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <4>; + clocks = <&>, + <&imgsys CLK_IMAGE_LARB4_SMI>; + clock-names = "apb", "smi"; + power-domains = TODO; + }; }; }; From 8720beb6c70f52ffc81fb12d15b1572c0cdbe97f Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 19:40:00 +0900 Subject: [PATCH 46/78] arm: dts: mediatek: mt6589: fill out display clocks and power-domains Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 39 +++++++++++++------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 0b63f94545dc84..54f3e3d6ed6898 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -396,10 +396,10 @@ smi_common: smi@10202000 { compatible = "mediatek,mt6589-smi-common"; reg = <0x10202000 0x1000>; - clocks = <&>, + clocks = <&infracfg CLK_INFRA_SMI>, <&infracfg CLK_INFRA_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; iommu: iommu@10205000 { @@ -410,7 +410,6 @@ clock-names = "bclk"; mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; #iommu-cells = <1>; - power-domains = TODO; }; gic: interrupt-controller@10211000 { @@ -553,7 +552,7 @@ <&iommu MT6589_M4U_PORT_OVL_CH1>, <&iommu MT6589_M4U_PORT_OVL_CH2>, <&iommu MT6589_M4U_PORT_OVL_CH3>; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; rdma0: rdma@14006000 { @@ -564,7 +563,7 @@ <&dispsys CLK_DISP0_RDMA0_SMI>, <&dispsys CLK_DISP0_RDMA0_OUTPUT>; iommus = <&iommu MT6589_M4U_PORT_RDMA0>; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; rdma1: rdma@14007000 { @@ -575,14 +574,14 @@ <&dispsys CLK_DISP0_RDMA1_SMI>, <&dispsys CLK_DISP0_RDMA1_OUTPUT>; iommus = <&iommu MT6589_M4U_PORT_RDMA1>; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; mutex: mutex@14011000 { compatible = "mediatek,mt6589-disp-mutex"; reg = <0x14011000 0x1000>; interrupts = ; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; dsi: dsi@1400d000 { @@ -595,7 +594,7 @@ clock-names = "engine", "digital", "hs"; phys = <&mipi_tx0>; phy-names = "dphy"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ status = "disabled"; }; @@ -604,10 +603,10 @@ reg = <0x17001000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <0>; - clocks = <&>, - <&>; + clocks = <&infracfg CLK_INFRA_SMI>, /* idk */ + <&infracfg CLK_INFRA_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; larb1: larb@16010000 { @@ -615,10 +614,10 @@ reg = <0x16010000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <1>; - clocks = <&>, - <&>; + clocks = <&infracfg CLK_INFRA_SMI>, /* idk */ + <&infracfg CLK_INFRA_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; larb2: larb@14010000 { @@ -626,10 +625,10 @@ reg = <0x14010000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <2>; - clocks = <&>, + clocks = <&dispsys CLK_DISP0_LARB2_SMI>, <&dispsys CLK_DISP0_LARB2_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; larb3: larb@15001000 { @@ -637,10 +636,10 @@ reg = <0x15001000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <3>; - clocks = <&>, + clocks = <&imgsys CLK_IMAGE_LARB3_SMI>, <&imgsys CLK_IMAGE_LARB3_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; larb4: larb@15002000 { @@ -648,10 +647,10 @@ reg = <0x15002000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <4>; - clocks = <&>, + clocks = <&imgsys CLK_IMAGE_LARB4_SMI>, <&imgsys CLK_IMAGE_LARB4_SMI>; clock-names = "apb", "smi"; - power-domains = TODO; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; }; }; From d53df6eb62c0146deba09e6cea23d31bea76b3c8 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 19:47:06 +0900 Subject: [PATCH 47/78] arm: dts: mediatek: lenovo-b8000: add panel Signed-off-by: Akari Tsuyukusa --- .../dts/mediatek/mt6589-lenovo-b8000.dtsi | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi index fcd26da41168be..f806e7858f0a31 100644 --- a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi @@ -6,8 +6,6 @@ #include "mt6589-lenovo-blade.dtsi" / { - /* TODO: panel */ - framebuffer0: framebuffer@bf600000 { compatible = "simple-framebuffer"; memory-region = <&framebuffer_reserved>; @@ -15,5 +13,44 @@ height = <800>; stride = <(1280 * 2)>; format = "r5g6b5"; + status = "disabled"; + }; + + reg_panel: regulator-panel { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.2V"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + regulator-always-on; + }; + +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + compatible = "boe,hx8896-a01"; + /* + * or innolux,hx8896-a01 + * TODO: panel mux + */ + reg = <0>; + power-supply = <®_panel>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + port { + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; }; }; From 47746764d2d040db2cbcd5637274c1094594d9fa Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:17:55 +0900 Subject: [PATCH 48/78] arm: dts: mediatek: mt6589: fix syntax Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 54f3e3d6ed6898..10241cc4432cf5 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -406,7 +406,7 @@ compatible = "mediatek,mt6589-m4u"; reg = <0x10205000 0x1000>; interrupts = ; - clocks = <&infrasys CLK_INFRA_M4U>; + clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; #iommu-cells = <1>; @@ -546,7 +546,7 @@ compatible = "mediatek,mt6589-disp-ovl"; reg = <0x14003000 0x1000>; interrupts = ; - clocks = <&dispsys CLK_DISP0_OVL_ENGINE> + clocks = <&dispsys CLK_DISP0_OVL_ENGINE>, <&dispsys CLK_DISP0_OVL_SMI>; iommus = <&iommu MT6589_M4U_PORT_OVL_CH0>, <&iommu MT6589_M4U_PORT_OVL_CH1>, From 030bb69a3cc081225ad21f9dec4f020e894d0078 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:20:22 +0900 Subject: [PATCH 49/78] arm: defconfig: lenovo-blade: add for drm Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index a676f3adacf808..a47ceb8ae275af 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -31,12 +31,20 @@ CONFIG_ARM_CPUIDLE=y ## IOMMU CONFIG_IOMMU_SUPPORT=y -# MediaTek M4U -#CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU=y + +## SMI +CONFIG_MEMORY=y +CONFIG_MTK_SMI=y ## Display +CONFIG_DRM=y +CONFIG_DRM_MEDIATEK=y +CONFIG_DRM_PANEL=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_MTK_MMSYS=y -## Framebuffer CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y From 17c48f9453ca03f67addabb2d296c81966740ac6 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:27:13 +0900 Subject: [PATCH 50/78] soc: mediatek: mmsys: add DBI0 for MT6589 Signed-off-by: Akari Tsuyukusa --- include/linux/soc/mediatek/mtk-mmsys.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 7d32c37add14af..d1b258510550b5 100644 --- a/include/linux/soc/mediatek/mtk-mmsys.h +++ b/include/linux/soc/mediatek/mtk-mmsys.h @@ -84,6 +84,7 @@ enum mtk_ddp_comp_id { DDP_COMPONENT_UFOE, DDP_COMPONENT_WDMA0, DDP_COMPONENT_WDMA1, + DDP_COMPONENT_DBI0, DDP_COMPONENT_ID_MAX, }; From 5f4901ee9d91eb2797a18b101f08aac3837ce94b Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:28:13 +0900 Subject: [PATCH 51/78] drm: panel-simple: fix typo --- drivers/gpu/drm/panel/panel-simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index f66690a97591eb..38e8b2f5972884 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -5482,7 +5482,7 @@ static const struct panel_desc_dsi auo_b080uan01 = { .lanes = 4, }; -static const struct drm_display_mode boe_hx8896a_01_mode = { +static const struct drm_display_mode boe_hx8896_a01_mode = { .clock = 69837, /* 1416 * 822 * 60 / 1000 kHz */ .hdisplay = 1280, .hsync_start = 1280 + 100, From e53f3f0096ffb4a5371d586f30b1d543e768b921 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:31:52 +0900 Subject: [PATCH 52/78] soc: mediatek: mt6589-dispsys: make mt6589_dispsys_routing_table an array to fix error Signed-off-by: Akari Tsuyukusa --- drivers/soc/mediatek/mt6589-dispsys.h | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/soc/mediatek/mt6589-dispsys.h b/drivers/soc/mediatek/mt6589-dispsys.h index cf1d0c9e6ec110..91e8bf5f2ca640 100644 --- a/drivers/soc/mediatek/mt6589-dispsys.h +++ b/drivers/soc/mediatek/mt6589-dispsys.h @@ -50,55 +50,55 @@ #define MT6589_DISP_BLS_SEL_IN 0x054 #define MT6589_DISP_DPI0_SEL_IN 0x05c #define MT6589_DISP_DBI_SEL_IN 0x058 - + /* OVL_MOUT_EN */ #define MT6589_OVL_MOUT_EN_WDMA1 BIT(0) #define MT6589_OVL_MOUT_EN_COLOR BIT(2) #define MT6589_OVL_MOUT_EN_MASK GENMASK(2, 0) - + /* COLOR_MOUT_EN */ #define MT6589_COLOR_MOUT_EN_BLS BIT(3) #define MT6589_COLOR_MOUT_EN_MASK GENMASK(3, 0) - + /* COLOR_SEL_IN */ #define MT6589_COLOR_SEL_IN_OVL 0x1 #define MT6589_COLOR_SEL_IN_MASK 0x1 - + /* BLS_SEL_IN */ #define MT6589_BLS_SEL_IN_COLOR 0x1 #define MT6589_BLS_SEL_IN_MASK 0x1 - + /* RDMA0_SOUT_SEL */ #define MT6589_RDMA0_SOUT_DBI 0x1 #define MT6589_RDMA0_SOUT_DPI0 0x2 #define MT6589_RDMA0_SOUT_MASK 0x3 - + /* RDMA1_SOUT_SEL */ #define MT6589_RDMA1_SOUT_DPI0 0x1 #define MT6589_RDMA1_SOUT_DPI1 0x2 #define MT6589_RDMA1_SOUT_MASK 0x3 - + /* DPI0_SEL_IN */ #define MT6589_DPI0_SEL_IN_RDMA1 0x1 #define MT6589_DPI0_SEL_IN_MASK 0x1 - + /* SCL_MOUT_EN */ #define MT6589_SCL_MOUT_EN_WDMA0 BIT(0) #define MT6589_SCL_MOUT_EN_MASK BIT(0) -static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { +static const struct mtk_mmsys_routes mt6589_dispsys_routing_table[] = { /* * Main path step 1: OVL output → COLOR * OVL_MOUT_EN selects COLOR as the downstream engine. * COLOR_SEL_IN confirms OVL as the upstream source. */ - MMSYS_ROUTE(OVL0, COLOR0, + MMSYS_ROUTE(OVL0, COLOR0, MT6589_DISP_OVL_MOUT_EN, - MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_COLOR), - MMSYS_ROUTE(OVL0, COLOR0, + MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_COLOR), + MMSYS_ROUTE(OVL0, COLOR0, MT6589_DISP_COLOR_SEL_IN, - MT6589_COLOR_SEL_IN_MASK, MT6589_COLOR_SEL_IN_OVL), - + MT6589_COLOR_SEL_IN_MASK, MT6589_COLOR_SEL_IN_OVL), + /* * Main path step 2: COLOR output → BLS * COLOR_MOUT_EN selects BLS as the downstream engine. @@ -109,8 +109,8 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { MT6589_COLOR_MOUT_EN_MASK, MT6589_COLOR_MOUT_EN_BLS), MMSYS_ROUTE(COLOR0, BLS, MT6589_DISP_BLS_SEL_IN, - MT6589_BLS_SEL_IN_MASK, MT6589_BLS_SEL_IN_COLOR), - + MT6589_BLS_SEL_IN_MASK, MT6589_BLS_SEL_IN_COLOR), + /* * Main path step 3: RDMA0 output → DSI0 / DBI / DPI0 * BLS feeds RDMA0 via direct-link (no SEL register needed). @@ -120,53 +120,53 @@ static const struct mtk_mmsys_routes mt6589_dispsys_routing_table = { * as the hardware resets to DSI0. Only the MOUT/SEL entries for * the OVL→COLOR and COLOR→BLS hops are required for this path. */ - + /* RDMA0 → DBI */ - MMSYS_ROUTE(RDMA0, DBI, + MMSYS_ROUTE(RDMA0, DBI0, MT6589_DISP_RDMA0_OUT_SEL, - MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DBI), - + MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DBI), + /* RDMA0 → DPI0 (OVL-sourced) */ - MMSYS_ROUTE(RDMA0, DPI0, + MMSYS_ROUTE(RDMA0, DPI0, MT6589_DISP_RDMA0_OUT_SEL, - MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DPI0), - + MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DPI0), + /* * Memory-out path: OVL → WDMA1 * Allows screen-capture concurrently with the main LCD path. * Enabled by setting bit[0] of OVL_MOUT_EN alongside bit[2]. */ - MMSYS_ROUTE(OVL0, WDMA1, + MMSYS_ROUTE(OVL0, WDMA1, MT6589_DISP_OVL_MOUT_EN, - MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_WDMA1), - + MT6589_OVL_MOUT_EN_MASK, MT6589_OVL_MOUT_EN_WDMA1), + /* * Direct RDMA1 paths: bypass OVL/COLOR/BLS entirely. * Used for external display (e.g. HDMI via bridge chip). */ - + /* RDMA1 → DPI0 */ - MMSYS_ROUTE(RDMA1, DPI0, - MT6589_DISP_RDMA1_OUT_SEL , - MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI0), - MMSYS_ROUTE(RDMA1, DPI0, + MMSYS_ROUTE(RDMA1, DPI0, + MT6589_DISP_RDMA1_OUT_SEL, + MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI0), + MMSYS_ROUTE(RDMA1, DPI0, MT6589_DISP_DPI0_SEL_IN, - MT6589_DPI0_SEL_IN_MASK, MT6589_DPI0_SEL_IN_RDMA1), - + MT6589_DPI0_SEL_IN_MASK, MT6589_DPI0_SEL_IN_RDMA1), + /* RDMA1 → DPI1 */ MMSYS_ROUTE(RDMA1, DPI1, - MT6589_DISP_RDMA1_OUT_SEL , - MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI1), - + MT6589_DISP_RDMA1_OUT_SEL, + MT6589_RDMA1_SOUT_MASK, MT6589_RDMA1_SOUT_DPI1), + /* * MDP path: SCL → WDMA0 * Used for MDP (Media Data Path) scaling + write-back. * ROT feeds SCL; SCL_MOUT_EN routes the output to WDMA0. * WDMA0_SEL_IN defaults to SCL (val=0x0); no SEL entry needed. */ - MMSYS_ROUTE(SCL, WDMA0, + MMSYS_ROUTE(SCL, WDMA0, MT6589_DISP_SCL_MOUT_EN, - MT6589_SCL_MOUT_EN_MASK, MT6589_SCL_MOUT_EN_WDMA0), + MT6589_SCL_MOUT_EN_MASK, MT6589_SCL_MOUT_EN_WDMA0), }; #endif /* __SOC_MEDIATEK_MT6589_DISPSYS_H */ From 45567aeff24f3f3e2e72bde88779a49408adf0a9 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 20:51:57 +0900 Subject: [PATCH 53/78] arm: defconfig: lenovo-blade: add CONFIG_PHY_MTK_MIPI_DSI Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index a47ceb8ae275af..bd95f3135f39b9 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -43,6 +43,7 @@ CONFIG_DRM_MEDIATEK=y CONFIG_DRM_PANEL=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_PHY_MTK_MIPI_DSI=y CONFIG_MTK_MMSYS=y CONFIG_FB=y From e4202ad9e39188bb1ad68f6ebb6892c3a42bd78f Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 21:08:46 +0900 Subject: [PATCH 54/78] wip: wip Signed-off-by: Akari Tsuyukusa --- .../arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi | 7 +++++-- arch/arm/boot/dts/mediatek/mt6589.dtsi | 14 +++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi index f806e7858f0a31..1fb85a449a1ab7 100644 --- a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi @@ -13,7 +13,7 @@ height = <800>; stride = <(1280 * 2)>; format = "r5g6b5"; - status = "disabled"; + //status = "disabled"; }; reg_panel: regulator-panel { @@ -41,16 +41,19 @@ reg = <0>; power-supply = <®_panel>; +/* port { panel_in: endpoint { remote-endpoint = <&dsi_out>; }; }; +*/ }; - +/* port { dsi_out: endpoint { remote-endpoint = <&panel_in>; }; }; +*/ }; diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 10241cc4432cf5..a340babb8600ba 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -150,9 +150,10 @@ power-domain@MT6589_POWER_DOMAIN_MFG { reg = ; - clocks = <&topckgen CLK_TOP_MUX_MFG>, - <&topckgen CLK_TOP_MUX_SMI_MFG_AS>; - clock-names = "mfg", "mfg_as"; + // clock get failed + // clocks = <&topckgen CLK_TOP_MUX_MFG>, + // <&topckgen CLK_TOP_MUX_SMI_MFG_AS>; + // clock-names = "mfg", "mfg_as"; #power-domain-cells = <0>; }; @@ -175,8 +176,9 @@ power-domain@MT6589_POWER_DOMAIN_VDE { reg = ; - clocks = <&topckgen CLK_TOP_MUX_VDEC>; - clock-names = "vdec"; + // clock get failed + // clocks = <&topckgen CLK_TOP_MUX_VDEC>; + // clock-names = "vdec"; #power-domain-cells = <0>; }; }; @@ -581,6 +583,8 @@ compatible = "mediatek,mt6589-disp-mutex"; reg = <0x14011000 0x1000>; interrupts = ; + /* not found in clock list */ + clocks = <&clk26m>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; From 0e21e00047dabcac95ac7102afca2ece42b6c4f8 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 21:54:54 +0900 Subject: [PATCH 55/78] arm: dts: mediatek: mt6589: larb clocks ``` int larb_clock_on(int larb_id) { char name[30]; sprintf(name, "smi+%d", larb_id); switch(larb_id) { case 0: enable_clock(MT_CG_VENC_VEN, name); break; case 1: enable_clock(MT_CG_VDEC0_VDE, name); enable_clock(MT_CG_VDEC1_SMI, name); break; case 2: enable_clock(MT_CG_DISP0_LARB2_SMI, name); break; case 3: enable_clock(MT_CG_IMAGE_LARB3_SMI, name); break; case 4: enable_clock(MT_CG_IMAGE_LARB4_SMI, name); break; case 5: enable_clock(MT_CG_IMAGE_LARB4_SMI, name); break; default: break; } return 0; } ``` https://github.com/bq/aquaris-5/blob/bc1d0d0e35c969670e2d869001be944ad0c9c5e5/mediatek/platform/mt6589/kernel/drivers/smi/smi_common.c#L120-L154 Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index a340babb8600ba..eab27bfdfb53e6 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -607,8 +607,8 @@ reg = <0x17001000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <0>; - clocks = <&infracfg CLK_INFRA_SMI>, /* idk */ - <&infracfg CLK_INFRA_SMI>; + clocks = <&vencsys CLK_VENC_VEN>, + <&vencsys CLK_VENC_VEN>; clock-names = "apb", "smi"; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; @@ -618,8 +618,8 @@ reg = <0x16010000 0x1000>; mediatek,smi = <&smi_common>; mediatek,larb-id = <1>; - clocks = <&infracfg CLK_INFRA_SMI>, /* idk */ - <&infracfg CLK_INFRA_SMI>; + clocks = <&vdecsys CLK_VDEC0_VDE>, + <&vdecsys CLK_VDEC1_SMI>; clock-names = "apb", "smi"; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; From 84aa08e26d4c1a97bb5d81e1fd41a262339b6f61 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 16 Mar 2026 23:07:35 +0900 Subject: [PATCH 56/78] wip: arm: dts: mediatek: mt6589: fix iommu Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index eab27bfdfb53e6..5a48e62aaa51c1 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -404,6 +404,7 @@ power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; +/* M4Ug iommu: iommu@10205000 { compatible = "mediatek,mt6589-m4u"; reg = <0x10205000 0x1000>; @@ -413,6 +414,27 @@ mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; #iommu-cells = <1>; }; +*/ + + iommu0: iommu@10205800 { + compatible = "mediatek,mt6589-m4u"; + reg = <0x10205800 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; + #iommu-cells = <1>; + }; + + iommu1: iommu@10205000 { + compatible = "mediatek,mt6589-m4u"; + reg = <0x10205000 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; + #iommu-cells = <1>; + }; gic: interrupt-controller@10211000 { compatible = "arm,cortex-a7-gic"; From 84cb16ecb6f3bf8edd69c84aac1331c2c3e479e7 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 00:14:20 +0900 Subject: [PATCH 57/78] wip: arm: dts: mediatek: mt6589: fix iommu 2 Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 5a48e62aaa51c1..99918bb7de70eb 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -404,21 +404,15 @@ power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; -/* M4Ug - iommu: iommu@10205000 { - compatible = "mediatek,mt6589-m4u"; - reg = <0x10205000 0x1000>; - interrupts = ; - clocks = <&infracfg CLK_INFRA_M4U>; - clock-names = "bclk"; - mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; - #iommu-cells = <1>; - }; -*/ + /* + * #define M4U_BASE0 0xf0205200 + * #define M4U_BASE1 0xf0205800 //0x16010000 + * #define M4U_BASEg 0xf0205000 + */ - iommu0: iommu@10205800 { + iommu0: iommu@10205200 { compatible = "mediatek,mt6589-m4u"; - reg = <0x10205800 0x1000>; + reg = <0x10205200 0x1000>; interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; @@ -426,9 +420,9 @@ #iommu-cells = <1>; }; - iommu1: iommu@10205000 { + iommu1: iommu@10205800 { compatible = "mediatek,mt6589-m4u"; - reg = <0x10205000 0x1000>; + reg = <0x10205800 0x1000>; interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; From 57f6ea4e91668f89f2284170b2f703eb23717b13 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 01:00:42 +0900 Subject: [PATCH 58/78] wip: arm: dts: mediatek: mt6589: fix iommu 2 ```c static unsigned int m4u_index_of_larb[SMI_LARB_NR] = {0,0,1,0,1}; static unsigned int m4u_index_of_larb5 = 0, m4u_index_of_larb6 = 0; static unsigned int smi_port0_in_larbx[SMI_LARB_NR+1] = {0, 10, 17, 29, 44 ,56}; static unsigned int m4u_port0_in_larbx[SMI_LARB_NR+1] = {0, 10, 17, 29, 43 ,53}; static unsigned int m4u_port_size_limit[M4U_PORT_NR] = {}; ``` https://github.com/bq/aquaris-5/blob/bc1d0d0e35c969670e2d869001be944ad0c9c5e5/mediatek/platform/mt6589/kernel/drivers/m4u/m4u.c#L278-L282 Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 99918bb7de70eb..b21cf078c2e17a 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -416,7 +416,7 @@ interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; - mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; + mediatek,larbs = <&larb0>, <&larb1>, <&larb3>; #iommu-cells = <1>; }; @@ -426,7 +426,7 @@ interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; - mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, <&larb3>, <&larb4>; + mediatek,larbs = <&larb2>, <&larb4>; #iommu-cells = <1>; }; From cccf1f9e84734c616b79d7442b14fe578324222f Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 01:29:40 +0900 Subject: [PATCH 59/78] wip: arm: dts: mediatek: mt6589: fix iommu 4 Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index b21cf078c2e17a..ea6c642fccee49 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -423,7 +423,7 @@ iommu1: iommu@10205800 { compatible = "mediatek,mt6589-m4u"; reg = <0x10205800 0x1000>; - interrupts = ; + interrupts = ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; mediatek,larbs = <&larb2>, <&larb4>; From dab063248ebb62bf078852fe9a627406ab30e8f7 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 01:43:45 +0900 Subject: [PATCH 60/78] wip: arm: dts: mediatek: mt6589: fix iommu 5 Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index ea6c642fccee49..9b5340ee4ce4d0 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -566,10 +566,10 @@ interrupts = ; clocks = <&dispsys CLK_DISP0_OVL_ENGINE>, <&dispsys CLK_DISP0_OVL_SMI>; - iommus = <&iommu MT6589_M4U_PORT_OVL_CH0>, - <&iommu MT6589_M4U_PORT_OVL_CH1>, - <&iommu MT6589_M4U_PORT_OVL_CH2>, - <&iommu MT6589_M4U_PORT_OVL_CH3>; + iommus = <&iommu1 MT6589_M4U_PORT_OVL_CH0>, + <&iommu1 MT6589_M4U_PORT_OVL_CH1>, + <&iommu1 MT6589_M4U_PORT_OVL_CH2>, + <&iommu1 MT6589_M4U_PORT_OVL_CH3>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; @@ -580,7 +580,7 @@ clocks = <&dispsys CLK_DISP0_RDMA0_ENGINE>, <&dispsys CLK_DISP0_RDMA0_SMI>, <&dispsys CLK_DISP0_RDMA0_OUTPUT>; - iommus = <&iommu MT6589_M4U_PORT_RDMA0>; + iommus = <&iommu1 MT6589_M4U_PORT_RDMA0>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; @@ -591,7 +591,7 @@ clocks = <&dispsys CLK_DISP0_RDMA1_ENGINE>, <&dispsys CLK_DISP0_RDMA1_SMI>, <&dispsys CLK_DISP0_RDMA1_OUTPUT>; - iommus = <&iommu MT6589_M4U_PORT_RDMA1>; + iommus = <&iommu1 MT6589_M4U_PORT_RDMA1>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; From d46ad1ee073421e7233928d32ee0484caeb372a8 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 01:54:21 +0900 Subject: [PATCH 61/78] arm: defconfig: lenovo-blade: CONFIG_MTK_IOMMU_V1 Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index bd95f3135f39b9..ec36f307a43e11 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -31,7 +31,7 @@ CONFIG_ARM_CPUIDLE=y ## IOMMU CONFIG_IOMMU_SUPPORT=y -CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU_V1=y ## SMI CONFIG_MEMORY=y From 902a85fc47e20ac4d82a98faa490d96b891c7c87 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 02:19:13 +0900 Subject: [PATCH 62/78] wip: arm: dts: mediatek: mt6589: drm not working Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi | 5 +---- arch/arm/boot/dts/mediatek/mt6589.dtsi | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi index 1fb85a449a1ab7..1f497944a0222a 100644 --- a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi @@ -41,19 +41,16 @@ reg = <0>; power-supply = <®_panel>; -/* port { panel_in: endpoint { remote-endpoint = <&dsi_out>; }; }; -*/ }; -/* + port { dsi_out: endpoint { remote-endpoint = <&panel_in>; }; }; -*/ }; diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 9b5340ee4ce4d0..e8ae519dabf93c 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -143,8 +143,8 @@ power-domain@MT6589_POWER_DOMAIN_DIS { reg = ; - clocks = <&topckgen CLK_TOP_MUX_DISP>; - clock-names = "disp"; + // clocks = <&topckgen CLK_TOP_MUX_DISP>; + // clock-names = "disp"; #power-domain-cells = <0>; }; From 6316de5e41080533f0f5d6a98c756e278bf2731a Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 10:25:51 +0900 Subject: [PATCH 63/78] iommu: mtk_iommu_v1: add more larb_port_offset --- drivers/iommu/mtk_iommu_v1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 5fb334074f680a..713fcc1a58bfbf 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -161,7 +161,9 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) static const int mt2701_m4u_in_larb[] = { LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, - LARB2_PORT_OFFSET, LARB3_PORT_OFFSET + LARB2_PORT_OFFSET, LARB3_PORT_OFFSET, + LARB4_PORT_OFFSET, LARB5_PORT_OFFSET, + LARB6_PORT_OFFSET, }; static inline int mt2701_m4u_to_larb(int id) From 943ce396bfb4b5bea3ad79597b80f000d4a012ae Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 10:32:55 +0900 Subject: [PATCH 64/78] arm: dts: mediatek: mt6589: add smi_common_ao base --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index e8ae519dabf93c..d655f3298612cf 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -397,7 +397,7 @@ smi_common: smi@10202000 { compatible = "mediatek,mt6589-smi-common"; - reg = <0x10202000 0x1000>; + reg = <0x10202000 0x1000>, <0x1000e000, 0x1000>; clocks = <&infracfg CLK_INFRA_SMI>, <&infracfg CLK_INFRA_SMI>; clock-names = "apb", "smi"; From 7a01654e149db7b066b0f1ba6ab4aa847e365ff4 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 10:47:54 +0900 Subject: [PATCH 65/78] dt-bindings: mtk-smi-common: fix for gen0 --- .../mediatek,smi-common.yaml | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml index c7ecd9b0d5ccb0..35d7d4c1ca6b65 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml @@ -52,9 +52,6 @@ properties: - const: mediatek,mt7623-smi-common - const: mediatek,mt2701-smi-common - reg: - maxItems: 1 - power-domains: maxItems: 1 @@ -87,6 +84,24 @@ required: - clock-names allOf: + - if: # Generation 0 HW (mt6589) + properties: + compatible: + contains: + const: mediatek,mt6589-smi-common + then: + properties: + reg: + items: + - description: SMI AO base + - description: SMI base + minItems: 2 + maxItems: 2 + else: + properties: + reg: + maxItems: 1 + - if: # only for gen1 HW properties: compatible: From 2e64fc985df7428c8d805ed94007d8a9e7415373 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 17:34:57 +0900 Subject: [PATCH 66/78] arm: dts: mediatek: mt6589: fix syntax Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index d655f3298612cf..9e31477cad0d4a 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -397,7 +397,7 @@ smi_common: smi@10202000 { compatible = "mediatek,mt6589-smi-common"; - reg = <0x10202000 0x1000>, <0x1000e000, 0x1000>; + reg = <0x10202000 0x1000>, <0x1000e000 0x1000>; clocks = <&infracfg CLK_INFRA_SMI>, <&infracfg CLK_INFRA_SMI>; clock-names = "apb", "smi"; From 4efe3c8706107894b41d9d805593e434c4b8e4aa Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 17:42:31 +0900 Subject: [PATCH 67/78] Revert "iommu: mtk_iommu_v1: add more larb_port_offset" This reverts commit 6316de5e41080533f0f5d6a98c756e278bf2731a. --- drivers/iommu/mtk_iommu_v1.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 713fcc1a58bfbf..5fb334074f680a 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -161,9 +161,7 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) static const int mt2701_m4u_in_larb[] = { LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, - LARB2_PORT_OFFSET, LARB3_PORT_OFFSET, - LARB4_PORT_OFFSET, LARB5_PORT_OFFSET, - LARB6_PORT_OFFSET, + LARB2_PORT_OFFSET, LARB3_PORT_OFFSET }; static inline int mt2701_m4u_to_larb(int id) From 38c2992830298d3746f58b4cebe950a2940f5b7c Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 18:03:27 +0900 Subject: [PATCH 68/78] memory: mtk-smi: fix mt6589 compatible name Signed-off-by: Akari Tsuyukusa --- drivers/memory/mtk-smi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index ed92a16425ac3f..2c381dfdb5806e 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -905,7 +905,7 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8365 = { static const struct of_device_id mtk_smi_common_of_ids[] = { {.compatible = "mediatek,mt2701-smi-common", .data = &mtk_smi_common_gen1}, {.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2}, - {.compatible = "mediatek,mt6572-smi-common", .data = &mtk_smi_common_mt6589}, + {.compatible = "mediatek,mt6589-smi-common", .data = &mtk_smi_common_mt6589}, {.compatible = "mediatek,mt6779-smi-common", .data = &mtk_smi_common_mt6779}, {.compatible = "mediatek,mt6795-smi-common", .data = &mtk_smi_common_mt6795}, {.compatible = "mediatek,mt6893-smi-common", .data = &mtk_smi_common_mt6893}, From b0c470a7c62687d85eed3a64e9e18b3e361b504a Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 17 Mar 2026 21:41:10 +0900 Subject: [PATCH 69/78] dt-bindings: memory: mt6589-larb-port: fix for v1 --- include/dt-bindings/memory/mt6589-larb-port.h | 122 +++++++++--------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/include/dt-bindings/memory/mt6589-larb-port.h b/include/dt-bindings/memory/mt6589-larb-port.h index 1f1b8cb208646a..34d5197ac2fe06 100644 --- a/include/dt-bindings/memory/mt6589-larb-port.h +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -6,79 +6,77 @@ #ifndef _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ #define _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ -#include - -#define M4U_LARB0_ID 0 -#define M4U_LARB1_ID 1 -#define M4U_LARB2_ID 2 -#define M4U_LARB3_ID 3 -#define M4U_LARB4_ID 4 -#define M4U_LARB5_ID 5 +#define MT6589_M4U_ID_LARB0(n) ((n)+0) +#define MT6589_M4U_ID_LARB1(n) ((n)+10) +#define MT6589_M4U_ID_LARB2(n) ((n)+17) +#define MT6589_M4U_ID_LARB3(n) ((n)+29) +#define MT6589_M4U_ID_LARB4(n) ((n)+43) +#define MT6589_M4U_ID_LARB5(n) ((n)+53) /* larb0 */ -#define MT6589_M4U_PORT_VENC_RCPU MTK_M4U_ID(M4U_LARB0_ID, 0) -#define MT6589_M4U_PORT_VENC_REF_LUMA MTK_M4U_ID(M4U_LARB0_ID, 1) -#define MT6589_M4U_PORT_VENC_REF_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 2) -#define MT6589_M4U_PORT_VENC_DB_READ MTK_M4U_ID(M4U_LARB0_ID, 3) -#define MT6589_M4U_PORT_VENC_DB_WRITE MTK_M4U_ID(M4U_LARB0_ID, 4) -#define MT6589_M4U_PORT_VENC_CUR_LUMA MTK_M4U_ID(M4U_LARB0_ID, 5) -#define MT6589_M4U_PORT_VENC_CUR_CHROMA MTK_M4U_ID(M4U_LARB0_ID, 6) -#define MT6589_M4U_PORT_VENC_RD_COMV MTK_M4U_ID(M4U_LARB0_ID, 7) -#define MT6589_M4U_PORT_VENC_SV_COMV MTK_M4U_ID(M4U_LARB0_ID, 8) -#define MT6589_M4U_PORT_VENC_BSDMA MTK_M4U_ID(M4U_LARB0_ID, 9) +#define MT6589_M4U_PORT_VENC_RCPU MT6589_M4U_ID_LARB0(0) +#define MT6589_M4U_PORT_VENC_REF_LUMA MT6589_M4U_ID_LARB0(1) +#define MT6589_M4U_PORT_VENC_REF_CHROMA MT6589_M4U_ID_LARB0(2) +#define MT6589_M4U_PORT_VENC_DB_READ MT6589_M4U_ID_LARB0(3) +#define MT6589_M4U_PORT_VENC_DB_WRITE MT6589_M4U_ID_LARB0(4) +#define MT6589_M4U_PORT_VENC_CUR_LUMA MT6589_M4U_ID_LARB0(5) +#define MT6589_M4U_PORT_VENC_CUR_CHROMA MT6589_M4U_ID_LARB0(6) +#define MT6589_M4U_PORT_VENC_RD_COMV MT6589_M4U_ID_LARB0(7) +#define MT6589_M4U_PORT_VENC_SV_COMV MT6589_M4U_ID_LARB0(8) +#define MT6589_M4U_PORT_VENC_BSDMA MT6589_M4U_ID_LARB0(9) /* larb1 */ -#define MT6589_M4U_PORT_HW_VDEC_MC_EXT MTK_M4U_ID(M4U_LARB1_ID, 0) -#define MT6589_M4U_PORT_HW_VDEC_PP_EXT MTK_M4U_ID(M4U_LARB1_ID, 1) -#define MT6589_M4U_PORT_HW_VDEC_AVC_MV_EXT MTK_M4U_ID(M4U_LARB1_ID, 2) -#define MT6589_M4U_PORT_HW_VDEC_PRED_RD_EXT MTK_M4U_ID(M4U_LARB1_ID, 3) -#define MT6589_M4U_PORT_HW_VDEC_PRED_WR_EXT MTK_M4U_ID(M4U_LARB1_ID, 4) -#define MT6589_M4U_PORT_HW_VDEC_VLD_EXT MTK_M4U_ID(M4U_LARB1_ID, 5) -#define MT6589_M4U_PORT_HW_VDEC_VLD2_EXT MTK_M4U_ID(M4U_LARB1_ID, 6) +#define MT6589_M4U_PORT_HW_VDEC_MC_EXT MT6589_M4U_ID_LARB1(0) +#define MT6589_M4U_PORT_HW_VDEC_PP_EXT MT6589_M4U_ID_LARB1(1) +#define MT6589_M4U_PORT_HW_VDEC_AVC_MV_EXT MT6589_M4U_ID_LARB1(2) +#define MT6589_M4U_PORT_HW_VDEC_PRED_RD_EXT MT6589_M4U_ID_LARB1(3) +#define MT6589_M4U_PORT_HW_VDEC_PRED_WR_EXT MT6589_M4U_ID_LARB1(4) +#define MT6589_M4U_PORT_HW_VDEC_VLD_EXT MT6589_M4U_ID_LARB1(5) +#define MT6589_M4U_PORT_HW_VDEC_VLD2_EXT MT6589_M4U_ID_LARB1(6) /* larb2 */ -#define MT6589_M4U_PORT_ROT_EXT MTK_M4U_ID(M4U_LARB2_ID, 0) -#define MT6589_M4U_PORT_OVL_CH0 MTK_M4U_ID(M4U_LARB2_ID, 1) -#define MT6589_M4U_PORT_OVL_CH1 MTK_M4U_ID(M4U_LARB2_ID, 2) -#define MT6589_M4U_PORT_OVL_CH2 MTK_M4U_ID(M4U_LARB2_ID, 3) -#define MT6589_M4U_PORT_OVL_CH3 MTK_M4U_ID(M4U_LARB2_ID, 4) -#define MT6589_M4U_PORT_WDMA0 MTK_M4U_ID(M4U_LARB2_ID, 5) -#define MT6589_M4U_PORT_WDMA1 MTK_M4U_ID(M4U_LARB2_ID, 6) -#define MT6589_M4U_PORT_RDMA0 MTK_M4U_ID(M4U_LARB2_ID, 7) -#define MT6589_M4U_PORT_RDMA1 MTK_M4U_ID(M4U_LARB2_ID, 8) -#define MT6589_M4U_PORT_CMDQ MTK_M4U_ID(M4U_LARB2_ID, 9) -#define MT6589_M4U_PORT_DBI MTK_M4U_ID(M4U_LARB2_ID, 10) -#define MT6589_M4U_PORT_G2D MTK_M4U_ID(M4U_LARB2_ID, 11) +#define MT6589_M4U_PORT_ROT_EXT MT6589_M4U_ID_LARB2(0) +#define MT6589_M4U_PORT_OVL_CH0 MT6589_M4U_ID_LARB2(1) +#define MT6589_M4U_PORT_OVL_CH1 MT6589_M4U_ID_LARB2(2) +#define MT6589_M4U_PORT_OVL_CH2 MT6589_M4U_ID_LARB2(3) +#define MT6589_M4U_PORT_OVL_CH3 MT6589_M4U_ID_LARB2(4) +#define MT6589_M4U_PORT_WDMA0 MT6589_M4U_ID_LARB2(5) +#define MT6589_M4U_PORT_WDMA1 MT6589_M4U_ID_LARB2(6) +#define MT6589_M4U_PORT_RDMA0 MT6589_M4U_ID_LARB2(7) +#define MT6589_M4U_PORT_RDMA1 MT6589_M4U_ID_LARB2(8) +#define MT6589_M4U_PORT_CMDQ MT6589_M4U_ID_LARB2(9) +#define MT6589_M4U_PORT_DBI MT6589_M4U_ID_LARB2(10) +#define MT6589_M4U_PORT_G2D MT6589_M4U_ID_LARB2(11) /* larb3 */ -#define MT6589_M4U_PORT_JPGDEC_WDMA MTK_M4U_ID(M4U_LARB3_ID, 0) -#define MT6589_M4U_PORT_JPGENC_RDMA MTK_M4U_ID(M4U_LARB3_ID, 1) -#define MT6589_M4U_PORT_VIPI MTK_M4U_ID(M4U_LARB3_ID, 2) -#define MT6589_M4U_PORT_IMGI MTK_M4U_ID(M4U_LARB3_ID, 3) -#define MT6589_M4U_PORT_DISPO MTK_M4U_ID(M4U_LARB3_ID, 4) -#define MT6589_M4U_PORT_DISPCO MTK_M4U_ID(M4U_LARB3_ID, 5) -#define MT6589_M4U_PORT_DISPVO MTK_M4U_ID(M4U_LARB3_ID, 6) -#define MT6589_M4U_PORT_VIDO MTK_M4U_ID(M4U_LARB3_ID, 7) -#define MT6589_M4U_PORT_VIDCO MTK_M4U_ID(M4U_LARB3_ID, 8) -#define MT6589_M4U_PORT_VIDVO MTK_M4U_ID(M4U_LARB3_ID, 9) -#define MT6589_M4U_PORT_VIP2I MTK_M4U_ID(M4U_LARB3_ID, 10) -#define MT6589_M4U_PORT_GDMA_SMI_WR MTK_M4U_ID(M4U_LARB3_ID, 11) -#define MT6589_M4U_PORT_JPGDEC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 12) -#define MT6589_M4U_PORT_JPGENC_BSDMA MTK_M4U_ID(M4U_LARB3_ID, 13) +#define MT6589_M4U_PORT_JPGDEC_WDMA MT6589_M4U_ID_LARB3(0) +#define MT6589_M4U_PORT_JPGENC_RDMA MT6589_M4U_ID_LARB3(1) +#define MT6589_M4U_PORT_VIPI MT6589_M4U_ID_LARB3(2) +#define MT6589_M4U_PORT_IMGI MT6589_M4U_ID_LARB3(3) +#define MT6589_M4U_PORT_DISPO MT6589_M4U_ID_LARB3(4) +#define MT6589_M4U_PORT_DISPCO MT6589_M4U_ID_LARB3(5) +#define MT6589_M4U_PORT_DISPVO MT6589_M4U_ID_LARB3(6) +#define MT6589_M4U_PORT_VIDO MT6589_M4U_ID_LARB3(7) +#define MT6589_M4U_PORT_VIDCO MT6589_M4U_ID_LARB3(8) +#define MT6589_M4U_PORT_VIDVO MT6589_M4U_ID_LARB3(9) +#define MT6589_M4U_PORT_VIP2I MT6589_M4U_ID_LARB3(10) +#define MT6589_M4U_PORT_GDMA_SMI_WR MT6589_M4U_ID_LARB3(11) +#define MT6589_M4U_PORT_JPGDEC_BSDMA MT6589_M4U_ID_LARB3(12) +#define MT6589_M4U_PORT_JPGENC_BSDMA MT6589_M4U_ID_LARB3(13) /* larb4 */ -#define MT6589_M4U_PORT_GDMA_SMI_RD MTK_M4U_ID(M4U_LARB4_ID, 0) -#define MT6589_M4U_PORT_IMGCI MTK_M4U_ID(M4U_LARB4_ID, 1) -#define MT6589_M4U_PORT_IMGO MTK_M4U_ID(M4U_LARB4_ID, 2) -#define MT6589_M4U_PORT_IMG2O MTK_M4U_ID(M4U_LARB4_ID, 3) -#define MT6589_M4U_PORT_LSCI MTK_M4U_ID(M4U_LARB4_ID, 4) -#define MT6589_M4U_PORT_FLKI MTK_M4U_ID(M4U_LARB4_ID, 5) -#define MT6589_M4U_PORT_LCEI MTK_M4U_ID(M4U_LARB4_ID, 6) -#define MT6589_M4U_PORT_LCSO MTK_M4U_ID(M4U_LARB4_ID, 7) -#define MT6589_M4U_PORT_ESFKO MTK_M4U_ID(M4U_LARB4_ID, 8) -#define MT6589_M4U_PORT_AAO MTK_M4U_ID(M4U_LARB4_ID, 9) +#define MT6589_M4U_PORT_GDMA_SMI_RD MT6589_M4U_ID_LARB4(0) +#define MT6589_M4U_PORT_IMGCI MT6589_M4U_ID_LARB4(1) +#define MT6589_M4U_PORT_IMGO MT6589_M4U_ID_LARB4(2) +#define MT6589_M4U_PORT_IMG2O MT6589_M4U_ID_LARB4(3) +#define MT6589_M4U_PORT_LSCI MT6589_M4U_ID_LARB4(4) +#define MT6589_M4U_PORT_FLKI MT6589_M4U_ID_LARB4(5) +#define MT6589_M4U_PORT_LCEI MT6589_M4U_ID_LARB4(6) +#define MT6589_M4U_PORT_LCSO MT6589_M4U_ID_LARB4(7) +#define MT6589_M4U_PORT_ESFKO MT6589_M4U_ID_LARB4(8) +#define MT6589_M4U_PORT_AAO MT6589_M4U_ID_LARB4(9) /* larb5 */ -#define MT6589_M4U_PORT_AUDIO MTK_M4U_ID(M4U_LARB5_ID, 0) +#define MT6589_M4U_PORT_AUDIO MT6589_M4U_ID_LARB5(0) #endif From 04ae9f1bba45a8deaac9890208b5ad49eb8e5b30 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 22 Jun 2026 18:57:27 +0900 Subject: [PATCH 70/78] arm: defconfig: lenovo-blade: use SIMPLEDRM insted of FB_SIMPLE Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index 8d5a7b79307e0d..ea66c838702a5a 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -39,6 +39,7 @@ CONFIG_MTK_SMI=y ## Display CONFIG_DRM=y +CONFIG_DRM_SIMPLEDRM=y CONFIG_DRM_MEDIATEK=y CONFIG_DRM_PANEL=y CONFIG_BACKLIGHT_CLASS_DEVICE=y @@ -47,7 +48,6 @@ CONFIG_PHY_MTK_MIPI_DSI=y CONFIG_MTK_MMSYS=y CONFIG_FB=y -CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y ## Clock From 0d7879b5ebf39719c4e351bf408a8e966e782220 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 22 Jun 2026 20:01:03 +0900 Subject: [PATCH 71/78] iommu/memory/dt-bindings: rename MediaTek macro name Signed-off-by: Akari Tsuyukusa --- drivers/iommu/mtk_iommu_v1.c | 4 ++-- drivers/memory/mtk-smi.c | 4 ++-- include/dt-bindings/memory/mt2701-larb-port.h | 14 +++++++------- include/dt-bindings/memory/mt6589-larb-port.h | 19 +++++++++++++------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 5fb334074f680a..0b8320174d643c 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -160,8 +160,8 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) } static const int mt2701_m4u_in_larb[] = { - LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, - LARB2_PORT_OFFSET, LARB3_PORT_OFFSET + MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, + MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET }; static inline int mt2701_m4u_to_larb(int id) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index 2c381dfdb5806e..f82a77447ecaa4 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -527,8 +527,8 @@ static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = { static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = { .port_in_larb = { - LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, - LARB2_PORT_OFFSET, LARB3_PORT_OFFSET + MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, + MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET }, .config_port = mtk_smi_larb_config_port_gen1, }; diff --git a/include/dt-bindings/memory/mt2701-larb-port.h b/include/dt-bindings/memory/mt2701-larb-port.h index 25d03526f142a2..dc2c98baf7891d 100644 --- a/include/dt-bindings/memory/mt2701-larb-port.h +++ b/include/dt-bindings/memory/mt2701-larb-port.h @@ -15,14 +15,14 @@ * But m4u generation 2 like mt8173 have different port number, it use fixed * offset for each larb, the first port's id for larb[N] would be (N * 32). */ -#define LARB0_PORT_OFFSET 0 -#define LARB1_PORT_OFFSET 11 -#define LARB2_PORT_OFFSET 21 -#define LARB3_PORT_OFFSET 44 +#define MT2701_LARB0_PORT_OFFSET 0 +#define MT2701_LARB1_PORT_OFFSET 11 +#define MT2701_LARB2_PORT_OFFSET 21 +#define MT2701_LARB3_PORT_OFFSET 44 -#define MT2701_M4U_ID_LARB0(port) ((port) + LARB0_PORT_OFFSET) -#define MT2701_M4U_ID_LARB1(port) ((port) + LARB1_PORT_OFFSET) -#define MT2701_M4U_ID_LARB2(port) ((port) + LARB2_PORT_OFFSET) +#define MT2701_M4U_ID_LARB0(port) ((port) + MT2701_LARB0_PORT_OFFSET) +#define MT2701_M4U_ID_LARB1(port) ((port) + MT2701_LARB1_PORT_OFFSET) +#define MT2701_M4U_ID_LARB2(port) ((port) + MT2701_LARB2_PORT_OFFSET) /* Port define for larb0 */ #define MT2701_M4U_PORT_DISP_OVL_0 MT2701_M4U_ID_LARB0(0) diff --git a/include/dt-bindings/memory/mt6589-larb-port.h b/include/dt-bindings/memory/mt6589-larb-port.h index 34d5197ac2fe06..9dc0183f5402ad 100644 --- a/include/dt-bindings/memory/mt6589-larb-port.h +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -6,12 +6,19 @@ #ifndef _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ #define _DT_BINDINGS_MEMORY_MT6589_LARB_PORT_H_ -#define MT6589_M4U_ID_LARB0(n) ((n)+0) -#define MT6589_M4U_ID_LARB1(n) ((n)+10) -#define MT6589_M4U_ID_LARB2(n) ((n)+17) -#define MT6589_M4U_ID_LARB3(n) ((n)+29) -#define MT6589_M4U_ID_LARB4(n) ((n)+43) -#define MT6589_M4U_ID_LARB5(n) ((n)+53) +#define MT6589_LARB0_PORT_OFFSET 0 +#define MT6589_LARB1_PORT_OFFSET 10 +#define MT6589_LARB2_PORT_OFFSET 17 +#define MT6589_LARB3_PORT_OFFSET 29 +#define MT6589_LARB4_PORT_OFFSET 43 +#define MT6589_LARB5_PORT_OFFSET 53 + +#define MT6589_M4U_ID_LARB0(n) ((n) + MT6589_LARB0_PORT_OFFSET) +#define MT6589_M4U_ID_LARB1(n) ((n) + MT6589_LARB1_PORT_OFFSET) +#define MT6589_M4U_ID_LARB2(n) ((n) + MT6589_LARB2_PORT_OFFSET) +#define MT6589_M4U_ID_LARB3(n) ((n) + MT6589_LARB3_PORT_OFFSET) +#define MT6589_M4U_ID_LARB4(n) ((n) + MT6589_LARB4_PORT_OFFSET) +#define MT6589_M4U_ID_LARB5(n) ((n) + MT6589_LARB5_PORT_OFFSET) /* larb0 */ #define MT6589_M4U_PORT_VENC_RCPU MT6589_M4U_ID_LARB0(0) From d84fec8c411d7b285e467f62d9ded2e39145d47c Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 22 Jun 2026 20:35:38 +0900 Subject: [PATCH 72/78] wip: iommu: introduce MT6589 M4U driver Signed-off-by: Akari Tsuyukusa --- arch/arm/configs/lenovo-blade_defconfig | 2 +- drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile | 1 + drivers/iommu/mtk_iommu_mt6589.c | 796 ++++++++++++++++++++++++ drivers/iommu/mtk_iommu_v1.c | 72 +-- 5 files changed, 831 insertions(+), 54 deletions(-) create mode 100644 drivers/iommu/mtk_iommu_mt6589.c diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index ea66c838702a5a..8a8a966c5e6112 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -31,7 +31,7 @@ CONFIG_ARM_CPUIDLE=y ## IOMMU CONFIG_IOMMU_SUPPORT=y -CONFIG_MTK_IOMMU_V1=y +CONFIG_MTK_IOMMU_MT6589=y ## SMI CONFIG_MEMORY=y diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 0a33d995d15dd7..dd3010df9a5dcf 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -350,6 +350,20 @@ config MTK_IOMMU_V1 if unsure, say N here. +config MTK_IOMMU_MT6589 + tristate "MediaTek MT6589 IOMMU Support" + depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST + select ARM_DMA_USE_IOMMU + select IOMMU_API + select MEMORY + select MTK_SMI + help + Support for the M4U on Mediatek MT6589 SoC. M4U is Multimedia Memory + Managememt Unit. This option enables remapping of DMA memory accesses + for the multimedia subsystem. + + if unsure, say N here. + config HYPERV_IOMMU bool "Hyper-V IRQ Handling" depends on HYPERV && X86 diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 355294fa9033f3..9b04fe0d8c19e4 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o +obj-$(CONFIG_MTK_IOMMU_MT6589) += mtk_iommu_mt6589.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o diff --git a/drivers/iommu/mtk_iommu_mt6589.c b/drivers/iommu/mtk_iommu_mt6589.c new file mode 100644 index 00000000000000..0b8320174d643c --- /dev/null +++ b/drivers/iommu/mtk_iommu_mt6589.c @@ -0,0 +1,796 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * IOMMU API for MTK architected m4u v1 implementations + * + * Copyright (c) 2015-2016 MediaTek Inc. + * Author: Honghui Zhang + * + * Based on driver/iommu/mtk_iommu.c + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_ARM) +#include +#else +#define arm_iommu_create_mapping(...) NULL +#define arm_iommu_attach_device(...) -ENODEV +struct dma_iommu_mapping { + struct iommu_domain *domain; +}; +#endif + +#define REG_MMU_PT_BASE_ADDR 0x000 + +#define F_ALL_INVLD 0x2 +#define F_MMU_INV_RANGE 0x1 +#define F_INVLD_EN0 BIT(0) +#define F_INVLD_EN1 BIT(1) + +#define F_MMU_FAULT_VA_MSK 0xfffff000 +#define MTK_PROTECT_PA_ALIGN 128 + +#define REG_MMU_CTRL_REG 0x210 +#define F_MMU_CTRL_COHERENT_EN BIT(8) +#define REG_MMU_IVRP_PADDR 0x214 +#define REG_MMU_INT_CONTROL 0x220 +#define F_INT_TRANSLATION_FAULT BIT(0) +#define F_INT_MAIN_MULTI_HIT_FAULT BIT(1) +#define F_INT_INVALID_PA_FAULT BIT(2) +#define F_INT_ENTRY_REPLACEMENT_FAULT BIT(3) +#define F_INT_TABLE_WALK_FAULT BIT(4) +#define F_INT_TLB_MISS_FAULT BIT(5) +#define F_INT_PFH_DMA_FIFO_OVERFLOW BIT(6) +#define F_INT_MISS_DMA_FIFO_OVERFLOW BIT(7) + +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_INT_CLR_BIT BIT(12) + +#define REG_MMU_FAULT_ST 0x224 +#define REG_MMU_FAULT_VA 0x228 +#define REG_MMU_INVLD_PA 0x22C +#define REG_MMU_INT_ID 0x388 +#define REG_MMU_INVALIDATE 0x5c0 +#define REG_MMU_INVLD_START_A 0x5c4 +#define REG_MMU_INVLD_END_A 0x5c8 + +#define REG_MMU_INV_SEL 0x5d8 +#define REG_MMU_STANDARD_AXI_MODE 0x5e8 + +#define REG_MMU_DCM 0x5f0 +#define F_MMU_DCM_ON BIT(1) +#define REG_MMU_CPE_DONE 0x60c +#define F_DESC_VALID 0x2 +#define F_DESC_NONSEC BIT(3) +#define MT2701_M4U_TF_LARB(TF) (6 - (((TF) >> 13) & 0x7)) +#define MT2701_M4U_TF_PORT(TF) (((TF) >> 8) & 0xF) + +#define MT65XX_MMU_INT_ID_PORT_ID GENMASK(12, 8) +#define MT65XX_MMU_INT_ID_LARB_ID GENMASK(14, 13) + +#define MT65XX_M4U_TF_PORT(TF) FIELD_GET(MT65XX_MMU_INT_ID_PORT_ID, TF) +#define MT65XX_M4U_TF_LARB(TF) (FIELD_GET(MT65XX_MMU_INT_ID_LARB_ID, TF) - 1) + +/* MTK generation one iommu HW only support 4K size mapping */ +#define MT2701_IOMMU_PAGE_SHIFT 12 +#define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) +#define MT2701_LARB_NR_MAX 3 + +/* + * MTK m4u support 4GB iova address space, and only support 4K page + * mapping. So the pagetable size should be exactly as 4M. + */ +#define M2701_IOMMU_PGT_SIZE SZ_4M + +enum mtk_iommu_type { + MTK_IOMMU_MT65XX, + MTK_IOMMU_V1, +}; + +struct mtk_iommu_v1_suspend_reg { + u32 standard_axi_mode; + u32 dcm_dis; + u32 ctrl_reg; + u32 int_control0; +}; + +struct mtk_iommu_v1_data { + void __iomem *base; + int irq; + struct device *dev; + struct clk *bclk; + phys_addr_t protect_base; /* protect memory base */ + struct mtk_iommu_v1_domain *m4u_dom; + + struct iommu_device iommu; + struct dma_iommu_mapping *mapping; + struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; + + struct mtk_iommu_v1_suspend_reg reg; + + enum mtk_iommu_type type; +}; + +struct mtk_iommu_v1_domain { + spinlock_t pgtlock; /* lock for page table */ + struct iommu_domain domain; + u32 *pgt_va; + dma_addr_t pgt_pa; + struct mtk_iommu_v1_data *data; +}; + +static int mtk_iommu_v1_bind(struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); + + return component_bind_all(dev, &data->larb_imu); +} + +static void mtk_iommu_v1_unbind(struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); + + component_unbind_all(dev, &data->larb_imu); +} + +static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) +{ + return container_of(dom, struct mtk_iommu_v1_domain, domain); +} + +static const int mt2701_m4u_in_larb[] = { + MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, + MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET +}; + +static inline int mt2701_m4u_to_larb(int id) +{ + int i; + + for (i = ARRAY_SIZE(mt2701_m4u_in_larb) - 1; i >= 0; i--) + if ((id) >= mt2701_m4u_in_larb[i]) + return i; + + return 0; +} + +static inline int mt2701_m4u_to_port(int id) +{ + int larb = mt2701_m4u_to_larb(id); + + return id - mt2701_m4u_in_larb[larb]; +} + +static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) +{ + u32 val = F_INVLD_EN0; + if (data->type == MTK_IOMMU_V1) + val |= F_INVLD_EN1; + + writel_relaxed(val, data->base + REG_MMU_INV_SEL); + writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); + wmb(); /* Make sure the tlb flush all done */ +} + +static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, + unsigned long iova, size_t size) +{ + int ret; + u32 tmp, val = F_INVLD_EN0; + if (data->type == MTK_IOMMU_V1) + val |= F_INVLD_EN1; + + writel_relaxed(val, data->base + REG_MMU_INV_SEL); + writel_relaxed(iova & F_MMU_FAULT_VA_MSK, + data->base + REG_MMU_INVLD_START_A); + writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, + data->base + REG_MMU_INVLD_END_A); + writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); + + if (data->type == MTK_IOMMU_V1) { + ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, + tmp, tmp != 0, 10, 100000); + if (ret) { + dev_warn(data->dev, + "Partial TLB flush timed out, falling back to full flush\n"); + mtk_iommu_v1_tlb_flush_all(data); + } + + /* Clear the CPE status */ + writel_relaxed(0, data->base + REG_MMU_CPE_DONE); + } else { + wmb(); + } +} + +static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) +{ + struct mtk_iommu_v1_data *data = dev_id; + struct mtk_iommu_v1_domain *dom = data->m4u_dom; + u32 int_state, regval, fault_iova, fault_pa; + unsigned int fault_larb, fault_port; + + /* Read error information from registers */ + int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST); + fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA); + + fault_iova &= F_MMU_FAULT_VA_MSK; + fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); + regval = readl_relaxed(data->base + REG_MMU_INT_ID); + + if (data->type == MTK_IOMMU_V1) { + fault_larb = MT2701_M4U_TF_LARB(regval); + fault_port = MT2701_M4U_TF_PORT(regval); + } else { + fault_larb = MT65XX_M4U_TF_LARB(regval); + fault_port = MT65XX_M4U_TF_PORT(regval); + } + + /* + * MTK v1 iommu HW could not determine whether the fault is read or + * write fault, report as read fault. + */ + if (report_iommu_fault(&dom->domain, data->dev, fault_iova, + IOMMU_FAULT_READ)) + dev_err_ratelimited(data->dev, + "fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d\n", + int_state, fault_iova, fault_pa, + fault_larb, fault_port); + + /* Interrupt clear */ + regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL); + regval |= F_INT_CLR_BIT; + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); + + mtk_iommu_v1_tlb_flush_all(data); + + return IRQ_HANDLED; +} + +static void mtk_iommu_v1_config(struct mtk_iommu_v1_data *data, + struct device *dev, bool enable) +{ + struct mtk_smi_larb_iommu *larb_mmu; + unsigned int larbid, portid; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + int i; + + for (i = 0; i < fwspec->num_ids; ++i) { + larbid = mt2701_m4u_to_larb(fwspec->ids[i]); + portid = mt2701_m4u_to_port(fwspec->ids[i]); + larb_mmu = &data->larb_imu[larbid]; + + dev_dbg(dev, "%s iommu port: %d\n", + str_enable_disable(enable), portid); + + if (enable) + larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); + else + larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); + } +} + +static int mtk_iommu_v1_domain_finalise(struct mtk_iommu_v1_data *data) +{ + struct mtk_iommu_v1_domain *dom = data->m4u_dom; + + spin_lock_init(&dom->pgtlock); + + dom->pgt_va = dma_alloc_coherent(data->dev, M2701_IOMMU_PGT_SIZE, + &dom->pgt_pa, GFP_KERNEL); + if (!dom->pgt_va) + return -ENOMEM; + + writel(dom->pgt_pa, data->base + REG_MMU_PT_BASE_ADDR); + + dom->data = data; + + return 0; +} + +static struct iommu_domain *mtk_iommu_v1_domain_alloc_paging(struct device *dev) +{ + struct mtk_iommu_v1_domain *dom; + + dom = kzalloc(sizeof(*dom), GFP_KERNEL); + if (!dom) + return NULL; + + return &dom->domain; +} + +static void mtk_iommu_v1_domain_free(struct iommu_domain *domain) +{ + struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); + struct mtk_iommu_v1_data *data = dom->data; + + dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE, + dom->pgt_va, dom->pgt_pa); + kfree(to_mtk_domain(domain)); +} + +static int mtk_iommu_v1_attach_device(struct iommu_domain *domain, struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); + struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); + struct dma_iommu_mapping *mtk_mapping; + int ret; + + /* Only allow the domain created internally. */ + mtk_mapping = data->mapping; + if (mtk_mapping->domain != domain) + return 0; + + if (!data->m4u_dom) { + data->m4u_dom = dom; + ret = mtk_iommu_v1_domain_finalise(data); + if (ret) { + data->m4u_dom = NULL; + return ret; + } + } + + mtk_iommu_v1_config(data, dev, true); + return 0; +} + +static int mtk_iommu_v1_identity_attach(struct iommu_domain *identity_domain, + struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); + + mtk_iommu_v1_config(data, dev, false); + return 0; +} + +static struct iommu_domain_ops mtk_iommu_v1_identity_ops = { + .attach_dev = mtk_iommu_v1_identity_attach, +}; + +static struct iommu_domain mtk_iommu_v1_identity_domain = { + .type = IOMMU_DOMAIN_IDENTITY, + .ops = &mtk_iommu_v1_identity_ops, +}; + +static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped) +{ + struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); + unsigned long flags; + unsigned int i; + u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); + u32 pabase = (u32)paddr; + + spin_lock_irqsave(&dom->pgtlock, flags); + for (i = 0; i < pgcount; i++) { + if (pgt_base_iova[i]) + break; + pgt_base_iova[i] = pabase | F_DESC_VALID | F_DESC_NONSEC; + pabase += MT2701_IOMMU_PAGE_SIZE; + } + + spin_unlock_irqrestore(&dom->pgtlock, flags); + + *mapped = i * MT2701_IOMMU_PAGE_SIZE; + mtk_iommu_v1_tlb_flush_range(dom->data, iova, *mapped); + + return i == pgcount ? 0 : -EEXIST; +} + +static size_t mtk_iommu_v1_unmap(struct iommu_domain *domain, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather) +{ + struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); + unsigned long flags; + u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); + size_t size = pgcount * MT2701_IOMMU_PAGE_SIZE; + + spin_lock_irqsave(&dom->pgtlock, flags); + memset(pgt_base_iova, 0, pgcount * sizeof(u32)); + spin_unlock_irqrestore(&dom->pgtlock, flags); + + mtk_iommu_v1_tlb_flush_range(dom->data, iova, size); + + return size; +} + +static phys_addr_t mtk_iommu_v1_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) +{ + struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); + unsigned long flags; + phys_addr_t pa; + + spin_lock_irqsave(&dom->pgtlock, flags); + pa = *(dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT)); + pa = pa & (~(MT2701_IOMMU_PAGE_SIZE - 1)); + spin_unlock_irqrestore(&dom->pgtlock, flags); + + return pa; +} + +static const struct iommu_ops mtk_iommu_v1_ops; + +/* + * MTK generation one iommu HW only support one iommu domain, and all the client + * sharing the same iova address space. + */ +static int mtk_iommu_v1_create_mapping(struct device *dev, + const struct of_phandle_args *args) +{ + struct mtk_iommu_v1_data *data; + struct platform_device *m4updev; + struct dma_iommu_mapping *mtk_mapping; + int ret; + + if (args->args_count != 1) { + dev_err(dev, "invalid #iommu-cells(%d) property for IOMMU\n", + args->args_count); + return -EINVAL; + } + + ret = iommu_fwspec_init(dev, of_fwnode_handle(args->np)); + if (ret) + return ret; + + if (!dev_iommu_priv_get(dev)) { + /* Get the m4u device */ + m4updev = of_find_device_by_node(args->np); + if (WARN_ON(!m4updev)) + return -EINVAL; + + dev_iommu_priv_set(dev, platform_get_drvdata(m4updev)); + } + + ret = iommu_fwspec_add_ids(dev, args->args, 1); + if (ret) + return ret; + + data = dev_iommu_priv_get(dev); + mtk_mapping = data->mapping; + if (!mtk_mapping) { + /* MTK iommu support 4GB iova address space. */ + mtk_mapping = arm_iommu_create_mapping(dev, 0, 1ULL << 32); + if (IS_ERR(mtk_mapping)) + return PTR_ERR(mtk_mapping); + + data->mapping = mtk_mapping; + } + + return 0; +} + +static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev) +{ + struct iommu_fwspec *fwspec = NULL; + struct of_phandle_args iommu_spec; + struct mtk_iommu_v1_data *data; + int err, idx = 0, larbid, larbidx; + struct device_link *link; + struct device *larbdev; + + while (!of_parse_phandle_with_args(dev->of_node, "iommus", + "#iommu-cells", + idx, &iommu_spec)) { + + err = mtk_iommu_v1_create_mapping(dev, &iommu_spec); + of_node_put(iommu_spec.np); + if (err) + return ERR_PTR(err); + + /* dev->iommu_fwspec might have changed */ + fwspec = dev_iommu_fwspec_get(dev); + idx++; + } + + if (!fwspec) + return ERR_PTR(-ENODEV); + + data = dev_iommu_priv_get(dev); + + /* Link the consumer device with the smi-larb device(supplier) */ + larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + if (larbid >= MT2701_LARB_NR_MAX) + return ERR_PTR(-EINVAL); + + for (idx = 1; idx < fwspec->num_ids; idx++) { + larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); + if (larbid != larbidx) { + dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n", + larbid, larbidx); + return ERR_PTR(-EINVAL); + } + } + + larbdev = data->larb_imu[larbid].dev; + if (!larbdev) + return ERR_PTR(-EINVAL); + + link = device_link_add(dev, larbdev, + DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); + if (!link) + dev_err(dev, "Unable to link %s\n", dev_name(larbdev)); + + return &data->iommu; +} + +static void mtk_iommu_v1_probe_finalize(struct device *dev) +{ + struct dma_iommu_mapping *mtk_mapping; + struct mtk_iommu_v1_data *data; + int err; + + data = dev_iommu_priv_get(dev); + mtk_mapping = data->mapping; + + err = arm_iommu_attach_device(dev, mtk_mapping); + if (err) + dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n"); +} + +static void mtk_iommu_v1_release_device(struct device *dev) +{ + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct mtk_iommu_v1_data *data; + struct device *larbdev; + unsigned int larbid; + + data = dev_iommu_priv_get(dev); + larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + larbdev = data->larb_imu[larbid].dev; + device_link_remove(dev, larbdev); +} + +static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) +{ + u32 regval; + int ret; + + ret = clk_prepare_enable(data->bclk); + if (ret) { + dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); + return ret; + } + + regval = F_MMU_TF_PROTECT_SEL(2); + if (data->type == MTK_IOMMU_V1) + regval |= F_MMU_CTRL_COHERENT_EN; + + writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); + + regval = F_INT_TRANSLATION_FAULT | + F_INT_MAIN_MULTI_HIT_FAULT | + F_INT_INVALID_PA_FAULT | + F_INT_ENTRY_REPLACEMENT_FAULT | + F_INT_TABLE_WALK_FAULT | + F_INT_TLB_MISS_FAULT | + F_INT_PFH_DMA_FIFO_OVERFLOW | + F_INT_MISS_DMA_FIFO_OVERFLOW; + writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); + + /* protect memory,hw will write here while translation fault */ + writel_relaxed(data->protect_base, + data->base + REG_MMU_IVRP_PADDR); + + writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM); + + if (devm_request_irq(data->dev, data->irq, mtk_iommu_v1_isr, 0, + dev_name(data->dev), (void *)data)) { + writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); + clk_disable_unprepare(data->bclk); + dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); + return -ENODEV; + } + + return 0; +} + +static const struct iommu_ops mtk_iommu_v1_ops = { + .identity_domain = &mtk_iommu_v1_identity_domain, + .domain_alloc_paging = mtk_iommu_v1_domain_alloc_paging, + .probe_device = mtk_iommu_v1_probe_device, + .probe_finalize = mtk_iommu_v1_probe_finalize, + .release_device = mtk_iommu_v1_release_device, + .device_group = generic_device_group, + .pgsize_bitmap = MT2701_IOMMU_PAGE_SIZE, + .owner = THIS_MODULE, + .default_domain_ops = &(const struct iommu_domain_ops) { + .attach_dev = mtk_iommu_v1_attach_device, + .map_pages = mtk_iommu_v1_map, + .unmap_pages = mtk_iommu_v1_unmap, + .iova_to_phys = mtk_iommu_v1_iova_to_phys, + .free = mtk_iommu_v1_domain_free, + } +}; + +static const struct of_device_id mtk_iommu_v1_of_ids[] = { + { .compatible = "mediatek,mt2701-m4u", .data = (void *)MTK_IOMMU_V1 }, + { .compatible = "mediatek,mt6589-m4u", .data = (void *)MTK_IOMMU_MT65XX }, + {} +}; +MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); + +static const struct component_master_ops mtk_iommu_v1_com_ops = { + .bind = mtk_iommu_v1_bind, + .unbind = mtk_iommu_v1_unbind, +}; + +static int mtk_iommu_v1_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_iommu_v1_data *data; + struct resource *res; + struct component_match *match = NULL; + void *protect; + int larb_nr, ret, i; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = dev; + data->type = (enum mtk_iommu_type)of_device_get_match_data(dev); + + /* Protect memory. HW will access here while translation fault.*/ + protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, + GFP_KERNEL | GFP_DMA); + if (!protect) + return -ENOMEM; + data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->base = devm_ioremap_resource(dev, res); + if (IS_ERR(data->base)) + return PTR_ERR(data->base); + + data->irq = platform_get_irq(pdev, 0); + if (data->irq < 0) + return data->irq; + + data->bclk = devm_clk_get(dev, "bclk"); + if (IS_ERR(data->bclk)) + return PTR_ERR(data->bclk); + + larb_nr = of_count_phandle_with_args(dev->of_node, + "mediatek,larbs", NULL); + if (larb_nr < 0) + return larb_nr; + + for (i = 0; i < larb_nr; i++) { + struct device_node *larbnode; + struct platform_device *plarbdev; + + larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); + if (!larbnode) + return -EINVAL; + + if (!of_device_is_available(larbnode)) { + of_node_put(larbnode); + continue; + } + + plarbdev = of_find_device_by_node(larbnode); + if (!plarbdev) { + of_node_put(larbnode); + return -ENODEV; + } + if (!plarbdev->dev.driver) { + of_node_put(larbnode); + return -EPROBE_DEFER; + } + data->larb_imu[i].dev = &plarbdev->dev; + + component_match_add_release(dev, &match, component_release_of, + component_compare_of, larbnode); + } + + platform_set_drvdata(pdev, data); + + ret = mtk_iommu_v1_hw_init(data); + if (ret) + return ret; + + ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, + dev_name(&pdev->dev)); + if (ret) + goto out_clk_unprepare; + + ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev); + if (ret) + goto out_sysfs_remove; + + ret = component_master_add_with_match(dev, &mtk_iommu_v1_com_ops, match); + if (ret) + goto out_dev_unreg; + return ret; + +out_dev_unreg: + iommu_device_unregister(&data->iommu); +out_sysfs_remove: + iommu_device_sysfs_remove(&data->iommu); +out_clk_unprepare: + clk_disable_unprepare(data->bclk); + return ret; +} + +static void mtk_iommu_v1_remove(struct platform_device *pdev) +{ + struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev); + + iommu_device_sysfs_remove(&data->iommu); + iommu_device_unregister(&data->iommu); + + clk_disable_unprepare(data->bclk); + devm_free_irq(&pdev->dev, data->irq, data); + component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops); +} + +static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); + struct mtk_iommu_v1_suspend_reg *reg = &data->reg; + void __iomem *base = data->base; + + reg->standard_axi_mode = readl_relaxed(base + + REG_MMU_STANDARD_AXI_MODE); + reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM); + reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); + reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL); + return 0; +} + +static int __maybe_unused mtk_iommu_v1_resume(struct device *dev) +{ + struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); + struct mtk_iommu_v1_suspend_reg *reg = &data->reg; + void __iomem *base = data->base; + + writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR); + writel_relaxed(reg->standard_axi_mode, + base + REG_MMU_STANDARD_AXI_MODE); + writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM); + writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); + writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL); + writel_relaxed(data->protect_base, base + REG_MMU_IVRP_PADDR); + return 0; +} + +static const struct dev_pm_ops mtk_iommu_v1_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_v1_suspend, mtk_iommu_v1_resume) +}; + +static struct platform_driver mtk_iommu_v1_driver = { + .probe = mtk_iommu_v1_probe, + .remove = mtk_iommu_v1_remove, + .driver = { + .name = "mtk-iommu-v1", + .of_match_table = mtk_iommu_v1_of_ids, + .pm = &mtk_iommu_v1_pm_ops, + } +}; +module_platform_driver(mtk_iommu_v1_driver); + +MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 0b8320174d643c..66824982e05fbf 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -85,13 +85,6 @@ struct dma_iommu_mapping { #define F_DESC_NONSEC BIT(3) #define MT2701_M4U_TF_LARB(TF) (6 - (((TF) >> 13) & 0x7)) #define MT2701_M4U_TF_PORT(TF) (((TF) >> 8) & 0xF) - -#define MT65XX_MMU_INT_ID_PORT_ID GENMASK(12, 8) -#define MT65XX_MMU_INT_ID_LARB_ID GENMASK(14, 13) - -#define MT65XX_M4U_TF_PORT(TF) FIELD_GET(MT65XX_MMU_INT_ID_PORT_ID, TF) -#define MT65XX_M4U_TF_LARB(TF) (FIELD_GET(MT65XX_MMU_INT_ID_LARB_ID, TF) - 1) - /* MTK generation one iommu HW only support 4K size mapping */ #define MT2701_IOMMU_PAGE_SHIFT 12 #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) @@ -103,11 +96,6 @@ struct dma_iommu_mapping { */ #define M2701_IOMMU_PGT_SIZE SZ_4M -enum mtk_iommu_type { - MTK_IOMMU_MT65XX, - MTK_IOMMU_V1, -}; - struct mtk_iommu_v1_suspend_reg { u32 standard_axi_mode; u32 dcm_dis; @@ -128,8 +116,6 @@ struct mtk_iommu_v1_data { struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; struct mtk_iommu_v1_suspend_reg reg; - - enum mtk_iommu_type type; }; struct mtk_iommu_v1_domain { @@ -160,8 +146,8 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) } static const int mt2701_m4u_in_larb[] = { - MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, - MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET + LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, + LARB2_PORT_OFFSET, LARB3_PORT_OFFSET }; static inline int mt2701_m4u_to_larb(int id) @@ -184,11 +170,8 @@ static inline int mt2701_m4u_to_port(int id) static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) { - u32 val = F_INVLD_EN0; - if (data->type == MTK_IOMMU_V1) - val |= F_INVLD_EN1; - - writel_relaxed(val, data->base + REG_MMU_INV_SEL); + writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, + data->base + REG_MMU_INV_SEL); writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); wmb(); /* Make sure the tlb flush all done */ } @@ -197,31 +180,25 @@ static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, unsigned long iova, size_t size) { int ret; - u32 tmp, val = F_INVLD_EN0; - if (data->type == MTK_IOMMU_V1) - val |= F_INVLD_EN1; + u32 tmp; - writel_relaxed(val, data->base + REG_MMU_INV_SEL); + writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, + data->base + REG_MMU_INV_SEL); writel_relaxed(iova & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_START_A); writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_END_A); writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); - if (data->type == MTK_IOMMU_V1) { - ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, - tmp, tmp != 0, 10, 100000); - if (ret) { - dev_warn(data->dev, - "Partial TLB flush timed out, falling back to full flush\n"); - mtk_iommu_v1_tlb_flush_all(data); - } - - /* Clear the CPE status */ - writel_relaxed(0, data->base + REG_MMU_CPE_DONE); - } else { - wmb(); + ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, + tmp, tmp != 0, 10, 100000); + if (ret) { + dev_warn(data->dev, + "Partial TLB flush timed out, falling back to full flush\n"); + mtk_iommu_v1_tlb_flush_all(data); } + /* Clear the CPE status */ + writel_relaxed(0, data->base + REG_MMU_CPE_DONE); } static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) @@ -238,14 +215,8 @@ static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) fault_iova &= F_MMU_FAULT_VA_MSK; fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); regval = readl_relaxed(data->base + REG_MMU_INT_ID); - - if (data->type == MTK_IOMMU_V1) { - fault_larb = MT2701_M4U_TF_LARB(regval); - fault_port = MT2701_M4U_TF_PORT(regval); - } else { - fault_larb = MT65XX_M4U_TF_LARB(regval); - fault_port = MT65XX_M4U_TF_PORT(regval); - } + fault_larb = MT2701_M4U_TF_LARB(regval); + fault_port = MT2701_M4U_TF_PORT(regval); /* * MTK v1 iommu HW could not determine whether the fault is read or @@ -574,10 +545,7 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) return ret; } - regval = F_MMU_TF_PROTECT_SEL(2); - if (data->type == MTK_IOMMU_V1) - regval |= F_MMU_CTRL_COHERENT_EN; - + regval = F_MMU_CTRL_COHERENT_EN | F_MMU_TF_PROTECT_SEL(2); writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); regval = F_INT_TRANSLATION_FAULT | @@ -626,8 +594,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = { }; static const struct of_device_id mtk_iommu_v1_of_ids[] = { - { .compatible = "mediatek,mt2701-m4u", .data = (void *)MTK_IOMMU_V1 }, - { .compatible = "mediatek,mt6589-m4u", .data = (void *)MTK_IOMMU_MT65XX }, + { .compatible = "mediatek,mt2701-m4u", }, {} }; MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); @@ -651,7 +618,6 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) return -ENOMEM; data->dev = dev; - data->type = (enum mtk_iommu_type)of_device_get_match_data(dev); /* Protect memory. HW will access here while translation fault.*/ protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, From c7c60f82e8b0aeec942e8efb5f353f464fd226ca Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 22 Jun 2026 20:55:47 +0900 Subject: [PATCH 73/78] wip: iommu: mtk_iommu_mt6589: cleanup Signed-off-by: Akari Tsuyukusa --- drivers/iommu/mtk_iommu_mt6589.c | 90 +++++++++----------------------- 1 file changed, 26 insertions(+), 64 deletions(-) diff --git a/drivers/iommu/mtk_iommu_mt6589.c b/drivers/iommu/mtk_iommu_mt6589.c index 0b8320174d643c..bc23730d67b3ca 100644 --- a/drivers/iommu/mtk_iommu_mt6589.c +++ b/drivers/iommu/mtk_iommu_mt6589.c @@ -1,11 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * IOMMU API for MTK architected m4u v1 implementations + * IOMMU API for MTK architected MT6589 M4U implementations + * + * Copyright (c) 2026 Akari Tsuyukusa * * Copyright (c) 2015-2016 MediaTek Inc. * Author: Honghui Zhang * - * Based on driver/iommu/mtk_iommu.c + * Based on driver/iommu/mtk_iommu.c, driver/iommu/mtk_iommu_v1.c */ #include #include @@ -28,7 +30,7 @@ #include #include #include -#include +#include #include #if defined(CONFIG_ARM) @@ -83,8 +85,6 @@ struct dma_iommu_mapping { #define REG_MMU_CPE_DONE 0x60c #define F_DESC_VALID 0x2 #define F_DESC_NONSEC BIT(3) -#define MT2701_M4U_TF_LARB(TF) (6 - (((TF) >> 13) & 0x7)) -#define MT2701_M4U_TF_PORT(TF) (((TF) >> 8) & 0xF) #define MT65XX_MMU_INT_ID_PORT_ID GENMASK(12, 8) #define MT65XX_MMU_INT_ID_LARB_ID GENMASK(14, 13) @@ -95,7 +95,7 @@ struct dma_iommu_mapping { /* MTK generation one iommu HW only support 4K size mapping */ #define MT2701_IOMMU_PAGE_SHIFT 12 #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) -#define MT2701_LARB_NR_MAX 3 +#define MT6589_LARB_NR_MAX 4 /* * MTK m4u support 4GB iova address space, and only support 4K page @@ -103,11 +103,6 @@ struct dma_iommu_mapping { */ #define M2701_IOMMU_PGT_SIZE SZ_4M -enum mtk_iommu_type { - MTK_IOMMU_MT65XX, - MTK_IOMMU_V1, -}; - struct mtk_iommu_v1_suspend_reg { u32 standard_axi_mode; u32 dcm_dis; @@ -128,8 +123,6 @@ struct mtk_iommu_v1_data { struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; struct mtk_iommu_v1_suspend_reg reg; - - enum mtk_iommu_type type; }; struct mtk_iommu_v1_domain { @@ -159,35 +152,32 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) return container_of(dom, struct mtk_iommu_v1_domain, domain); } -static const int mt2701_m4u_in_larb[] = { - MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, - MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET +static const int mt6589_m4u_in_larb[] = { + MT6589_LARB0_PORT_OFFSET, MT6589_LARB1_PORT_OFFSET, + MT6589_LARB2_PORT_OFFSET, MT6589_LARB3_PORT_OFFSET }; -static inline int mt2701_m4u_to_larb(int id) +static inline int mt6589_m4u_to_larb(int id) { int i; - for (i = ARRAY_SIZE(mt2701_m4u_in_larb) - 1; i >= 0; i--) - if ((id) >= mt2701_m4u_in_larb[i]) + for (i = ARRAY_SIZE(mt6589_m4u_in_larb) - 1; i >= 0; i--) + if ((id) >= mt6589_m4u_in_larb[i]) return i; return 0; } -static inline int mt2701_m4u_to_port(int id) +static inline int mt6589_m4u_to_port(int id) { - int larb = mt2701_m4u_to_larb(id); + int larb = mt6589_m4u_to_larb(id); - return id - mt2701_m4u_in_larb[larb]; + return id - mt6589_m4u_in_larb[larb]; } static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) { u32 val = F_INVLD_EN0; - if (data->type == MTK_IOMMU_V1) - val |= F_INVLD_EN1; - writel_relaxed(val, data->base + REG_MMU_INV_SEL); writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); wmb(); /* Make sure the tlb flush all done */ @@ -196,32 +186,14 @@ static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, unsigned long iova, size_t size) { - int ret; - u32 tmp, val = F_INVLD_EN0; - if (data->type == MTK_IOMMU_V1) - val |= F_INVLD_EN1; - + u32 val = F_INVLD_EN0; writel_relaxed(val, data->base + REG_MMU_INV_SEL); writel_relaxed(iova & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_START_A); writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, data->base + REG_MMU_INVLD_END_A); writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); - - if (data->type == MTK_IOMMU_V1) { - ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, - tmp, tmp != 0, 10, 100000); - if (ret) { - dev_warn(data->dev, - "Partial TLB flush timed out, falling back to full flush\n"); - mtk_iommu_v1_tlb_flush_all(data); - } - - /* Clear the CPE status */ - writel_relaxed(0, data->base + REG_MMU_CPE_DONE); - } else { - wmb(); - } + wmb(); } static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) @@ -239,13 +211,8 @@ static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); regval = readl_relaxed(data->base + REG_MMU_INT_ID); - if (data->type == MTK_IOMMU_V1) { - fault_larb = MT2701_M4U_TF_LARB(regval); - fault_port = MT2701_M4U_TF_PORT(regval); - } else { - fault_larb = MT65XX_M4U_TF_LARB(regval); - fault_port = MT65XX_M4U_TF_PORT(regval); - } + fault_larb = MT65XX_M4U_TF_LARB(regval); + fault_port = MT65XX_M4U_TF_PORT(regval); /* * MTK v1 iommu HW could not determine whether the fault is read or @@ -277,8 +244,8 @@ static void mtk_iommu_v1_config(struct mtk_iommu_v1_data *data, int i; for (i = 0; i < fwspec->num_ids; ++i) { - larbid = mt2701_m4u_to_larb(fwspec->ids[i]); - portid = mt2701_m4u_to_port(fwspec->ids[i]); + larbid = mt6589_m4u_to_larb(fwspec->ids[i]); + portid = mt6589_m4u_to_port(fwspec->ids[i]); larb_mmu = &data->larb_imu[larbid]; dev_dbg(dev, "%s iommu port: %d\n", @@ -511,12 +478,12 @@ static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev) data = dev_iommu_priv_get(dev); /* Link the consumer device with the smi-larb device(supplier) */ - larbid = mt2701_m4u_to_larb(fwspec->ids[0]); - if (larbid >= MT2701_LARB_NR_MAX) + larbid = mt6589_m4u_to_larb(fwspec->ids[0]); + if (larbid >= MT6589_LARB_NR_MAX) return ERR_PTR(-EINVAL); for (idx = 1; idx < fwspec->num_ids; idx++) { - larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); + larbidx = mt6589_m4u_to_larb(fwspec->ids[idx]); if (larbid != larbidx) { dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n", larbid, larbidx); @@ -558,7 +525,7 @@ static void mtk_iommu_v1_release_device(struct device *dev) unsigned int larbid; data = dev_iommu_priv_get(dev); - larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + larbid = mt6589_m4u_to_larb(fwspec->ids[0]); larbdev = data->larb_imu[larbid].dev; device_link_remove(dev, larbdev); } @@ -575,9 +542,6 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) } regval = F_MMU_TF_PROTECT_SEL(2); - if (data->type == MTK_IOMMU_V1) - regval |= F_MMU_CTRL_COHERENT_EN; - writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); regval = F_INT_TRANSLATION_FAULT | @@ -626,8 +590,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = { }; static const struct of_device_id mtk_iommu_v1_of_ids[] = { - { .compatible = "mediatek,mt2701-m4u", .data = (void *)MTK_IOMMU_V1 }, - { .compatible = "mediatek,mt6589-m4u", .data = (void *)MTK_IOMMU_MT65XX }, + { .compatible = "mediatek,mt6589-m4u" }, {} }; MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); @@ -651,7 +614,6 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev) return -ENOMEM; data->dev = dev; - data->type = (enum mtk_iommu_type)of_device_get_match_data(dev); /* Protect memory. HW will access here while translation fault.*/ protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, From 1f1a6acd018e558b125d746eac470f5723eebd17 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Mon, 22 Jun 2026 23:52:06 +0900 Subject: [PATCH 74/78] arm: dts: mediatek: mt6589: change iommu for feature changes Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 43 ++++++++++---------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index bc102909cc7264..507dee1ddd3d30 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -427,29 +427,20 @@ power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; - /* - * #define M4U_BASE0 0xf0205200 - * #define M4U_BASE1 0xf0205800 //0x16010000 - * #define M4U_BASEg 0xf0205000 - */ - - iommu0: iommu@10205200 { - compatible = "mediatek,mt6589-m4u"; - reg = <0x10205200 0x1000>; - interrupts = ; - clocks = <&infracfg CLK_INFRA_M4U>; - clock-names = "bclk"; - mediatek,larbs = <&larb0>, <&larb1>, <&larb3>; - #iommu-cells = <1>; - }; - - iommu1: iommu@10205800 { + iommu: iommu@10205000 { compatible = "mediatek,mt6589-m4u"; - reg = <0x10205800 0x1000>; - interrupts = ; + reg = <0x10205000 0x200>, + <0x10205200 0x600>, + <0x10205800 0x600>; + reg-names = "global", "m4u0", "m4u1"; + interrupts = , + , + , + ; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; - mediatek,larbs = <&larb2>, <&larb4>; + mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, + <&larb3>, <&larb4>; #iommu-cells = <1>; }; @@ -589,10 +580,10 @@ interrupts = ; clocks = <&dispsys CLK_DISP0_OVL_ENGINE>, <&dispsys CLK_DISP0_OVL_SMI>; - iommus = <&iommu1 MT6589_M4U_PORT_OVL_CH0>, - <&iommu1 MT6589_M4U_PORT_OVL_CH1>, - <&iommu1 MT6589_M4U_PORT_OVL_CH2>, - <&iommu1 MT6589_M4U_PORT_OVL_CH3>; + iommus = <&iommu MT6589_M4U_PORT_OVL_CH0>, + <&iommu MT6589_M4U_PORT_OVL_CH1>, + <&iommu MT6589_M4U_PORT_OVL_CH2>, + <&iommu MT6589_M4U_PORT_OVL_CH3>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; @@ -603,7 +594,7 @@ clocks = <&dispsys CLK_DISP0_RDMA0_ENGINE>, <&dispsys CLK_DISP0_RDMA0_SMI>, <&dispsys CLK_DISP0_RDMA0_OUTPUT>; - iommus = <&iommu1 MT6589_M4U_PORT_RDMA0>; + iommus = <&iommu MT6589_M4U_PORT_RDMA0>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; @@ -614,7 +605,7 @@ clocks = <&dispsys CLK_DISP0_RDMA1_ENGINE>, <&dispsys CLK_DISP0_RDMA1_SMI>, <&dispsys CLK_DISP0_RDMA1_OUTPUT>; - iommus = <&iommu1 MT6589_M4U_PORT_RDMA1>; + iommus = <&iommu MT6589_M4U_PORT_RDMA1>; power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ }; From af85840a330fa62962d9ec8b1c63f30f18171947 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 23 Jun 2026 00:00:47 +0900 Subject: [PATCH 75/78] arm: dts: mediatek: mt6589: add iommu interrupt-names Signed-off-by: Akari Tsuyukusa --- arch/arm/boot/dts/mediatek/mt6589.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index 507dee1ddd3d30..f9ca4ec1765771 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -437,6 +437,7 @@ , , ; + interrupt-names = "m4u0", "m4u1", "m4ul2", "m4ul2-sec"; clocks = <&infracfg CLK_INFRA_M4U>; clock-names = "bclk"; mediatek,larbs = <&larb0>, <&larb1>, <&larb2>, From f677e5aab1a964cc8a645dd71ff4ec42ab52d168 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 30 Jun 2026 12:51:35 +0900 Subject: [PATCH 76/78] iommu: drop mt6589's --- arch/arm/configs/lenovo-blade_defconfig | 2 +- drivers/iommu/Kconfig | 14 - drivers/iommu/Makefile | 1 - drivers/iommu/mtk_iommu_mt6589.c | 758 ------------------------ 4 files changed, 1 insertion(+), 774 deletions(-) delete mode 100644 drivers/iommu/mtk_iommu_mt6589.c diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index 8a8a966c5e6112..ea66c838702a5a 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -31,7 +31,7 @@ CONFIG_ARM_CPUIDLE=y ## IOMMU CONFIG_IOMMU_SUPPORT=y -CONFIG_MTK_IOMMU_MT6589=y +CONFIG_MTK_IOMMU_V1=y ## SMI CONFIG_MEMORY=y diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index dd3010df9a5dcf..0a33d995d15dd7 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -350,20 +350,6 @@ config MTK_IOMMU_V1 if unsure, say N here. -config MTK_IOMMU_MT6589 - tristate "MediaTek MT6589 IOMMU Support" - depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST - select ARM_DMA_USE_IOMMU - select IOMMU_API - select MEMORY - select MTK_SMI - help - Support for the M4U on Mediatek MT6589 SoC. M4U is Multimedia Memory - Managememt Unit. This option enables remapping of DMA memory accesses - for the multimedia subsystem. - - if unsure, say N here. - config HYPERV_IOMMU bool "Hyper-V IRQ Handling" depends on HYPERV && X86 diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 9b04fe0d8c19e4..355294fa9033f3 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o obj-$(CONFIG_MTK_IOMMU_V1) += mtk_iommu_v1.o -obj-$(CONFIG_MTK_IOMMU_MT6589) += mtk_iommu_mt6589.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o diff --git a/drivers/iommu/mtk_iommu_mt6589.c b/drivers/iommu/mtk_iommu_mt6589.c deleted file mode 100644 index bc23730d67b3ca..00000000000000 --- a/drivers/iommu/mtk_iommu_mt6589.c +++ /dev/null @@ -1,758 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * IOMMU API for MTK architected MT6589 M4U implementations - * - * Copyright (c) 2026 Akari Tsuyukusa - * - * Copyright (c) 2015-2016 MediaTek Inc. - * Author: Honghui Zhang - * - * Based on driver/iommu/mtk_iommu.c, driver/iommu/mtk_iommu_v1.c - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_ARM) -#include -#else -#define arm_iommu_create_mapping(...) NULL -#define arm_iommu_attach_device(...) -ENODEV -struct dma_iommu_mapping { - struct iommu_domain *domain; -}; -#endif - -#define REG_MMU_PT_BASE_ADDR 0x000 - -#define F_ALL_INVLD 0x2 -#define F_MMU_INV_RANGE 0x1 -#define F_INVLD_EN0 BIT(0) -#define F_INVLD_EN1 BIT(1) - -#define F_MMU_FAULT_VA_MSK 0xfffff000 -#define MTK_PROTECT_PA_ALIGN 128 - -#define REG_MMU_CTRL_REG 0x210 -#define F_MMU_CTRL_COHERENT_EN BIT(8) -#define REG_MMU_IVRP_PADDR 0x214 -#define REG_MMU_INT_CONTROL 0x220 -#define F_INT_TRANSLATION_FAULT BIT(0) -#define F_INT_MAIN_MULTI_HIT_FAULT BIT(1) -#define F_INT_INVALID_PA_FAULT BIT(2) -#define F_INT_ENTRY_REPLACEMENT_FAULT BIT(3) -#define F_INT_TABLE_WALK_FAULT BIT(4) -#define F_INT_TLB_MISS_FAULT BIT(5) -#define F_INT_PFH_DMA_FIFO_OVERFLOW BIT(6) -#define F_INT_MISS_DMA_FIFO_OVERFLOW BIT(7) - -#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) -#define F_INT_CLR_BIT BIT(12) - -#define REG_MMU_FAULT_ST 0x224 -#define REG_MMU_FAULT_VA 0x228 -#define REG_MMU_INVLD_PA 0x22C -#define REG_MMU_INT_ID 0x388 -#define REG_MMU_INVALIDATE 0x5c0 -#define REG_MMU_INVLD_START_A 0x5c4 -#define REG_MMU_INVLD_END_A 0x5c8 - -#define REG_MMU_INV_SEL 0x5d8 -#define REG_MMU_STANDARD_AXI_MODE 0x5e8 - -#define REG_MMU_DCM 0x5f0 -#define F_MMU_DCM_ON BIT(1) -#define REG_MMU_CPE_DONE 0x60c -#define F_DESC_VALID 0x2 -#define F_DESC_NONSEC BIT(3) - -#define MT65XX_MMU_INT_ID_PORT_ID GENMASK(12, 8) -#define MT65XX_MMU_INT_ID_LARB_ID GENMASK(14, 13) - -#define MT65XX_M4U_TF_PORT(TF) FIELD_GET(MT65XX_MMU_INT_ID_PORT_ID, TF) -#define MT65XX_M4U_TF_LARB(TF) (FIELD_GET(MT65XX_MMU_INT_ID_LARB_ID, TF) - 1) - -/* MTK generation one iommu HW only support 4K size mapping */ -#define MT2701_IOMMU_PAGE_SHIFT 12 -#define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) -#define MT6589_LARB_NR_MAX 4 - -/* - * MTK m4u support 4GB iova address space, and only support 4K page - * mapping. So the pagetable size should be exactly as 4M. - */ -#define M2701_IOMMU_PGT_SIZE SZ_4M - -struct mtk_iommu_v1_suspend_reg { - u32 standard_axi_mode; - u32 dcm_dis; - u32 ctrl_reg; - u32 int_control0; -}; - -struct mtk_iommu_v1_data { - void __iomem *base; - int irq; - struct device *dev; - struct clk *bclk; - phys_addr_t protect_base; /* protect memory base */ - struct mtk_iommu_v1_domain *m4u_dom; - - struct iommu_device iommu; - struct dma_iommu_mapping *mapping; - struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; - - struct mtk_iommu_v1_suspend_reg reg; -}; - -struct mtk_iommu_v1_domain { - spinlock_t pgtlock; /* lock for page table */ - struct iommu_domain domain; - u32 *pgt_va; - dma_addr_t pgt_pa; - struct mtk_iommu_v1_data *data; -}; - -static int mtk_iommu_v1_bind(struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); - - return component_bind_all(dev, &data->larb_imu); -} - -static void mtk_iommu_v1_unbind(struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); - - component_unbind_all(dev, &data->larb_imu); -} - -static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) -{ - return container_of(dom, struct mtk_iommu_v1_domain, domain); -} - -static const int mt6589_m4u_in_larb[] = { - MT6589_LARB0_PORT_OFFSET, MT6589_LARB1_PORT_OFFSET, - MT6589_LARB2_PORT_OFFSET, MT6589_LARB3_PORT_OFFSET -}; - -static inline int mt6589_m4u_to_larb(int id) -{ - int i; - - for (i = ARRAY_SIZE(mt6589_m4u_in_larb) - 1; i >= 0; i--) - if ((id) >= mt6589_m4u_in_larb[i]) - return i; - - return 0; -} - -static inline int mt6589_m4u_to_port(int id) -{ - int larb = mt6589_m4u_to_larb(id); - - return id - mt6589_m4u_in_larb[larb]; -} - -static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) -{ - u32 val = F_INVLD_EN0; - writel_relaxed(val, data->base + REG_MMU_INV_SEL); - writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); - wmb(); /* Make sure the tlb flush all done */ -} - -static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, - unsigned long iova, size_t size) -{ - u32 val = F_INVLD_EN0; - writel_relaxed(val, data->base + REG_MMU_INV_SEL); - writel_relaxed(iova & F_MMU_FAULT_VA_MSK, - data->base + REG_MMU_INVLD_START_A); - writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, - data->base + REG_MMU_INVLD_END_A); - writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); - wmb(); -} - -static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) -{ - struct mtk_iommu_v1_data *data = dev_id; - struct mtk_iommu_v1_domain *dom = data->m4u_dom; - u32 int_state, regval, fault_iova, fault_pa; - unsigned int fault_larb, fault_port; - - /* Read error information from registers */ - int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST); - fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA); - - fault_iova &= F_MMU_FAULT_VA_MSK; - fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); - regval = readl_relaxed(data->base + REG_MMU_INT_ID); - - fault_larb = MT65XX_M4U_TF_LARB(regval); - fault_port = MT65XX_M4U_TF_PORT(regval); - - /* - * MTK v1 iommu HW could not determine whether the fault is read or - * write fault, report as read fault. - */ - if (report_iommu_fault(&dom->domain, data->dev, fault_iova, - IOMMU_FAULT_READ)) - dev_err_ratelimited(data->dev, - "fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d\n", - int_state, fault_iova, fault_pa, - fault_larb, fault_port); - - /* Interrupt clear */ - regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL); - regval |= F_INT_CLR_BIT; - writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); - - mtk_iommu_v1_tlb_flush_all(data); - - return IRQ_HANDLED; -} - -static void mtk_iommu_v1_config(struct mtk_iommu_v1_data *data, - struct device *dev, bool enable) -{ - struct mtk_smi_larb_iommu *larb_mmu; - unsigned int larbid, portid; - struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); - int i; - - for (i = 0; i < fwspec->num_ids; ++i) { - larbid = mt6589_m4u_to_larb(fwspec->ids[i]); - portid = mt6589_m4u_to_port(fwspec->ids[i]); - larb_mmu = &data->larb_imu[larbid]; - - dev_dbg(dev, "%s iommu port: %d\n", - str_enable_disable(enable), portid); - - if (enable) - larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); - else - larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); - } -} - -static int mtk_iommu_v1_domain_finalise(struct mtk_iommu_v1_data *data) -{ - struct mtk_iommu_v1_domain *dom = data->m4u_dom; - - spin_lock_init(&dom->pgtlock); - - dom->pgt_va = dma_alloc_coherent(data->dev, M2701_IOMMU_PGT_SIZE, - &dom->pgt_pa, GFP_KERNEL); - if (!dom->pgt_va) - return -ENOMEM; - - writel(dom->pgt_pa, data->base + REG_MMU_PT_BASE_ADDR); - - dom->data = data; - - return 0; -} - -static struct iommu_domain *mtk_iommu_v1_domain_alloc_paging(struct device *dev) -{ - struct mtk_iommu_v1_domain *dom; - - dom = kzalloc(sizeof(*dom), GFP_KERNEL); - if (!dom) - return NULL; - - return &dom->domain; -} - -static void mtk_iommu_v1_domain_free(struct iommu_domain *domain) -{ - struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); - struct mtk_iommu_v1_data *data = dom->data; - - dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE, - dom->pgt_va, dom->pgt_pa); - kfree(to_mtk_domain(domain)); -} - -static int mtk_iommu_v1_attach_device(struct iommu_domain *domain, struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); - struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); - struct dma_iommu_mapping *mtk_mapping; - int ret; - - /* Only allow the domain created internally. */ - mtk_mapping = data->mapping; - if (mtk_mapping->domain != domain) - return 0; - - if (!data->m4u_dom) { - data->m4u_dom = dom; - ret = mtk_iommu_v1_domain_finalise(data); - if (ret) { - data->m4u_dom = NULL; - return ret; - } - } - - mtk_iommu_v1_config(data, dev, true); - return 0; -} - -static int mtk_iommu_v1_identity_attach(struct iommu_domain *identity_domain, - struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); - - mtk_iommu_v1_config(data, dev, false); - return 0; -} - -static struct iommu_domain_ops mtk_iommu_v1_identity_ops = { - .attach_dev = mtk_iommu_v1_identity_attach, -}; - -static struct iommu_domain mtk_iommu_v1_identity_domain = { - .type = IOMMU_DOMAIN_IDENTITY, - .ops = &mtk_iommu_v1_identity_ops, -}; - -static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t pgsize, size_t pgcount, - int prot, gfp_t gfp, size_t *mapped) -{ - struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); - unsigned long flags; - unsigned int i; - u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); - u32 pabase = (u32)paddr; - - spin_lock_irqsave(&dom->pgtlock, flags); - for (i = 0; i < pgcount; i++) { - if (pgt_base_iova[i]) - break; - pgt_base_iova[i] = pabase | F_DESC_VALID | F_DESC_NONSEC; - pabase += MT2701_IOMMU_PAGE_SIZE; - } - - spin_unlock_irqrestore(&dom->pgtlock, flags); - - *mapped = i * MT2701_IOMMU_PAGE_SIZE; - mtk_iommu_v1_tlb_flush_range(dom->data, iova, *mapped); - - return i == pgcount ? 0 : -EEXIST; -} - -static size_t mtk_iommu_v1_unmap(struct iommu_domain *domain, unsigned long iova, - size_t pgsize, size_t pgcount, - struct iommu_iotlb_gather *gather) -{ - struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); - unsigned long flags; - u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); - size_t size = pgcount * MT2701_IOMMU_PAGE_SIZE; - - spin_lock_irqsave(&dom->pgtlock, flags); - memset(pgt_base_iova, 0, pgcount * sizeof(u32)); - spin_unlock_irqrestore(&dom->pgtlock, flags); - - mtk_iommu_v1_tlb_flush_range(dom->data, iova, size); - - return size; -} - -static phys_addr_t mtk_iommu_v1_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) -{ - struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); - unsigned long flags; - phys_addr_t pa; - - spin_lock_irqsave(&dom->pgtlock, flags); - pa = *(dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT)); - pa = pa & (~(MT2701_IOMMU_PAGE_SIZE - 1)); - spin_unlock_irqrestore(&dom->pgtlock, flags); - - return pa; -} - -static const struct iommu_ops mtk_iommu_v1_ops; - -/* - * MTK generation one iommu HW only support one iommu domain, and all the client - * sharing the same iova address space. - */ -static int mtk_iommu_v1_create_mapping(struct device *dev, - const struct of_phandle_args *args) -{ - struct mtk_iommu_v1_data *data; - struct platform_device *m4updev; - struct dma_iommu_mapping *mtk_mapping; - int ret; - - if (args->args_count != 1) { - dev_err(dev, "invalid #iommu-cells(%d) property for IOMMU\n", - args->args_count); - return -EINVAL; - } - - ret = iommu_fwspec_init(dev, of_fwnode_handle(args->np)); - if (ret) - return ret; - - if (!dev_iommu_priv_get(dev)) { - /* Get the m4u device */ - m4updev = of_find_device_by_node(args->np); - if (WARN_ON(!m4updev)) - return -EINVAL; - - dev_iommu_priv_set(dev, platform_get_drvdata(m4updev)); - } - - ret = iommu_fwspec_add_ids(dev, args->args, 1); - if (ret) - return ret; - - data = dev_iommu_priv_get(dev); - mtk_mapping = data->mapping; - if (!mtk_mapping) { - /* MTK iommu support 4GB iova address space. */ - mtk_mapping = arm_iommu_create_mapping(dev, 0, 1ULL << 32); - if (IS_ERR(mtk_mapping)) - return PTR_ERR(mtk_mapping); - - data->mapping = mtk_mapping; - } - - return 0; -} - -static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev) -{ - struct iommu_fwspec *fwspec = NULL; - struct of_phandle_args iommu_spec; - struct mtk_iommu_v1_data *data; - int err, idx = 0, larbid, larbidx; - struct device_link *link; - struct device *larbdev; - - while (!of_parse_phandle_with_args(dev->of_node, "iommus", - "#iommu-cells", - idx, &iommu_spec)) { - - err = mtk_iommu_v1_create_mapping(dev, &iommu_spec); - of_node_put(iommu_spec.np); - if (err) - return ERR_PTR(err); - - /* dev->iommu_fwspec might have changed */ - fwspec = dev_iommu_fwspec_get(dev); - idx++; - } - - if (!fwspec) - return ERR_PTR(-ENODEV); - - data = dev_iommu_priv_get(dev); - - /* Link the consumer device with the smi-larb device(supplier) */ - larbid = mt6589_m4u_to_larb(fwspec->ids[0]); - if (larbid >= MT6589_LARB_NR_MAX) - return ERR_PTR(-EINVAL); - - for (idx = 1; idx < fwspec->num_ids; idx++) { - larbidx = mt6589_m4u_to_larb(fwspec->ids[idx]); - if (larbid != larbidx) { - dev_err(dev, "Can only use one larb. Fail@larb%d-%d.\n", - larbid, larbidx); - return ERR_PTR(-EINVAL); - } - } - - larbdev = data->larb_imu[larbid].dev; - if (!larbdev) - return ERR_PTR(-EINVAL); - - link = device_link_add(dev, larbdev, - DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); - if (!link) - dev_err(dev, "Unable to link %s\n", dev_name(larbdev)); - - return &data->iommu; -} - -static void mtk_iommu_v1_probe_finalize(struct device *dev) -{ - struct dma_iommu_mapping *mtk_mapping; - struct mtk_iommu_v1_data *data; - int err; - - data = dev_iommu_priv_get(dev); - mtk_mapping = data->mapping; - - err = arm_iommu_attach_device(dev, mtk_mapping); - if (err) - dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n"); -} - -static void mtk_iommu_v1_release_device(struct device *dev) -{ - struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); - struct mtk_iommu_v1_data *data; - struct device *larbdev; - unsigned int larbid; - - data = dev_iommu_priv_get(dev); - larbid = mt6589_m4u_to_larb(fwspec->ids[0]); - larbdev = data->larb_imu[larbid].dev; - device_link_remove(dev, larbdev); -} - -static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) -{ - u32 regval; - int ret; - - ret = clk_prepare_enable(data->bclk); - if (ret) { - dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); - return ret; - } - - regval = F_MMU_TF_PROTECT_SEL(2); - writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); - - regval = F_INT_TRANSLATION_FAULT | - F_INT_MAIN_MULTI_HIT_FAULT | - F_INT_INVALID_PA_FAULT | - F_INT_ENTRY_REPLACEMENT_FAULT | - F_INT_TABLE_WALK_FAULT | - F_INT_TLB_MISS_FAULT | - F_INT_PFH_DMA_FIFO_OVERFLOW | - F_INT_MISS_DMA_FIFO_OVERFLOW; - writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); - - /* protect memory,hw will write here while translation fault */ - writel_relaxed(data->protect_base, - data->base + REG_MMU_IVRP_PADDR); - - writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM); - - if (devm_request_irq(data->dev, data->irq, mtk_iommu_v1_isr, 0, - dev_name(data->dev), (void *)data)) { - writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); - clk_disable_unprepare(data->bclk); - dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); - return -ENODEV; - } - - return 0; -} - -static const struct iommu_ops mtk_iommu_v1_ops = { - .identity_domain = &mtk_iommu_v1_identity_domain, - .domain_alloc_paging = mtk_iommu_v1_domain_alloc_paging, - .probe_device = mtk_iommu_v1_probe_device, - .probe_finalize = mtk_iommu_v1_probe_finalize, - .release_device = mtk_iommu_v1_release_device, - .device_group = generic_device_group, - .pgsize_bitmap = MT2701_IOMMU_PAGE_SIZE, - .owner = THIS_MODULE, - .default_domain_ops = &(const struct iommu_domain_ops) { - .attach_dev = mtk_iommu_v1_attach_device, - .map_pages = mtk_iommu_v1_map, - .unmap_pages = mtk_iommu_v1_unmap, - .iova_to_phys = mtk_iommu_v1_iova_to_phys, - .free = mtk_iommu_v1_domain_free, - } -}; - -static const struct of_device_id mtk_iommu_v1_of_ids[] = { - { .compatible = "mediatek,mt6589-m4u" }, - {} -}; -MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); - -static const struct component_master_ops mtk_iommu_v1_com_ops = { - .bind = mtk_iommu_v1_bind, - .unbind = mtk_iommu_v1_unbind, -}; - -static int mtk_iommu_v1_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct mtk_iommu_v1_data *data; - struct resource *res; - struct component_match *match = NULL; - void *protect; - int larb_nr, ret, i; - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->dev = dev; - - /* Protect memory. HW will access here while translation fault.*/ - protect = devm_kcalloc(dev, 2, MTK_PROTECT_PA_ALIGN, - GFP_KERNEL | GFP_DMA); - if (!protect) - return -ENOMEM; - data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data->base = devm_ioremap_resource(dev, res); - if (IS_ERR(data->base)) - return PTR_ERR(data->base); - - data->irq = platform_get_irq(pdev, 0); - if (data->irq < 0) - return data->irq; - - data->bclk = devm_clk_get(dev, "bclk"); - if (IS_ERR(data->bclk)) - return PTR_ERR(data->bclk); - - larb_nr = of_count_phandle_with_args(dev->of_node, - "mediatek,larbs", NULL); - if (larb_nr < 0) - return larb_nr; - - for (i = 0; i < larb_nr; i++) { - struct device_node *larbnode; - struct platform_device *plarbdev; - - larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); - if (!larbnode) - return -EINVAL; - - if (!of_device_is_available(larbnode)) { - of_node_put(larbnode); - continue; - } - - plarbdev = of_find_device_by_node(larbnode); - if (!plarbdev) { - of_node_put(larbnode); - return -ENODEV; - } - if (!plarbdev->dev.driver) { - of_node_put(larbnode); - return -EPROBE_DEFER; - } - data->larb_imu[i].dev = &plarbdev->dev; - - component_match_add_release(dev, &match, component_release_of, - component_compare_of, larbnode); - } - - platform_set_drvdata(pdev, data); - - ret = mtk_iommu_v1_hw_init(data); - if (ret) - return ret; - - ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, - dev_name(&pdev->dev)); - if (ret) - goto out_clk_unprepare; - - ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev); - if (ret) - goto out_sysfs_remove; - - ret = component_master_add_with_match(dev, &mtk_iommu_v1_com_ops, match); - if (ret) - goto out_dev_unreg; - return ret; - -out_dev_unreg: - iommu_device_unregister(&data->iommu); -out_sysfs_remove: - iommu_device_sysfs_remove(&data->iommu); -out_clk_unprepare: - clk_disable_unprepare(data->bclk); - return ret; -} - -static void mtk_iommu_v1_remove(struct platform_device *pdev) -{ - struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev); - - iommu_device_sysfs_remove(&data->iommu); - iommu_device_unregister(&data->iommu); - - clk_disable_unprepare(data->bclk); - devm_free_irq(&pdev->dev, data->irq, data); - component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops); -} - -static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); - struct mtk_iommu_v1_suspend_reg *reg = &data->reg; - void __iomem *base = data->base; - - reg->standard_axi_mode = readl_relaxed(base + - REG_MMU_STANDARD_AXI_MODE); - reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM); - reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); - reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL); - return 0; -} - -static int __maybe_unused mtk_iommu_v1_resume(struct device *dev) -{ - struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); - struct mtk_iommu_v1_suspend_reg *reg = &data->reg; - void __iomem *base = data->base; - - writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR); - writel_relaxed(reg->standard_axi_mode, - base + REG_MMU_STANDARD_AXI_MODE); - writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM); - writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); - writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL); - writel_relaxed(data->protect_base, base + REG_MMU_IVRP_PADDR); - return 0; -} - -static const struct dev_pm_ops mtk_iommu_v1_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_v1_suspend, mtk_iommu_v1_resume) -}; - -static struct platform_driver mtk_iommu_v1_driver = { - .probe = mtk_iommu_v1_probe, - .remove = mtk_iommu_v1_remove, - .driver = { - .name = "mtk-iommu-v1", - .of_match_table = mtk_iommu_v1_of_ids, - .pm = &mtk_iommu_v1_pm_ops, - } -}; -module_platform_driver(mtk_iommu_v1_driver); - -MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations"); -MODULE_LICENSE("GPL v2"); From f01ef2250e39ce1156e1173d2d327b18c1690f70 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 30 Jun 2026 12:53:25 +0900 Subject: [PATCH 77/78] iommu/mediatek-v1: add larb port offset prefix --- drivers/iommu/mtk_iommu_v1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 66824982e05fbf..3e359f6aede016 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -146,8 +146,8 @@ static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) } static const int mt2701_m4u_in_larb[] = { - LARB0_PORT_OFFSET, LARB1_PORT_OFFSET, - LARB2_PORT_OFFSET, LARB3_PORT_OFFSET + MT2701_LARB0_PORT_OFFSET, MT2701_LARB1_PORT_OFFSET, + MT2701_LARB2_PORT_OFFSET, MT2701_LARB3_PORT_OFFSET }; static inline int mt2701_m4u_to_larb(int id) From 8005cabe525f0b65f7d4e8ddf2bf2c860e55d4c5 Mon Sep 17 00:00:00 2001 From: Akari Tsuyukusa Date: Tue, 30 Jun 2026 13:00:33 +0900 Subject: [PATCH 78/78] memory: mtk-smi: update mt6589 port_in_larb based on smi_port0_in_larbx --- drivers/memory/mtk-smi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index f82a77447ecaa4..38c4734d25e1b3 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c @@ -539,7 +539,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = { }; static const struct mtk_smi_larb_gen mtk_smi_larb_mt6589 = { - .port_in_larb = { 0, 10, 17, 29, 43, 53, 54, 54 }, + .port_in_larb = { 0, 10, 17, 29, 44 ,56 }, .config_port = mtk_smi_larb_config_port_gen0, .flags_general = MTK_SMI_FLAG_BW_CALIBRATE, };