dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] eDP driver for mt8196
@ 2025-04-18  6:52 Bincai Liu
  2025-04-18  6:52 ` [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml " Bincai Liu
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu


Bincai Liu (5):
  dt-bindings: eDP: mediatek: add eDP yaml for mt8196
  dt-bindings: dvo: mediatek: add dvo yaml for mt8196
  drm/mediatek: Add dvo driver for mt8196
  drm/mediatek: Add eDP driver for mt8196
  drm/mediatek: Add eDP phy driver for mt8196

 .../display/mediatek/mediatek,dp.yaml         |   2 +
 .../display/mediatek/mediatek,dpi.yaml        |   1 +
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c       |   5 +-
 drivers/gpu/drm/mediatek/mtk_ddp_comp.h       |   1 +
 drivers/gpu/drm/mediatek/mtk_dp.c             | 484 +++++++++++++++---
 drivers/gpu/drm/mediatek/mtk_dp_reg.h         | 126 +++++
 drivers/gpu/drm/mediatek/mtk_dpi.c            | 240 +++++++--
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h       |  66 +++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |   5 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/phy/mediatek/Makefile                 |   1 +
 drivers/phy/mediatek/phy-mtk-edp.c            | 262 ++++++++++
 12 files changed, 1100 insertions(+), 94 deletions(-)
 create mode 100644 drivers/phy/mediatek/phy-mtk-edp.c

-- 
2.45.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml for mt8196
  2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
@ 2025-04-18  6:52 ` Bincai Liu
  2025-04-21  5:09   ` CK Hu (胡俊光)
  2025-04-18  6:52 ` [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo " Bincai Liu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu

Add compatible string to support eDP for MT8196.

Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,dp.yaml       | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
index 75ce92f4a5fd..26997feba66b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
@@ -25,6 +25,7 @@ properties:
       - mediatek,mt8188-edp-tx
       - mediatek,mt8195-dp-tx
       - mediatek,mt8195-edp-tx
+      - mediatek,mt8196-edp-tx
 
   reg:
     maxItems: 1
@@ -98,6 +99,7 @@ allOf:
               enum:
                 - mediatek,mt8188-dp-tx
                 - mediatek,mt8195-dp-tx
+                - mediatek,mt8196-edp-tx
     then:
       properties:
         '#sound-dai-cells': false
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo yaml for mt8196
  2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
  2025-04-18  6:52 ` [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml " Bincai Liu
@ 2025-04-18  6:52 ` Bincai Liu
  2025-04-21  5:07   ` CK Hu (胡俊光)
  2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu

Add compatible string to support dvo for MT8196.

Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,dpi.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
index b659d79393a8..4f897f05cb36 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
@@ -28,6 +28,7 @@ properties:
           - mediatek,mt8192-dpi
           - mediatek,mt8195-dp-intf
           - mediatek,mt8195-dpi
+          - mediatek,mt8196-edp-dvo
       - items:
           - enum:
               - mediatek,mt6795-dpi
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
  2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
  2025-04-18  6:52 ` [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml " Bincai Liu
  2025-04-18  6:52 ` [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo " Bincai Liu
@ 2025-04-18  6:52 ` Bincai Liu
  2025-04-19  7:19   ` kernel test robot
                     ` (2 more replies)
  2025-04-18  6:52 ` [PATCH 4/5] drm/mediatek: Add eDP " Bincai Liu
  2025-04-18  6:52 ` [PATCH 5/5] drm/mediatek: Add eDP phy " Bincai Liu
  4 siblings, 3 replies; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu

Add code to support dvo for mt8196.

Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_ddp_comp.c |   5 +-
 drivers/gpu/drm/mediatek/mtk_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 240 ++++++++++++++++++++----
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |  66 +++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   5 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
 6 files changed, 284 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index edc6417639e6..7fbb9509fb0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -445,6 +445,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DP_INTF] = "dp-intf",
 	[MTK_DPI] = "dpi",
 	[MTK_DSI] = "dsi",
+	[MTK_DVO] = "dvo",
 };
 
 struct mtk_ddp_comp_match {
@@ -472,6 +473,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]		= { MTK_DSI,			3, &ddp_dsi },
+	[DDP_COMPONENT_DVO0]            = { MTK_DVO,                    0, &ddp_dpi },
 	[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,		0, &ddp_gamma },
 	[DDP_COMPONENT_MERGE0]		= { MTK_DISP_MERGE,		0, &ddp_merge },
 	[DDP_COMPONENT_MERGE1]		= { MTK_DISP_MERGE,		1, &ddp_merge },
@@ -662,7 +664,8 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
 	    type == MTK_DP_INTF ||
-	    type == MTK_DSI)
+	    type == MTK_DSI ||
+	    type == MTK_DVO)
 		return 0;
 
 	priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
index 39720b27f4e9..daa98a594acb 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
@@ -43,6 +43,7 @@ enum mtk_ddp_comp_type {
 	MTK_DPI,
 	MTK_DP_INTF,
 	MTK_DSI,
+	MTK_DVO,
 	MTK_DDP_COMP_TYPE_MAX,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 0f3b1ef8e497..98d385905a0e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -62,6 +62,29 @@ enum mtk_dpi_out_color_format {
 	MTK_DPI_COLOR_FORMAT_YCBCR_422
 };
 
+enum mtk_dpi_golden_setting_level {
+	MTK_DPI_FHD_60FPS_1920 = 0,
+	MTK_DPI_FHD_60FPS_2180,
+	MTK_DPI_FHD_60FPS_2400,
+	MTK_DPI_FHD_60FPS_2520,
+	MTK_DPI_FHD_90FPS,
+	MTK_DPI_FHD_120FPS,
+	MTK_DPI_WQHD_60FPS,
+	MTK_DPI_WQHD_120FPS,
+	MTK_DPI_8K_30FPS,
+	MTK_DPI_GSL_MAX,
+};
+
+enum mtk_dpi_type {
+	MTK_DISP_DPI = 0,
+	MTK_DSIP_DVO,
+};
+
+struct mtk_dpi_gs_info {
+	u32 dpi_buf_sodi_high;
+	u32 dpi_buf_sodi_low;
+};
+
 struct mtk_dpi {
 	struct drm_encoder encoder;
 	struct drm_bridge bridge;
@@ -73,6 +96,7 @@ struct mtk_dpi {
 	struct clk *engine_clk;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
+	struct clk *hf_fdpi_clk;
 	int irq;
 	struct drm_display_mode mode;
 	const struct mtk_dpi_conf *conf;
@@ -85,6 +109,7 @@ struct mtk_dpi {
 	struct pinctrl_state *pins_dpi;
 	u32 output_fmt;
 	int refcount;
+	enum mtk_dpi_golden_setting_level gs_level;
 };
 
 static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
@@ -171,6 +196,13 @@ struct mtk_dpi_conf {
 	bool edge_cfg_in_mmsys;
 	bool clocked_by_hdmi;
 	bool output_1pixel;
+	u32 out_np_sel;
+	u8 dpi_ver;
+};
+
+static struct mtk_dpi_gs_info mtk_dpi_gs[MTK_DPI_GSL_MAX] = {
+	[MTK_DPI_FHD_60FPS_1920] = {6880, 511},
+	[MTK_DPI_8K_30FPS] = {5255, 3899},
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -208,6 +240,86 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
 	mtk_dpi_mask(dpi, DPI_EN, 0, EN);
 }
 
+static void mtk_dpi_irq_enable(struct mtk_dpi *dpi)
+{
+	mtk_dpi_mask(dpi, DPI_INTEN, INT_VDE_END_EN, INT_VDE_END_EN);
+}
+
+static void mtk_dpi_info_queue_start(struct mtk_dpi *dpi)
+{
+	mtk_dpi_mask(dpi, DPI_TGEN_INFOQ_LATENCY, 0,
+		     INFOQ_START_LATENCY_MASK | INFOQ_END_LATENCY_MASK);
+}
+
+static void mtk_dpi_buffer_ctrl(struct mtk_dpi *dpi)
+{
+	mtk_dpi_mask(dpi, DPI_BUF_CON0, DISP_BUF_EN, DISP_BUF_EN);
+	mtk_dpi_mask(dpi, DPI_BUF_CON0, FIFO_UNDERFLOW_DONE_BLOCK, FIFO_UNDERFLOW_DONE_BLOCK);
+}
+
+static void mtk_dpi_trailing_blank_setting(struct mtk_dpi *dpi)
+{
+	mtk_dpi_mask(dpi, DPI_TGEN_V_LAST_TRAILING_BLANK, 0x20, V_LAST_TRAILING_BLANK_MASK);
+	mtk_dpi_mask(dpi, DPI_TGEN_OUTPUT_DELAY_LINE, 0x20, EXT_TG_DLY_LINE_MASK);
+}
+
+static void mtk_dpi_get_gs_level(struct mtk_dpi *dpi)
+{
+	struct drm_display_mode *mode = &dpi->mode;
+	enum mtk_dpi_golden_setting_level *gsl = &dpi->gs_level;
+
+	if (mode->hdisplay == 1920 && mode->vdisplay == 1080)
+		*gsl = MTK_DPI_FHD_60FPS_1920;
+	else
+		*gsl = MTK_DPI_8K_30FPS;
+}
+
+static void mtk_dpi_golden_setting(struct mtk_dpi *dpi)
+{
+	struct mtk_dpi_gs_info *gs_info = NULL;
+
+	if (dpi->gs_level >= MTK_DPI_GSL_MAX) {
+		dev_info(dpi->dev, "%s invalid gs_level %d\n",
+			 __func__, dpi->gs_level);
+		return;
+	}
+
+	gs_info = &mtk_dpi_gs[dpi->gs_level];
+
+	mtk_dpi_mask(dpi, DPI_BUF_SODI_HIGHT, gs_info->dpi_buf_sodi_high, GENMASK(31, 0));
+	mtk_dpi_mask(dpi, DPI_BUF_SODI_LOW, gs_info->dpi_buf_sodi_low, GENMASK(31, 0));
+}
+
+static void mtk_dpi_shadow_ctrl(struct mtk_dpi *dpi)
+{
+	mtk_dpi_mask(dpi, DPI_SHADOW_CTRL, 0, BYPASS_SHADOW);
+	mtk_dpi_mask(dpi, DPI_SHADOW_CTRL, FORCE_COMMIT, FORCE_COMMIT);
+}
+
+static void mtk_dpi_config_timing(struct mtk_dpi *dpi,
+				 struct mtk_dpi_sync_param *hsync,
+				 struct mtk_dpi_sync_param *vsync)
+{
+	mtk_dpi_mask(dpi, DPI_TGEN_H0,
+		     hsync->sync_width << HSYNC,
+		     dpi->conf->dimension_mask << HSYNC);
+	mtk_dpi_mask(dpi, DPI_TGEN_H0,
+		     hsync->front_porch << DPI_HFP,
+		     dpi->conf->dimension_mask << DPI_HFP);
+	mtk_dpi_mask(dpi, DPI_TGEN_H1,
+		     (hsync->back_porch + hsync->sync_width) << HSYNC2ACT,
+		     dpi->conf->dimension_mask << HSYNC2ACT);
+	mtk_dpi_mask(dpi, DPI_TGEN_V0,
+		     vsync->sync_width << VSYNC,
+		     dpi->conf->dimension_mask << VSYNC);
+	mtk_dpi_mask(dpi, DPI_TGEN_V0,
+		     vsync->front_porch << VFP,
+		     dpi->conf->dimension_mask << VFP);
+	mtk_dpi_mask(dpi, DPI_TGEN_V1,
+		     (vsync->back_porch + vsync->sync_width) << VSYNC2ACT,
+		     dpi->conf->dimension_mask << VSYNC2ACT);
+}
+
 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
 				 struct mtk_dpi_sync_param *sync)
 {
@@ -296,10 +408,27 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
 
 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
 {
-	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
-		     dpi->conf->hvsize_mask << HSIZE);
-	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
-		     dpi->conf->hvsize_mask << VSIZE);
+	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
+		mtk_dpi_mask(dpi, DPI_SRC_SIZE, width << SRC_HSIZE,
+			dpi->conf->hvsize_mask << SRC_HSIZE);
+		mtk_dpi_mask(dpi, DPI_SRC_SIZE, height << SRC_VSIZE,
+			dpi->conf->hvsize_mask << SRC_VSIZE);
+
+		mtk_dpi_mask(dpi, DPI_PIC_SIZE, width << PIC_HSIZE,
+			dpi->conf->hvsize_mask << PIC_HSIZE);
+		mtk_dpi_mask(dpi, DPI_PIC_SIZE, height << PIC_VSIZE,
+			dpi->conf->hvsize_mask << PIC_VSIZE);
+
+		mtk_dpi_mask(dpi, DPI_TGEN_H1, (width / dpi->conf->pixels_per_iter) << HACT,
+			dpi->conf->hvsize_mask << HACT);
+		mtk_dpi_mask(dpi, DPI_TGEN_V1, height << VACT,
+			dpi->conf->hvsize_mask << VACT);
+	} else {
+		mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
+			dpi->conf->hvsize_mask << HSIZE);
+		mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
+			dpi->conf->hvsize_mask << VSIZE);
+	}
 }
 
 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
@@ -501,6 +630,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->tvd_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->hf_fdpi_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -528,8 +658,16 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_pixel;
 	}
 
+	ret = clk_prepare_enable(dpi->hf_fdpi_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hf_fdpi_clk clock: %d\n", ret);
+		goto err_hf_fdpi_clk;
+	}
+
 	return 0;
 
+err_hf_fdpi_clk:
+	clk_disable_unprepare(dpi->hf_fdpi_clk);
 err_pixel:
 	clk_disable_unprepare(dpi->tvd_clk);
 err_engine:
@@ -610,7 +748,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
 	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
 			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
-
 	/*
 	 * Depending on the IP version, we may output a different amount of
 	 * pixels for each iteration: divide the clock by this number and
@@ -643,14 +780,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	}
 	mtk_dpi_sw_reset(dpi, true);
 	mtk_dpi_config_pol(dpi, &dpi_pol);
+	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
+		mtk_dpi_irq_enable(dpi);
+		mtk_dpi_config_timing(dpi, &hsync, &vsync_lodd);
+	} else {
+		mtk_dpi_config_hsync(dpi, &hsync);
+		mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
+		mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
+		mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
+		mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
+		mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
+	}
 
-	mtk_dpi_config_hsync(dpi, &hsync);
-	mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
-	mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
-	mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
-	mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
-
-	mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
 	mtk_dpi_config_interface(dpi, !!(vm.flags &
 					 DISPLAY_FLAGS_INTERLACED));
 	if (vm.flags & DISPLAY_FLAGS_INTERLACED)
@@ -658,26 +799,41 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
 
-	mtk_dpi_config_channel_limit(dpi);
-	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
-	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
-	mtk_dpi_config_color_format(dpi, dpi->color_format);
-	if (dpi->conf->support_direct_pin) {
-		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
-		mtk_dpi_config_2n_h_fre(dpi);
-
-		/* DPI can connect to either an external bridge or the internal HDMI encoder */
-		if (dpi->conf->output_1pixel)
-			mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
-		else
-			mtk_dpi_dual_edge(dpi);
-
-		mtk_dpi_config_disable_edge(dpi);
-	}
-	if (dpi->conf->input_2p_en_bit) {
-		mtk_dpi_mask(dpi, DPI_CON, dpi->conf->input_2p_en_bit,
-			     dpi->conf->input_2p_en_bit);
+	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
+		mtk_dpi_info_queue_start(dpi);
+		mtk_dpi_buffer_ctrl(dpi);
+		mtk_dpi_trailing_blank_setting(dpi);
+		mtk_dpi_get_gs_level(dpi);
+		mtk_dpi_golden_setting(dpi);
+		mtk_dpi_shadow_ctrl(dpi);
+		mtk_dpi_mask(dpi, DPI_OUTPUT_SET, dpi->conf->out_np_sel, OUT_NP_SEL);
+	} else {
+		mtk_dpi_config_channel_limit(dpi);
+		mtk_dpi_config_bit_num(dpi, dpi->bit_num);
+		mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
+		mtk_dpi_config_color_format(dpi, dpi->color_format);
+		if (dpi->conf->support_direct_pin) {
+			mtk_dpi_config_yc_map(dpi, dpi->yc_map);
+			mtk_dpi_config_2n_h_fre(dpi);
+
+			/*
+			 * DPI can connect to either an external bridge
+			 * or the internal HDMI encoder
+			 */
+			if (dpi->conf->output_1pixel)
+				mtk_dpi_mask(dpi, DPI_CON,
+						  DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
+			else
+				mtk_dpi_dual_edge(dpi);
+
+			mtk_dpi_config_disable_edge(dpi);
+		}
+		if (dpi->conf->input_2p_en_bit) {
+			mtk_dpi_mask(dpi, DPI_CON, dpi->conf->input_2p_en_bit,
+				dpi->conf->input_2p_en_bit);
+		}
 	}
+
 	mtk_dpi_sw_reset(dpi, false);
 
 	return 0;
@@ -700,7 +856,7 @@ static u32 *mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
 	}
 
 	output_fmts = kcalloc(dpi->conf->num_output_fmts, sizeof(*output_fmts),
-			     GFP_KERNEL);
+			      GFP_KERNEL);
 	if (!output_fmts)
 		return NULL;
 
@@ -1173,6 +1329,20 @@ static const struct mtk_dpi_conf mt8195_dpintf_conf = {
 	.input_2p_en_bit = DPINTF_INPUT_2P_EN,
 };
 
+static const struct mtk_dpi_conf mt8196_conf = {
+	.dpi_factor = dpi_factor_mt8195_dp_intf,
+	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
+	.out_np_sel = 0x2,
+	.reg_h_fre_con = 0xb0,
+	.max_clock_khz = 1330000,
+	.output_fmts = mt8195_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
+	.pixels_per_iter = 4,
+	.dimension_mask = DPINTF_HPW_MASK,
+	.hvsize_mask = PIC_HSIZE_MASK,
+	.dpi_ver = MTK_DSIP_DVO,
+};
+
 static int mtk_dpi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1227,6 +1397,11 @@ static int mtk_dpi_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(dpi->tvd_clk),
 				     "Failed to get tvdpll clock\n");
 
+	dpi->hf_fdpi_clk = devm_clk_get_optional(dev, "hf_fdvo_clk");
+	if (IS_ERR(dpi->hf_fdpi_clk))
+		return dev_err_probe(dev, PTR_ERR(dpi->hf_fdpi_clk),
+				     "Failed to get hf_fdpi_clk clock\n");
+
 	dpi->irq = platform_get_irq(pdev, 0);
 	if (dpi->irq < 0)
 		return dpi->irq;
