Hello Everyone ,
I have a custom panel with dual LVDS support (2 × 4 lanes) 1280 × 960 @ 60 Hz with an 81 MHz pixel clock, and I am using the i.MX 8M Plus Applications Processor.
Based on the calculations for 81 MHz in dual-channel mode, I have applied the below changes.
index 9335f1713ce6..528d460aa06f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -752,7 +752,7 @@ clk: clock-controller@30380000 {
<800000000>,
<393216000>,
<361267200>,
- <1039500000>;
+ <567000000>;
};
src: reset-controller@30390000 {
@@ -1505,7 +1505,7 @@ media_blk_ctrl: blk-ctrl@32ec0000 {
<&clk IMX8MP_VIDEO_PLL1_OUT>,
<&clk IMX8MP_VIDEO_PLL1_OUT>;
assigned-clock-rates = <500000000>, <200000000>,
- <0>, <0>, <1039500000>;
+ <0>, <0>, <567000000>;
#power-domain-cells = <1>;
};
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 6c17786ecb9f..a10d7b7b6532 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -75,6 +75,8 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c),
PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845),
PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07),
+ PLL_1443X_RATE(567000000U, 189, 2, 2, 0),
};
struct imx_pll14xx_clk imx_1443x_pll = {
diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c
index e3f5c5e6e842..c89ee510ec8f 100644
--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
+++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
@@ -190,10 +190,10 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode fixup here in case any mode is unsupported.
*/
- if (ldb->dual)
+ /*if (ldb->dual)
mode->clock = mode->clock > 100000 ? 148500 : 74250;
else
- mode->clock = 74250;
+ mode->clock = 74250;*/
return 0;
}
@@ -216,11 +216,11 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode valid check here.
*/
- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
+ /*if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
return MODE_NOCLOCK;
if (!ldb->dual && mode->clock != 74250)
- return MODE_NOCLOCK;
+ return MODE_NOCLOCK;*/
return MODE_OK;
}
Below is the clock output from my setup.
However, I am experiencing flickering in the image.
I have some doubt here ,
Could you please clarify?
Thanks for your response.
I believe we need to make this modification because I have configured the setup for dual-channel mode. Therefore, the clock should be set to 162 MHz (81 MHz × 2). Based on the existing code, it appears to be hardcoded to 148.5 MHz for dual-channel mode.
diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c
index e3f5c5e6e842..c89ee510ec8f 100644
--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
+++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
@@ -190,10 +190,10 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode fixup here in case any mode is unsupported.
*/
- if (ldb->dual)
+ /*if (ldb->dual)
mode->clock = mode->clock > 100000 ? 148500 : 74250;
else
- mode->clock = 74250;
+ mode->clock = 74250;*/
return 0;
}
@@ -216,11 +216,11 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode valid check here.
*/
- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
+ /*if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
return MODE_NOCLOCK;
if (!ldb->dual && mode->clock != 74250)
- return MODE_NOCLOCK;
+ return MODE_NOCLOCK;*/
return MODE_OK;
}
Current Timing Parameters:
static const struct display_timing testing_simple_timing = {
.pixelclock = { 162000000, 162000000, 162000000 }, // 81 MHz
.hactive = { 1280, 1280, 1280 }, // Horizontal active pixels
.vactive = { 960, 960, 960 }, // Vertical active pixels
.hfront_porch = { 38, 38, 38 }, // Horizontal front porch
.hback_porch = { 16, 16, 16 }, // Horizontal back porch
.hsync_len = { 16, 16, 16 }, // Horizontal sync length
.vsync_len = { 6, 6, 6 }, // Vertical sync length
.vfront_porch = { 14, 14, 14 }, // Vertical front porch
.vback_porch = { 20, 20, 20 }, // Vertical back porch
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
};
static const struct panel_desc test_simple_panel = {
.timings = &testing_simple_timing,
.num_timings = 1,
.bpc = 8, // Bits per channel (8 for RGB888)
.size = {
.width = 13, // Width in millimeters (physical)
.height = 9, // Height in millimeters (physical)
},
.delay = {
.prepare = 50, // Prepare delay in ms
.enable = 50, // Enable delay in ms
.unprepare = 50, // Unprepare delay in ms
.disable = 50, // Disable delay in ms
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, // Keep DE signal high
.connector_type = DRM_MODE_CONNECTOR_LVDS, // Use LVDS connector
};
However, I am still uncertain about the correct LVDS clock and pixel clock settings.
I have attached a document that contains the detailed LCD panel parameters we are using. Could you please review it and provide guidance on the appropriate settings .
Hello,
If you are using one panel with LVDS0 and LVDS1 interface. The correct pixel clock is .pixelclock = { 81000000, 81000000, 81000000 }, Please revert your changes in lvds driver.
The 162MHz pixel is for 1280 * (960*2)=1280x1920 resolution which is not supported by controller.
Dual asynchronous channels (8 data, 2 clocks). This is intended for a single panel
with two interfaces, transferring across two channels (even pixel/odd pixel). This is
supported at up to 160MHz pixel clock, which is up to 80MHz LVDS clock (due to 2
pixels per LVDS clock). This supports resolutions above 1366x768p60, up to
1080p60.
Best Regards,
Zhiming
Thanks for the clarification.
I am using a single panel with two interfaces with dual mode transferring data across two channels (even pixel/odd pixel).
Now, I have removed all other LDB driver changes and I am only passing the pixel clock as 81 MHz.
However, I am observing that the media_ldb clock is set to 259,875,000 Hz instead of the expected 283,500,000 Hz.
After further debugging, I found that in the function imx8mp_ldb_encoder_atomic_mode_set, the mode clock is being set to 74.25 MHz, resulting in:
74,250×3,500=259,875,000
But it should be:
81,000×3,500=283,500,000
Do I need to change any other structure parameters to support 283,500,000 Hz properly?
Hello,
For dual channel, did you add this property in dts? This flag will be read by driver and set the dual flag in driver. If the driver is still using 74.25 MHz , this means driver still work as single channel.
&ldb {
fsl,dual-channel;
};
Or can you attach your dts node about ldb and panel?
Best Regards,
Zhiming
Hi
--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
+++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
@@ -190,10 +190,10 @@ imx8mp_ldb_encoder_atomic_check(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode fixup here in case any mode is unsupported.
*/
- if (ldb->dual)
+ /*if (ldb->dual)
mode->clock = mode->clock > 100000 ? 148500 : 74250;
else
- mode->clock = 74250;
+ mode->clock = 74250;*/
return 0;
}
@@ -216,11 +216,11 @@ imx8mp_ldb_encoder_mode_valid(struct drm_encoder *encoder,
* Due to limited video PLL frequency points on i.MX8mp,
* we do mode valid check here.
*/
- if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
+ /*if (ldb->dual && mode->clock != 74250 && mode->clock != 148500)
return MODE_NOCLOCK;
if (!ldb->dual && mode->clock != 74250)
- return MODE_NOCLOCK;
+ return MODE_NOCLOCK;*/
return MODE_OK;
}
After adding above code , I am getting serial_clk as 283500000 hz in this function imx8mp_ldb_encoder_atomic_mode_set
Also ldb->dual showing as 1 , that means dual mode is set properly .
&ldb { fsl,dual-channel; };
Above code is also present in my device tree file .
Now the issue is somehow clk_set_rate is not setting the clock properly .
for verification I called clk_get_rate , with that its still returning 259,875,000 Hz only .
Below is the clock output
video_pll1_ref_sel 1 1 0 24000000 0 0 50000 Y deviceless no_connection_id
video_pll1 1 1 0 1039500000 0 0 50000 Y deviceless no_connection_id
video_pll1_bypass 1 1 0 1039500000 0 0 50000 Y deviceless no_connection_id
video_pll1_out 2 2 0 1039500000 0 0 50000 Y deviceless no_connection_id
media_ldb 1 1 0 259875000 0 0 50000 Y deviceless no_connection_id
media_ldb_root_clk 1 1 0 259875000 0 0 50000 Y ldb-display-controller ldb
deviceless no_connection_id
media_disp1_pix 0 0 0 1039500000 0 0 50000 N deviceless no_connection_id
media_disp1_pix_root_clk 0 0 0 1039500000 0 0 50000 N 32e80000.lcd-controller pix
Here as you mentioned it earlier , media_ldb_root_clk this is represent lvds clock
Do I need to set media_disp1_pix_root_clk also for pixel clock.
Is there any calculation in case of 81Mhz pixel clock ,
what will be clokc rate for video_pll1 , media_ldb_root_clk and media_disp1_pix_root_clk
Thanks
Jyo
Hello,
The clocks relationship is:
VIDEO_PLL/div--->DISP2_PIX/div--->LDB CLK
Did you add the new pll table in this case now? The 259875000 is divided from 519750000U in
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -75,6 +75,8 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c),
PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845),
PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07),
+ PLL_1443X_RATE(567000000U, 189, 2, 2, 0),
};
media_disp1_pix_root_clk is for mipi dsi, the LDB clock is from IMX8MP_CLK_MEDIA_DISP2_PIX
Best Regards,
Zhiming
HI
Yes , I have added below PLL entries
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -75,6 +75,9 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c),
PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845),
PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07),
+ PLL_1443X_RATE(283500000U,189,2,4,0),
Do I need to increase VIDEO_PLL also
because in default case of 259875000 media_ldb clock , video_pll1 and media_disp1_pix showing as 1039500000
So if I am using media_ldb clock as 283500000 , do I need to modify video_pll1 and media_disp1_pix to 1134000000 to make it as same divisor .
Hi Zhiming_Liu
I did below changes
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -752,7 +752,7 @@ clk: clock-controller@30380000 {
<800000000>,
<393216000>,
<361267200>,
- <1039500000>;
+ <1134000000>;
};
src: reset-controller@30390000 {
@@ -1505,7 +1505,7 @@ media_blk_ctrl: blk-ctrl@32ec0000 {
<&clk IMX8MP_VIDEO_PLL1_OUT>,
<&clk IMX8MP_VIDEO_PLL1_OUT>;
assigned-clock-rates = <500000000>, <200000000>,
- <0>, <0>, <1039500000>;
+ <0>, <0>, <1134000000>;
#power-domain-cells = <1>;
};
I have changed video Pll to 1134000000 = 283500000 * 7 *2
Added both the PLL entires (mdeia ldb and video_pll)
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -75,6 +75,9 @@ static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
PLL_1443X_RATE(49152000U, 393, 3, 6, 0x374c),
PLL_1443X_RATE(45158400U, 241, 2, 6, 0xd845),
PLL_1443X_RATE(40960000U, 109, 1, 6, 0x3a07),
+ PLL_1443X_RATE(283500000U,189,2,4,0),
+ PLL_1443X_RATE(1134000000U, 189, 2, 1, 0),
};
cat /sys/kernel/debug/clk/clk_summary
video_pll1_ref_sel 24000000
video_pll1 1134000000
video_pll1_bypass 1134000000
video_pll1_out 1134000000
media_ldb 283500000
media_ldb_root_clk 283500000
media_disp2_pix 81000000
media_disp2_pix_root_clk 81000000
I have checked the output clock , Both LOVDS0 and LVDS1 is showing 40.5 Mhz output clock .
Now the image is proper , image is not stretch .
But its flickering and colour is also not proper.
Could you please confirm if my clock configuration is proper or not.
Hello,
Please share the flickering photo, device tree configuration and your panel spec.
If you don't want to attach panel spec here, you can share it with private message.
Best Regards,
Zhiming
Hello,
1. Does NXP hardware support an 81 MHz frequency or not?
-->Support.
2.You don't have to modify the drivers/gpu/drm/imx/imx8mp-ldb.c driver, this driver have already supported dual channel mode.
3. The media_ldb_root_clk should be 81Mhz * 3.5. The driver get pixel clock and calculate it in driver. The imx8mp_ldb->clk_root is media_ldb_root_clk.
serial_clk = mode->clock * (ldb->dual ? 3500UL : 7000UL);
clk_set_rate(imx8mp_ldb->clk_root, serial_clk);
4. Please share your timing in spec and your timing setting in code.
Best Regards,
Zhiming