i.MX8X MIPI DSI-Display hsync-active, front and back porch issue

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

i.MX8X MIPI DSI-Display hsync-active, front and back porch issue

773 次查看
stefan_eichenberger
Contributor I

Hello,

We have an issue with the MIPI DSI display interface in combination with our DSI to HDMI bridge. It seems we are affected by the exact same issue described in this commit message:
https://github.com/nxp-imx/linux-imx/commit/b3255e50de75062b50385a432e86742948117716

The patch does not work 1:1 therefore we slightly modified it so that it looks like this:

 

From 38497481dad86797720d7a0fd329f4b8f3ceabbc Mon Sep 17 00:00:00 2001
From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Date: Mon, 9 Oct 2023 09:22:52 +0200
Subject: [PATCH] drm/bridge: nwl-dsi: Add a workaround for the Lontium
 LT8912B

Setting the porch values for the Lontium LT8912B does not work properly.
So we need a similar workaround as for the RM68200 and HX8394F until NXP
fixes it by using some magic formula, see commit a8ac1d81bbed ("LF-4250
drm/bridge: nwl-dsi: Workaround RM68200 panel display shift issue")
Unfortunately, the exact same workaround does not work. The applied
workaround was found by trial and error. The only known non-working
resolution is 640x480.

Upstream-Status: Inappropriate [other]

This fix only applies to downstream kernel. The upstream kernel does not
support the NXP i.MX8X MIPI DSI interface yet.

Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/gpu/drm/bridge/nwl-dsi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index b19cf038025d5..4094aebe25d39 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -434,6 +434,19 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 		hbp = bytes * hback_porch - 10;
 		hsa = bytes * hsync_len - 10;
 		hsa = roundup(hsa, 2);
+	} else if (of_device_is_compatible(dsi->panel_bridge->of_node,
+				           "lontium,lt8912b")) {
+		int bytes = mipi_dsi_pixel_format_to_bpp(dsi->format) >> 3;
+
+		/*
+		 * Most likely we have the same issue with the LT8912B as
+		 * described above. However, magic timings are a bit different
+		 * compared to the displays.
+		 */
+		hfp = hfront_porch;
+		hbp = bytes * hback_porch;
+		hsa = bytes * hsync_len;
+		hsa = roundup(hsa, 2);
 	} else {
 		hfp = hfront_porch;
 		hbp = hback_porch;
-- 
2.39.2

 

However, this is not a proper solution. Are there any plans by NXP to implement the correct formula as described in this commit message?
https://github.com/nxp-imx/linux-imx/commit/b3255e50de75062b50385a432e86742948117716

Best regards,
Stefan 

0 项奖励
回复
2 回复数

730 次查看
qiang_li-mpu_se
NXP Employee
NXP Employee

Some MIPI DSI bridge chips required no LP mode on data line for each video line, then you can try the followed setting:

In nwl-dsi.c, function nwl_dsi_config_dpi():

nwl_dsi_write(dsi, NWL_DSI_HFP, hfront_porch * 3 - 10);
nwl_dsi_write(dsi, NWL_DSI_HBP, hback_porch * 3 - 10);
nwl_dsi_write(dsi, NWL_DSI_HSA, hsync_len * 3 - 12);
 
nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x0);
nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
 
nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay);
nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);

 

Note: for "- 10, - 10, -12", When converting from RGB display signals to MIPI DSI signals, there will be added MIPI short packages, header and CRC for long packages(video and blank), total 32 bytes for each line: HSS(4 bytes shor package), HSA(4 bytes header + 2 bytes CRC), HSE(4 bytes short package), HBP(4 bytes header + 2 bytes CRC), Video (4 bytes header + 2 bytes CRC) and HFP(4 bytes header + 2 bytes CRC).

