Hi,
I'm debugging our LCD panel based Ilitek ILI9881C on our new i.MX93 board with BSP version LF-6.1.22-2.0.0, it works fine on our some other boards based on i.MX8MN, i.MX8MM, i.MX8MQ, i.MX8ULP.
Below is our DTS configuration for MIPI LCD panel:
&dphy {
status = "okay";
};
&lcdif {
status = "okay";
assigned-clock-rates = <282404000>, <70601000>, <400000000>, <133333333>;
};
&dsi{
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
compatible = "avnet,ph720128t003", "ilitek,ili9881c";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio_backlight>;
pwn-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
dsi-lanes = <2>;
backlight = <&backlight>;
port {
panel_in: endpoint {
remote-endpoint = <&mipi_dsi_out>;
};
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
mipi_dsi_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
};
And this our LCD driver configuration, it works fine on all other i.MX8 serial boards.
static const struct drm_display_mode ph720128t003_default_mode = {
.clock = 70601, /* htotal*vtotal*fps = 900x1307x60.02= 70,601,526 */
.hdisplay = 720,
.hsync_start= 720 + 120,
.hsync_end = 720 + 120 + 40,
.htotal = 720 + 120 + 40 + 20,
.vdisplay = 1280,
.vsync_start= 1280 + 10,
.vsync_end = 1280 + 10 + 2,
.vtotal = 1280 + 10 + 2 + 15,
.width_mm = 153,
.height_mm = 90,
};
But it can not work on I.MX93 board.
I try to modify the assigned-clock-rates value in &lcdif in the DTS file, but there is no effect whatsoever. Then I try to change pix clock in the LCD panel driver, and found it can work on 72.6MHz (Not 70.601MHz) with some bugs.
static const struct drm_display_mode ph720128t003_default_mode = {
.clock = 72600, /* htotal*vtotal*fps = 900x1307x60.02= 70,601,526 */
.hdisplay = 720,
.hsync_start= 720 + 120,
.hsync_end = 720 + 120 + 40,
.htotal = 720 + 120 + 40 + 20,
.vdisplay = 1280,
.vsync_start= 1280 + 10,
.vsync_end = 1280 + 10 + 2,
.vtotal = 1280 + 10 + 2 + 15,
.width_mm = 153,
.height_mm = 90,
};
Below is the LCD display result when I execute "modetest -M imx-drm -D 1 -a -s 35@33:720x1280 -P 31@33:720x1280" for some times.
Now the problem is:
1, The RGB color will change when I execute command "modetest -M imx-drm -D 1 -a -s 35@33:720x1280 -P 31@33:720x1280" every time;
2, Some pixels will overflow from bottom/right to top/left, and can not be fixed by change the value of HSPW/HFP/HBP/VSPW/VFP/VBP;
So my question is how to configure the MIPI-DSI clock for our custom panel, and can anyone give me some guide to fix this bug? Thanks in advanced!
Hi, I'm Wenxue_Guo's colleague.
We have determined the LCD parameters through the original factory. Now it has been set, and the clock has been set according to the method provided above, but it is still not correct. The following is some information I modified and the picture is attached. Now there may be some problems, how should we check? Please take a look, Thanks a lot!
The following is the lcd parameters we want to find the manufacturer:
Here are my code changes:
Gets the clock after recompiling:
Using fb-test to test the screen, the screen does not display properly:
Hi @leevi_li
I have another idea, please keep timing as before and dump MIPI DSI and DPHY registers.
Hi, @Zhiming_Liu
I have dumped the MIPI DSI and DPHY registers, and restore the previous lcd configuration parameters. Here are my changes and the results:
I added a function to the dw_mipi_dsi_host_transfer function that prints the register as follows:
Added dump_MIPI_DSI_and_DPHY_registers() functions:
520 static void dump_MIPI_DSI_and_DPHY_registers(struct dw_mipi_dsi *dsi)
521 {
522 u32 address = 0;
523 u32 val = 0;
524
525 printk("[%s.%d],\n\n", __FUNCTION__,__LINE__);
526
527 address = DSI_VERSION;
528 val = dsi_read(dsi, address);
529 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
530
531 address = DSI_PWR_UP;
532 val = dsi_read(dsi, address);
533 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
534
535 address = DSI_CLKMGR_CFG;
536 val = dsi_read(dsi, address);
537 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
538
539 address = DSI_DPI_VCID;
540 val = dsi_read(dsi, address);
541 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
542
543 address = DSI_DPI_COLOR_CODING;
544 val = dsi_read(dsi, address);
545 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
546
547 address = DSI_DPI_CFG_POL;
548 val = dsi_read(dsi, address);
549 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
550
551 address = DSI_DPI_LP_CMD_TIM;
552 val = dsi_read(dsi, address);
553 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
554
555 address = DSI_DBI_VCID;
556 val = dsi_read(dsi, address);
557 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
558
559 address = DSI_DBI_CFG;
560 val = dsi_read(dsi, address);
561 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
562
563 address = DSI_DBI_PARTITIONING_EN;
564 val = dsi_read(dsi, address);
565 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
566
567 address = DSI_DBI_CMDSIZE;
568 val = dsi_read(dsi, address);
569 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
570
571 address = DSI_PCKHDL_CFG;
572 val = dsi_read(dsi, address);
573 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
574
575 address = DSI_GEN_VCID;
576 val = dsi_read(dsi, address);
577 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
578
579 address = DSI_MODE_CFG;
580 val = dsi_read(dsi, address);
581 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
582
583 address = DSI_VID_MODE_CFG;
584 val = dsi_read(dsi, address);
585 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
586
587 address = DSI_VID_PKT_SIZE;
588 val = dsi_read(dsi, address);
589 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
590
591 address = DSI_VID_NUM_CHUNKS;
592 val = dsi_read(dsi, address);
593 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
594
595 address = DSI_VID_NULL_SIZE;
596 val = dsi_read(dsi, address);
597 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
598
599 address = DSI_VID_HSA_TIME;
600 val = dsi_read(dsi, address);
601 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
602
603 address = DSI_VID_HBP_TIME;
604 val = dsi_read(dsi, address);
605 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
606
607 address = DSI_VID_HLINE_TIME;
608 val = dsi_read(dsi, address);
609 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
610
611 address = DSI_VID_VSA_LINES;
612 val = dsi_read(dsi, address);
613 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
614
615 address = DSI_VID_VBP_LINES;
616 val = dsi_read(dsi, address);
617 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
618
619 address = DSI_VID_VFP_LINES;
620 val = dsi_read(dsi, address);
621 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
622
623 address = DSI_VID_VACTIVE_LINES;
624 val = dsi_read(dsi, address);
625 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
626
627 address = DSI_EDPI_CMD_SIZE;
628 val = dsi_read(dsi, address);
629 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
630
631 address = DSI_CMD_MODE_CFG;
632 val = dsi_read(dsi, address);
633 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
634
635 address = DSI_GEN_HDR;
636 val = dsi_read(dsi, address);
637 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
638
639 address = DSI_GEN_PLD_DATA;
640 val = dsi_read(dsi, address);
641 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
642
643 address = DSI_CMD_PKT_STATUS;
644 val = dsi_read(dsi, address);
645 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
646
647 address = DSI_TO_CNT_CFG;
648 val = dsi_read(dsi, address);
649 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
650
651 address = DSI_HS_RD_TO_CNT;
652 val = dsi_read(dsi, address);
653 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
654
655 address = DSI_LP_RD_TO_CNT;
656 val = dsi_read(dsi, address);
657 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
658
659 address = DSI_HS_WR_TO_CNT;
660 val = dsi_read(dsi, address);
661 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
662
663 address = DSI_LP_WR_TO_CNT;
664 val = dsi_read(dsi, address);
665 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
666
667 address = DSI_BTA_TO_CNT;
668 val = dsi_read(dsi, address);
669 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
670
671 address = DSI_LPCLK_CTRL;
672 val = dsi_read(dsi, address);
673 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
674
675 address = DSI_PHY_TMR_LPCLK_CFG;
676 val = dsi_read(dsi, address);
677 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
678
679 address = DSI_PHY_TMR_CFG;
680 val = dsi_read(dsi, address);
681 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
682
683 address = DSI_PHY_RSTZ;
684 val = dsi_read(dsi, address);
685 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
686
687 address = DSI_PHY_IF_CFG;
688 val = dsi_read(dsi, address);
689 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
690
691 address = DSI_PHY_ULPS_CTRL;
692 val = dsi_read(dsi, address);
693 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
694
695 address = DSI_PHY_TX_TRIGGERS;
696 val = dsi_read(dsi, address);
697 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
698
699 address = DSI_PHY_STATUS;
700 val = dsi_read(dsi, address);
701 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
702
703 address = DSI_PHY_TST_CTRL0;
704 val = dsi_read(dsi, address);
705 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
706
707 address = DSI_PHY_TST_CTRL1;
708 val = dsi_read(dsi, address);
709 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
710
711 address = DSI_INT_ST0;
712 val = dsi_read(dsi, address);
713 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
714
715 address = DSI_INT_ST1;
716 val = dsi_read(dsi, address);
717 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
718
719 address = DSI_INT_MSK0;
720 val = dsi_read(dsi, address);
721 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
722
723 address = DSI_INT_MSK1;
724 val = dsi_read(dsi, address);
725 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
726
727 address = DSI_PHY_TMR_RD_CFG;
728 val = dsi_read(dsi, address);
729 printk("[%s.%d], address=0x%x, val=0x%x\n", __FUNCTION__,__LINE__, address, val);
730
731 }
The final printed result is as follows:
[ 1723.823656] [dw_mipi_dsi_host_transfer.742],
[ 1723.823656]
[ 1723.831052] [dump_MIPI_DSI_and_DPHY_registers.525],
[ 1723.831052]
[ 1723.839049] [dump_MIPI_DSI_and_DPHY_registers.529], address=0x0, val=0x3134312a
[ 1723.847252] [dump_MIPI_DSI_and_DPHY_registers.533], address=0x4, val=0x1
[ 1723.854839] [dump_MIPI_DSI_and_DPHY_registers.537], address=0x8, val=0x6
[ 1723.862551] [dump_MIPI_DSI_and_DPHY_registers.541], address=0xc, val=0x0
[ 1723.870157] [dump_MIPI_DSI_and_DPHY_registers.545], address=0x10, val=0x5
[ 1723.877835] [dump_MIPI_DSI_and_DPHY_registers.549], address=0x14, val=0x0
[ 1723.885515] [dump_MIPI_DSI_and_DPHY_registers.553], address=0x18, val=0x100004
[ 1723.893612] [dump_MIPI_DSI_and_DPHY_registers.557], address=0x1c, val=0x0
[ 1723.901279] [dump_MIPI_DSI_and_DPHY_registers.561], address=0x20, val=0x0
[ 1723.908989] [dump_MIPI_DSI_and_DPHY_registers.565], address=0x24, val=0x0
[ 1723.916678] [dump_MIPI_DSI_and_DPHY_registers.569], address=0x28, val=0x0
[ 1723.924370] [dump_MIPI_DSI_and_DPHY_registers.573], address=0x2c, val=0x1c
[ 1723.932137] [dump_MIPI_DSI_and_DPHY_registers.577], address=0x30, val=0x0
[ 1723.939916] [dump_MIPI_DSI_and_DPHY_registers.581], address=0x34, val=0x0
[ 1723.947605] [dump_MIPI_DSI_and_DPHY_registers.585], address=0x38, val=0xbf00
[ 1723.955530] [dump_MIPI_DSI_and_DPHY_registers.589], address=0x3c, val=0x2d0
[ 1723.963365] [dump_MIPI_DSI_and_DPHY_registers.593], address=0x40, val=0x0
[ 1723.971024] [dump_MIPI_DSI_and_DPHY_registers.597], address=0x44, val=0x0
[ 1723.978688] [dump_MIPI_DSI_and_DPHY_registers.601], address=0x48, val=0x3c
[ 1723.986443] [dump_MIPI_DSI_and_DPHY_registers.605], address=0x4c, val=0x1e
[ 1723.994200] [dump_MIPI_DSI_and_DPHY_registers.609], address=0x50, val=0x546
[ 1724.002005] [dump_MIPI_DSI_and_DPHY_registers.613], address=0x54, val=0x2
[ 1724.009646] [dump_MIPI_DSI_and_DPHY_registers.617], address=0x58, val=0xf
[ 1724.017251] [dump_MIPI_DSI_and_DPHY_registers.621], address=0x5c, val=0xa
[ 1724.024846] [dump_MIPI_DSI_and_DPHY_registers.625], address=0x60, val=0x500
[ 1724.032584] [dump_MIPI_DSI_and_DPHY_registers.629], address=0x64, val=0x0
[ 1724.040152] [dump_MIPI_DSI_and_DPHY_registers.633], address=0x68, val=0x10f7f00
[ 1724.048247] [dump_MIPI_DSI_and_DPHY_registers.637], address=0x6c, val=0x2905
[ 1724.056082] [dump_MIPI_DSI_and_DPHY_registers.641], address=0x70, val=0x0
[ 1724.063645] [dump_MIPI_DSI_and_DPHY_registers.645], address=0x74, val=0x50015
[ 1724.071586] [dump_MIPI_DSI_and_DPHY_registers.649], address=0x78, val=0x3e803e8
[ 1724.079679] [dump_MIPI_DSI_and_DPHY_registers.653], address=0x7c, val=0x0
[ 1724.087260] [dump_MIPI_DSI_and_DPHY_registers.657], address=0x80, val=0x0
[ 1724.094955] [dump_MIPI_DSI_and_DPHY_registers.661], address=0x84, val=0x0
[ 1724.102567] [dump_MIPI_DSI_and_DPHY_registers.665], address=0x88, val=0x0
[ 1724.110277] [dump_MIPI_DSI_and_DPHY_registers.669], address=0x8c, val=0xd00
[ 1724.118049] [dump_MIPI_DSI_and_DPHY_registers.673], address=0x94, val=0x1
[ 1724.125635] [dump_MIPI_DSI_and_DPHY_registers.677], address=0x98, val=0x3a0073
[ 1724.133657] [dump_MIPI_DSI_and_DPHY_registers.681], address=0x9c, val=0x230058
[ 1724.141676] [dump_MIPI_DSI_and_DPHY_registers.685], address=0xa0, val=0xf
[ 1724.149329] [dump_MIPI_DSI_and_DPHY_registers.689], address=0xa4, val=0x2001
[ 1724.157188] [dump_MIPI_DSI_and_DPHY_registers.693], address=0xa8, val=0x0
[ 1724.164766] [dump_MIPI_DSI_and_DPHY_registers.697], address=0xac, val=0x0
[ 1724.172346] [dump_MIPI_DSI_and_DPHY_registers.701], address=0xb0, val=0x1529
[ 1724.180323] [dump_MIPI_DSI_and_DPHY_registers.705], address=0xb4, val=0x0
[ 1724.187939] [dump_MIPI_DSI_and_DPHY_registers.709], address=0xb8, val=0x0
[ 1724.195545] [dump_MIPI_DSI_and_DPHY_registers.713], address=0xbc, val=0x0
[ 1724.203132] [dump_MIPI_DSI_and_DPHY_registers.717], address=0xc0, val=0x800
[ 1724.210893] [dump_MIPI_DSI_and_DPHY_registers.721], address=0xc4, val=0x0
[ 1724.218477] [dump_MIPI_DSI_and_DPHY_registers.725], address=0xc8, val=0x0
[ 1724.226060] [dump_MIPI_DSI_and_DPHY_registers.729], address=0xf4, val=0x2710
My lcd parameters remain the same as before, but the clock has been fixed:
static const struct drm_display_mode ph720128t005_default_mode = {
.clock = 70500, // clock = 900 * 1307 * 60.02fps = 70601526
.hdisplay = 720,
.hsync_start= 720 + 120,
.hsync_end = 720 + 120 + 40,
.htotal = 720 + 120 + 40 + 20,
.vdisplay = 1280,
.vsync_start= 1280 + 10,
.vsync_end = 1280 + 10 + 2,
.vtotal = 1280 + 10 + 2 + 15,
.width_mm = 155,
.height_mm = 87,
};
Gets the clock after recompiling:
After this modification, I was surprised to find that the screen seemed to display normally,
Below is the display of fb-test and the startup screen:
As for the modification, I checked it and finally found that it was affected by the added printing. I removed the printing in the dw_mipi_dsi_host_transfer function, and the test result returned to the previous state, as shown in the figure below,:
Now the question is, why is printing added to the dw_mipi_dsi_host_transfer function, so there are different results, please help analyze it, Thanks a lot.
Hi @leevi_li
The data sync may have issue for the dsi default setting, you can refer below photo, the current frame exists previous frame. This is root cause. As @guowen_xue said, this panel works on i.MX8 series, and i.MX93 is using DWC DSI IP, so the default DSI setting except timing may be different. You added the log print causes the transfer delay and then this delay fixup the sync issue.
Here is sync settings in DSI driver
static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
{
u32 val;
/*
* TODO dw drv improvements
* enabling low power is panel-dependent, we should use the
* panel configuration here...
*/
val = ENABLE_LOW_POWER;
if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
val |= VID_MODE_TYPE_BURST;
else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
val |= VID_MODE_TYPE_NON_BURST_SYNC_PULSES;
else
val |= VID_MODE_TYPE_NON_BURST_SYNC_EVENTS;
#ifdef CONFIG_DEBUG_FS
if (dsi->vpg_defs.vpg) {
val |= VID_MODE_VPG_ENABLE;
val |= dsi->vpg_defs.vpg_horizontal ?
VID_MODE_VPG_HORIZONTAL : 0;
val |= dsi->vpg_defs.vpg_ber_pattern ? VID_MODE_VPG_MODE : 0;
}
#endif /* CONFIG_DEBUG_FS */
dsi_write(dsi, DSI_VID_MODE_CFG, val);
}
static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
unsigned long mode_flags)
{
u32 val;
dsi_write(dsi, DSI_PWR_UP, RESET);
if (mode_flags & MIPI_DSI_MODE_VIDEO) {
dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
dw_mipi_dsi_video_mode_config(dsi);
} else {
dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
}
val = PHY_TXREQUESTCLKHS;
if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
val |= AUTO_CLKLANE_CTRL;
dsi_write(dsi, DSI_LPCLK_CTRL, val);
dsi_write(dsi, DSI_PWR_UP, POWERUP);
}
static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
const struct drm_display_mode *mode)
{
u32 val = 0, color = 0;
switch (dsi->format) {
case MIPI_DSI_FMT_RGB888:
color = DPI_COLOR_CODING_24BIT;
break;
case MIPI_DSI_FMT_RGB666:
color = DPI_COLOR_CODING_18BIT_2 | LOOSELY18_EN;
break;
case MIPI_DSI_FMT_RGB666_PACKED:
color = DPI_COLOR_CODING_18BIT_1;
break;
case MIPI_DSI_FMT_RGB565:
color = DPI_COLOR_CODING_16BIT_1;
break;
}
if (mode->flags & DRM_MODE_FLAG_NVSYNC)
val |= VSYNC_ACTIVE_LOW;
if (mode->flags & DRM_MODE_FLAG_NHSYNC)
val |= HSYNC_ACTIVE_LOW;
dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel));
dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
dsi_write(dsi, DSI_DPI_CFG_POL, val);
}
You need confirm what's type of sync about your panel and add these sync flags into the panel-simple.c
Usable flags:
static const struct drm_display_mode boe_tv080wum_nl0_mode = {
.clock = 160000,
.hdisplay = 1200,
.hsync_start = 1200 + 120,
.hsync_end = 1200 + 120 + 20,
.htotal = 1200 + 120 + 20 + 21,
.vdisplay = 1920,
.vsync_start = 1920 + 21,
.vsync_end = 1920 + 21 + 3,
.vtotal = 1920 + 21 + 3 + 18,
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct panel_desc_dsi boe_tv080wum_nl0 = {
.desc = {
.modes = &boe_tv080wum_nl0_mode,
.num_modes = 1,
.size = {
.width = 107,
.height = 172,
},
.connector_type = DRM_MODE_CONNECTOR_DSI,
},
.flags = MIPI_DSI_MODE_VIDEO |
MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
.format = MIPI_DSI_FMT_RGB888,
.lanes = 4,
};
Hi, @Zhiming_Liu
You mean, there's still something wrong with the sync signal. We still have to fix the sync signal error?
At present, I first handled this problem according to the delay, and replaced the previous printing with a delay. Currently, both screens in the test are normal. After I added the delay, all the changes are as follows:
Now, I follow the changes you provided, but there are compilation problems. Below are my modifications, and the compilation error messages printed
At the same time, I have a question, this added struct, how does it get called?
Attached is the complete file panel-ilitek-ili9881c.c
Thanks a lot!
You need modify drivers/clk/imx/clk-fracn-gppll.c to support new pixel clock
Please refer 74.2.3 Clock configuration in RM.
If we add a frequency of 537.6MHz(Pixel clock *4), then MFI=112, MFN=0, MFD=1, rdiv=0, odiv=5
The root source of VIDEO_PLL is Fref = 24M, then Fvco = Fref * (MFI + MFN / MFD)=2688
Then Fout = Fvco / (rdiv * odiv)= 537.6
Configure new pixel clock 134.4MHz and VIDEO_PLL to LCDIF in dts:
You can try below value:
mfi: 141
mfn: 1
mfd: 5
rdiv: 1
odiv: 12
Hi @Zhiming_Liu ,
Thanks for your reply! After do the modify as your guide, the LCD panel still get same bugs.
The clock seems changed.
root@maaxboardosm93:~# cat /sys/kernel/debug/clk/media_disp_pix_root/clk_rate
70600000
But the RGB color still changes when execute modetest command, and the first pixel coordinates is wrong now.
Can you give me some other clue?
By the way, My Reference Manual is Rev. 1, 10/2022, there is no 74.2.3 Clock configuration in this document. I'm a bit confused about this formula:
Fvco = Fref * (MFI + MFN / MFD)
Fout = Fvco / (rdiv * odiv)
Take these configuration in the source code as example:
PLL_FRACN_GP(1700000000U, 141, 0, 0, 1, 2),
Fvco = Fref * (MFI + MFN / MFD)=24*(141+0/0) ?
PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12)
Fvco = Fref * (MFI + MFN / MFD)=24*(150+0/1) = 3600
Fout = Fvco / (rdiv * odiv)= 3600 / ( 0*12 ) ??
Thanks a lot!
For the issue in photo , you need set output section in /etc/xdg/weston/weston.ini.
Add your panel information and rotate. Can you confirm that your timing is correct?
For mfd, rdiv and odiv, if they are zero, the hardware will treat them as 1.
Hi @Zhiming_Liu ,
1, It's not for the weston configuration, because the linux penguin logo Tux display on the wrong position too when kernel boot up, and libdrm test command modetest get the same result.
2, This LCD panel timing can work fine on our i.MX8MN, i.MX8MM, i.MX8MQ, i.MX8ULP boards, and I'll confirm with our LCD panel provider.
3, Yep, the div bit set be 0 always treat them as 1(Fout=Fin/(div+1)). Then how does set it be 1 for mfd, rdiv and odiv? Does the hardware treat them as 1 or 2, and the value in formula should be 1 or 2?
Thanks a lot!
If mfd, rdiv, odiv equals 1, they are still 1. The zero is special case.