@@ -1262,6 +1437,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
 	{ .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
 	{ .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
+	{ .compatible = "mediatek,mt8196-edp-dvo", .data = &mt8196_conf },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
index 23eeefce8fd2..3e2a64c2bca0 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -16,6 +16,7 @@
 #define INT_VSYNC_EN			BIT(0)
 #define INT_VDE_EN			BIT(1)
 #define INT_UNDERFLOW_EN		BIT(2)
+#define INT_VDE_END_EN			BIT(4)
 
 #define DPI_INTSTA		0x0C
 #define INT_VSYNC_STA			BIT(0)
@@ -240,6 +241,71 @@
 #define MATRIX_SEL_RGB_TO_JPEG		0
 #define MATRIX_SEL_RGB_TO_BT601		2
 
+#define DPI_TGEN_INFOQ_LATENCY	0x80
+#define INFOQ_START_LATENCY		0
+#define INFOQ_START_LATENCY_MASK	(0xffff << 0)
+#define INFOQ_END_LATENCY		16
+#define INFOQ_END_LATENCY_MASK		(0xffff << 16)
+
+#define DPI_BUF_CON0		0x220
+#define DISP_BUF_EN			BIT(0)
+#define FIFO_UNDERFLOW_DONE_BLOCK	BIT(4)
+
+#define DPI_TGEN_V_LAST_TRAILING_BLANK	0x6c
+#define V_LAST_TRAILING_BLANK			0
+#define V_LAST_TRAILING_BLANK_MASK		(0xffff << 0)
+
+#define DPI_TGEN_OUTPUT_DELAY_LINE	0x7c
+#define EXT_TG_DLY_LINE				0
+#define EXT_TG_DLY_LINE_MASK			(0xffff << 0)
+
+#define DPI_SHADOW_CTRL			0x190
+#define FORCE_COMMIT				BIT(0)
+#define BYPASS_SHADOW				BIT(1)
+#define READ_WRK_REG				BIT(2)
+
+#define DPI_BUF_SODI_HIGHT		0x230
+#define DPI_BUF_SODI_LOW		0x234
+
+#define DPI_OUTPUT_SET		0x18
+#define OUT_NP_SEL			(0x3 << 0)
+
+#define DPI_SRC_SIZE		0x20
+#define SRC_HSIZE			0
+#define SRC_HSIZE_MASK			(0xffff << 0)
+#define SRC_VSIZE			16
+#define SRC_VSIZE_MASK			(0xffff << 16)
+
+#define DPI_PIC_SIZE		0x24
+#define PIC_HSIZE			0
+#define PIC_HSIZE_MASK			(0xffff << 0)
+#define PIC_VSIZE			16
+#define PIC_VSIZE_MASK			(0xffff << 16)
+
+#define DPI_TGEN_H0		0x50
+#define DPI_HFP				0
+#define DPI_HFP_MASK			(0xffff << 0)
+#define HSYNC				16
+#define HSYNC_MASK			(0xffff << 16)
+
+#define DPI_TGEN_H1		0x54
+#define HSYNC2ACT			0
+#define HSYNC2ACT_MASK			(0xffff << 0)
+#define HACT				16
+#define HACT_MASK			(0xffff << 16)
+
+#define DPI_TGEN_V0		0x58
+#define VFP				0
+#define VFP_MASK			(0xffff << 0)
+#define VSYNC				16
+#define VSYNC_MASK			(0xffff << 16)
+
+#define DPI_TGEN_V1		0x5c
+#define VSYNC2ACT			0
+#define VSYNC2ACT_MASK			(0xffff << 0)
+#define VACT				16
+#define VACT_MASK			(0xffff << 16)
+
 #define DPI_PATTERN0		0xf00
 #define DPI_PAT_EN			BIT(0)
 #define DPI_PAT_SEL			GENMASK(6, 4)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 74158b9d6503..870d97c023ed 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -830,6 +830,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8188-dsi",
 	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8196-edp-dvo",
+	  .data = (void *)MTK_DVO },
 	{ }
 };
 
@@ -1176,7 +1178,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DP_INTF ||
 		    comp_type == MTK_DPI ||
-		    comp_type == MTK_DSI) {
+		    comp_type == MTK_DSI ||
+		    comp_type == MTK_DVO) {
 			dev_info(dev, "Adding component match for %pOF\n",
 				 node);
 			drm_of_component_match_add(dev, &match, component_compare_of,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 675cdc90a440..6d2796148813 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -79,6 +79,7 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_dvo_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
 extern struct platform_driver mtk_padding_driver;
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/5] drm/mediatek: Add eDP driver for mt8196
  2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
                   ` (2 preceding siblings ...)
  2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
@ 2025-04-18  6:52 ` Bincai Liu
  2025-05-27 10:24   ` CK Hu (胡俊光)
  2025-04-18  6:52 ` [PATCH 5/5] drm/mediatek: Add eDP phy " Bincai Liu
  4 siblings, 1 reply; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu

Add code to support eDP 1.4 driver for mt8196.

Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c     | 484 ++++++++++++++++++++++----
 drivers/gpu/drm/mediatek/mtk_dp_reg.h | 126 +++++++
 2 files changed, 550 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index b2408abb9d49..159ab5ebb9d2 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -35,6 +35,9 @@
 
 #include "mtk_dp_reg.h"
 
+#define EDP_VIDEO_UNMUTE		0x22
+#define EDP_VIDEO_UNMUTE_VAL		0xfefd
+#define MTK_SIP_DP_CONTROL		(0x82000523 | 0x40000000)
 #define MTK_DP_SIP_CONTROL_AARCH32	MTK_SIP_SMC_CMD(0x523)
 #define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE	(BIT(0) | BIT(5))
 #define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
@@ -51,6 +54,7 @@
 #define MTK_DP_TRAIN_DOWNSCALE_RETRY 10
 #define MTK_DP_VERSION 0x11
 #define MTK_DP_SDP_AUI 0x4
+#define EDP_REINIT_TIMES 4
 
 enum {
 	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
@@ -102,6 +106,7 @@ struct mtk_dp {
 	bool enabled;
 	bool need_debounce;
 	int irq;
+	int swing_value;
 	u8 max_lanes;
 	u8 max_linkrate;
 	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
@@ -110,6 +115,8 @@ struct mtk_dp {
 	/* irq_thread_lock is used to protect irq_thread_handle */
 	spinlock_t irq_thread_lock;
 
+	struct clk *power_clk;
+
 	struct device *dev;
 	struct drm_bridge bridge;
 	struct drm_bridge *next_bridge;
@@ -124,6 +131,7 @@ struct mtk_dp {
 	struct platform_device *phy_dev;
 	struct phy *phy;
 	struct regmap *regs;
+	struct regmap *phy_regs;
 	struct timer_list debounce_timer;
 
 	/* For audio */
@@ -134,6 +142,9 @@ struct mtk_dp {
 	struct device *codec_dev;
 	/* protect the plugged_cb as it's used in both bridge ops and audio */
 	struct mutex update_plugged_status_lock;
+	/* For edp power control */
+	void __iomem *pwr_regs;
+	u32 retry_times;
 };
 
 struct mtk_dp_data {
@@ -143,6 +154,7 @@ struct mtk_dp_data {
 	bool audio_supported;
 	bool audio_pkt_in_hblank_area;
 	u16 audio_m_div2_bit;
+	u32 edp_ver;
 };
 
 static const struct mtk_dp_efuse_fmt mt8188_dp_efuse_fmt[MTK_DP_CAL_MAX] = {
@@ -402,6 +414,16 @@ static const struct regmap_config mtk_dp_regmap_config = {
 	.name = "mtk-dp-registers",
 };
 
+static const struct regmap_config mtk_edp_phy_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = SEC_OFFSET + 0x90,
+	.name = "mtk-edp-phy-registers",
+};
+
+static int mtk_dp_poweron(struct mtk_dp *mtk_dp);
+
 static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
 {
 	return container_of(b, struct mtk_dp, bridge);
@@ -459,6 +481,26 @@ static void mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
 	}
 }
 
+static void mtk_edp_pm_ctl(struct mtk_dp *mtk_dp, bool enable)
+{
+	/* DISP_EDPTX_PWR_CON udelay 10us to ensure that the power state is stable */
+	udelay(10);
+	if (enable) {
+		/* Enable subsys clock, just set bit4 to 0 */
+		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_CLK_DIS, mtk_dp->pwr_regs);
+		udelay(1);
+		/* Subsys power-on reset, firstly set bit0 to 0 and then set bit0 to 1 */
+		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
+		udelay(1);
+		writel(readl(mtk_dp->pwr_regs) | DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
+	} else {
+		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
+		udelay(1);
+		writel(readl(mtk_dp->pwr_regs) | DISP_EDPTX_PWR_CLK_DIS, mtk_dp->pwr_regs);
+	}
+	udelay(10);
+}
+
 static void mtk_dp_msa_bypass_enable(struct mtk_dp *mtk_dp, bool enable)
 {
 	u32 mask = HTOTAL_SEL_DP_ENC0_P0 | VTOTAL_SEL_DP_ENC0_P0 |
@@ -514,9 +556,14 @@ static void mtk_dp_set_msa(struct mtk_dp *mtk_dp)
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C,
 			   vm->hsync_len,
 			   PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
-			   vm->hback_porch + vm->hsync_len,
-			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	if (mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				   vm->hback_porch + vm->hsync_len + vm->hfront_porch,
+				   PGEN_HFDE_START_DP_ENC0_P0_MASK);
+	else
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
+				   vm->hback_porch + vm->hsync_len,
+				   PGEN_HFDE_START_DP_ENC0_P0_MASK);
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164,
 			   vm->hactive,
 			   PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
@@ -531,9 +578,14 @@ static void mtk_dp_set_msa(struct mtk_dp *mtk_dp)
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170,
 			   vm->vsync_len,
 			   PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
-			   vm->vback_porch + vm->vsync_len,
-			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	if (mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				   vm->vback_porch + vm->vsync_len +  vm->vfront_porch,
+				   PGEN_VFDE_START_DP_ENC0_P0_MASK);
+	else
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
+				   vm->vback_porch + vm->vsync_len,
+				   PGEN_VFDE_START_DP_ENC0_P0_MASK);
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178,
 			   vm->vactive,
 			   PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
@@ -543,7 +595,7 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
 				   enum dp_pixelformat color_format)
 {
 	u32 val;
-	u32 misc0_color;
+	u32 misc0_color = 0;
 
 	switch (color_format) {
 	case DP_PIXELFORMAT_YUV422:
@@ -554,6 +606,9 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
 		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
 		misc0_color = DP_COLOR_FORMAT_RGB;
 		break;
+	case DP_PIXELFORMAT_YUV420:
+		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;
+		break;
 	default:
 		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
 			 color_format);
@@ -612,7 +667,8 @@ static void mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
 			   FIFO_READ_START_POINT_DP_ENC1_P0_VAL << 12,
 			   FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
-	mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368, DP_ENC1_P0_3368_VAL);
+	if (!mtk_dp->data->edp_ver)
+		mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368, DP_ENC1_P0_3368_VAL);
 }
 
 static void mtk_dp_pg_enable(struct mtk_dp *mtk_dp, bool enable)
@@ -972,8 +1028,8 @@ static void mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
 	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
 
 	dev_dbg(mtk_dp->dev,
-		"link training: swing_val = 0x%x, pre-emphasis = 0x%x\n",
-		swing_val, preemphasis);
+		"link training: swing_val = 0x%x, pre-emphasis = 0x%x lane_num = %d\n",
+		swing_val, preemphasis, lane_num);
 
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
 			   swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
@@ -981,6 +1037,28 @@ static void mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
 			   preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
 			   DP_TX0_PRE_EMPH_MASK << lane_shift);
+	if (mtk_dp->data->edp_ver && mtk_dp->phy_regs) {
+		/* set swing and pre */
+		switch (lane_num) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+			regmap_update_bits(mtk_dp->phy_regs,
+					   PHYD_DIG_DRV_FORCE_LANE(lane_num),
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   swing_val << 1 |
+					   preemphasis << 3);
+			break;
+		default:
+			break;
+		}
+		if (preemphasis != 0)
+			mtk_dp_update_bits(mtk_dp, RG_DSI_DEM_EN,
+					   DSI_DE_EMPHASIS_ENABLE,
+					   DSI_DE_EMPHASIS_ENABLE);
+	}
 }
 
 static void mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
@@ -1039,6 +1117,44 @@ static void mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
 
 static void mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
 {
+	if (mtk_dp->data->edp_ver) {
+		mtk_dp_update_bits(mtk_dp, REG_3F04_DP_ENC_P0_3, 0,
+				   FRAME_START_MARKER_0_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F08_DP_ENC_P0_3,
+				   FRAME_START_MARKER_1_DP_ENC_P0_3,
+				   FRAME_START_MARKER_1_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F0C_DP_ENC_P0_3,
+				   FRAME_END_MARKER_0_DP_ENC_P0_3,
+				   FRAME_END_MARKER_0_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F10_DP_ENC_P0_3,
+				   FRAME_END_MARKER_1_DP_ENC_P0_3,
+				   FRAME_END_MARKER_1_DP_ENC_P0_3_MASK);
+
+		mtk_dp_update_bits(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0,
+				   SDP_TESTBUS_SEL_DP_ENC_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_33C0_DP_ENCODER1_P0,
+				   SDP_TESTBUS_SEL_BIT4_DP_ENC,
+				   SDP_TESTBUS_SEL_BIT4_DP_ENC_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_33C4_DP_ENCODER1_P0,
+				   DP_TX_ENCODER_TESTBUS_SEL_DP_ENC,
+				   DP_TX_ENCODER_TESTBUS_SEL_DP_ENC_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F28_DP_ENC_P0_3,
+				   DP_TX_SDP_PSR_AS_TESTBUS,
+				   DP_TX_SDP_PSR_AS_TESTBUS_MASK);
+		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
+				   RG_SW_RST,
+				   RG_SW_RST_MASK);
+		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
+				   RG_PROBE_LOW_SEL,
+				   RG_PROBE_LOW_SEL_MASK);
+		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
+				   RG_PROBE_LOW_HIGH_SWAP,
+				   RG_PROBE_LOW_HIGH_SWAP_MASK);
+
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK,
+				   ENCODER_IRQ_MSK | TRANS_IRQ_MSK,
+				   ENCODER_IRQ_MSK | TRANS_IRQ_MSK);
+	}
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
 			   XTAL_FREQ_DP_TRANS_P0_DEFAULT,
 			   XTAL_FREQ_DP_TRANS_P0_MASK);
@@ -1057,27 +1173,34 @@ static void mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
 static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
 {
 	u32 val;
-	/* Debounce threshold */
-	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
-			   8, HPD_DEB_THD_DP_TRANS_P0_MASK);
 
-	val = (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
-	       HPD_INT_THD_DP_TRANS_P0_UPPER_1100US) << 4;
-	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
-			   val, HPD_INT_THD_DP_TRANS_P0_MASK);
+	if (mtk_dp->data->edp_ver) {
+		mtk_dp_update_bits(mtk_dp, REG_364C_AUX_TX_P0,
+				   HPD_INT_THD_FLDMASK_VAL << 4,
+				   HPD_INT_THD_FLDMASK);
+	} else {
+		/* Debounce threshold */
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+				   8, HPD_DEB_THD_DP_TRANS_P0_MASK);
 
-	/*
-	 * Connect threshold 1.5ms + 5 x 0.1ms = 2ms
-	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms
-	 */
-	val = (5 << 8) | (5 << 12);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
-			   val,
-			   HPD_DISC_THD_DP_TRANS_P0_MASK |
-			   HPD_CONN_THD_DP_TRANS_P0_MASK);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
-			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
-			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+		val = (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
+		       HPD_INT_THD_DP_TRANS_P0_UPPER_1100US) << 4;
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+				   val, HPD_INT_THD_DP_TRANS_P0_MASK);
+
+		/*
+		 * Connect threshold 1.5ms + 5 x 0.1ms = 2ms
+		 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms
+		 */
+		val = (5 << 8) | (5 << 12);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
+				   val,
+				   HPD_DISC_THD_DP_TRANS_P0_MASK |
+				   HPD_CONN_THD_DP_TRANS_P0_MASK);
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
+				   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
+				   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
+	}
 }
 
 static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
@@ -1088,6 +1211,10 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
 			   AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
 	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658,
 			   0, AUX_TX_OV_EN_AUX_TX_P0_MASK);
+	if (mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, REG_36A0_AUX_TX_P0,
+				   DP_TX_INIT_MASK_15_TO_2,
+				   DP_TX_INIT_MASK_15_TO_2_MASK);
 	/* 25 for 26M */
 	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
 			   AUX_TX_OVER_SAMPLE_RATE_FOR_26M << 8,
@@ -1104,6 +1231,46 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
 	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
 			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0,
 			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0);
+
+	if (mtk_dp->data->edp_ver) {
+		/*Con Thd = 1.5ms+Vx0.1ms*/
+		mtk_dp_update_bits(mtk_dp, REG_367C_AUX_TX_P0,
+				   HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS << 6,
+				   HPD_CONN_THD_AUX_TX_P0_FLDMASK);
+		/*DisCon Thd = 1.5ms+Vx0.1ms*/
+		mtk_dp_update_bits(mtk_dp, REG_37A0_AUX_TX_P0,
+				   HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS << 4,
+				   HPD_DISC_THD_AUX_TX_P0_FLDMASK);
+		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
+				   XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_VALUE << 9,
+				   XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_366C_AUX_TX_P0,
+				   XTAL_FREQ_DP_TX_AUX_366C_VALUE << 8,
+				   XTAL_FREQ_DP_TX_AUX_366C_MASK);
+	}
+}
+
+static void mtk_edp_phyd_wait_aux_ldo_ready(struct mtk_dp *mtk_dp,
+					    unsigned long wait_us)
+{
+	int ret = 0;
+	u32 val = 0x0;
+	u32 mask = RGS_BG_CORE_EN_READY | RGS_AUX_LDO_EN_READY;
+
+	if (mtk_dp->phy_regs) {
+		ret = regmap_read_poll_timeout(mtk_dp->phy_regs,
+					       DP_PHY_DIG_GLB_STATUS_0,
+					       val, !!(val & mask),
+					       wait_us / 100, wait_us);
+	} else {
+		ret = regmap_read_poll_timeout(mtk_dp->regs,
+					       DP_PHY_DIG_GLB_STATUS_0,
+					       val, !!(val & mask),
+					       wait_us / 100, wait_us);
+	}
+
+	if (ret)
+		dev_err(mtk_dp->dev, "%s AUX not ready\n", __func__);
 }
 
 static void mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
@@ -1115,15 +1282,63 @@ static void mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
 			   BS2BS_MODE_DP_ENC1_P0_VAL << 12,
 			   BS2BS_MODE_DP_ENC1_P0_MASK);
 
+	if (mtk_dp->data->edp_ver) {
+		/* dp I-mode enable */
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+				   DP_I_MODE_ENABLE, DP_I_MODE_ENABLE);
+		/*symbol_cnt_reset */
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
+				   REG_BS_SYMBOL_CNT_RESET,
+				   REG_BS_SYMBOL_CNT_RESET);
+		mtk_dp_update_bits(mtk_dp, REG_3368_DP_ENCODER1_P0,
+				   VIDEO_SRAM_FIFO_CNT_RESET_SEL_VALUE,
+				   VIDEO_SRAM_FIFO_CNT_RESET_SEL_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3368_DP_ENCODER1_P0,
+				   BS_FOLLOW_SEL_DP_ENC0_P0,
+				   BS_FOLLOW_SEL_DP_ENC0_P0);
+		/*[5:0]video sram start address*/
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
+				   SRAM_START_READ_THRD_DP_ENC0_P0_VALUE,
+				   SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
+		/* reg_psr_patgen_avt_en disable psr pattern */
+		mtk_dp_update_bits(mtk_dp, REG_3F80_DP_ENC_P0_3,
+				   0, PSR_PATGEN_AVT_EN_FLDMASK);
+		/* phy D enable */
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   ALL_POWER_ON,
+				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
+		mtk_edp_phyd_wait_aux_ldo_ready(mtk_dp, 100000);
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+
+		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
+				   PHY_STATE_W_1_DP_ENC_P0_3,
+				   PHY_STATE_W_1_DP_ENC_P0_3_MASK);
+		/* reg_dvo_on_ow_en */
+		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
+				   DVO_ON_W_1_FLDMASK,
+				   DVO_ON_W_1_FLDMASK);
+	}
 	/* dp tx encoder reset all sw */
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
 			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0,
 			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
+	if (mtk_dp->data->edp_ver) {
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
+		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
+				   PHY_STATE_RESET_ALL_VALUE,
+				   PHY_STATE_RESET_ALL_MASK);
+	}
 
 	/* Wait for sw reset to complete */
 	usleep_range(1000, 5000);
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
-			   0, DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
+	if (!mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
+				   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
 }
 
 static void mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
@@ -1152,6 +1367,19 @@ static void mtk_dp_sdp_path_reset(struct mtk_dp *mtk_dp)
 
 static void mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
 {
+	if (mtk_dp->data->edp_ver) {
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   BIAS_POWER_ON,
+				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
+
+		mtk_edp_phyd_wait_aux_ldo_ready(mtk_dp, 100000);
+
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+	}
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
 			   lanes == 0 ? 0 : DP_TRANS_DUMMY_RW_0,
 			   DP_TRANS_DUMMY_RW_0_MASK);
@@ -1266,15 +1494,20 @@ static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
 			.ssc = mtk_dp->train_info.sink_ssc,
 		}
 	};
-
-	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
-			   DP_PWR_STATE_MASK);
+	if (!mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
+				   DP_PWR_STATE_BANDGAP, DP_PWR_STATE_MASK);
 
 	ret = phy_configure(mtk_dp->phy, &phy_opts);
 	if (ret)
 		return ret;
 
 	mtk_dp_set_calibration_data(mtk_dp);
+	/* Turn on phy power after phy configure */
+	if (mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
+				   PHY_STATE_W_1_DP_ENC_P0_3,
+				   PHY_STATE_W_1_DP_ENC_P0_3_MASK);
 	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
 			   DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
 