And if the 24bpp display has total 600 lines (includes blank lines), then for each frame, it totally added 32 bytes * 600 / (24bpp / = 6400 pixel clocks to transfer a frame. Then in DPU driver, you can reduce the DPU pixel clock as followed to get the finally correct MIPI clock (file dpu-framegen.c, function framegen_cfg_videomode()):

disp_clock_rate = m->crtc_clock * 1000;
+ disp_clock_rate -= 6400;
 
if (encoder_type == DRM_MODE_ENCODER_TMDS) {

 

  

With the above changes, it can remove the LP state on data line during video transfer, this can meet the requirement for MIPI bridge chips.

0 项奖励
回复

699 次查看
stefan_eichenberger
Contributor I

Hi @qiang_li-mpu_se 

Unfortunately, these settings don't work for us. I'm also not sure if I understood everything. If I look at this code:

	if (of_device_is_compatible(dsi->panel_bridge->of_node,
				    "raydium,rm68200") ||
	    of_device_is_compatible(dsi->panel_bridge->of_node,
				    "rocktech,hx8394f")) {
		int bytes = mipi_dsi_pixel_format_to_bpp(dsi->format) >> 3;

		/*
		 * FIXME: This is a workaround for display shift
		 * of the RM68200 and HX8394F panels. It is based
		 * on previous knowledge got from support task for
		 * external DSI bridges by turning the hfp/hbp/hsa
		 * to be in bytes and substracting certain magic values.
		 * Furthermore, rounding hsa up to 2 is needed.
		 * This can be fixed as soon as formulas to
		 * determine the settings are available.
		 */
		hfp = bytes * hfront_porch - 12;
		hbp = bytes * hback_porch - 10;
		hsa = bytes * hsync_len - 10;
		hsa = roundup(hsa, 2);

It looks like hfp is -12 but in your example, it is hsa which subtracts 12 is there a reason for this difference? Also, could it be that the values are somehow related to the amount of lanes?

I tried the following patch which should correspond to what you describe but did not work:

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index b19cf038025d5..6e5f0d44741b7 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -434,6 +434,18 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 		hbp = bytes * hback_porch - 10;
 		hsa = bytes * hsync_len - 10;
 		hsa = roundup(hsa, 2);
+	} else if (of_device_is_compatible(dsi->panel_bridge->of_node,
+					   "lontium,lt8912b")) {
+		int bytes = mipi_dsi_pixel_format_to_bpp(dsi->format) >> 3;
+
+		/*
+		 * Most likely we have the same issue with the LT8912B as
+		 * described above. However, magic timings are a bit different
+		 * compared to the displays.
+		 */
+		hfp = bytes * hfront_porch - 10;
+		hbp = bytes * hback_porch - 10;
+		hsa = bytes * hsync_len - 12;
 	} else {
 		hfp = hfront_porch;
 		hbp = hback_porch;
@@ -445,12 +457,12 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 	nwl_dsi_write(dsi, NWL_DSI_HSA, hsa);
 
 	nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
-	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
+	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x0);
 	nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
 	nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
 
 	nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
-	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay - 1);
+	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay);
 	nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
 	nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);
 
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
index 50d7d50e1ff87..7cd443f546e0f 100644
--- a/drivers/gpu/imx/dpu/dpu-framegen.c
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -248,6 +248,7 @@ void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
 	dpu_fg_write(fg, FGCCR, 0);
 
 	disp_clock_rate = m->crtc_clock * 1000;
+	disp_clock_rate -= 32 * hact / 3;
 
 	if (encoder_type == DRM_MODE_ENCODER_TMDS) {
 		clk_set_parent(fg->clk_disp, fg->clk_bypass);

By trial and error I found out that I think I should not subtract anything from hbp and hsa but I have to subtract at least 24 from hfp. If I change the settings to something like this it worked again:

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index b19cf038025d5..8a97bdc363571 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -434,6 +434,18 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 		hbp = bytes * hback_porch - 10;
 		hsa = bytes * hsync_len - 10;
 		hsa = roundup(hsa, 2);
+	} else if (of_device_is_compatible(dsi->panel_bridge->of_node,
+					   "lontium,lt8912b")) {
+		int bytes = mipi_dsi_pixel_format_to_bpp(dsi->format) >> 3;
+
+		/*
+		 * Most likely we have the same issue with the LT8912B as
+		 * described above. However, magic timings are a bit different
+		 * compared to the displays.
+		 */
+		hfp = bytes * hfront_porch - 24;
+		hbp = bytes * hback_porch;
+		hsa = bytes * hsync_len;
 	} else {
 		hfp = hfront_porch;
 		hbp = hback_porch;
@@ -445,12 +457,12 @@ static int nwl_dsi_config_dpi(struct nwl_dsi *dsi)
 	nwl_dsi_write(dsi, NWL_DSI_HSA, hsa);
 
 	nwl_dsi_write(dsi, NWL_DSI_ENABLE_MULT_PKTS, 0x0);
-	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x1);
+	nwl_dsi_write(dsi, NWL_DSI_BLLP_MODE, 0x0);
 	nwl_dsi_write(dsi, NWL_DSI_USE_NULL_PKT_BLLP, 0x0);
 	nwl_dsi_write(dsi, NWL_DSI_VC, 0x0);
 
 	nwl_dsi_write(dsi, NWL_DSI_PIXEL_PAYLOAD_SIZE, dsi->mode.hdisplay);
-	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay - 1);
+	nwl_dsi_write(dsi, NWL_DSI_VACTIVE, dsi->mode.vdisplay);
 	nwl_dsi_write(dsi, NWL_DSI_VBP, vback_porch);
 	nwl_dsi_write(dsi, NWL_DSI_VFP, vfront_porch);
 
diff --git a/drivers/gpu/imx/dpu/dpu-framegen.c b/drivers/gpu/imx/dpu/dpu-framegen.c
index 50d7d50e1ff87..7cd443f546e0f 100644
--- a/drivers/gpu/imx/dpu/dpu-framegen.c
+++ b/drivers/gpu/imx/dpu/dpu-framegen.c
@@ -248,6 +248,7 @@ void framegen_cfg_videomode(struct dpu_framegen *fg, struct drm_display_mode *m,
 	dpu_fg_write(fg, FGCCR, 0);
 
 	disp_clock_rate = m->crtc_clock * 1000;
+	disp_clock_rate -= 32 * hact / 3;
 
 	if (encoder_type == DRM_MODE_ENCODER_TMDS) {
 		clk_set_parent(fg->clk_disp, fg->clk_bypass);

Do you have an idea why the correct formula does not work? 

Regards,
Stefan

0 项奖励
回复