How to set custome LVDS clock

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

How to set custome LVDS clock

2,619 次查看
Jyo
Contributor III

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.

video_pll1_ref_sel 1 1 0 24000000 0 0 50000 Y deviceless no_connection_id
video_pll1 1 1 0 567000000 0 0 50000 Y deviceless no_connection_id
video_pll1_bypass 1 1 0 567000000 0 0 50000 Y deviceless no_connection_id
video_pll1_out 2 2 0 567000000 0 0 50000 Y deviceless no_connection_id
media_ldb 1 1 0 567000000 0 0 50000 Y deviceless no_connection_id
media_ldb_root_clk 1 1 0 567000000 0 0 50000 Y ldb-display-controller ldb
deviceless no_connection_id
media_disp1_pix 0 0 0 567000000 0 0 50000 N deviceless no_connection_id
media_disp1_pix_root_clk 0 0 0 567000000 0 0 50000 N 32e80000.lcd-controller pix

However, I am experiencing flickering in the image.

I have some doubt here , 

  1. Does NXP hardware support an 81 MHz frequency or not?
  2. What is the relationship between the following clocks?
    • IMX8MP_CLK_MEDIA_LDB
    • IMX8MP_CLK_MEDIA_LDB_ROOT
    • IMX8MP_VIDEO_PLL1_OUT
    • IMX8MP_CLK_MEDIA_DISP1_PIX
  3. I have set 567000000 (162000 × 3500). Is my calculation correct for 81 MHz in dual-channel mode?

Could you please clarify?

@imx8mp_developer

标记 (3)
0 项奖励
回复
10 回复数

2,559 次查看
Jyo
Contributor III

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 . 




0 项奖励
回复

2,558 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

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

0 项奖励
回复

2,542 次查看
Jyo
Contributor III

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.

.pixelclock = { 81000000, 81000000, 81000000 },



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?

0 项奖励
回复

2,534 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

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

0 项奖励
回复

2,509 次查看
Jyo
Contributor III

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

0 项奖励
回复

2,503 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

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 

imx_pll1443x_tbl.
 

+++ 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

0 项奖励
回复

2,501 次查看
Jyo
Contributor III

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 . 


0 项奖励
回复

2,496 次查看
Jyo
Contributor III

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.  


0 项奖励
回复

2,494 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

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

0 项奖励
回复

2,573 次查看
Zhiming_Liu
NXP TechSupport
NXP TechSupport

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

0 项奖励
回复