@@ -1326,16 +1559,20 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
 	struct arm_smccc_res res;
 	u32 val = VIDEO_MUTE_SEL_DP_ENC0_P0 |
 		  (enable ? VIDEO_MUTE_SW_DP_ENC0_P0 : 0);
+	u32 smmc_para;
 
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
 			   val,
 			   VIDEO_MUTE_SEL_DP_ENC0_P0 |
 			   VIDEO_MUTE_SW_DP_ENC0_P0);
-
-	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32,
-		      mtk_dp->data->smc_cmd, enable,
-		      0, 0, 0, 0, 0, &res);
-
+	if (mtk_dp->data->edp_ver) {
+		smmc_para = (EDP_VIDEO_UNMUTE << 16) | enable;
+		arm_smccc_smc(MTK_SIP_DP_CONTROL, EDP_VIDEO_UNMUTE, enable,
+			      smmc_para, EDP_VIDEO_UNMUTE_VAL, 0, 0, 0, &res);
+	} else {
+		arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32,
+			      mtk_dp->data->smc_cmd, enable, 0, 0, 0, 0, 0, &res);
+	}
 	dev_dbg(mtk_dp->dev, "smc cmd: 0x%x, p1: %s, ret: 0x%lx-0x%lx\n",
 		mtk_dp->data->smc_cmd, enable ? "enable" : "disable", res.a0, res.a1);
 }
@@ -1410,6 +1647,16 @@ static void mtk_dp_power_enable(struct mtk_dp *mtk_dp)
 static void mtk_dp_power_disable(struct mtk_dp *mtk_dp)
 {
 	mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
+	if (mtk_dp->data->edp_ver) {
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
+				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   ALL_POWER_OFF,
+				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
+		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
+				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
+	}
 
 	mtk_dp_update_bits(mtk_dp, MTK_DP_0034,
 			   DA_CKM_CKTX0_EN_FORCE_EN, DA_CKM_CKTX0_EN_FORCE_EN);
@@ -1424,9 +1671,13 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
 {
 	bool plugged_in = (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP);
 
-	mtk_dp->train_info.link_rate = DP_LINK_BW_5_4;
+	if (mtk_dp->data->edp_ver)
+		mtk_dp->train_info.link_rate = DP_LINK_BW_8_1;
+	else
+		mtk_dp->train_info.link_rate = DP_LINK_BW_5_4;
 	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
 	mtk_dp->train_info.cable_plugged_in = plugged_in;
+	mtk_dp->train_info.sink_ssc = false;
 
 	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
 	memset(&mtk_dp->info.vm, 0, sizeof(struct videomode));
@@ -1545,11 +1796,15 @@ static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
 		int index = lane / 2;
 		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
 
-		swing = (dpcd_adjust_req[index] >> shift) &
-			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		if (mtk_dp->swing_value != 0) {
+			swing = mtk_dp->swing_value;
+		} else {
+			swing = (dpcd_adjust_req[index] >> shift) &
+				DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
+		}
 		preemphasis = ((dpcd_adjust_req[index] >> shift) &
-			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
-			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
+				DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
+				DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
 		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
 		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 
@@ -1969,6 +2224,11 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
 	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
 
 	mtk_dp_digital_sw_reset(mtk_dp);
+
+	if (mtk_dp->data->edp_ver)
+		mtk_dp_update_bits(mtk_dp, EDP_TX_TOP_CLKGEN_0,
+				   EDP_TX_TOP_CLKGEN_REST_VALUE,
+				   EDP_TX_TOP_CLKGEN_REST_MASK);
 }
 
 static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
@@ -2047,9 +2307,15 @@ static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wa
 	u32 val;
 	int ret;
 
-	ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414,
-				       val, !!(val & HPD_DB_DP_TRANS_P0_MASK),
-				       wait_us / 100, wait_us);
+	if (mtk_dp->data->edp_ver)
+		ret = regmap_read_poll_timeout(mtk_dp->regs, REG_364C_AUX_TX_P0,
+					       val, !!(val & HPD_STATUS_DP_AUX_TX_P0_MASK),
+					       wait_us / 100, wait_us);
+	else
+		ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414,
+					       val, !!(val & HPD_DB_DP_TRANS_P0_MASK),
+					       wait_us / 100, wait_us);
+
 	if (ret) {
 		mtk_dp->train_info.cable_plugged_in = false;
 		return ret;
@@ -2072,7 +2338,10 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	struct device_node *endpoint;
 	struct device *dev = &pdev->dev;
 	int ret;
+	int level;
+	struct resource *regs;
 	void __iomem *base;
+	void __iomem *phy_base;
 	u32 linkrate;
 	int len;
 
@@ -2084,6 +2353,22 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 	if (IS_ERR(mtk_dp->regs))
 		return PTR_ERR(mtk_dp->regs);
 
+	phy_base = devm_platform_ioremap_resource(pdev, 1);
+	if (!IS_ERR_OR_NULL(phy_base)) {
+		mtk_dp->phy_regs = devm_regmap_init_mmio(dev, phy_base,
+					&mtk_edp_phy_regmap_config);
+		if (IS_ERR(mtk_dp->phy_regs))
+			mtk_dp->phy_regs = NULL;
+	}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	if (!IS_ERR_OR_NULL(regs)) {
+		mtk_dp->pwr_regs = devm_ioremap(&pdev->dev, regs->start, 0x4);
+		if (IS_ERR(mtk_dp->pwr_regs))
+			dev_err(dev, "Failed to get pwr_regs: %ld\n",
+				PTR_ERR(mtk_dp->pwr_regs));
+	}
+
 	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 1, -1);
 	len = of_property_count_elems_of_size(endpoint,
 					      "data-lanes", sizeof(u32));
@@ -2102,6 +2387,11 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
 
 	mtk_dp->max_linkrate = drm_dp_link_rate_to_bw_code(linkrate * 100);
 
+	if (of_get_property(dev->of_node, "swing-level", &level)) {
+		of_property_read_u32(dev->of_node,
+				     "swing-level", &mtk_dp->swing_value);
+	}
+
 	return 0;
 }
 
@@ -2672,17 +2962,28 @@ static int mtk_dp_register_phy(struct mtk_dp *mtk_dp)
 {
 	struct device *dev = mtk_dp->dev;
 
-	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
-							PLATFORM_DEVID_AUTO,
-							&mtk_dp->regs,
-							sizeof(struct regmap *));
+	if (mtk_dp->phy_regs)
+		mtk_dp->phy_dev = platform_device_register_data(dev,
+					"mediatek-edp-phy",
+					PLATFORM_DEVID_AUTO,
+					&mtk_dp->phy_regs,
+					sizeof(struct regmap *));
+	else
+		mtk_dp->phy_dev = platform_device_register_data(dev,
+					"mediatek-dp-phy",
+					PLATFORM_DEVID_AUTO,
+					&mtk_dp->regs,
+					sizeof(struct regmap *));
 	if (IS_ERR(mtk_dp->phy_dev))
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev),
 				     "Failed to create device mediatek-dp-phy\n");
 
 	mtk_dp_get_calibration_data(mtk_dp);
 
-	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
+	if (mtk_dp->data->edp_ver)
+		mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "edp");
+	else
+		mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
 	if (IS_ERR(mtk_dp->phy)) {
 		platform_device_unregister(mtk_dp->phy_dev);
 		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
@@ -2770,6 +3071,20 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	mtk_dp->aux.wait_hpd_asserted = mtk_dp_wait_hpd_asserted;
 	drm_dp_aux_init(&mtk_dp->aux);
 
+	mtk_dp->power_clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(mtk_dp->power_clk)) {
+		dev_info(dev, "Failed to get optional clock power_clk\n");
+		mtk_dp->power_clk = NULL;
+	}
+
+	if (mtk_dp->power_clk)
+		clk_prepare_enable(mtk_dp->power_clk);
+
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+	if (mtk_dp->pwr_regs)
+		mtk_edp_pm_ctl(mtk_dp, true);
+
 	platform_set_drvdata(pdev, mtk_dp);
 
 	if (mtk_dp->data->audio_supported) {
@@ -2795,10 +3110,13 @@ static int mtk_dp_probe(struct platform_device *pdev)
 		 * properly close the eDP port to avoid stalls and then
 		 * reinitialize, reset and power on the AUX block.
 		 */
-		mtk_dp_set_idle_pattern(mtk_dp, true);
-		mtk_dp_initialize_aux_settings(mtk_dp);
-		mtk_dp_power_enable(mtk_dp);
-
+		if (mtk_dp->data->edp_ver) {
+			mtk_dp_poweron(mtk_dp);
+		} else {
+			mtk_dp_set_idle_pattern(mtk_dp, true);
+			mtk_dp_initialize_aux_settings(mtk_dp);
+			mtk_dp_power_enable(mtk_dp);
+		}
 		/* Disable HW interrupts: we don't need any for eDP */
 		mtk_dp_hwirq_enable(mtk_dp, false);
 
@@ -2835,8 +3153,8 @@ static int mtk_dp_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, ret, "Failed to add bridge\n");
 	}
 
-	pm_runtime_enable(dev);
-	pm_runtime_get_sync(dev);
+	dev_dbg(dev, "%s power.usage_count %d\n",
+		__func__, atomic_read(&dev->power.usage_count));
 
 	return 0;
 }
@@ -2847,6 +3165,7 @@ static void mtk_dp_remove(struct platform_device *pdev)
 
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+
 	if (mtk_dp->data->bridge_type != DRM_MODE_CONNECTOR_eDP)
 		timer_delete_sync(&mtk_dp->debounce_timer);
 	platform_device_unregister(mtk_dp->phy_dev);
@@ -2859,10 +3178,23 @@ static int mtk_dp_suspend(struct device *dev)
 {
 	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
 
+	dev_dbg(mtk_dp->dev, "%s usage_count %d\n",
+		__func__, atomic_read(&dev->power.usage_count));
+
 	mtk_dp_power_disable(mtk_dp);
 	if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP)
 		mtk_dp_hwirq_enable(mtk_dp, false);
-	pm_runtime_put_sync(dev);
+
+	if (mtk_dp->power_clk)
+		clk_disable_unprepare(mtk_dp->power_clk);
+
+	if (mtk_dp->pwr_regs)
+		mtk_edp_pm_ctl(mtk_dp, false);
+
+	pm_runtime_force_suspend(dev);
+
+	dev_dbg(mtk_dp->dev, "%s usage_count %d\n", __func__,
+		atomic_read(&dev->power.usage_count));
 
 	return 0;
 }
@@ -2870,13 +3202,32 @@ static int mtk_dp_suspend(struct device *dev)
 static int mtk_dp_resume(struct device *dev)
 {
 	struct mtk_dp *mtk_dp = dev_get_drvdata(dev);
+	int ret;
 
-	pm_runtime_get_sync(dev);
+	dev_dbg(mtk_dp->dev, "%s usage_count %d\n", __func__,
+		atomic_read(&dev->power.usage_count));
+
+	pm_runtime_force_resume(dev);
+
+	if (mtk_dp->power_clk)
+		clk_prepare_enable(mtk_dp->power_clk);
+	if (mtk_dp->pwr_regs)
+		mtk_edp_pm_ctl(mtk_dp, true);
+
+	ret = phy_init(mtk_dp->phy);
+	if (ret) {
+		dev_err(mtk_dp->dev, "Failed to initialize phy: %d\n", ret);
+		return ret;
+	}
+	mtk_dp->retry_times = 0;
 	mtk_dp_init_port(mtk_dp);
 	if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP)
 		mtk_dp_hwirq_enable(mtk_dp, true);
 	mtk_dp_power_enable(mtk_dp);
 
+	dev_dbg(mtk_dp->dev, "%s usage_count %d\n", __func__,
+		atomic_read(&dev->power.usage_count));
+
 	return 0;
 }
 #endif
@@ -2908,6 +3259,15 @@ static const struct mtk_dp_data mt8195_dp_data = {
 	.audio_m_div2_bit = MT8195_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
 };
 
