diff mbox series

[v4,8/8] drm/mediatek: dpi: Add mt8195 hdmi to DPI driver

Message ID 20220919-v4-8-687f09a06dd9@baylibre.com (mailing list archive)
State New, archived
Headers show
Series Add MT8195 HDMI support | expand

Commit Message

Guillaume Ranquet May 29, 2023, 2:31 p.m. UTC
Add the DPI1 hdmi path support in mtk dpi driver

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dpi.c      | 121 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/mediatek/mtk_dpi_regs.h |   5 ++
 2 files changed, 119 insertions(+), 7 deletions(-)

Comments

CK Hu (胡俊光) June 14, 2023, 6:14 a.m. UTC | #1
Hi, Guillaume:

On Mon, 2023-05-29 at 16:31 +0200, Guillaume Ranquet wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Add the DPI1 hdmi path support in mtk dpi driver
> 
> Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c      | 121
> ++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h |   5 ++
>  2 files changed, 119 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 948a53f1f4b3..b83a38e8bd60 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -9,12 +9,15 @@
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
>  #include <linux/media-bus-format.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/of_graph.h>
>  #include <linux/pinctrl/consumer.h>
>  #include <linux/platform_device.h>
>  #include <linux/soc/mediatek/mtk-mmsys.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
>  #include <linux/types.h>
>  
>  #include <video/videomode.h>
> @@ -67,11 +70,14 @@ struct mtk_dpi {
>  struct drm_bridge *next_bridge;
>  struct drm_connector *connector;
>  void __iomem *regs;
> +struct reset_control *reset_ctl;
>  struct device *dev;
>  struct device *mmsys_dev;
>  struct clk *engine_clk;
> +struct clk *dpi_ck_cg;
>  struct clk *pixel_clk;
>  struct clk *tvd_clk;
> +struct clk *hdmi_cg;
>  int irq;
>  struct drm_display_mode mode;
>  const struct mtk_dpi_conf *conf;
> @@ -138,6 +144,7 @@ struct mtk_dpi_yc_limit {
>   * @csc_enable_bit: Enable bit of CSC.
>   * @pixels_per_iter: Quantity of transferred pixels per iteration.
>   * @edge_cfg_in_mmsys: If the edge configuration for DPI's output
> needs to be set in MMSYS.
> + * @is_internal_hdmi: True if this DPI block is directly connected
> to SoC internal HDMI block.
>   */
>  struct mtk_dpi_conf {
>  unsigned int (*cal_factor)(int clock);
> @@ -157,6 +164,7 @@ struct mtk_dpi_conf {
>  u32 csc_enable_bit;
>  u32 pixels_per_iter;
>  bool edge_cfg_in_mmsys;
> +bool is_internal_hdmi;
>  };
>  
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val,
> u32 mask)
> @@ -471,8 +479,14 @@ static void mtk_dpi_power_off(struct mtk_dpi
> *dpi)
>  return;
>  
>  mtk_dpi_disable(dpi);
> +
> +reset_control_rearm(dpi->reset_ctl);
> +
>  clk_disable_unprepare(dpi->pixel_clk);
>  clk_disable_unprepare(dpi->engine_clk);
> +clk_disable_unprepare(dpi->dpi_ck_cg);
> +clk_disable_unprepare(dpi->hdmi_cg);
> +clk_disable_unprepare(dpi->tvd_clk);
>  }
>  
>  static int mtk_dpi_power_on(struct mtk_dpi *dpi)
> @@ -488,15 +502,44 @@ static int mtk_dpi_power_on(struct mtk_dpi
> *dpi)
>  goto err_refcount;
>  }
>  
> +ret = clk_prepare_enable(dpi->tvd_clk);
> +if (ret) {
> +dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
> +goto err_engine;
> +}
> +
> +ret = clk_prepare_enable(dpi->hdmi_cg);
> +if (ret) {
> +dev_err(dpi->dev, "Failed to enable hdmi_cg clock: %d\n", ret);
> +goto err_tvd;
> +}
> +
> +ret = clk_prepare_enable(dpi->dpi_ck_cg);
> +if (ret) {
> +dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
> +goto err_hdmi_cg;
> +}
> +
>  ret = clk_prepare_enable(dpi->pixel_clk);
>  if (ret) {
>  dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
>  goto err_pixel;
>  }
>  
> +reset_control_reset(dpi->reset_ctl);
> +
> +if (dpi->pinctrl && dpi->pins_dpi)
> +pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
> +
>  return 0;
>  
>  err_pixel:
> +clk_disable_unprepare(dpi->dpi_ck_cg);
> +err_hdmi_cg:
> +clk_disable_unprepare(dpi->hdmi_cg);
> +err_tvd:
> +clk_disable_unprepare(dpi->tvd_clk);
> +err_engine:
>  clk_disable_unprepare(dpi->engine_clk);
>  err_refcount:
>  dpi->refcount--;
> @@ -541,7 +584,6 @@ static int mtk_dpi_set_display_mode(struct
> mtk_dpi *dpi,
>  else
>  clk_set_rate(dpi->pixel_clk, vm.pixelclock);
>  
> -
>  vm.pixelclock = clk_get_rate(dpi->pixel_clk);
>  
>  dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
> @@ -608,7 +650,16 @@ static int mtk_dpi_set_display_mode(struct
> mtk_dpi *dpi,
>  if (dpi->conf->support_direct_pin) {
>  mtk_dpi_config_yc_map(dpi, dpi->yc_map);
>  mtk_dpi_config_2n_h_fre(dpi);
> -mtk_dpi_dual_edge(dpi);
> +/* DPI could be connecting to external bridge
> + * or internal HDMI encoder. */
> +if (dpi->conf->is_internal_hdmi) {
> +mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN,
> +     DPI_OUTPUT_1T1P_EN);
> +mtk_dpi_mask(dpi, DPI_CON, DPI_INPUT_2P_EN,
> +     DPI_INPUT_2P_EN);
> +} else {
> +mtk_dpi_dual_edge(dpi);
> +}
>  mtk_dpi_config_disable_edge(dpi);
>  }
>  if (dpi->conf->input_2pixel) {
> @@ -723,7 +774,10 @@ static void mtk_dpi_bridge_disable(struct
> drm_bridge *bridge)
>  {
>  struct mtk_dpi *dpi = bridge_to_dpi(bridge);
>  
> -mtk_dpi_power_off(dpi);
> +if (dpi->conf->is_internal_hdmi)
> +mtk_dpi_power_off(dpi);
> +else
> +mtk_dpi_disable(dpi);
>  
>  if (dpi->pinctrl && dpi->pins_gpio)
>  pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
> @@ -772,14 +826,16 @@ void mtk_dpi_start(struct device *dev)
>  {
>  struct mtk_dpi *dpi = dev_get_drvdata(dev);
>  
> -mtk_dpi_power_on(dpi);
> +if (!dpi->conf->is_internal_hdmi)
> +mtk_dpi_power_on(dpi);
>  }
>  
>  void mtk_dpi_stop(struct device *dev)
>  {
>  struct mtk_dpi *dpi = dev_get_drvdata(dev);
>  
> -mtk_dpi_power_off(dpi);
> +if (!dpi->conf->is_internal_hdmi)
> +mtk_dpi_power_off(dpi);
>  }
>  
>  static int mtk_dpi_bind(struct device *dev, struct device *master,
> void *data)
> @@ -864,6 +920,11 @@ static unsigned int mt8183_calculate_factor(int
> clock)
>  return 2;
>  }
>  
> +static unsigned int mt8195_calculate_factor(int clock)
> +{
> +return 1;
> +}
> +
>  static unsigned int mt8195_dpintf_calculate_factor(int clock)
>  {
>  if (clock < 70000)
> @@ -989,6 +1050,24 @@ static const struct mtk_dpi_conf mt8192_conf =
> {
>  .csc_enable_bit = CSC_ENABLE,
>  };
>  
> +static const struct mtk_dpi_conf mt8195_conf = {
> +.cal_factor = mt8195_calculate_factor,
> +.max_clock_khz = 594000,
> +.reg_h_fre_con = 0xe0,
> +.output_fmts = mt8183_output_fmts,
> +.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
> +.pixels_per_iter = 1,
> +.is_ck_de_pol = true,
> +.swap_input_support = true,
> +.dimension_mask = HPW_MASK,
> +.hvsize_mask = HSIZE_MASK,
> +.channel_swap_shift = CH_SWAP,
> +.yuv422_en_bit = YUV422_EN,
> +.csc_enable_bit = CSC_ENABLE,
> +.is_internal_hdmi = true,

mt8173 dpi is also connect to internal mt8173 hdmi.

> +.support_direct_pin = true,
> +};
> +
>  static const struct mtk_dpi_conf mt8195_dpintf_conf = {
>  .cal_factor = mt8195_dpintf_calculate_factor,
>  .max_clock_khz = 600000,
> @@ -1046,6 +1125,12 @@ static int mtk_dpi_probe(struct
> platform_device *pdev)
>  return ret;
>  }
>  
> +dpi->reset_ctl = devm_reset_control_get_optional_exclusive(dev,
> "dpi_on");
> +if (IS_ERR(dpi->reset_ctl)) {
> +dev_err(dev, "Failed to get reset_ctl: %ld\n", PTR_ERR(dpi-
> >reset_ctl));
> +return PTR_ERR(dpi->reset_ctl);
> +}
> +
>  dpi->engine_clk = devm_clk_get(dev, "engine");
>  if (IS_ERR(dpi->engine_clk)) {
>  ret = PTR_ERR(dpi->engine_clk);
> @@ -1055,7 +1140,26 @@ static int mtk_dpi_probe(struct
> platform_device *pdev)
>  return ret;
>  }
>  
> -dpi->pixel_clk = devm_clk_get(dev, "pixel");
> +dpi->hdmi_cg = devm_clk_get_optional(dev, "hdmi_cg");

This clock is not defined in binding document.

> +if (IS_ERR(dpi->hdmi_cg)) {
> +ret = PTR_ERR(dpi->hdmi_cg);
> +if (ret != -EPROBE_DEFER)
> +dev_err(dev, "Failed to get hdmi_cg clock: %d\n", ret);
> +
> +return ret;
> +}
> +
> +dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");

This clock is not defined in binding document.

Regards,
CK

> +if (IS_ERR(dpi->dpi_ck_cg)) {
> +ret = PTR_ERR(dpi->dpi_ck_cg);
> +if (ret != -EPROBE_DEFER)
> +dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
> +ret);
> +
> +return ret;
> +}
> +
> +dpi->pixel_clk = devm_clk_get_optional(dev, "pixel");
>  if (IS_ERR(dpi->pixel_clk)) {
>  ret = PTR_ERR(dpi->pixel_clk);
>  if (ret != -EPROBE_DEFER)
> @@ -1064,7 +1168,7 @@ static int mtk_dpi_probe(struct platform_device
> *pdev)
>  return ret;
>  }
>  
> -dpi->tvd_clk = devm_clk_get(dev, "pll");
> +dpi->tvd_clk = devm_clk_get_optional(dev, "pll");
>  if (IS_ERR(dpi->tvd_clk)) {
>  ret = PTR_ERR(dpi->tvd_clk);
>  if (ret != -EPROBE_DEFER)
> @@ -1134,6 +1238,9 @@ static const struct of_device_id
> mtk_dpi_of_ids[] = {
>  { .compatible = "mediatek,mt8195-dp-intf",
>    .data = &mt8195_dpintf_conf,
>  },
> +{ .compatible = "mediatek,mt8195-dpi",
> +  .data = &mt8195_conf,
> +},
>  { },
>  };
>  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 62bd4931b344..653ef4b93a97 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
> @@ -43,6 +43,11 @@
>  #define DPINTF_YUV422_ENBIT(24)
>  #define DPINTF_CSC_ENABLEBIT(26)
>  #define DPINTF_INPUT_2P_ENBIT(29)
> +#define DPI_OUTPUT_1T1P_ENBIT(24)
> +#define DPI_INPUT_2P_ENBIT(25)
> +#define DPI_EXT_VSYNC_ENBIT(26)
> +#define DPI_RGB565_ENBIT(27)
> +#define DPI_RGB880_ENBIT(28)
>  
>  #define DPI_OUTPUT_SETTING0x14
>  #define CH_SWAP0
> 
> -- 
> 2.40.0
> 
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
index 948a53f1f4b3..b83a38e8bd60 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
@@ -9,12 +9,15 @@ 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/media-bus-format.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
 #include <linux/types.h>
 
 #include <video/videomode.h>
@@ -67,11 +70,14 @@  struct mtk_dpi {
 	struct drm_bridge *next_bridge;
 	struct drm_connector *connector;
 	void __iomem *regs;
+	struct reset_control *reset_ctl;
 	struct device *dev;
 	struct device *mmsys_dev;
 	struct clk *engine_clk;
+	struct clk *dpi_ck_cg;
 	struct clk *pixel_clk;
 	struct clk *tvd_clk;
+	struct clk *hdmi_cg;
 	int irq;
 	struct drm_display_mode mode;
 	const struct mtk_dpi_conf *conf;
@@ -138,6 +144,7 @@  struct mtk_dpi_yc_limit {
  * @csc_enable_bit: Enable bit of CSC.
  * @pixels_per_iter: Quantity of transferred pixels per iteration.
  * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
+ * @is_internal_hdmi: True if this DPI block is directly connected to SoC internal HDMI block.
  */
 struct mtk_dpi_conf {
 	unsigned int (*cal_factor)(int clock);
@@ -157,6 +164,7 @@  struct mtk_dpi_conf {
 	u32 csc_enable_bit;
 	u32 pixels_per_iter;
 	bool edge_cfg_in_mmsys;
+	bool is_internal_hdmi;
 };
 
 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
@@ -471,8 +479,14 @@  static void mtk_dpi_power_off(struct mtk_dpi *dpi)
 		return;
 
 	mtk_dpi_disable(dpi);
+
+	reset_control_rearm(dpi->reset_ctl);
+
 	clk_disable_unprepare(dpi->pixel_clk);
 	clk_disable_unprepare(dpi->engine_clk);
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+	clk_disable_unprepare(dpi->hdmi_cg);
+	clk_disable_unprepare(dpi->tvd_clk);
 }
 
 static int mtk_dpi_power_on(struct mtk_dpi *dpi)
@@ -488,15 +502,44 @@  static int mtk_dpi_power_on(struct mtk_dpi *dpi)
 		goto err_refcount;
 	}
 
+	ret = clk_prepare_enable(dpi->tvd_clk);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable tvd pll: %d\n", ret);
+		goto err_engine;
+	}
+
+	ret = clk_prepare_enable(dpi->hdmi_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable hdmi_cg clock: %d\n", ret);
+		goto err_tvd;
+	}
+
+	ret = clk_prepare_enable(dpi->dpi_ck_cg);
+	if (ret) {
+		dev_err(dpi->dev, "Failed to enable dpi_ck_cg clock: %d\n", ret);
+		goto err_hdmi_cg;
+	}
+
 	ret = clk_prepare_enable(dpi->pixel_clk);
 	if (ret) {
 		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
 		goto err_pixel;
 	}
 
+	reset_control_reset(dpi->reset_ctl);
+
+	if (dpi->pinctrl && dpi->pins_dpi)
+		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+
 	return 0;
 
 err_pixel:
+	clk_disable_unprepare(dpi->dpi_ck_cg);
+err_hdmi_cg:
+	clk_disable_unprepare(dpi->hdmi_cg);
+err_tvd:
+	clk_disable_unprepare(dpi->tvd_clk);
+err_engine:
 	clk_disable_unprepare(dpi->engine_clk);
 err_refcount:
 	dpi->refcount--;
@@ -541,7 +584,6 @@  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	else
 		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
 
-
 	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
 
 	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
@@ -608,7 +650,16 @@  static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
 	if (dpi->conf->support_direct_pin) {
 		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
 		mtk_dpi_config_2n_h_fre(dpi);
-		mtk_dpi_dual_edge(dpi);
+		/* DPI could be connecting to external bridge
+		 * or internal HDMI encoder. */
+		if (dpi->conf->is_internal_hdmi) {
+			mtk_dpi_mask(dpi, DPI_CON, DPI_OUTPUT_1T1P_EN,
+				     DPI_OUTPUT_1T1P_EN);
+			mtk_dpi_mask(dpi, DPI_CON, DPI_INPUT_2P_EN,
+				     DPI_INPUT_2P_EN);
+		} else {
+			mtk_dpi_dual_edge(dpi);
+		}
 		mtk_dpi_config_disable_edge(dpi);
 	}
 	if (dpi->conf->input_2pixel) {
@@ -723,7 +774,10 @@  static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
 {
 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
 
-	mtk_dpi_power_off(dpi);
+	if (dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_off(dpi);
+	else
+		mtk_dpi_disable(dpi);
 
 	if (dpi->pinctrl && dpi->pins_gpio)
 		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
@@ -772,14 +826,16 @@  void mtk_dpi_start(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_on(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_on(dpi);
 }
 
 void mtk_dpi_stop(struct device *dev)
 {
 	struct mtk_dpi *dpi = dev_get_drvdata(dev);
 
-	mtk_dpi_power_off(dpi);
+	if (!dpi->conf->is_internal_hdmi)
+		mtk_dpi_power_off(dpi);
 }
 
 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
@@ -864,6 +920,11 @@  static unsigned int mt8183_calculate_factor(int clock)
 		return 2;
 }
 
+static unsigned int mt8195_calculate_factor(int clock)
+{
+	return 1;
+}
+
 static unsigned int mt8195_dpintf_calculate_factor(int clock)
 {
 	if (clock < 70000)
@@ -989,6 +1050,24 @@  static const struct mtk_dpi_conf mt8192_conf = {
 	.csc_enable_bit = CSC_ENABLE,
 };
 
+static const struct mtk_dpi_conf mt8195_conf = {
+	.cal_factor = mt8195_calculate_factor,
+	.max_clock_khz = 594000,
+	.reg_h_fre_con = 0xe0,
+	.output_fmts = mt8183_output_fmts,
+	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
+	.pixels_per_iter = 1,
+	.is_ck_de_pol = true,
+	.swap_input_support = true,
+	.dimension_mask = HPW_MASK,
+	.hvsize_mask = HSIZE_MASK,
+	.channel_swap_shift = CH_SWAP,
+	.yuv422_en_bit = YUV422_EN,
+	.csc_enable_bit = CSC_ENABLE,
+	.is_internal_hdmi = true,
+	.support_direct_pin = true,
+};
+
 static const struct mtk_dpi_conf mt8195_dpintf_conf = {
 	.cal_factor = mt8195_dpintf_calculate_factor,
 	.max_clock_khz = 600000,
@@ -1046,6 +1125,12 @@  static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dpi->reset_ctl = devm_reset_control_get_optional_exclusive(dev, "dpi_on");
+	if (IS_ERR(dpi->reset_ctl)) {
+		dev_err(dev, "Failed to get reset_ctl: %ld\n", PTR_ERR(dpi->reset_ctl));
+		return PTR_ERR(dpi->reset_ctl);
+	}
+
 	dpi->engine_clk = devm_clk_get(dev, "engine");
 	if (IS_ERR(dpi->engine_clk)) {
 		ret = PTR_ERR(dpi->engine_clk);
@@ -1055,7 +1140,26 @@  static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dpi->pixel_clk = devm_clk_get(dev, "pixel");
+	dpi->hdmi_cg = devm_clk_get_optional(dev, "hdmi_cg");
+	if (IS_ERR(dpi->hdmi_cg)) {
+		ret = PTR_ERR(dpi->hdmi_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get hdmi_cg clock: %d\n", ret);
+
+		return ret;
+	}
+
+	dpi->dpi_ck_cg = devm_clk_get_optional(dev, "ck_cg");
+	if (IS_ERR(dpi->dpi_ck_cg)) {
+		ret = PTR_ERR(dpi->dpi_ck_cg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get dpi ck cg clock: %d\n",
+				ret);
+
+		return ret;
+	}
+
+	dpi->pixel_clk = devm_clk_get_optional(dev, "pixel");
 	if (IS_ERR(dpi->pixel_clk)) {
 		ret = PTR_ERR(dpi->pixel_clk);
 		if (ret != -EPROBE_DEFER)
@@ -1064,7 +1168,7 @@  static int mtk_dpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	dpi->tvd_clk = devm_clk_get(dev, "pll");
+	dpi->tvd_clk = devm_clk_get_optional(dev, "pll");
 	if (IS_ERR(dpi->tvd_clk)) {
 		ret = PTR_ERR(dpi->tvd_clk);
 		if (ret != -EPROBE_DEFER)
@@ -1134,6 +1238,9 @@  static const struct of_device_id mtk_dpi_of_ids[] = {
 	{ .compatible = "mediatek,mt8195-dp-intf",
 	  .data = &mt8195_dpintf_conf,
 	},
+	{ .compatible = "mediatek,mt8195-dpi",
+	  .data = &mt8195_conf,
+	},
 	{ },
 };
 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 62bd4931b344..653ef4b93a97 100644
--- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h
@@ -43,6 +43,11 @@ 
 #define DPINTF_YUV422_EN		BIT(24)
 #define DPINTF_CSC_ENABLE		BIT(26)
 #define DPINTF_INPUT_2P_EN		BIT(29)
+#define DPI_OUTPUT_1T1P_EN		BIT(24)
+#define DPI_INPUT_2P_EN			BIT(25)
+#define DPI_EXT_VSYNC_EN		BIT(26)
+#define DPI_RGB565_EN			BIT(27)
+#define DPI_RGB880_EN			BIT(28)
 
 #define DPI_OUTPUT_SETTING	0x14
 #define CH_SWAP				0