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 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 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 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 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 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 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 diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml index 0762e0ff66ef02..35d7d4c1ca6b65 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 @@ -51,9 +52,6 @@ properties: - const: mediatek,mt7623-smi-common - const: mediatek,mt2701-smi-common - reg: - maxItems: 1 - power-domains: maxItems: 1 @@ -86,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: 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 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 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 diff --git a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi index 645267e60fe9b2..1f497944a0222a 100644 --- a/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589-lenovo-b8000.dtsi @@ -13,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>; + }; }; }; diff --git a/arch/arm/boot/dts/mediatek/mt6589.dtsi b/arch/arm/boot/dts/mediatek/mt6589.dtsi index ce940c302fa618..9e31477cad0d4a 100644 --- a/arch/arm/boot/dts/mediatek/mt6589.dtsi +++ b/arch/arm/boot/dts/mediatek/mt6589.dtsi @@ -9,6 +9,8 @@ #include #include #include +#include +#include / { #address-cells = <1>; @@ -113,6 +115,75 @@ #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 = ; + // 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>; + }; + + 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 = ; + // clock get failed + // clocks = <&topckgen CLK_TOP_MUX_VDEC>; + // clock-names = "vdec"; + #power-domain-cells = <0>; + }; + }; + }; + mfgsys: syscon@10206000 { compatible = "mediatek,mt6589-mfgsys", "syscon"; reg = <0x10206000 0x1000>; @@ -305,6 +376,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 +395,41 @@ reg = <0x10200100 0x1c>; }; + smi_common: smi@10202000 { + compatible = "mediatek,mt6589-smi-common"; + reg = <0x10202000 0x1000>, <0x1000e000 0x1000>; + clocks = <&infracfg CLK_INFRA_SMI>, + <&infracfg CLK_INFRA_SMI>; + clock-names = "apb", "smi"; + 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 { + compatible = "mediatek,mt6589-m4u"; + reg = <0x10205800 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb2>, <&larb4>; + #iommu-cells = <1>; + }; + gic: interrupt-controller@10211000 { compatible = "arm,cortex-a7-gic"; interrupt-controller; @@ -443,6 +559,119 @@ 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 = <&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 */ + }; + + 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 = <&iommu1 MT6589_M4U_PORT_RDMA0>; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + 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 = <&iommu1 MT6589_M4U_PORT_RDMA1>; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + mutex: mutex@14011000 { + compatible = "mediatek,mt6589-disp-mutex"; + reg = <0x14011000 0x1000>; + interrupts = ; + /* not found in clock list */ + clocks = <&clk26m>; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + 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 = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + status = "disabled"; + }; + + larb0: larb@17001000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x17001000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&vencsys CLK_VENC_VEN>, + <&vencsys CLK_VENC_VEN>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + larb1: larb@16010000 { + compatible = "mediatek,mt6589-smi-larb"; + reg = <0x16010000 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <1>; + clocks = <&vdecsys CLK_VDEC0_VDE>, + <&vdecsys CLK_VDEC1_SMI>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + 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>, + <&dispsys CLK_DISP0_LARB2_SMI>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + 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>, + <&imgsys CLK_IMAGE_LARB3_SMI>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; + + 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>, + <&imgsys CLK_IMAGE_LARB4_SMI>; + clock-names = "apb", "smi"; + power-domains = <&spm MT6589_POWER_DOMAIN_DIS>; /* maybe */ + }; }; }; diff --git a/arch/arm/configs/lenovo-blade_defconfig b/arch/arm/configs/lenovo-blade_defconfig index 70269fdf50122a..c922d96def321a 100644 --- a/arch/arm/configs/lenovo-blade_defconfig +++ b/arch/arm/configs/lenovo-blade_defconfig @@ -31,12 +31,21 @@ CONFIG_ARM_CPUIDLE=y ## IOMMU CONFIG_IOMMU_SUPPORT=y -# MediaTek M4U -#CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU_V1=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_PHY_MTK_MIPI_DSI=y +CONFIG_MTK_MMSYS=y -## Framebuffer CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -119,6 +128,9 @@ CONFIG_BMC150_MAGN_I2C=y ## Reset #CONFIG_RESET_CONTROLLER +## Power Management +CONFIG_MTK_SCPSYS_PM_DOMAINS=y + ## Battery ## Regulator diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index e0236353d4997e..99544a3e7ffd36 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) @@ -671,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, @@ -742,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", 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", 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 }, diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 9f81fa960b4602..38e8b2f5972884 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_hx8896_a01_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 diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 66824982e05fbf..5fb334074f680a 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,8 @@ 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 }, + { .compatible = "mediatek,mt6589-m4u", .data = (void *)MTK_IOMMU_MT65XX }, {} }; MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids); @@ -618,6 +651,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, diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index c086c22511f7f6..2c381dfdb5806e 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,19 @@ #define SMI_LARB_SW_FLAG 0x40 #define SMI_LARB_SW_FLAG_1 0x1 +/* 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)) +#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 +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_BWFILTER_REG_V2 BIT(5) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) struct mtk_smi_reg_pair { @@ -100,6 +113,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 +155,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; }; @@ -188,6 +200,71 @@ 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, offset; + 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)) { + 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 + offset); + + 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 + offset); + writel_relaxed(0xffffffff, + larb->base + offset); + } + } + + return 0; +} + static int mtk_smi_larb_config_port_gen1(struct device *dev) { struct mtk_smi_larb *larb = dev_get_drvdata(dev); @@ -283,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}, @@ -459,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 = @@ -515,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}, @@ -562,25 +648,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; } @@ -641,6 +730,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; } @@ -651,6 +741,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) @@ -701,6 +792,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}, @@ -725,6 +820,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, @@ -805,6 +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,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}, @@ -845,31 +946,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); @@ -884,6 +996,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) @@ -897,13 +1010,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; } 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) diff --git a/drivers/soc/mediatek/mt6589-dispsys.h b/drivers/soc/mediatek/mt6589-dispsys.h new file mode 100644 index 00000000000000..91e8bf5f2ca640 --- /dev/null +++ b/drivers/soc/mediatek/mt6589-dispsys.h @@ -0,0 +1,172 @@ +/* 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" + +/* + * 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 + */ + +#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) +#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[] = { + /* + * 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, DBI0, + MT6589_DISP_RDMA0_OUT_SEL, + MT6589_RDMA0_SOUT_MASK, MT6589_RDMA0_SOUT_DBI), + + /* RDMA0 → DPI0 (OVL-sourced) */ + MMSYS_ROUTE(RDMA0, DPI0, + MT6589_DISP_RDMA0_OUT_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_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), + + /* RDMA1 → DPI1 */ + MMSYS_ROUTE(RDMA1, 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, + MT6589_DISP_SCL_MOUT_EN, + MT6589_SCL_MOUT_EN_MASK, MT6589_SCL_MOUT_EN_WDMA0), +}; + +#endif /* __SOC_MEDIATEK_MT6589_DISPSYS_H */ diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index bb4639ca0b8cdc..5597fceb26ace1 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 }, diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c index aaa965d4b050a7..a8e65bfd543389 100644 --- a/drivers/soc/mediatek/mtk-mutex.c +++ b/drivers/soc/mediatek/mtk-mutex.c @@ -377,6 +377,20 @@ 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] = { + [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] = { [DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL, [DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR, @@ -724,6 +738,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 +1150,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 }, 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..34d5197ac2fe06 --- /dev/null +++ b/include/dt-bindings/memory/mt6589-larb-port.h @@ -0,0 +1,82 @@ +// 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_ + +#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 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 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 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 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 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 MT6589_M4U_ID_LARB5(0) + +#endif diff --git a/include/dt-bindings/power/mt6589-power.h b/include/dt-bindings/power/mt6589-power.h new file mode 100644 index 00000000000000..14d2c941015543 --- /dev/null +++ b/include/dt-bindings/power/mt6589-power.h @@ -0,0 +1,16 @@ +/* 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 + +#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 */ diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h index 4885b065b849fb..d1b258510550b5 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,9 +79,12 @@ 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, + DDP_COMPONENT_DBI0, DDP_COMPONENT_ID_MAX, };