+static const struct mtk_dp_data mt8196_edp_data = {
+	.bridge_type = DRM_MODE_CONNECTOR_eDP,
+	.smc_cmd = MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE,
+	.efuse_fmt = mt8195_edp_efuse_fmt,
+	.audio_supported = false,
+	.audio_m_div2_bit = MT8195_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
+	.edp_ver = 1,
+};
+
 static const struct of_device_id mtk_dp_of_match[] = {
 	{
 		.compatible = "mediatek,mt8188-edp-tx",
@@ -2925,6 +3285,10 @@ static const struct of_device_id mtk_dp_of_match[] = {
 		.compatible = "mediatek,mt8195-dp-tx",
 		.data = &mt8195_dp_data,
 	},
+	{
+		.compatible = "mediatek,mt8196-edp-tx",
+		.data = &mt8196_edp_data,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_dp_of_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_dp_reg.h b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
index 8ad7a9cc259e..bacf2d239eac 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp_reg.h
+++ b/drivers/gpu/drm/mediatek/mtk_dp_reg.h
@@ -12,11 +12,22 @@
 #define MTK_DP_HPD_CONNECT		BIT(2)
 #define MTK_DP_HPD_INTERRUPT		BIT(3)
 
+#define MTK_EDP_HPD_DISCONNECT		BIT(10)
+#define MTK_EDP_HPD_CONNECT		BIT(0)
+#define MTK_EDP_HPD_INTERRUPT		BIT(2)
+
 /* offset: 0x0 */
 #define DP_PHY_GLB_BIAS_GEN_00		0x0
 #define RG_XTP_GLB_BIAS_INTR_CTRL		GENMASK(20, 16)
 #define DP_PHY_GLB_DPAUX_TX		0x8
 #define RG_CKM_PT0_CKTX_IMPSEL			GENMASK(23, 20)
+#define DP_TX_TOP_RESET_AND_PROBE	0x2020
+#define RG_SW_RST_MASK				GENMASK(7, 0)
+#define RG_SW_RST				0xff
+#define RG_PROBE_LOW_SEL_MASK			GENMASK(18, 16)
+#define RG_PROBE_LOW_SEL			BIT(16)
+#define RG_PROBE_LOW_HIGH_SWAP_MASK		BIT(23)
+#define RG_PROBE_LOW_HIGH_SWAP			BIT(23)
 #define MTK_DP_0034			0x34
 #define DA_XTP_GLB_CKDET_EN_FORCE_VAL		BIT(15)
 #define DA_XTP_GLB_CKDET_EN_FORCE_EN		BIT(14)
@@ -51,6 +62,15 @@
 #define RG_XTP_GLB_CKDET_EN			BIT(1)
 #define RG_DPAUX_RX_EN				BIT(0)
 
+/* offset: PHY_OFFSET */
+#define DP_PHY_DIG_GLB_STATUS_0		0x146c
+#define RGS_BG_CORE_EN_READY			BIT(0)
+#define RGS_AUX_LDO_EN_READY			BIT(1)
+
+#define MTK_EDP_PWR_DOMAIN		0x0074
+#define EDP_PWR_RST				BIT(0)
+#define EDP_PWR_CLK_DIS				BIT(4)
+
 /* offset: TOP_OFFSET (0x2000) */
 #define MTK_DP_TOP_PWR_STATE		0x2000
 #define DP_PWR_STATE_MASK			GENMASK(1, 0)
@@ -71,22 +91,33 @@
 #define DP_TX3_PRE_EMPH_MASK			GENMASK(27, 26)
 #define MTK_DP_TOP_RESET_AND_PROBE	0x2020
 #define SW_RST_B_PHYD				BIT(4)
+#define DP_TX_TOP_SOFT_PROBE		0x2024
 #define MTK_DP_TOP_IRQ_MASK		0x202c
+#define ENCODER_IRQ_MSK				BIT(0)
+#define TRANS_IRQ_MSK				BIT(1)
 #define IRQ_MASK_AUX_TOP_IRQ			BIT(2)
+#define IRQ_OUT_HIGH_ACTIVE_FLDMASK		0x100
 #define MTK_DP_TOP_MEM_PD		0x2038
 #define MEM_ISO_EN				BIT(0)
 #define FUSE_SEL				BIT(2)
 
+#define EDP_TX_TOP_CLKGEN_0		0x2074
+#define EDP_TX_TOP_CLKGEN_REST_MASK		0xf
+#define EDP_TX_TOP_CLKGEN_REST_VALUE		0xf
+
 /* offset: ENC0_OFFSET (0x3000) */
 #define MTK_DP_ENC0_P0_3000			0x3000
 #define LANE_NUM_DP_ENC0_P0_MASK			GENMASK(1, 0)
 #define VIDEO_MUTE_SW_DP_ENC0_P0			BIT(2)
 #define VIDEO_MUTE_SEL_DP_ENC0_P0			BIT(3)
 #define ENHANCED_FRAME_EN_DP_ENC0_P0			BIT(4)
+#define DP_I_MODE_ENABLE				BIT(6)
+#define REG_BS_SYMBOL_CNT_RESET				BIT(7)
 #define MTK_DP_ENC0_P0_3004			0x3004
 #define VIDEO_M_CODE_SEL_DP_ENC0_P0_MASK		BIT(8)
 #define DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0		BIT(9)
 #define SDP_RESET_SW_DP_ENC0_P0				BIT(13)
+#define DP_TX_MUX_DP_ENC0_P0				BIT(14)
 #define MTK_DP_ENC0_P0_3010			0x3010
 #define HTOTAL_SW_DP_ENC0_P0_MASK			GENMASK(15, 0)
 #define MTK_DP_ENC0_P0_3014			0x3014
@@ -119,10 +150,13 @@
 #define VBID_AUDIO_MUTE_FLAG_SW_DP_ENC0_P0		BIT(11)
 #define VBID_AUDIO_MUTE_FLAG_SEL_DP_ENC0_P0		BIT(12)
 #define MTK_DP_ENC0_P0_3034			0x3034
+#define VIDEO_COLOR_FORMAT_DP_ENC0_P0_MASK		BIT(3)
+#define VIDEO_COLOR_FORMAT_DP_ENC0_P0_VALUE		BIT(3)
 #define MTK_DP_ENC0_P0_3038			0x3038
 #define VIDEO_SOURCE_SEL_DP_ENC0_P0_MASK		BIT(11)
 #define MTK_DP_ENC0_P0_303C			0x303c
 #define SRAM_START_READ_THRD_DP_ENC0_P0_MASK		GENMASK(5, 0)
+#define SRAM_START_READ_THRD_DP_ENC0_P0_VALUE		0x8
 #define VIDEO_COLOR_DEPTH_DP_ENC0_P0_MASK		GENMASK(10, 8)
 #define VIDEO_COLOR_DEPTH_DP_ENC0_P0_16BIT		(0 << 8)
 #define VIDEO_COLOR_DEPTH_DP_ENC0_P0_12BIT		(1 << 8)
@@ -139,9 +173,14 @@
 #define SDP_DOWN_CNT_INIT_DP_ENC0_P0_MASK		GENMASK(11, 0)
 #define MTK_DP_ENC0_P0_304C			0x304c
 #define VBID_VIDEO_MUTE_DP_ENC0_P0_MASK			BIT(2)
+#define VBID_VIDEO_MUTE_IDLE_PATTERN_DP_ENC0_P0_MASK	BIT(3)
 #define SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK		BIT(8)
 #define MTK_DP_ENC0_P0_3064			0x3064
 #define HDE_NUM_LAST_DP_ENC0_P0_MASK			GENMASK(15, 0)
+#define REG_3368_DP_ENCODER1_P0			0x3368
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_MASK		GENMASK(1, 0)
+#define VIDEO_SRAM_FIFO_CNT_RESET_SEL_VALUE		BIT(0)
+#define BS_FOLLOW_SEL_DP_ENC0_P0			BIT(15)
 #define MTK_DP_ENC0_P0_3088			0x3088
 #define AU_EN_DP_ENC0_P0				BIT(6)
 #define AUDIO_8CH_EN_DP_ENC0_P0_MASK			BIT(7)
@@ -240,6 +279,14 @@
 #define SDP_ASP_INSERT_IN_HBLANK_DP_ENC1_P0_MASK	BIT(12)
 #define SDP_DOWN_ASP_CNT_INIT_DP_ENC1_P0_MASK		GENMASK(11, 0)
 
+#define REG_33C0_DP_ENCODER1_P0			0x33c0
+#define SDP_TESTBUS_SEL_DP_ENC_MASK			0xf000
+#define SDP_TESTBUS_SEL_BIT4_DP_ENC_MASK		0x80
+#define SDP_TESTBUS_SEL_BIT4_DP_ENC			0x80
+#define REG_33C4_DP_ENCODER1_P0			0x33c4
+#define DP_TX_ENCODER_TESTBUS_SEL_DP_ENC_MASK		GENMASK(6, 5)
+#define DP_TX_ENCODER_TESTBUS_SEL_DP_ENC		BIT(5)
+
 #define MTK_DP_ENC1_P0_33F4			0x33f4
 #define DP_ENC_DUMMY_RW_1_AUDIO_RST_EN			BIT(0)
 #define DP_ENC_DUMMY_RW_1				BIT(9)
@@ -296,9 +343,14 @@
 #define DP_TRANS_DUMMY_RW_0_MASK				GENMASK(3, 2)
 
 /* offset: AUX_OFFSET (0x3600) */
+#define REG_3608_AUX_TX_P0			0x3608
+#define HPD_CONNECT_EVENT				BIT(0)
+#define HPD_INTERRUPT_EVENT				BIT(2)
+#define HPD_DISCONNECT_EVENT				BIT(10)
 #define MTK_DP_AUX_P0_360C			0x360c
 #define AUX_TIMEOUT_THR_AUX_TX_P0_MASK			GENMASK(12, 0)
 #define AUX_TIMEOUT_THR_AUX_TX_P0_VAL			0x1595
+#define AUX_TIMEOUT_THR_AUX_TX_P0_VAL_1			0x1d0c
 #define MTK_DP_AUX_P0_3614			0x3614
 #define AUX_RX_UI_CNT_THR_AUX_TX_P0_MASK		GENMASK(6, 0)
 #define AUX_RX_UI_CNT_THR_AUX_FOR_26M			13
@@ -344,19 +396,93 @@
 #define MCU_REQUEST_ADDRESS_LSB_AUX_TX_P0_MASK		GENMASK(15, 0)
 #define MTK_DP_AUX_P0_364C			0x364c
 #define MCU_REQUEST_ADDRESS_MSB_AUX_TX_P0_MASK		GENMASK(3, 0)
+#define REG_364C_AUX_TX_P0			0x364c
+#define HPD_INT_THD_FLDMASK_VAL				0x32
+#define HPD_INT_THD_FLDMASK				0x3f0
+#define HPD_STATUS_DP_AUX_TX_P0_MASK			BIT(15)
 #define MTK_DP_AUX_P0_3650			0x3650
 #define MCU_REQ_DATA_NUM_AUX_TX_P0_MASK			GENMASK(15, 12)
 #define PHY_FIFO_RST_AUX_TX_P0_MASK			BIT(9)
 #define MCU_ACK_TRAN_COMPLETE_AUX_TX_P0			BIT(8)
 #define MTK_DP_AUX_P0_3658			0x3658
 #define AUX_TX_OV_EN_AUX_TX_P0_MASK			BIT(0)
+
+#define REG_3660_AUX_TX_P0			0x3660
+#define AUX_DP_TX_INT_3660_VALUE		0xffff
+#define AUX_DP_TX_INT_3660_MASK			0xffff
+
+#define REG_3668_AUX_TX_P0			0x3668
+
+#define REG_366C_AUX_TX_P0			0x366c
+#define XTAL_FREQ_DP_TX_AUX_366C_VALUE			0x68
+#define XTAL_FREQ_DP_TX_AUX_366C_MASK			0xff00
+
+#define REG_367C_AUX_TX_P0			0x367c
+#define HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS		5
+#define HPD_CONN_THD_AUX_TX_P0_FLDMASK			0x3c0
 #define MTK_DP_AUX_P0_3690			0x3690
 #define RX_REPLY_COMPLETE_MODE_AUX_TX_P0		BIT(8)
+
+#define REG_36A0_AUX_TX_P0			0x36a0
+#define DP_TX_INIT_MASK_15_TO_2_MASK			0xfffc
+#define DP_TX_INIT_MASK_15_TO_2				0xfffc
 #define MTK_DP_AUX_P0_3704			0x3704
 #define AUX_TX_FIFO_WDATA_NEW_MODE_T_AUX_TX_P0_MASK	BIT(1)
 #define AUX_TX_FIFO_NEW_MODE_EN_AUX_TX_P0		BIT(2)
 #define MTK_DP_AUX_P0_3708			0x3708
+
+#define REG_37A0_AUX_TX_P0			0x37a0
+#define HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS		5
+#define HPD_DISC_THD_AUX_TX_P0_FLDMASK			0xf0
+
 #define MTK_DP_AUX_P0_37C8			0x37c8
 #define MTK_ATOP_EN_AUX_TX_P0				BIT(0)
 
+/* offset info queue */
+#define REG_3F04_DP_ENC_P0_3			0x3f04
+#define FRAME_START_MARKER_0_DP_ENC_P0_3_MASK		0xffff
+#define REG_3F08_DP_ENC_P0_3			0x3f08
+#define FRAME_START_MARKER_1_DP_ENC_P0_3_MASK		BIT(3)
+#define FRAME_START_MARKER_1_DP_ENC_P0_3		BIT(3)
+#define REG_3F0C_DP_ENC_P0_3			0x3f0C
+#define FRAME_END_MARKER_0_DP_ENC_P0_3_MASK		BIT(1)
+#define FRAME_END_MARKER_0_DP_ENC_P0_3			BIT(1)
+#define REG_3F10_DP_ENC_P0_3			0x3f10
+#define FRAME_END_MARKER_1_DP_ENC_P0_3_MASK		BIT(3)
+#define FRAME_END_MARKER_1_DP_ENC_P0_3			BIT(3)
+#define REG_3F28_DP_ENC_P0_3			0x3f28
+#define DP_TX_SDP_PSR_AS_TESTBUS_MASK			GENMASK(5, 2)
+#define DP_TX_SDP_PSR_AS_TESTBUS			(0xa << 2)
+#define REG_3F44_DP_ENC_P0_3			0x3f44
+#define PHY_PWR_STATE_OW_EN_DP_ENC_P0_3			BIT(2)
+#define PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK		BIT(2)
+#define ALL_POWER_OFF					(0x0 << 3)
+#define BIAS_POWER_ON					(0x1 << 3)
+#define BIAS_AND_PLL_POWER_ON				(0x2 << 3)
+#define ALL_POWER_ON					(0x3 << 3)
+#define PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK		GENMASK(4, 3)
+
+#define REG_3F80_DP_ENC_P0_3			0x3f80
+#define PSR_PATGEN_AVT_EN_FLDMASK			0x20
+#define REG_3FF8_DP_ENC_P0_3			0x3ff8
+#define PHY_STATE_RESET_ALL_MASK			0xff
+#define PHY_STATE_RESET_ALL_VALUE			0xff
+#define PHY_STATE_W_1_DP_ENC_P0_3			BIT(6)
+#define PHY_STATE_W_1_DP_ENC_P0_3_MASK			BIT(6)
+
+#define DVO_ON_W_1_FLDMASK				0x20
+#define XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_VALUE		25
+#define XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_MASK		0x3e00
+
+#define DISP_EDPTX_PWR_RST_B				(1 << 0)
+#define DISP_EDPTX_PWR_CLK_DIS				(1 << 4)
+
+/* offset: PHYD_OFFSET (0x1000) */
+#define PHYD_DIG_DRV_FORCE_LANE(lane)		(0x1030 + 0x100 * (lane))
+#define EDP_TX_LN_VOLT_SWING_VAL_FLDMASK	0x6
+#define EDP_TX_LN_PRE_EMPH_VAL_FLDMASK		0x18
+
+#define RG_DSI_DEM_EN			0x500
+#define DSI_DE_EMPHASIS_ENABLE	BIT(1)
+
 #endif /*_MTK_DP_REG_H_*/
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/5] drm/mediatek: Add eDP phy driver for mt8196
  2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
                   ` (3 preceding siblings ...)
  2025-04-18  6:52 ` [PATCH 4/5] drm/mediatek: Add eDP " Bincai Liu
@ 2025-04-18  6:52 ` Bincai Liu
  2025-04-18 11:30   ` Vinod Koul
  2025-05-28  1:52   ` CK Hu (胡俊光)
  4 siblings, 2 replies; 14+ messages in thread
From: Bincai Liu @ 2025-04-18  6:52 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: dri-devel, linux-mediatek, devicetree, linux-kernel,
	linux-arm-kernel, linux-phy, Bincai Liu

Add code to support eDP phy for mt8196.

Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
---
 drivers/phy/mediatek/Makefile      |   1 +
 drivers/phy/mediatek/phy-mtk-edp.c | 262 +++++++++++++++++++++++++++++
 2 files changed, 263 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-edp.c

diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index 1b8088df71e8..49d9ea42497a 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-dp.o
+obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-edp.o
 obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
diff --git a/drivers/phy/mediatek/phy-mtk-edp.c b/drivers/phy/mediatek/phy-mtk-edp.c
new file mode 100644
index 000000000000..fadcbda55b70
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-edp.c
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019-2022 MediaTek Inc.
+ * Copyright (c) 2022 BayLibre
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define PHYD_OFFSET			0x0000
+#define PHYD_DIG_LAN0_OFFSET		0x1000
+#define PHYD_DIG_LAN1_OFFSET		0x1100
+#define PHYD_DIG_LAN2_OFFSET		0x1200
+#define PHYD_DIG_LAN3_OFFSET		0x1300
+#define PHYD_DIG_GLB_OFFSET		0x1400
+
+#define DP_PHY_DIG_PLL_CTL_0		(PHYD_DIG_GLB_OFFSET + 0x10)
+#define FORCE_PWORE_STATE_FLDMASK		GENMASK(2, 0)
+#define FORCE_PWORE_STATE_VALUE			0x7
+
+#define IPMUX_CONTROL			(PHYD_DIG_GLB_OFFSET + 0x98)
+#define EDPTX_DSI_PHYD_SEL_FLDMASK		0x1
+#define EDPTX_DSI_PHYD_SEL_FLDMASK_POS		0
+
+#define DP_PHY_DIG_TX_CTL_0		(PHYD_DIG_GLB_OFFSET + 0x74)
+#define TX_LN_EN_FLDMASK			0xf
+
+#define mtk_edp_PHY_DIG_PLL_CTL_1	(PHYD_DIG_GLB_OFFSET + 0x14)
+#define TPLL_SSC_EN				BIT(8)
+
+#define mtk_edp_PHY_DIG_BIT_RATE		(PHYD_DIG_GLB_OFFSET + 0x3C)
+#define BIT_RATE_RBR				0x1
+#define BIT_RATE_HBR				0x4
+#define BIT_RATE_HBR2				0x7
+#define BIT_RATE_HBR3				0x9
+
+#define mtk_edp_PHY_DIG_SW_RST		(PHYD_DIG_GLB_OFFSET + 0x38)
+#define DP_GLB_SW_RST_PHYD			BIT(0)
+#define DP_GLB_SW_RST_PHYD_MASK			BIT(0)
+
+#define DRIVING_FORCE			0x30
+#define EDP_TX_LN_VOLT_SWING_VAL_FLDMASK	0x6
+#define EDP_TX_LN_VOLT_SWING_VAL_FLDMASK_POS	1
+#define EDP_TX_LN_PRE_EMPH_VAL_FLDMASK		0x18
+#define EDP_TX_LN_PRE_EMPH_VAL_FLDMASK_POS	3
+
+struct mtk_edp_phy {
+	struct regmap *regs;
+};
+
+enum DPTX_LANE_NUM {
+	DPTX_LANE0 = 0x0,
+	DPTX_LANE1 = 0x1,
+	DPTX_LANE2 = 0x2,
+	DPTX_LANE3 = 0x3,
+	DPTX_LANE_MAX,
+};
+
+enum DPTX_LANE_COUNT {
+	DPTX_LANE_COUNT1 = 0x1,
+	DPTX_LANE_COUNT2 = 0x2,
+	DPTX_LANE_COUNT4 = 0x4,
+};
+
+static void mtk_edptx_phyd_reset_swing_pre(struct mtk_edp_phy *edp_phy)
+{
+	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN0_OFFSET + DRIVING_FORCE,
+			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
+	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN1_OFFSET + DRIVING_FORCE,
+			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
+	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN2_OFFSET + DRIVING_FORCE,
+			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
+	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN3_OFFSET + DRIVING_FORCE,
+			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
+}
+
+static int mtk_edp_phy_init(struct phy *phy)
+{
+	struct mtk_edp_phy *edp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(edp_phy->regs, IPMUX_CONTROL, 0,
+			   EDPTX_DSI_PHYD_SEL_FLDMASK);
+
+	regmap_update_bits(edp_phy->regs, DP_PHY_DIG_PLL_CTL_0,
+			   FORCE_PWORE_STATE_VALUE,
+			   FORCE_PWORE_STATE_FLDMASK);
+
+	return 0;
+}
+
+static int mtk_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct mtk_edp_phy *edp_phy = phy_get_drvdata(phy);
+	u32 val;
+
+	if (opts->dp.set_rate) {
+		switch (opts->dp.link_rate) {
+		case 1620:
+			val = BIT_RATE_RBR;
+			break;
+		case 2700:
+			val = BIT_RATE_HBR;
+			break;
+		case 5400:
+			val = BIT_RATE_HBR2;
+			break;
+		case 8100:
+			val = BIT_RATE_HBR3;
+			break;
+		default:
+			dev_err(&phy->dev,
+				"Implementation error, unknown linkrate %x\n",
+				opts->dp.link_rate);
+			return -EINVAL;
+		}
+		regmap_write(edp_phy->regs, mtk_edp_PHY_DIG_BIT_RATE, val);
+	}
+
+	if (opts->dp.set_lanes) {
+		for (val = 0; val < 4; val++) {
+			regmap_update_bits(edp_phy->regs, DP_PHY_DIG_TX_CTL_0,
+					   ((1 << (val + 1)) - 1),
+					   TX_LN_EN_FLDMASK);
+		}
+	}
+
+	if (opts->dp.set_voltages) {
+		switch (opts->dp.lanes) {
+		case DPTX_LANE_COUNT1:
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN0_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE0] << 1 |
+					   opts->dp.pre[DPTX_LANE0] << 3);
+		break;
+		case DPTX_LANE_COUNT2:
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN0_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE0] << 1 |
+					   opts->dp.pre[DPTX_LANE0] << 3);
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN1_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE1] << 1 |
+					   opts->dp.pre[DPTX_LANE1] << 3);
+		break;
+		case DPTX_LANE_COUNT4:
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN0_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE0] << 1 |
+					   opts->dp.pre[DPTX_LANE0] << 3);
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN1_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE1] << 1 |
+					   opts->dp.pre[DPTX_LANE1] << 3);
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN2_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE2] << 1 |
+					   opts->dp.pre[DPTX_LANE2] << 3);
+			regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN3_OFFSET +
+					   DRIVING_FORCE,
+					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
+					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
+					   opts->dp.voltage[DPTX_LANE3] << 1 |
+					   opts->dp.pre[DPTX_LANE3] << 3);
+		break;
+		default:
+			dev_err(&phy->dev, "Wrong lanes config: %x\n",
+				opts->dp.lanes);
+			return -EINVAL;
+		}
+	}
+
+	regmap_update_bits(edp_phy->regs, mtk_edp_PHY_DIG_PLL_CTL_1,
+			   TPLL_SSC_EN, opts->dp.ssc ? 0 : TPLL_SSC_EN);
+
+	return 0;
+}
+
+static int mtk_edp_phy_reset(struct phy *phy)
+{
+	struct mtk_edp_phy *edp_phy = phy_get_drvdata(phy);
+
+	regmap_update_bits(edp_phy->regs, mtk_edp_PHY_DIG_SW_RST,
+			   0, DP_GLB_SW_RST_PHYD_MASK);
+	usleep_range(50, 200);
+	regmap_update_bits(edp_phy->regs, mtk_edp_PHY_DIG_SW_RST,
+			   DP_GLB_SW_RST_PHYD, DP_GLB_SW_RST_PHYD_MASK);
+	regmap_update_bits(edp_phy->regs, DP_PHY_DIG_TX_CTL_0,
+			   0x0, TX_LN_EN_FLDMASK);
+	mtk_edptx_phyd_reset_swing_pre(edp_phy);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_edp_phy_dev_ops = {
+	.init = mtk_edp_phy_init,
+	.configure = mtk_edp_phy_configure,
+	.reset = mtk_edp_phy_reset,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_edp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_edp_phy *edp_phy;
+	struct phy *phy;
+	struct regmap *regs;
+
+	regs = *(struct regmap **)dev->platform_data;
+	if (!regs)
+		return dev_err_probe(dev, -EINVAL,
+				     "No data passed, requires struct regmap**\n");
+
+	edp_phy = devm_kzalloc(dev, sizeof(*edp_phy), GFP_KERNEL);
+	if (!edp_phy)
+		return -ENOMEM;
+
+	edp_phy->regs = regs;
+	phy = devm_phy_create(dev, NULL, &mtk_edp_phy_dev_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy),
+				     "Failed to create DP PHY\n");
+
+	phy_set_drvdata(phy, edp_phy);
+	if (!dev->of_node)
+		phy_create_lookup(phy, "edp", dev_name(dev));
+
+	return 0;
+}
+
+struct platform_driver mtk_edp_phy_driver = {
+	.probe = mtk_edp_phy_probe,
+	.driver = {
+		.name = "mediatek-edp-phy",
+	},
+};
+
+module_platform_driver(mtk_edp_phy_driver);
+
+MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
+MODULE_DESCRIPTION("MediaTek DP PHY Driver");
+MODULE_LICENSE("GPL");
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] drm/mediatek: Add eDP phy driver for mt8196
  2025-04-18  6:52 ` [PATCH 5/5] drm/mediatek: Add eDP phy " Bincai Liu
@ 2025-04-18 11:30   ` Vinod Koul
  2025-05-28  1:52   ` CK Hu (胡俊光)
  1 sibling, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2025-04-18 11:30 UTC (permalink / raw)
  To: Bincai Liu
  Cc: Chun-Kuang Hu, Philipp Zabel, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Chunfeng Yun, Kishon Vijay Abraham I,
	Jitao shi, CK Hu, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy

On 18-04-25, 14:52, Bincai Liu wrote:
> Add code to support eDP phy for mt8196.

Why is the patch title not "phy: add eDP phy...." why is this tagged
drm? 

> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---
>  drivers/phy/mediatek/Makefile      |   1 +
>  drivers/phy/mediatek/phy-mtk-edp.c | 262 +++++++++++++++++++++++++++++
>  2 files changed, 263 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-edp.c
> 
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index 1b8088df71e8..49d9ea42497a 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -4,6 +4,7 @@
>  #
>  
>  obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-dp.o
> +obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-edp.o
>  obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
> diff --git a/drivers/phy/mediatek/phy-mtk-edp.c b/drivers/phy/mediatek/phy-mtk-edp.c
> new file mode 100644
> index 000000000000..fadcbda55b70
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-edp.c
> @@ -0,0 +1,262 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019-2022 MediaTek Inc.
> + * Copyright (c) 2022 BayLibre
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define PHYD_OFFSET			0x0000
> +#define PHYD_DIG_LAN0_OFFSET		0x1000
> +#define PHYD_DIG_LAN1_OFFSET		0x1100
> +#define PHYD_DIG_LAN2_OFFSET		0x1200
> +#define PHYD_DIG_LAN3_OFFSET		0x1300
> +#define PHYD_DIG_GLB_OFFSET		0x1400
> +
> +#define DP_PHY_DIG_PLL_CTL_0		(PHYD_DIG_GLB_OFFSET + 0x10)
> +#define FORCE_PWORE_STATE_FLDMASK		GENMASK(2, 0)
> +#define FORCE_PWORE_STATE_VALUE			0x7
> +
> +#define IPMUX_CONTROL			(PHYD_DIG_GLB_OFFSET + 0x98)
> +#define EDPTX_DSI_PHYD_SEL_FLDMASK		0x1
> +#define EDPTX_DSI_PHYD_SEL_FLDMASK_POS		0
> +
> +#define DP_PHY_DIG_TX_CTL_0		(PHYD_DIG_GLB_OFFSET + 0x74)
> +#define TX_LN_EN_FLDMASK			0xf
> +
> +#define mtk_edp_PHY_DIG_PLL_CTL_1	(PHYD_DIG_GLB_OFFSET + 0x14)
> +#define TPLL_SSC_EN				BIT(8)
> +
> +#define mtk_edp_PHY_DIG_BIT_RATE		(PHYD_DIG_GLB_OFFSET + 0x3C)
> +#define BIT_RATE_RBR				0x1
> +#define BIT_RATE_HBR				0x4
> +#define BIT_RATE_HBR2				0x7
> +#define BIT_RATE_HBR3				0x9
> +
> +#define mtk_edp_PHY_DIG_SW_RST		(PHYD_DIG_GLB_OFFSET + 0x38)
> +#define DP_GLB_SW_RST_PHYD			BIT(0)
> +#define DP_GLB_SW_RST_PHYD_MASK			BIT(0)
> +
> +#define DRIVING_FORCE			0x30
> +#define EDP_TX_LN_VOLT_SWING_VAL_FLDMASK	0x6
> +#define EDP_TX_LN_VOLT_SWING_VAL_FLDMASK_POS	1
> +#define EDP_TX_LN_PRE_EMPH_VAL_FLDMASK		0x18
> +#define EDP_TX_LN_PRE_EMPH_VAL_FLDMASK_POS	3
> +
> +struct mtk_edp_phy {
> +	struct regmap *regs;
> +};
> +
> +enum DPTX_LANE_NUM {
> +	DPTX_LANE0 = 0x0,
> +	DPTX_LANE1 = 0x1,
> +	DPTX_LANE2 = 0x2,
> +	DPTX_LANE3 = 0x3,
> +	DPTX_LANE_MAX,
> +};
> +
> +enum DPTX_LANE_COUNT {
> +	DPTX_LANE_COUNT1 = 0x1,
> +	DPTX_LANE_COUNT2 = 0x2,
> +	DPTX_LANE_COUNT4 = 0x4,
> +};
> +
> +static void mtk_edptx_phyd_reset_swing_pre(struct mtk_edp_phy *edp_phy)
> +{
> +	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN0_OFFSET + DRIVING_FORCE,
> +			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
> +			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
> +	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN1_OFFSET + DRIVING_FORCE,
> +			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
> +			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
> +	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN2_OFFSET + DRIVING_FORCE,
> +			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
> +			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
> +	regmap_update_bits(edp_phy->regs, PHYD_DIG_LAN3_OFFSET + DRIVING_FORCE,
> +			   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
> +			   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK, 0x0);
> +}
> +
> +static int mtk_edp_phy_init(struct phy *phy)
> +{
> +	struct mtk_edp_phy *edp_phy = phy_get_drvdata(phy);
> +
> +	regmap_update_bits(edp_phy->regs, IPMUX_CONTROL, 0,
> +			   EDPTX_DSI_PHYD_SEL_FLDMASK);
> +
> +	regmap_update_bits(edp_phy->regs, DP_PHY_DIG_PLL_CTL_0,
> +			   FORCE_PWORE_STATE_VALUE,
> +			   FORCE_PWORE_STATE_FLDMASK);
> +
> +	return 0;

consider making this void return type

-- 
~Vinod

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
  2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
@ 2025-04-19  7:19   ` kernel test robot
  2025-04-19  8:01   ` kernel test robot
  2025-05-27  6:24   ` CK Hu (胡俊光)
  2 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2025-04-19  7:19 UTC (permalink / raw)
  To: Bincai Liu, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: llvm, oe-kbuild-all, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, Bincai Liu

Hi Bincai,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next linus/master v6.15-rc2 next-20250417]
[cannot apply to pza/imx-drm/next drm-misc/drm-misc-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Bincai-Liu/dt-bindings-eDP-mediatek-add-eDP-yaml-for-mt8196/20250418-145911
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20250418065313.8972-4-bincai.liu%40mediatek.com
patch subject: [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
config: i386-buildonly-randconfig-006-20250419 (https://download.01.org/0day-ci/archive/20250419/202504191551.u0FJoQ3O-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250419/202504191551.u0FJoQ3O-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504191551.u0FJoQ3O-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/mediatek/mtk_ddp_comp.c:476:3: error: use of undeclared identifier 'DDP_COMPONENT_DVO0'
     476 |         [DDP_COMPONENT_DVO0]            = { MTK_DVO,                    0, &ddp_dpi },
         |          ^
   1 error generated.


vim +/DDP_COMPONENT_DVO0 +476 drivers/gpu/drm/mediatek/mtk_ddp_comp.c

   456	
   457	static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX] = {
   458		[DDP_COMPONENT_AAL0]		= { MTK_DISP_AAL,		0, &ddp_aal },
   459		[DDP_COMPONENT_AAL1]		= { MTK_DISP_AAL,		1, &ddp_aal },
   460		[DDP_COMPONENT_BLS]		= { MTK_DISP_BLS,		0, NULL },
   461		[DDP_COMPONENT_CCORR]		= { MTK_DISP_CCORR,		0, &ddp_ccorr },
   462		[DDP_COMPONENT_COLOR0]		= { MTK_DISP_COLOR,		0, &ddp_color },
   463		[DDP_COMPONENT_COLOR1]		= { MTK_DISP_COLOR,		1, &ddp_color },
   464		[DDP_COMPONENT_DITHER0]		= { MTK_DISP_DITHER,		0, &ddp_dither },
   465		[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,		0, &ddp_dpi },
   466		[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,		1, &ddp_dpi },
   467		[DDP_COMPONENT_DPI0]		= { MTK_DPI,			0, &ddp_dpi },
   468		[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
   469		[DDP_COMPONENT_DRM_OVL_ADAPTOR]	= { MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
   470		[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
   471		[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
   472		[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
   473		[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
   474		[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
   475		[DDP_COMPONENT_DSI3]		= { MTK_DSI,			3, &ddp_dsi },
 > 476		[DDP_COMPONENT_DVO0]            = { MTK_DVO,                    0, &ddp_dpi },
   477		[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,		0, &ddp_gamma },
   478		[DDP_COMPONENT_MERGE0]		= { MTK_DISP_MERGE,		0, &ddp_merge },
   479		[DDP_COMPONENT_MERGE1]		= { MTK_DISP_MERGE,		1, &ddp_merge },
   480		[DDP_COMPONENT_MERGE2]		= { MTK_DISP_MERGE,		2, &ddp_merge },
   481		[DDP_COMPONENT_MERGE3]		= { MTK_DISP_MERGE,		3, &ddp_merge },
   482		[DDP_COMPONENT_MERGE4]		= { MTK_DISP_MERGE,		4, &ddp_merge },
   483		[DDP_COMPONENT_MERGE5]		= { MTK_DISP_MERGE,		5, &ddp_merge },
   484		[DDP_COMPONENT_OD0]		= { MTK_DISP_OD,		0, &ddp_od },
   485		[DDP_COMPONENT_OD1]		= { MTK_DISP_OD,		1, &ddp_od },
   486		[DDP_COMPONENT_OVL0]		= { MTK_DISP_OVL,		0, &ddp_ovl },
   487		[DDP_COMPONENT_OVL1]		= { MTK_DISP_OVL,		1, &ddp_ovl },
   488		[DDP_COMPONENT_OVL_2L0]		= { MTK_DISP_OVL_2L,		0, &ddp_ovl },
   489		[DDP_COMPONENT_OVL_2L1]		= { MTK_DISP_OVL_2L,		1, &ddp_ovl },
   490		[DDP_COMPONENT_OVL_2L2]		= { MTK_DISP_OVL_2L,		2, &ddp_ovl },
   491		[DDP_COMPONENT_POSTMASK0]	= { MTK_DISP_POSTMASK,		0, &ddp_postmask },
   492		[DDP_COMPONENT_PWM0]		= { MTK_DISP_PWM,		0, NULL },
   493		[DDP_COMPONENT_PWM1]		= { MTK_DISP_PWM,		1, NULL },
   494		[DDP_COMPONENT_PWM2]		= { MTK_DISP_PWM,		2, NULL },
   495		[DDP_COMPONENT_RDMA0]		= { MTK_DISP_RDMA,		0, &ddp_rdma },
   496		[DDP_COMPONENT_RDMA1]		= { MTK_DISP_RDMA,		1, &ddp_rdma },
   497		[DDP_COMPONENT_RDMA2]		= { MTK_DISP_RDMA,		2, &ddp_rdma },
   498		[DDP_COMPONENT_RDMA4]		= { MTK_DISP_RDMA,		4, &ddp_rdma },
   499		[DDP_COMPONENT_UFOE]		= { MTK_DISP_UFOE,		0, &ddp_ufoe },
   500		[DDP_COMPONENT_WDMA0]		= { MTK_DISP_WDMA,		0, NULL },
   501		[DDP_COMPONENT_WDMA1]		= { MTK_DISP_WDMA,		1, NULL },
   502	};
   503	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
  2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
  2025-04-19  7:19   ` kernel test robot
@ 2025-04-19  8:01   ` kernel test robot
  2025-05-27  6:24   ` CK Hu (胡俊光)
  2 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2025-04-19  8:01 UTC (permalink / raw)
  To: Bincai Liu, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Simona Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Jitao shi, CK Hu
  Cc: oe-kbuild-all, dri-devel, linux-mediatek, devicetree,
	linux-kernel, linux-arm-kernel, linux-phy, Bincai Liu

Hi Bincai,

kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on pza/reset/next linus/master v6.15-rc2 next-20250417]
[cannot apply to pza/imx-drm/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Bincai-Liu/dt-bindings-eDP-mediatek-add-eDP-yaml-for-mt8196/20250418-145911
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20250418065313.8972-4-bincai.liu%40mediatek.com
patch subject: [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
config: i386-buildonly-randconfig-001-20250419 (https://download.01.org/0day-ci/archive/20250419/202504191549.ufJBsMvZ-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250419/202504191549.ufJBsMvZ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504191549.ufJBsMvZ-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

>> drivers/gpu/drm/mediatek/mtk_ddp_comp.c:476:10: error: 'DDP_COMPONENT_DVO0' undeclared here (not in a function); did you mean 'DDP_COMPONENT_OVL0'?
     476 |         [DDP_COMPONENT_DVO0]            = { MTK_DVO,                    0, &ddp_dpi },
         |          ^~~~~~~~~~~~~~~~~~
         |          DDP_COMPONENT_OVL0
>> drivers/gpu/drm/mediatek/mtk_ddp_comp.c:476:10: error: array index in initializer not of integer type
   drivers/gpu/drm/mediatek/mtk_ddp_comp.c:476:10: note: (near initialization for 'mtk_ddp_matches')
--
>> drivers/gpu/drm/mediatek/mtk_dpi.c:201: warning: Function parameter or struct member 'out_np_sel' not described in 'mtk_dpi_conf'
>> drivers/gpu/drm/mediatek/mtk_dpi.c:201: warning: Function parameter or struct member 'dpi_ver' not described in 'mtk_dpi_conf'


vim +476 drivers/gpu/drm/mediatek/mtk_ddp_comp.c

   456	
   457	static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX] = {
   458		[DDP_COMPONENT_AAL0]		= { MTK_DISP_AAL,		0, &ddp_aal },
   459		[DDP_COMPONENT_AAL1]		= { MTK_DISP_AAL,		1, &ddp_aal },
   460		[DDP_COMPONENT_BLS]		= { MTK_DISP_BLS,		0, NULL },
   461		[DDP_COMPONENT_CCORR]		= { MTK_DISP_CCORR,		0, &ddp_ccorr },
   462		[DDP_COMPONENT_COLOR0]		= { MTK_DISP_COLOR,		0, &ddp_color },
   463		[DDP_COMPONENT_COLOR1]		= { MTK_DISP_COLOR,		1, &ddp_color },
   464		[DDP_COMPONENT_DITHER0]		= { MTK_DISP_DITHER,		0, &ddp_dither },
   465		[DDP_COMPONENT_DP_INTF0]	= { MTK_DP_INTF,		0, &ddp_dpi },
   466		[DDP_COMPONENT_DP_INTF1]	= { MTK_DP_INTF,		1, &ddp_dpi },
   467		[DDP_COMPONENT_DPI0]		= { MTK_DPI,			0, &ddp_dpi },
   468		[DDP_COMPONENT_DPI1]		= { MTK_DPI,			1, &ddp_dpi },
   469		[DDP_COMPONENT_DRM_OVL_ADAPTOR]	= { MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
   470		[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,		0, &ddp_dsc },
   471		[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,		1, &ddp_dsc },
   472		[DDP_COMPONENT_DSI0]		= { MTK_DSI,			0, &ddp_dsi },
   473		[DDP_COMPONENT_DSI1]		= { MTK_DSI,			1, &ddp_dsi },
   474		[DDP_COMPONENT_DSI2]		= { MTK_DSI,			2, &ddp_dsi },
   475		[DDP_COMPONENT_DSI3]		= { MTK_DSI,			3, &ddp_dsi },
 > 476		[DDP_COMPONENT_DVO0]            = { MTK_DVO,                    0, &ddp_dpi },
   477		[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,		0, &ddp_gamma },
   478		[DDP_COMPONENT_MERGE0]		= { MTK_DISP_MERGE,		0, &ddp_merge },
   479		[DDP_COMPONENT_MERGE1]		= { MTK_DISP_MERGE,		1, &ddp_merge },
   480		[DDP_COMPONENT_MERGE2]		= { MTK_DISP_MERGE,		2, &ddp_merge },
   481		[DDP_COMPONENT_MERGE3]		= { MTK_DISP_MERGE,		3, &ddp_merge },
   482		[DDP_COMPONENT_MERGE4]		= { MTK_DISP_MERGE,		4, &ddp_merge },
   483		[DDP_COMPONENT_MERGE5]		= { MTK_DISP_MERGE,		5, &ddp_merge },
   484		[DDP_COMPONENT_OD0]		= { MTK_DISP_OD,		0, &ddp_od },
   485		[DDP_COMPONENT_OD1]		= { MTK_DISP_OD,		1, &ddp_od },
   486		[DDP_COMPONENT_OVL0]		= { MTK_DISP_OVL,		0, &ddp_ovl },
   487		[DDP_COMPONENT_OVL1]		= { MTK_DISP_OVL,		1, &ddp_ovl },
   488		[DDP_COMPONENT_OVL_2L0]		= { MTK_DISP_OVL_2L,		0, &ddp_ovl },
   489		[DDP_COMPONENT_OVL_2L1]		= { MTK_DISP_OVL_2L,		1, &ddp_ovl },
   490		[DDP_COMPONENT_OVL_2L2]		= { MTK_DISP_OVL_2L,		2, &ddp_ovl },
   491		[DDP_COMPONENT_POSTMASK0]	= { MTK_DISP_POSTMASK,		0, &ddp_postmask },
   492		[DDP_COMPONENT_PWM0]		= { MTK_DISP_PWM,		0, NULL },
   493		[DDP_COMPONENT_PWM1]		= { MTK_DISP_PWM,		1, NULL },
   494		[DDP_COMPONENT_PWM2]		= { MTK_DISP_PWM,		2, NULL },
   495		[DDP_COMPONENT_RDMA0]		= { MTK_DISP_RDMA,		0, &ddp_rdma },
   496		[DDP_COMPONENT_RDMA1]		= { MTK_DISP_RDMA,		1, &ddp_rdma },
   497		[DDP_COMPONENT_RDMA2]		= { MTK_DISP_RDMA,		2, &ddp_rdma },
   498		[DDP_COMPONENT_RDMA4]		= { MTK_DISP_RDMA,		4, &ddp_rdma },
   499		[DDP_COMPONENT_UFOE]		= { MTK_DISP_UFOE,		0, &ddp_ufoe },
   500		[DDP_COMPONENT_WDMA0]		= { MTK_DISP_WDMA,		0, NULL },
   501		[DDP_COMPONENT_WDMA1]		= { MTK_DISP_WDMA,		1, NULL },
   502	};
   503	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo yaml for mt8196
  2025-04-18  6:52 ` [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo " Bincai Liu
@ 2025-04-21  5:07   ` CK Hu (胡俊光)
  0 siblings, 0 replies; 14+ messages in thread
From: CK Hu (胡俊光) @ 2025-04-21  5:07 UTC (permalink / raw)
  To: robh@kernel.org, Chunfeng Yun (云春峰),
	kishon@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
	mripard@kernel.org, AngeloGioacchino Del Regno,
	Bincai Liu (刘彬才),
	Jitao Shi (石记涛),
	maarten.lankhorst@linux.intel.com, conor+dt@kernel.org,
	chunkuang.hu@kernel.org, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, airlied@gmail.com, matthias.bgg@gmail.com
  Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

On Fri, 2025-04-18 at 14:52 +0800, Bincai Liu wrote:
> Add compatible string to support dvo for MT8196.

Say something about dvo.
What does 'dvo' mean?
What's the mt8196-edp-dvo primary new function?

Regards,
CK

> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---
>  .../devicetree/bindings/display/mediatek/mediatek,dpi.yaml       | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> index b659d79393a8..4f897f05cb36 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml
> @@ -28,6 +28,7 @@ properties:
>            - mediatek,mt8192-dpi
>            - mediatek,mt8195-dp-intf
>            - mediatek,mt8195-dpi
> +          - mediatek,mt8196-edp-dvo
>        - items:
>            - enum:
>                - mediatek,mt6795-dpi


[-- Attachment #2: Type: text/html, Size: 2698 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml for mt8196
  2025-04-18  6:52 ` [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml " Bincai Liu
@ 2025-04-21  5:09   ` CK Hu (胡俊光)
  0 siblings, 0 replies; 14+ messages in thread
From: CK Hu (胡俊光) @ 2025-04-21  5:09 UTC (permalink / raw)
  To: robh@kernel.org, Chunfeng Yun (云春峰),
	kishon@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
	mripard@kernel.org, AngeloGioacchino Del Regno,
	Bincai Liu (刘彬才),
	Jitao Shi (石记涛),
	maarten.lankhorst@linux.intel.com, conor+dt@kernel.org,
	chunkuang.hu@kernel.org, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, airlied@gmail.com, matthias.bgg@gmail.com
  Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org

[-- Attachment #1: Type: text/plain, Size: 1211 bytes --]

On Fri, 2025-04-18 at 14:52 +0800, Bincai Liu wrote:
> Add compatible string to support eDP for MT8196.

Say something about mt8196-edp-tx.
What's the mt8196-edp-tx primary new function?

Regards,
CK

> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---
>  .../devicetree/bindings/display/mediatek/mediatek,dp.yaml       | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> index 75ce92f4a5fd..26997feba66b 100644
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dp.yaml
> @@ -25,6 +25,7 @@ properties:
>        - mediatek,mt8188-edp-tx
>        - mediatek,mt8195-dp-tx
>        - mediatek,mt8195-edp-tx
> +      - mediatek,mt8196-edp-tx
>  
>    reg:
>      maxItems: 1
> @@ -98,6 +99,7 @@ allOf:
>                enum:
>                  - mediatek,mt8188-dp-tx
>                  - mediatek,mt8195-dp-tx
> +                - mediatek,mt8196-edp-tx
>      then:
>        properties:
>          '#sound-dai-cells': false


[-- Attachment #2: Type: text/html, Size: 3126 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] drm/mediatek: Add dvo driver for mt8196
  2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
  2025-04-19  7:19   ` kernel test robot
  2025-04-19  8:01   ` kernel test robot
@ 2025-05-27  6:24   ` CK Hu (胡俊光)
  2 siblings, 0 replies; 14+ messages in thread
From: CK Hu (胡俊光) @ 2025-05-27  6:24 UTC (permalink / raw)
  To: robh@kernel.org, Chunfeng Yun (云春峰),
	kishon@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
	mripard@kernel.org, AngeloGioacchino Del Regno,
	Bincai Liu (刘彬才),
	Jitao Shi (石记涛),
	maarten.lankhorst@linux.intel.com, conor+dt@kernel.org,
	chunkuang.hu@kernel.org, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, airlied@gmail.com, matthias.bgg@gmail.com
  Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org

[-- Attachment #1: Type: text/plain, Size: 17931 bytes --]

On Fri, 2025-04-18 at 14:52 +0800, Bincai Liu wrote:
> Add code to support dvo for mt8196.

Say something about dvo.
I don't know what is dvo.

> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---

[snip]

>  
> +enum mtk_dpi_golden_setting_level {
> +	MTK_DPI_FHD_60FPS_1920 = 0,
> +	MTK_DPI_FHD_60FPS_2180,
> +	MTK_DPI_FHD_60FPS_2400,
> +	MTK_DPI_FHD_60FPS_2520,
> +	MTK_DPI_FHD_90FPS,
> +	MTK_DPI_FHD_120FPS,
> +	MTK_DPI_WQHD_60FPS,
> +	MTK_DPI_WQHD_120FPS,
> +	MTK_DPI_8K_30FPS,
> +	MTK_DPI_GSL_MAX,
> +};
> +
> +enum mtk_dpi_type {
> +	MTK_DISP_DPI = 0,
> +	MTK_DSIP_DVO,
> +};
> +
> +struct mtk_dpi_gs_info {
> +	u32 dpi_buf_sodi_high;
> +	u32 dpi_buf_sodi_low;
> +};
> +
>  struct mtk_dpi {
>  	struct drm_encoder encoder;
>  	struct drm_bridge bridge;
> @@ -73,6 +96,7 @@ struct mtk_dpi {
>  	struct clk *engine_clk;
>  	struct clk *pixel_clk;
>  	struct clk *tvd_clk;
> +	struct clk *hf_fdpi_clk;
>  	int irq;
>  	struct drm_display_mode mode;
>  	const struct mtk_dpi_conf *conf;
> @@ -85,6 +109,7 @@ struct mtk_dpi {
>  	struct pinctrl_state *pins_dpi;
>  	u32 output_fmt;
>  	int refcount;
> +	enum mtk_dpi_golden_setting_level gs_level;

Drop this.

>  };
>  
>  static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
> @@ -171,6 +196,13 @@ struct mtk_dpi_conf {
>  	bool edge_cfg_in_mmsys;
>  	bool clocked_by_hdmi;
>  	bool output_1pixel;
> +	u32 out_np_sel;

Drop this.

> +	u8 dpi_ver;
> +};
> +
> +static struct mtk_dpi_gs_info mtk_dpi_gs[MTK_DPI_GSL_MAX] = {
> +	[MTK_DPI_FHD_60FPS_1920] = {6880, 511},
> +	[MTK_DPI_8K_30FPS] = {5255, 3899},
>  };

Drop this.

>  
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> @@ -208,6 +240,86 @@ static void mtk_dpi_disable(struct mtk_dpi *dpi)
>  	mtk_dpi_mask(dpi, DPI_EN, 0, EN);
>  }
>  
> +static void mtk_dpi_irq_enable(struct mtk_dpi *dpi)
> +{
> +	mtk_dpi_mask(dpi, DPI_INTEN, INT_VDE_END_EN, INT_VDE_END_EN);
> +}
> +
> +static void mtk_dpi_info_queue_start(struct mtk_dpi *dpi)
> +{
> +	mtk_dpi_mask(dpi, DPI_TGEN_INFOQ_LATENCY, 0,
> +		     INFOQ_START_LATENCY_MASK | INFOQ_END_LATENCY_MASK);
> +}
> +
> +static void mtk_dpi_buffer_ctrl(struct mtk_dpi *dpi)
> +{
> +	mtk_dpi_mask(dpi, DPI_BUF_CON0, DISP_BUF_EN, DISP_BUF_EN);
> +	mtk_dpi_mask(dpi, DPI_BUF_CON0, FIFO_UNDERFLOW_DONE_BLOCK, FIFO_UNDERFLOW_DONE_BLOCK);
> +}
> +
> +static void mtk_dpi_trailing_blank_setting(struct mtk_dpi *dpi)
> +{
> +	mtk_dpi_mask(dpi, DPI_TGEN_V_LAST_TRAILING_BLANK, 0x20, V_LAST_TRAILING_BLANK_MASK);
> +	mtk_dpi_mask(dpi, DPI_TGEN_OUTPUT_DELAY_LINE, 0x20, EXT_TG_DLY_LINE_MASK);
> +}
> +
> +static void mtk_dpi_get_gs_level(struct mtk_dpi *dpi)
> +{
> +	struct drm_display_mode *mode = &dpi->mode;
> +	enum mtk_dpi_golden_setting_level *gsl = &dpi->gs_level;
> +
> +	if (mode->hdisplay == 1920 && mode->vdisplay == 1080)
> +		*gsl = MTK_DPI_FHD_60FPS_1920;
> +	else
> +		*gsl = MTK_DPI_8K_30FPS;
> +}

Drop this function.

> +
> +static void mtk_dpi_golden_setting(struct mtk_dpi *dpi)

Change the function name to mtk_dpi_sod()

> +{
> +	struct mtk_dpi_gs_info *gs_info = NULL;
> +
> +	if (dpi->gs_level >= MTK_DPI_GSL_MAX) {
> +		dev_info(dpi->dev, "%s invalid gs_level %d\n",
> +			 __func__, dpi->gs_level);
> +		return;
> +	}
> +
> +	gs_info = &mtk_dpi_gs[dpi->gs_level];
> +
> +	mtk_dpi_mask(dpi, DPI_BUF_SODI_HIGHT, gs_info->dpi_buf_sodi_high, GENMASK(31, 0));
> +	mtk_dpi_mask(dpi, DPI_BUF_SODI_LOW, gs_info->dpi_buf_sodi_low, GENMASK(31, 0));

The golden setting has only two case, so drop the golden setting array.

	struct drm_display_mode *mode = &dpi->mode;

if (mode->hdisplay == 1920 && mode->vdisplay == 1080) {
	mtk_dpi_mask(dpi, DPI_BUF_SODI_HIGHT, 6880, GENMASK(31, 0));
	mtk_dpi_mask(dpi, DPI_BUF_SODI_LOW, 511, GENMASK(31, 0));
} else {
	mtk_dpi_mask(dpi, DPI_BUF_SODI_HIGHT, 5255, GENMASK(31, 0));
	mtk_dpi_mask(dpi, DPI_BUF_SODI_LOW, 3899, GENMASK(31, 0));
}

> +}
> +
> +static void mtk_dpi_shadow_ctrl(struct mtk_dpi *dpi)
> +{
> +	mtk_dpi_mask(dpi, DPI_SHADOW_CTRL, 0, BYPASS_SHADOW);
> +	mtk_dpi_mask(dpi, DPI_SHADOW_CTRL, FORCE_COMMIT, FORCE_COMMIT);
> +}
> +
> +static void mtk_dpi_config_timing(struct mtk_dpi *dpi,
> +				 struct mtk_dpi_sync_param *hsync,
> +				 struct mtk_dpi_sync_param *vsync)
> +{
> +	mtk_dpi_mask(dpi, DPI_TGEN_H0,
> +		     hsync->sync_width << HSYNC,
> +		     dpi->conf->dimension_mask << HSYNC);
> +	mtk_dpi_mask(dpi, DPI_TGEN_H0,
> +		     hsync->front_porch << DPI_HFP,
> +		     dpi->conf->dimension_mask << DPI_HFP);
> +	mtk_dpi_mask(dpi, DPI_TGEN_H1,
> +		     (hsync->back_porch + hsync->sync_width) << HSYNC2ACT,
> +		     dpi->conf->dimension_mask << HSYNC2ACT);
> +	mtk_dpi_mask(dpi, DPI_TGEN_V0,
> +		     vsync->sync_width << VSYNC,
> +		     dpi->conf->dimension_mask << VSYNC);
> +	mtk_dpi_mask(dpi, DPI_TGEN_V0,
> +		     vsync->front_porch << VFP,
> +		     dpi->conf->dimension_mask << VFP);
> +	mtk_dpi_mask(dpi, DPI_TGEN_V1,
> +		     (vsync->back_porch + vsync->sync_width) << VSYNC2ACT,
> +		     dpi->conf->dimension_mask << VSYNC2ACT);
> +}
> +
>  static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
>  				 struct mtk_dpi_sync_param *sync)
>  {
> @@ -296,10 +408,27 @@ static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
>  
>  static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
>  {
> -	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> -		     dpi->conf->hvsize_mask << HSIZE);
> -	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> -		     dpi->conf->hvsize_mask << VSIZE);
> +	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
> +		mtk_dpi_mask(dpi, DPI_SRC_SIZE, width << SRC_HSIZE,
> +			dpi->conf->hvsize_mask << SRC_HSIZE);
> +		mtk_dpi_mask(dpi, DPI_SRC_SIZE, height << SRC_VSIZE,
> +			dpi->conf->hvsize_mask << SRC_VSIZE);
> +
> +		mtk_dpi_mask(dpi, DPI_PIC_SIZE, width << PIC_HSIZE,
> +			dpi->conf->hvsize_mask << PIC_HSIZE);
> +		mtk_dpi_mask(dpi, DPI_PIC_SIZE, height << PIC_VSIZE,
> +			dpi->conf->hvsize_mask << PIC_VSIZE);
> +
> +		mtk_dpi_mask(dpi, DPI_TGEN_H1, (width / dpi->conf->pixels_per_iter) << HACT,
> +			dpi->conf->hvsize_mask << HACT);
> +		mtk_dpi_mask(dpi, DPI_TGEN_V1, height << VACT,
> +			dpi->conf->hvsize_mask << VACT);
> +	} else {
> +		mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
> +			dpi->conf->hvsize_mask << HSIZE);
> +		mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
> +			dpi->conf->hvsize_mask << VSIZE);
> +	}
>  }
>  
>  static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
> @@ -501,6 +630,7 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
>  	clk_disable_unprepare(dpi->pixel_clk);
>  	clk_disable_unprepare(dpi->tvd_clk);
>  	clk_disable_unprepare(dpi->engine_clk);
> +	clk_disable_unprepare(dpi->hf_fdpi_clk);
>  }
>  
>  static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -528,8 +658,16 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
>  		goto err_pixel;
>  	}
>  
> +	ret = clk_prepare_enable(dpi->hf_fdpi_clk);
> +	if (ret) {
> +		dev_err(dpi->dev, "Failed to enable hf_fdpi_clk clock: %d\n", ret);
> +		goto err_hf_fdpi_clk;
> +	}
> +
>  	return 0;
>  
> +err_hf_fdpi_clk:
> +	clk_disable_unprepare(dpi->hf_fdpi_clk);

You fail to prepare enable dpi->hf_fdpi_clk,
so you don't need to disable unprepare it.

clk_disable_unprepare(dpi->pixel_clk);

>  err_pixel:
>  	clk_disable_unprepare(dpi->tvd_clk);
>  err_engine:
> @@ -610,7 +748,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>  			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
>  	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
>  			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
> -
>  	/*
>  	 * Depending on the IP version, we may output a different amount of
>  	 * pixels for each iteration: divide the clock by this number and
> @@ -643,14 +780,18 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>  	}
>  	mtk_dpi_sw_reset(dpi, true);
>  	mtk_dpi_config_pol(dpi, &dpi_pol);
> +	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
> +		mtk_dpi_irq_enable(dpi);

This driver has no irq handler, so drop this.

> +		mtk_dpi_config_timing(dpi, &hsync, &vsync_lodd);
> +	} else {
> +		mtk_dpi_config_hsync(dpi, &hsync);
> +		mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
> +		mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
> +		mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
> +		mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
> +		mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
> +	}
>  
> -	mtk_dpi_config_hsync(dpi, &hsync);
> -	mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
> -	mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
> -	mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
> -	mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
> -
> -	mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
>  	mtk_dpi_config_interface(dpi, !!(vm.flags &
>  					 DISPLAY_FLAGS_INTERLACED));
>  	if (vm.flags & DISPLAY_FLAGS_INTERLACED)
> @@ -658,26 +799,41 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>  	else
>  		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
>  
> -	mtk_dpi_config_channel_limit(dpi);
> -	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> -	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> -	mtk_dpi_config_color_format(dpi, dpi->color_format);
> -	if (dpi->conf->support_direct_pin) {
> -		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> -		mtk_dpi_config_2n_h_fre(dpi);
> -
> -		/* DPI can connect to either an external bridge or the internal HDMI encoder */
> -		if (dpi->conf->output_1pixel)
> -			mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
> -		else
> -			mtk_dpi_dual_edge(dpi);
> -
> -		mtk_dpi_config_disable_edge(dpi);
> -	}
> -	if (dpi->conf->input_2p_en_bit) {
> -		mtk_dpi_mask(dpi, DPI_CON, dpi->conf->input_2p_en_bit,
> -			     dpi->conf->input_2p_en_bit);
> +	if (dpi->conf->dpi_ver == MTK_DSIP_DVO) {
> +		mtk_dpi_info_queue_start(dpi);
> +		mtk_dpi_buffer_ctrl(dpi);
> +		mtk_dpi_trailing_blank_setting(dpi);
> +		mtk_dpi_get_gs_level(dpi);
> +		mtk_dpi_golden_setting(dpi);
> +		mtk_dpi_shadow_ctrl(dpi);
> +		mtk_dpi_mask(dpi, DPI_OUTPUT_SET, dpi->conf->out_np_sel, OUT_NP_SEL);

Up to now, only mt8196 dvo set DPI_OUTPUT_SET, so it's not necessary to have a private data to store out_np_sel.

#define DPI_OUTPUT_SET		0x18
#define DPI_OUTPUT_SET_XXX		2
#define OUT_NP_SEL			GENMASK(1, 0)

mtk_dpi_mask(dpi, DPI_OUTPUT_SET, DPI_OUTPUT_SET_XXX, OUT_NP_SEL);

> +	} else {
> +		mtk_dpi_config_channel_limit(dpi);
> +		mtk_dpi_config_bit_num(dpi, dpi->bit_num);
> +		mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
> +		mtk_dpi_config_color_format(dpi, dpi->color_format);
> +		if (dpi->conf->support_direct_pin) {
> +			mtk_dpi_config_yc_map(dpi, dpi->yc_map);
> +			mtk_dpi_config_2n_h_fre(dpi);
> +
> +			/*
> +			 * DPI can connect to either an external bridge
> +			 * or the internal HDMI encoder
> +			 */
> +			if (dpi->conf->output_1pixel)
> +				mtk_dpi_mask(dpi, DPI_CON,
> +						  DPI_OUTPUT_1T1P_EN, DPI_OUTPUT_1T1P_EN);
> +			else
> +				mtk_dpi_dual_edge(dpi);
> +
> +			mtk_dpi_config_disable_edge(dpi);
> +		}
> +		if (dpi->conf->input_2p_en_bit) {
> +			mtk_dpi_mask(dpi, DPI_CON, dpi->conf->input_2p_en_bit,
> +				dpi->conf->input_2p_en_bit);
> +		}
>  	}
> +
>  	mtk_dpi_sw_reset(dpi, false);
>  
>  	return 0;
> @@ -700,7 +856,7 @@ static u32 *mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>  	}
>  
>  	output_fmts = kcalloc(dpi->conf->num_output_fmts, sizeof(*output_fmts),
> -			     GFP_KERNEL);
> +			      GFP_KERNEL);

This is not related to the title. Separate this to a refinement patch.

>  	if (!output_fmts)
>  		return NULL;
>  
> @@ -1173,6 +1329,20 @@ static const struct mtk_dpi_conf mt8195_dpintf_conf = {
>  	.input_2p_en_bit = DPINTF_INPUT_2P_EN,
>  };
>  
> +static const struct mtk_dpi_conf mt8196_conf = {
> +	.dpi_factor = dpi_factor_mt8195_dp_intf,
> +	.num_dpi_factor = ARRAY_SIZE(dpi_factor_mt8195_dp_intf),
> +	.out_np_sel = 0x2,
> +	.reg_h_fre_con = 0xb0,
> +	.max_clock_khz = 1330000,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.pixels_per_iter = 4,
> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = PIC_HSIZE_MASK,
> +	.dpi_ver = MTK_DSIP_DVO,
> +};
> +
>  static int mtk_dpi_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -1227,6 +1397,11 @@ static int mtk_dpi_probe(struct platform_device *pdev)
>  		return dev_err_probe(dev, PTR_ERR(dpi->tvd_clk),
>  				     "Failed to get tvdpll clock\n");
>  
> +	dpi->hf_fdpi_clk = devm_clk_get_optional(dev, "hf_fdvo_clk");
> +	if (IS_ERR(dpi->hf_fdpi_clk))
> +		return dev_err_probe(dev, PTR_ERR(dpi->hf_fdpi_clk),
> +				     "Failed to get hf_fdpi_clk clock\n");
> +
>  	dpi->irq = platform_get_irq(pdev, 0);
>  	if (dpi->irq < 0)
>  		return dpi->irq;
> @@ -1262,6 +1437,7 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>  	{ .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
>  	{ .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
>  	{ .compatible = "mediatek,mt8195-dpi", .data = &mt8195_conf },
> +	{ .compatible = "mediatek,mt8196-edp-dvo", .data = &mt8196_conf },
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> index 23eeefce8fd2..3e2a64c2bca0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -16,6 +16,7 @@
>  #define INT_VSYNC_EN			BIT(0)
>  #define INT_VDE_EN			BIT(1)
>  #define INT_UNDERFLOW_EN		BIT(2)
> +#define INT_VDE_END_EN			BIT(4)
>  
>  #define DPI_INTSTA		0x0C
>  #define INT_VSYNC_STA			BIT(0)
> @@ -240,6 +241,71 @@
>  #define MATRIX_SEL_RGB_TO_JPEG		0
>  #define MATRIX_SEL_RGB_TO_BT601		2
>  
> +#define DPI_TGEN_INFOQ_LATENCY	0x80
> +#define INFOQ_START_LATENCY		0
> +#define INFOQ_START_LATENCY_MASK	(0xffff << 0)
> +#define INFOQ_END_LATENCY		16
> +#define INFOQ_END_LATENCY_MASK		(0xffff << 16)
> +
> +#define DPI_BUF_CON0		0x220
> +#define DISP_BUF_EN			BIT(0)
> +#define FIFO_UNDERFLOW_DONE_BLOCK	BIT(4)
> +
> +#define DPI_TGEN_V_LAST_TRAILING_BLANK	0x6c
> +#define V_LAST_TRAILING_BLANK			0
> +#define V_LAST_TRAILING_BLANK_MASK		(0xffff << 0)
> +
> +#define DPI_TGEN_OUTPUT_DELAY_LINE	0x7c
> +#define EXT_TG_DLY_LINE				0
> +#define EXT_TG_DLY_LINE_MASK			(0xffff << 0)
> +
> +#define DPI_SHADOW_CTRL			0x190
> +#define FORCE_COMMIT				BIT(0)
> +#define BYPASS_SHADOW				BIT(1)
> +#define READ_WRK_REG				BIT(2)
> +
> +#define DPI_BUF_SODI_HIGHT		0x230
> +#define DPI_BUF_SODI_LOW		0x234
> +
> +#define DPI_OUTPUT_SET		0x18
> +#define OUT_NP_SEL			(0x3 << 0)
> +
> +#define DPI_SRC_SIZE		0x20
> +#define SRC_HSIZE			0
> +#define SRC_HSIZE_MASK			(0xffff << 0)
> +#define SRC_VSIZE			16
> +#define SRC_VSIZE_MASK			(0xffff << 16)
> +
> +#define DPI_PIC_SIZE		0x24
> +#define PIC_HSIZE			0
> +#define PIC_HSIZE_MASK			(0xffff << 0)
> +#define PIC_VSIZE			16
> +#define PIC_VSIZE_MASK			(0xffff << 16)
> +
> +#define DPI_TGEN_H0		0x50
> +#define DPI_HFP				0
> +#define DPI_HFP_MASK			(0xffff << 0)
> +#define HSYNC				16
> +#define HSYNC_MASK			(0xffff << 16)
> +
> +#define DPI_TGEN_H1		0x54
> +#define HSYNC2ACT			0
> +#define HSYNC2ACT_MASK			(0xffff << 0)
> +#define HACT				16
> +#define HACT_MASK			(0xffff << 16)
> +
> +#define DPI_TGEN_V0		0x58
> +#define VFP				0
> +#define VFP_MASK			(0xffff << 0)
> +#define VSYNC				16
> +#define VSYNC_MASK			(0xffff << 16)
> +
> +#define DPI_TGEN_V1		0x5c
> +#define VSYNC2ACT			0
> +#define VSYNC2ACT_MASK			(0xffff << 0)
> +#define VACT				16
> +#define VACT_MASK			(0xffff << 16)
> +
>  #define DPI_PATTERN0		0xf00
>  #define DPI_PAT_EN			BIT(0)
>  #define DPI_PAT_SEL			GENMASK(6, 4)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 74158b9d6503..870d97c023ed 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -830,6 +830,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>  	  .data = (void *)MTK_DSI },
>  	{ .compatible = "mediatek,mt8188-dsi",
>  	  .data = (void *)MTK_DSI },
> +	{ .compatible = "mediatek,mt8196-edp-dvo",
> +	  .data = (void *)MTK_DVO },
>  	{ }
>  };
>  
> @@ -1176,7 +1178,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		    comp_type == MTK_DISP_RDMA ||
>  		    comp_type == MTK_DP_INTF ||
>  		    comp_type == MTK_DPI ||
> -		    comp_type == MTK_DSI) {
> +		    comp_type == MTK_DSI ||
> +		    comp_type == MTK_DVO) {

DVO is a kind of DPI, so why not reuse DPI and drop DVO?

Regards,
CK

>  			dev_info(dev, "Adding component match for %pOF\n",
>  				 node);
>  			drm_of_component_match_add(dev, &match, component_compare_of,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index 675cdc90a440..6d2796148813 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -79,6 +79,7 @@ extern struct platform_driver mtk_disp_ovl_driver;
>  extern struct platform_driver mtk_disp_rdma_driver;
>  extern struct platform_driver mtk_dpi_driver;
>  extern struct platform_driver mtk_dsi_driver;
> +extern struct platform_driver mtk_dvo_driver;
>  extern struct platform_driver mtk_ethdr_driver;
>  extern struct platform_driver mtk_mdp_rdma_driver;
>  extern struct platform_driver mtk_padding_driver;


[-- Attachment #2: Type: text/html, Size: 27683 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/5] drm/mediatek: Add eDP driver for mt8196
  2025-04-18  6:52 ` [PATCH 4/5] drm/mediatek: Add eDP " Bincai Liu
@ 2025-05-27 10:24   ` CK Hu (胡俊光)
  0 siblings, 0 replies; 14+ messages in thread
From: CK Hu (胡俊光) @ 2025-05-27 10:24 UTC (permalink / raw)
  To: robh@kernel.org, Chunfeng Yun (云春峰),
	kishon@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
	mripard@kernel.org, AngeloGioacchino Del Regno,
	Bincai Liu (刘彬才),
	Jitao Shi (石记涛),
	maarten.lankhorst@linux.intel.com, conor+dt@kernel.org,
	chunkuang.hu@kernel.org, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, airlied@gmail.com, matthias.bgg@gmail.com
  Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org

[-- Attachment #1: Type: text/plain, Size: 30247 bytes --]

On Fri, 2025-04-18 at 14:52 +0800, Bincai Liu wrote:
> Add code to support eDP 1.4 driver for mt8196.
> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dp.c     | 484 ++++++++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h | 126 +++++++
>  2 files changed, 550 insertions(+), 60 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
> index b2408abb9d49..159ab5ebb9d2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -35,6 +35,9 @@
>  
>  #include "mtk_dp_reg.h"
>  
> +#define EDP_VIDEO_UNMUTE		0x22
> +#define EDP_VIDEO_UNMUTE_VAL		0xfefd
> +#define MTK_SIP_DP_CONTROL		(0x82000523 | 0x40000000)
>  #define MTK_DP_SIP_CONTROL_AARCH32	MTK_SIP_SMC_CMD(0x523)
>  #define MTK_DP_SIP_ATF_EDP_VIDEO_UNMUTE	(BIT(0) | BIT(5))
>  #define MTK_DP_SIP_ATF_VIDEO_UNMUTE	BIT(5)
> @@ -51,6 +54,7 @@
>  #define MTK_DP_TRAIN_DOWNSCALE_RETRY 10
>  #define MTK_DP_VERSION 0x11
>  #define MTK_DP_SDP_AUI 0x4
> +#define EDP_REINIT_TIMES 4
>  
>  enum {
>  	MTK_DP_CAL_GLB_BIAS_TRIM = 0,
> @@ -102,6 +106,7 @@ struct mtk_dp {
>  	bool enabled;
>  	bool need_debounce;
>  	int irq;
> +	int swing_value;
>  	u8 max_lanes;
>  	u8 max_linkrate;
>  	u8 rx_cap[DP_RECEIVER_CAP_SIZE];
> @@ -110,6 +115,8 @@ struct mtk_dp {
>  	/* irq_thread_lock is used to protect irq_thread_handle */
>  	spinlock_t irq_thread_lock;
>  
> +	struct clk *power_clk;
> +
>  	struct device *dev;
>  	struct drm_bridge bridge;
>  	struct drm_bridge *next_bridge;
> @@ -124,6 +131,7 @@ struct mtk_dp {
>  	struct platform_device *phy_dev;
>  	struct phy *phy;
>  	struct regmap *regs;
> +	struct regmap *phy_regs;
>  	struct timer_list debounce_timer;
>  
>  	/* For audio */
> @@ -134,6 +142,9 @@ struct mtk_dp {
>  	struct device *codec_dev;
>  	/* protect the plugged_cb as it's used in both bridge ops and audio */
>  	struct mutex update_plugged_status_lock;
> +	/* For edp power control */
> +	void __iomem *pwr_regs;
> +	u32 retry_times;
>  };
>  
>  struct mtk_dp_data {
> @@ -143,6 +154,7 @@ struct mtk_dp_data {
>  	bool audio_supported;
>  	bool audio_pkt_in_hblank_area;
>  	u16 audio_m_div2_bit;
> +	u32 edp_ver;
>  };
>  
>  static const struct mtk_dp_efuse_fmt mt8188_dp_efuse_fmt[MTK_DP_CAL_MAX] = {
> @@ -402,6 +414,16 @@ static const struct regmap_config mtk_dp_regmap_config = {
>  	.name = "mtk-dp-registers",
>  };
>  
> +static const struct regmap_config mtk_edp_phy_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = SEC_OFFSET + 0x90,
> +	.name = "mtk-edp-phy-registers",
> +};
> +
> +static int mtk_dp_poweron(struct mtk_dp *mtk_dp);
> +
>  static struct mtk_dp *mtk_dp_from_bridge(struct drm_bridge *b)
>  {
>  	return container_of(b, struct mtk_dp, bridge);
> @@ -459,6 +481,26 @@ static void mtk_dp_bulk_16bit_write(struct mtk_dp *mtk_dp, u32 offset, u8 *buf,
>  	}
>  }
>  
> +static void mtk_edp_pm_ctl(struct mtk_dp *mtk_dp, bool enable)
> +{
> +	/* DISP_EDPTX_PWR_CON udelay 10us to ensure that the power state is stable */
> +	udelay(10);
> +	if (enable) {
> +		/* Enable subsys clock, just set bit4 to 0 */
> +		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_CLK_DIS, mtk_dp->pwr_regs);
> +		udelay(1);
> +		/* Subsys power-on reset, firstly set bit0 to 0 and then set bit0 to 1 */
> +		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
> +		udelay(1);
> +		writel(readl(mtk_dp->pwr_regs) | DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
> +	} else {
> +		writel(readl(mtk_dp->pwr_regs) & ~DISP_EDPTX_PWR_RST_B, mtk_dp->pwr_regs);
> +		udelay(1);
> +		writel(readl(mtk_dp->pwr_regs) | DISP_EDPTX_PWR_CLK_DIS, mtk_dp->pwr_regs);
> +	}
> +	udelay(10);
> +}
> +
>  static void mtk_dp_msa_bypass_enable(struct mtk_dp *mtk_dp, bool enable)
>  {
>  	u32 mask = HTOTAL_SEL_DP_ENC0_P0 | VTOTAL_SEL_DP_ENC0_P0 |
> @@ -514,9 +556,14 @@ static void mtk_dp_set_msa(struct mtk_dp *mtk_dp)
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_315C,
>  			   vm->hsync_len,
>  			   PGEN_HSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
> -			   vm->hback_porch + vm->hsync_len,
> -			   PGEN_HFDE_START_DP_ENC0_P0_MASK);
> +	if (mtk_dp->data->edp_ver)

I would like a name about what it does rather than a version number.
It seem this is to add horizontal front porch to PGEN_HFDE_START_DP_ENC0_P0_MASK.
Maybe the name should be

if (mtk_dp->data->xxx_hfp) {
 

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
> +				   vm->hback_porch + vm->hsync_len + vm->hfront_porch,
> +				   PGEN_HFDE_START_DP_ENC0_P0_MASK);
> +	else
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3160,
> +				   vm->hback_porch + vm->hsync_len,
> +				   PGEN_HFDE_START_DP_ENC0_P0_MASK);
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3164,
>  			   vm->hactive,
>  			   PGEN_HFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
> @@ -531,9 +578,14 @@ static void mtk_dp_set_msa(struct mtk_dp *mtk_dp)
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3170,
>  			   vm->vsync_len,
>  			   PGEN_VSYNC_PULSE_WIDTH_DP_ENC0_P0_MASK);
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
> -			   vm->vback_porch + vm->vsync_len,
> -			   PGEN_VFDE_START_DP_ENC0_P0_MASK);
> +	if (mtk_dp->data->edp_ver)

I would like a name about what it does rather than a version number.
It seem this is to add vertical front porch to PGEN_VFDE_START_DP_ENC0_P0_MASK.
Maybe the name should be

if (mtk_dp->data->xxx_vfp) {

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
> +				   vm->vback_porch + vm->vsync_len +  vm->vfront_porch,
> +				   PGEN_VFDE_START_DP_ENC0_P0_MASK);
> +	else
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3174,
> +				   vm->vback_porch + vm->vsync_len,
> +				   PGEN_VFDE_START_DP_ENC0_P0_MASK);
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3178,
>  			   vm->vactive,
>  			   PGEN_VFDE_ACTIVE_WIDTH_DP_ENC0_P0_MASK);
> @@ -543,7 +595,7 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
>  				   enum dp_pixelformat color_format)
>  {
>  	u32 val;
> -	u32 misc0_color;
> +	u32 misc0_color = 0;

Drop this.

>  
>  	switch (color_format) {
>  	case DP_PIXELFORMAT_YUV422:
> @@ -554,6 +606,9 @@ static int mtk_dp_set_color_format(struct mtk_dp *mtk_dp,
>  		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
>  		misc0_color = DP_COLOR_FORMAT_RGB;
>  		break;
> +	case DP_PIXELFORMAT_YUV420:
> +		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR420;


After you drop misc0_color = 0, then add below statement.
But I feel it's weird that color format is RGB.

		misc0_color = DP_COLOR_FORMAT_RGB;

This register also exist in mt8188 and mt8195 edp, so this modification is not only about mt8196.
Separate this to an independent patch.

> +		break;
>  	default:
>  		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
>  			 color_format);
> @@ -612,7 +667,8 @@ static void mtk_dp_setup_encoder(struct mtk_dp *mtk_dp)
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC1_P0_3364,
>  			   FIFO_READ_START_POINT_DP_ENC1_P0_VAL << 12,
>  			   FIFO_READ_START_POINT_DP_ENC1_P0_MASK);
> -	mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368, DP_ENC1_P0_3368_VAL);
> +	if (!mtk_dp->data->edp_ver)

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		mtk_dp_write(mtk_dp, MTK_DP_ENC1_P0_3368, DP_ENC1_P0_3368_VAL);
>  }
>  
>  static void mtk_dp_pg_enable(struct mtk_dp *mtk_dp, bool enable)
> @@ -972,8 +1028,8 @@ static void mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
>  	u32 lane_shift = lane_num * DP_TX1_VOLT_SWING_SHIFT;
>  
>  	dev_dbg(mtk_dp->dev,
> -		"link training: swing_val = 0x%x, pre-emphasis = 0x%x\n",
> -		swing_val, preemphasis);
> +		"link training: swing_val = 0x%x, pre-emphasis = 0x%x lane_num = %d\n",
> +		swing_val, preemphasis, lane_num);
>  
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
>  			   swing_val << (DP_TX0_VOLT_SWING_SHIFT + lane_shift),
> @@ -981,6 +1037,28 @@ static void mtk_dp_set_swing_pre_emphasis(struct mtk_dp *mtk_dp, int lane_num,
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_SWING_EMP,
>  			   preemphasis << (DP_TX0_PRE_EMPH_SHIFT + lane_shift),
>  			   DP_TX0_PRE_EMPH_MASK << lane_shift);
> +	if (mtk_dp->data->edp_ver && mtk_dp->phy_regs) {
> +		/* set swing and pre */
> +		switch (lane_num) {
> +		case 0:
> +		case 1:
> +		case 2:
> +		case 3:
> +			regmap_update_bits(mtk_dp->phy_regs,
> +					   PHYD_DIG_DRV_FORCE_LANE(lane_num),
> +					   EDP_TX_LN_VOLT_SWING_VAL_FLDMASK |
> +					   EDP_TX_LN_PRE_EMPH_VAL_FLDMASK,
> +					   swing_val << 1 |
> +					   preemphasis << 3);

In struct phy_ops {}, it has configure member, and you could pass lanes and pre in that interface.
I'm not sure swing_val could be passed by that interface or not.
If not, maybe add new parameter for swing_val.

> +			break;
> +		default:
> +			break;
> +		}
> +		if (preemphasis != 0)
> +			mtk_dp_update_bits(mtk_dp, RG_DSI_DEM_EN,
> +					   DSI_DE_EMPHASIS_ENABLE,
> +					   DSI_DE_EMPHASIS_ENABLE);
> +	}
>  }
>  
>  static void mtk_dp_reset_swing_pre_emphasis(struct mtk_dp *mtk_dp)
> @@ -1039,6 +1117,44 @@ static void mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
>  
>  static void mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
>  {
> +	if (mtk_dp->data->edp_ver) {

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		mtk_dp_update_bits(mtk_dp, REG_3F04_DP_ENC_P0_3, 0,
> +				   FRAME_START_MARKER_0_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F08_DP_ENC_P0_3,
> +				   FRAME_START_MARKER_1_DP_ENC_P0_3,
> +				   FRAME_START_MARKER_1_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F0C_DP_ENC_P0_3,
> +				   FRAME_END_MARKER_0_DP_ENC_P0_3,
> +				   FRAME_END_MARKER_0_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F10_DP_ENC_P0_3,
> +				   FRAME_END_MARKER_1_DP_ENC_P0_3,
> +				   FRAME_END_MARKER_1_DP_ENC_P0_3_MASK);
> +
> +		mtk_dp_update_bits(mtk_dp, REG_33C0_DP_ENCODER1_P0, 0,
> +				   SDP_TESTBUS_SEL_DP_ENC_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_33C0_DP_ENCODER1_P0,
> +				   SDP_TESTBUS_SEL_BIT4_DP_ENC,
> +				   SDP_TESTBUS_SEL_BIT4_DP_ENC_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_33C4_DP_ENCODER1_P0,
> +				   DP_TX_ENCODER_TESTBUS_SEL_DP_ENC,
> +				   DP_TX_ENCODER_TESTBUS_SEL_DP_ENC_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F28_DP_ENC_P0_3,
> +				   DP_TX_SDP_PSR_AS_TESTBUS,
> +				   DP_TX_SDP_PSR_AS_TESTBUS_MASK);
> +		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
> +				   RG_SW_RST,
> +				   RG_SW_RST_MASK);
> +		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
> +				   RG_PROBE_LOW_SEL,
> +				   RG_PROBE_LOW_SEL_MASK);
> +		mtk_dp_update_bits(mtk_dp, DP_TX_TOP_RESET_AND_PROBE,
> +				   RG_PROBE_LOW_HIGH_SWAP,
> +				   RG_PROBE_LOW_HIGH_SWAP_MASK);
> +
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK,
> +				   ENCODER_IRQ_MSK | TRANS_IRQ_MSK,
> +				   ENCODER_IRQ_MSK | TRANS_IRQ_MSK);
> +	}
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
>  			   XTAL_FREQ_DP_TRANS_P0_DEFAULT,
>  			   XTAL_FREQ_DP_TRANS_P0_MASK);
> @@ -1057,27 +1173,34 @@ static void mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
>  static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp *mtk_dp)
>  {
>  	u32 val;
> -	/* Debounce threshold */
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> -			   8, HPD_DEB_THD_DP_TRANS_P0_MASK);
>  
> -	val = (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
> -	       HPD_INT_THD_DP_TRANS_P0_UPPER_1100US) << 4;
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> -			   val, HPD_INT_THD_DP_TRANS_P0_MASK);
> +	if (mtk_dp->data->edp_ver) {

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		mtk_dp_update_bits(mtk_dp, REG_364C_AUX_TX_P0,
> +				   HPD_INT_THD_FLDMASK_VAL << 4,
> +				   HPD_INT_THD_FLDMASK);
> +	} else {
> +		/* Debounce threshold */
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +				   8, HPD_DEB_THD_DP_TRANS_P0_MASK);
>  
> -	/*
> -	 * Connect threshold 1.5ms + 5 x 0.1ms = 2ms
> -	 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms
> -	 */
> -	val = (5 << 8) | (5 << 12);
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> -			   val,
> -			   HPD_DISC_THD_DP_TRANS_P0_MASK |
> -			   HPD_CONN_THD_DP_TRANS_P0_MASK);
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
> -			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
> -			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
> +		val = (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
> +		       HPD_INT_THD_DP_TRANS_P0_UPPER_1100US) << 4;
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +				   val, HPD_INT_THD_DP_TRANS_P0_MASK);
> +
> +		/*
> +		 * Connect threshold 1.5ms + 5 x 0.1ms = 2ms
> +		 * Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms
> +		 */
> +		val = (5 << 8) | (5 << 12);
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +				   val,
> +				   HPD_DISC_THD_DP_TRANS_P0_MASK |
> +				   HPD_CONN_THD_DP_TRANS_P0_MASK);
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
> +				   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
> +				   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
> +	}
>  }
>  
>  static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
> @@ -1088,6 +1211,10 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
>  			   AUX_TIMEOUT_THR_AUX_TX_P0_MASK);
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3658,
>  			   0, AUX_TX_OV_EN_AUX_TX_P0_MASK);
> +	if (mtk_dp->data->edp_ver)

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		mtk_dp_update_bits(mtk_dp, REG_36A0_AUX_TX_P0,
> +				   DP_TX_INIT_MASK_15_TO_2,
> +				   DP_TX_INIT_MASK_15_TO_2_MASK);
>  	/* 25 for 26M */
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3634,
>  			   AUX_TX_OVER_SAMPLE_RATE_FOR_26M << 8,
> @@ -1104,6 +1231,46 @@ static void mtk_dp_initialize_aux_settings(struct mtk_dp *mtk_dp)
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
>  			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0,
>  			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0);
> +
> +	if (mtk_dp->data->edp_ver) {

Ditto.

> +		/*Con Thd = 1.5ms+Vx0.1ms*/
> +		mtk_dp_update_bits(mtk_dp, REG_367C_AUX_TX_P0,
> +				   HPD_CONN_THD_AUX_TX_P0_FLDMASK_POS << 6,
> +				   HPD_CONN_THD_AUX_TX_P0_FLDMASK);
> +		/*DisCon Thd = 1.5ms+Vx0.1ms*/
> +		mtk_dp_update_bits(mtk_dp, REG_37A0_AUX_TX_P0,
> +				   HPD_DISC_THD_AUX_TX_P0_FLDMASK_POS << 4,
> +				   HPD_DISC_THD_AUX_TX_P0_FLDMASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
> +				   XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_VALUE << 9,
> +				   XTAL_FREQ_FOR_PSR_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_366C_AUX_TX_P0,
> +				   XTAL_FREQ_DP_TX_AUX_366C_VALUE << 8,
> +				   XTAL_FREQ_DP_TX_AUX_366C_MASK);
> +	}
> +}
> +
> +static void mtk_edp_phyd_wait_aux_ldo_ready(struct mtk_dp *mtk_dp,
> +					    unsigned long wait_us)
> +{
> +	int ret = 0;
> +	u32 val = 0x0;
> +	u32 mask = RGS_BG_CORE_EN_READY | RGS_AUX_LDO_EN_READY;
> +
> +	if (mtk_dp->phy_regs) {
> +		ret = regmap_read_poll_timeout(mtk_dp->phy_regs,
> +					       DP_PHY_DIG_GLB_STATUS_0,
> +					       val, !!(val & mask),
> +					       wait_us / 100, wait_us);

Could this waiting be placed in phy driver?
In phy_init() or phy_configure()?

> +	} else {
> +		ret = regmap_read_poll_timeout(mtk_dp->regs,
> +					       DP_PHY_DIG_GLB_STATUS_0,
> +					       val, !!(val & mask),
> +					       wait_us / 100, wait_us);
> +	}
> +
> +	if (ret)
> +		dev_err(mtk_dp->dev, "%s AUX not ready\n", __func__);
>  }
>  
>  static void mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
> @@ -1115,15 +1282,63 @@ static void mtk_dp_initialize_digital_settings(struct mtk_dp *mtk_dp)
>  			   BS2BS_MODE_DP_ENC1_P0_VAL << 12,
>  			   BS2BS_MODE_DP_ENC1_P0_MASK);
>  
> +	if (mtk_dp->data->edp_ver) {

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		/* dp I-mode enable */
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
> +				   DP_I_MODE_ENABLE, DP_I_MODE_ENABLE);
> +		/*symbol_cnt_reset */
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
> +				   REG_BS_SYMBOL_CNT_RESET,
> +				   REG_BS_SYMBOL_CNT_RESET);
> +		mtk_dp_update_bits(mtk_dp, REG_3368_DP_ENCODER1_P0,
> +				   VIDEO_SRAM_FIFO_CNT_RESET_SEL_VALUE,
> +				   VIDEO_SRAM_FIFO_CNT_RESET_SEL_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3368_DP_ENCODER1_P0,
> +				   BS_FOLLOW_SEL_DP_ENC0_P0,
> +				   BS_FOLLOW_SEL_DP_ENC0_P0);
> +		/*[5:0]video sram start address*/
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
> +				   SRAM_START_READ_THRD_DP_ENC0_P0_VALUE,
> +				   SRAM_START_READ_THRD_DP_ENC0_P0_MASK);
> +		/* reg_psr_patgen_avt_en disable psr pattern */
> +		mtk_dp_update_bits(mtk_dp, REG_3F80_DP_ENC_P0_3,
> +				   0, PSR_PATGEN_AVT_EN_FLDMASK);
> +		/* phy D enable */
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   ALL_POWER_ON,
> +				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
> +		mtk_edp_phyd_wait_aux_ldo_ready(mtk_dp, 100000);
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +
> +		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
> +				   PHY_STATE_W_1_DP_ENC_P0_3,
> +				   PHY_STATE_W_1_DP_ENC_P0_3_MASK);
> +		/* reg_dvo_on_ow_en */
> +		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
> +				   DVO_ON_W_1_FLDMASK,
> +				   DVO_ON_W_1_FLDMASK);
> +	}
>  	/* dp tx encoder reset all sw */
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
>  			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0,
>  			   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
> +	if (mtk_dp->data->edp_ver) {

Ditto.

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
> +				   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
> +		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
> +				   PHY_STATE_RESET_ALL_VALUE,
> +				   PHY_STATE_RESET_ALL_MASK);
> +	}
>  
>  	/* Wait for sw reset to complete */
>  	usleep_range(1000, 5000);
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004,
> -			   0, DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
> +	if (!mtk_dp->data->edp_ver)

Ditto.

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3004, 0,
> +				   DP_TX_ENCODER_4P_RESET_SW_DP_ENC0_P0);
>  }
>  
>  static void mtk_dp_digital_sw_reset(struct mtk_dp *mtk_dp)
> @@ -1152,6 +1367,19 @@ static void mtk_dp_sdp_path_reset(struct mtk_dp *mtk_dp)
>  
>  static void mtk_dp_set_lanes(struct mtk_dp *mtk_dp, int lanes)
>  {
> +	if (mtk_dp->data->edp_ver) {

Ditto.

> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   BIAS_POWER_ON,
> +				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
> +
> +		mtk_edp_phyd_wait_aux_ldo_ready(mtk_dp, 100000);
> +
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +	}
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35F0,
>  			   lanes == 0 ? 0 : DP_TRANS_DUMMY_RW_0,
>  			   DP_TRANS_DUMMY_RW_0_MASK);
> @@ -1266,15 +1494,20 @@ static int mtk_dp_phy_configure(struct mtk_dp *mtk_dp,
>  			.ssc = mtk_dp->train_info.sink_ssc,
>  		}
>  	};
> -
> -	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE, DP_PWR_STATE_BANDGAP,
> -			   DP_PWR_STATE_MASK);
> +	if (!mtk_dp->data->edp_ver)

Ditto.

> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
> +				   DP_PWR_STATE_BANDGAP, DP_PWR_STATE_MASK);
>  
>  	ret = phy_configure(mtk_dp->phy, &phy_opts);
>  	if (ret)
>  		return ret;
>  
>  	mtk_dp_set_calibration_data(mtk_dp);
> +	/* Turn on phy power after phy configure */
> +	if (mtk_dp->data->edp_ver)

Ditto.

> +		mtk_dp_update_bits(mtk_dp, REG_3FF8_DP_ENC_P0_3,
> +				   PHY_STATE_W_1_DP_ENC_P0_3,
> +				   PHY_STATE_W_1_DP_ENC_P0_3_MASK);
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_PWR_STATE,
>  			   DP_PWR_STATE_BANDGAP_TPLL_LANE, DP_PWR_STATE_MASK);
>  
> @@ -1326,16 +1559,20 @@ static void mtk_dp_video_mute(struct mtk_dp *mtk_dp, bool enable)
>  	struct arm_smccc_res res;
>  	u32 val = VIDEO_MUTE_SEL_DP_ENC0_P0 |
>  		  (enable ? VIDEO_MUTE_SW_DP_ENC0_P0 : 0);
> +	u32 smmc_para;
>  
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3000,
>  			   val,
>  			   VIDEO_MUTE_SEL_DP_ENC0_P0 |
>  			   VIDEO_MUTE_SW_DP_ENC0_P0);
> -
> -	arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32,
> -		      mtk_dp->data->smc_cmd, enable,
> -		      0, 0, 0, 0, 0, &res);
> -
> +	if (mtk_dp->data->edp_ver) {

Ditto.

> +		smmc_para = (EDP_VIDEO_UNMUTE << 16) | enable;
> +		arm_smccc_smc(MTK_SIP_DP_CONTROL, EDP_VIDEO_UNMUTE, enable,
> +			      smmc_para, EDP_VIDEO_UNMUTE_VAL, 0, 0, 0, &res);
> +	} else {
> +		arm_smccc_smc(MTK_DP_SIP_CONTROL_AARCH32,
> +			      mtk_dp->data->smc_cmd, enable, 0, 0, 0, 0, 0, &res);
> +	}
>  	dev_dbg(mtk_dp->dev, "smc cmd: 0x%x, p1: %s, ret: 0x%lx-0x%lx\n",
>  		mtk_dp->data->smc_cmd, enable ? "enable" : "disable", res.a0, res.a1);
>  }
> @@ -1410,6 +1647,16 @@ static void mtk_dp_power_enable(struct mtk_dp *mtk_dp)
>  static void mtk_dp_power_disable(struct mtk_dp *mtk_dp)
>  {
>  	mtk_dp_write(mtk_dp, MTK_DP_TOP_PWR_STATE, 0);
> +	if (mtk_dp->data->edp_ver) {

Ditto.

> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3,
> +				   PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   ALL_POWER_OFF,
> +				   PHY_PWR_STATE_OW_VALUE_DP_ENC_P0_3_MASK);
> +		mtk_dp_update_bits(mtk_dp, REG_3F44_DP_ENC_P0_3,
> +				   0, PHY_PWR_STATE_OW_EN_DP_ENC_P0_3_MASK);
> +	}
>  
>  	mtk_dp_update_bits(mtk_dp, MTK_DP_0034,
>  			   DA_CKM_CKTX0_EN_FORCE_EN, DA_CKM_CKTX0_EN_FORCE_EN);
> @@ -1424,9 +1671,13 @@ static void mtk_dp_initialize_priv_data(struct mtk_dp *mtk_dp)
>  {
>  	bool plugged_in = (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP);
>  
> -	mtk_dp->train_info.link_rate = DP_LINK_BW_5_4;
> +	if (mtk_dp->data->edp_ver)

Ditto.

> +		mtk_dp->train_info.link_rate = DP_LINK_BW_8_1;
> +	else
> +		mtk_dp->train_info.link_rate = DP_LINK_BW_5_4;
>  	mtk_dp->train_info.lane_count = mtk_dp->max_lanes;
>  	mtk_dp->train_info.cable_plugged_in = plugged_in;
> +	mtk_dp->train_info.sink_ssc = false;
>  
>  	mtk_dp->info.format = DP_PIXELFORMAT_RGB;
>  	memset(&mtk_dp->info.vm, 0, sizeof(struct videomode));
> @@ -1545,11 +1796,15 @@ static void mtk_dp_train_update_swing_pre(struct mtk_dp *mtk_dp, int lanes,
>  		int index = lane / 2;
>  		int shift = lane % 2 ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : 0;
>  
> -		swing = (dpcd_adjust_req[index] >> shift) &
> -			DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
> +		if (mtk_dp->swing_value != 0) {
> +			swing = mtk_dp->swing_value;
> +		} else {
> +			swing = (dpcd_adjust_req[index] >> shift) &
> +				DP_ADJUST_VOLTAGE_SWING_LANE0_MASK;
> +		}
>  		preemphasis = ((dpcd_adjust_req[index] >> shift) &
> -			       DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
> -			      DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;
> +				DP_ADJUST_PRE_EMPHASIS_LANE0_MASK) >>
> +				DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT;

It seems this just modify indent.
Separate this to an refinement patch.

>  		val = swing << DP_TRAIN_VOLTAGE_SWING_SHIFT |
>  		      preemphasis << DP_TRAIN_PRE_EMPHASIS_SHIFT;
>  
> @@ -1969,6 +2224,11 @@ static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
>  	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
>  
>  	mtk_dp_digital_sw_reset(mtk_dp);
> +
> +	if (mtk_dp->data->edp_ver)

I would like a name about what it does rather than a version number.
Give it a meaningful name.

> +		mtk_dp_update_bits(mtk_dp, EDP_TX_TOP_CLKGEN_0,
> +				   EDP_TX_TOP_CLKGEN_REST_VALUE,
> +				   EDP_TX_TOP_CLKGEN_REST_MASK);
>  }
>  
>  static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> @@ -2047,9 +2307,15 @@ static int mtk_dp_wait_hpd_asserted(struct drm_dp_aux *mtk_aux, unsigned long wa
>  	u32 val;
>  	int ret;
>  
> -	ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414,
> -				       val, !!(val & HPD_DB_DP_TRANS_P0_MASK),
> -				       wait_us / 100, wait_us);
> +	if (mtk_dp->data->edp_ver)

Ditto.

> +		ret = regmap_read_poll_timeout(mtk_dp->regs, REG_364C_AUX_TX_P0,
> +					       val, !!(val & HPD_STATUS_DP_AUX_TX_P0_MASK),
> +					       wait_us / 100, wait_us);
> +	else
> +		ret = regmap_read_poll_timeout(mtk_dp->regs, MTK_DP_TRANS_P0_3414,
> +					       val, !!(val & HPD_DB_DP_TRANS_P0_MASK),
> +					       wait_us / 100, wait_us);
> +
>  	if (ret) {
>  		mtk_dp->train_info.cable_plugged_in = false;
>  		return ret;
> @@ -2072,7 +2338,10 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
>  	struct device_node *endpoint;
>  	struct device *dev = &pdev->dev;
>  	int ret;
> +	int level;
> +	struct resource *regs;
>  	void __iomem *base;
> +	void __iomem *phy_base;
>  	u32 linkrate;
>  	int len;
>  
> @@ -2084,6 +2353,22 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
>  	if (IS_ERR(mtk_dp->regs))
>  		return PTR_ERR(mtk_dp->regs);
>  
> +	phy_base = devm_platform_ioremap_resource(pdev, 1);
> +	if (!IS_ERR_OR_NULL(phy_base)) {
> +		mtk_dp->phy_regs = devm_regmap_init_mmio(dev, phy_base,
> +					&mtk_edp_phy_regmap_config);
> +		if (IS_ERR(mtk_dp->phy_regs))
> +			mtk_dp->phy_regs = NULL;
> +	}
> +
> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 2);

You does not define this in binding document.
You should define it in binding document first then you could use it.

> +	if (!IS_ERR_OR_NULL(regs)) {
> +		mtk_dp->pwr_regs = devm_ioremap(&pdev->dev, regs->start, 0x4);
> +		if (IS_ERR(mtk_dp->pwr_regs))
> +			dev_err(dev, "Failed to get pwr_regs: %ld\n",
> +				PTR_ERR(mtk_dp->pwr_regs));
> +	}
> +
>  	endpoint = of_graph_get_endpoint_by_regs(pdev->dev.of_node, 1, -1);
>  	len = of_property_count_elems_of_size(endpoint,
>  					      "data-lanes", sizeof(u32));
> @@ -2102,6 +2387,11 @@ static int mtk_dp_dt_parse(struct mtk_dp *mtk_dp,
>  
>  	mtk_dp->max_linkrate = drm_dp_link_rate_to_bw_code(linkrate * 100);
>  
> +	if (of_get_property(dev->of_node, "swing-level", &level)) {

You does not define this property in binding document, so drop this.
If you want to use this, define it in binding document first.

> +		of_property_read_u32(dev->of_node,
> +				     "swing-level", &mtk_dp->swing_value);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -2672,17 +2962,28 @@ static int mtk_dp_register_phy(struct mtk_dp *mtk_dp)
>  {
>  	struct device *dev = mtk_dp->dev;
>  
> -	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-dp-phy",
> -							PLATFORM_DEVID_AUTO,
> -							&mtk_dp->regs,
> -							sizeof(struct regmap *));
> +	if (mtk_dp->phy_regs)
> +		mtk_dp->phy_dev = platform_device_register_data(dev,
> +					"mediatek-edp-phy",
> +					PLATFORM_DEVID_AUTO,
> +					&mtk_dp->phy_regs,
> +					sizeof(struct regmap *));
> +	else
> +		mtk_dp->phy_dev = platform_device_register_data(dev,
> +					"mediatek-dp-phy",
> +					PLATFORM_DEVID_AUTO,
> +					&mtk_dp->regs,
> +					sizeof(struct regmap *));
>  	if (IS_ERR(mtk_dp->phy_dev))
>  		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy_dev),
>  				     "Failed to create device mediatek-dp-phy\n");
>  
>  	mtk_dp_get_calibration_data(mtk_dp);
>  
> -	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
> +	if (mtk_dp->data->edp_ver)
> +		mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "edp");
> +	else
> +		mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
>  	if (IS_ERR(mtk_dp->phy)) {
>  		platform_device_unregister(mtk_dp->phy_dev);
>  		return dev_err_probe(dev, PTR_ERR(mtk_dp->phy), "Failed to get phy\n");
> @@ -2770,6 +3071,20 @@ static int mtk_dp_probe(struct platform_device *pdev)
>  	mtk_dp->aux.wait_hpd_asserted = mtk_dp_wait_hpd_asserted;
>  	drm_dp_aux_init(&mtk_dp->aux);
>  
> +	mtk_dp->power_clk = devm_clk_get_optional(dev, NULL);

In binding document, it does not define clk, so drop this.
If you want to use it, define it in binding document first.

Regards,
CK

> +	if (IS_ERR(mtk_dp->power_clk)) {
> +		dev_info(dev, "Failed to get optional clock power_clk\n");
> +		mtk_dp->power_clk = NULL;
> +	}
> +
> +	if (mtk_dp->power_clk)
> +		clk_prepare_enable(mtk_dp->power_clk);
> +
> +	pm_runtime_enable(dev);
> +	pm_runtime_get_sync(dev);
> +	if (mtk_dp->pwr_regs)
> +		mtk_edp_pm_ctl(mtk_dp, true);
> +
>  	platform_set_drvdata(pdev, mtk_dp);
>  
>  	if (mtk_dp->data->audio_supported) {
> @@ -2795,10 +3110,13 @@ static int mtk_dp_probe(struct platform_device *pdev)
>  		 * properly close the eDP port to avoid stalls and then
>  		 * reinitialize, reset and power on the AUX block.
>  		 */
> -		mtk_dp_set_idle_pattern(mtk_dp, true);
> -		mtk_dp_initialize_aux_settings(mtk_dp);
> -		mtk_dp_power_enable(mtk_dp);
> -
> +		if (mtk_dp->data->edp_ver) {
> +			mtk_dp_poweron(mtk_dp);
> +		} else {
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			mtk_dp_initialize_aux_settings(mtk_dp);
> +			mtk_dp_power_enable(mtk_dp);
> +		}
>  		/* Disable HW interrupts: we don't need any for eDP */
>  		mtk_dp_hwirq_enable(mtk_dp, false);
>  
> @@ -2835,8 +3153,8 @@ static int mtk_dp_probe(struct platform_device *pdev)
>  			return dev_err_probe(dev, ret, "Failed to add bridge\n");
>  	}
>  
> -	pm_runtime_enable(dev);
> -	pm_runtime_get_sync(dev);
> +	dev_dbg(dev, "%s power.usage_count %d\n",
> +		__func__, atomic_read(&dev->power.usage_count));
>  
>  	return 0;
>  }
> 


[-- Attachment #2: Type: text/html, Size: 46108 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] drm/mediatek: Add eDP phy driver for mt8196
  2025-04-18  6:52 ` [PATCH 5/5] drm/mediatek: Add eDP phy " Bincai Liu
  2025-04-18 11:30   ` Vinod Koul
@ 2025-05-28  1:52   ` CK Hu (胡俊光)
  1 sibling, 0 replies; 14+ messages in thread
From: CK Hu (胡俊光) @ 2025-05-28  1:52 UTC (permalink / raw)
  To: robh@kernel.org, Chunfeng Yun (云春峰),
	kishon@kernel.org, tzimmermann@suse.de, simona@ffwll.ch,
	mripard@kernel.org, AngeloGioacchino Del Regno,
	Bincai Liu (刘彬才),
	Jitao Shi (石记涛),
	maarten.lankhorst@linux.intel.com, conor+dt@kernel.org,
	chunkuang.hu@kernel.org, vkoul@kernel.org, krzk+dt@kernel.org,
	p.zabel@pengutronix.de, airlied@gmail.com, matthias.bgg@gmail.com
  Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org

[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]

On Fri, 2025-04-18 at 14:52 +0800, Bincai Liu wrote:
> Add code to support eDP phy for mt8196.
> 
> Signed-off-by: Bincai Liu <bincai.liu@mediatek.com>
> ---
>  drivers/phy/mediatek/Makefile      |   1 +
>  drivers/phy/mediatek/phy-mtk-edp.c | 262 +++++++++++++++++++++++++++++
>  2 files changed, 263 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-edp.c
> 
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index 1b8088df71e8..49d9ea42497a 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -4,6 +4,7 @@
>  #
>  
>  obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-dp.o
> +obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-edp.o

phy-mtk-dp.c support mt8188 edp phy and mt8195 edp phy function.
phy-mtk-edp.c support mt8196 edp phy function.
So I would like to rename file as:

phy-mtk-dp-mt8188.c (support mt8188/mt8195 dp/edp phy function, use "mediatek-dp-phy-mt8188" as driver name)
phy-mtk-dp-mt8196.c (support mt8196 edp phy function, use "mediatek-dp-phy-mt8196" as driver name)

When dp driver register phy driver, use the according sub driver name.

Regards,
CK

>  obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
> 


[-- Attachment #2: Type: text/html, Size: 2924 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-05-28  1:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-18  6:52 [PATCH 0/5] eDP driver for mt8196 Bincai Liu
2025-04-18  6:52 ` [PATCH 1/5] dt-bindings: eDP: mediatek: add eDP yaml " Bincai Liu
2025-04-21  5:09   ` CK Hu (胡俊光)
2025-04-18  6:52 ` [PATCH 2/5] dt-bindings: dvo: mediatek: add dvo " Bincai Liu
2025-04-21  5:07   ` CK Hu (胡俊光)
2025-04-18  6:52 ` [PATCH 3/5] drm/mediatek: Add dvo driver " Bincai Liu
2025-04-19  7:19   ` kernel test robot
2025-04-19  8:01   ` kernel test robot
2025-05-27  6:24   ` CK Hu (胡俊光)
2025-04-18  6:52 ` [PATCH 4/5] drm/mediatek: Add eDP " Bincai Liu
2025-05-27 10:24   ` CK Hu (胡俊光)
2025-04-18  6:52 ` [PATCH 5/5] drm/mediatek: Add eDP phy " Bincai Liu
2025-04-18 11:30   ` Vinod Koul
2025-05-28  1:52   ` CK Hu (胡俊光)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).