This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM623: LVDS panel configuration on 6.12 kernel

Part Number: AM623

Tool/software:

I'm trying to determine the correct device tree setup to use our LCD panel on the OLDI interface. Examples and reference materials seem to quite scarce, and seem to relate to instead using the VOUT interface, which is tied up on our board with other signals. 

The best reference I've found is this:

LVDS Panel Integration on AM62P

I'm looking at the various examples in the DTS (this is the 6.12 kernel) also and have cobbled together a DTS from all this which is clearly not 100% correct. There did seem to be some renaming from dss -> dss0 etc as well, but I'm not clear if this is processor-specific or something not updated in all the DTS. 

When I boot, I get:

[ 20.932104] platform 30200000.dss: deferred probe pending: tidss: no panel/bridge for OLDI0.

I'm not 100% sure what it's after - the driver code here is pretty terse. 


DTS pasted here. Forgive all the commented sections - as I said, it was assembled from various pieces (and cut and paste lost the indentation).  Let me know what other information I can provide. 

/ {
 display {
 compatible = "panel-lvds";

 data-mapping = "vesa-24";
 width-mm = <154>;
 height-mm = <86>;
 //enable-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
 panel-timing {
 clock-frequency = <51200000>;
 hactive = <1024>;
 vactive = <600>;
 hback-porch = <160>;
 hfront-porch = <160>;
 vback-porch = <23>;
 vfront-porch = <12>;
 hsync-len = <70>;
 vsync-len = <10>;
 hsync-active = <0>;
 vsync-active = <0>;
 de-active = <1>;
 pixelclk-active = <0>;
 };

 /*
 * Note that the OLDI TX 0 transmits the odd set of pixels
 * while the OLDI TX 1 transmits the even set. This is a
 * fixed configuration in the IP integration and is not
 * changeable. The properties, "dual-lvds-odd-pixels" and
 * "dual-lvds-even-pixels" have been used to merely
 * identify if a Dual Link configuration is required.
 * Swapping them will cause an error in the dss oldi driver.
 */
 ports {
 #address-cells = <1>;
 #size-cells = <0>;

 port@0 {
 reg = <0>;
 dual-lvds-odd-pixels;

 lcd_in0: endpoint {
 //remote-endpoint = <&oldi0_dss0_out>;
 remote-endpoint = <&oldi_out0>;
 };
 };
 port@1 {
 reg = <1>;
 dual-lvds-even-pixels;

 lcd_in1: endpoint {
 //remote-endpoint = <&oldi1_dss0_out>;
 remote-endpoint = <&oldi_out1>;
 };
 };
 };
 };

 dss0_vp1_clk: clock-divider-oldi-dss0 {
 compatible = "fixed-factor-clock";
 clocks = <&k3_clks 186 0>;
 #clock-cells = <0>;
 clock-div = <7>;
 clock-mult = <1>;
 };

 dss1_vp1_clk: clock-divider-oldi-dss1 {
 compatible = "fixed-factor-clock";
 clocks = <&k3_clks 232 0>;
 #clock-cells = <0>;
 clock-div = <7>;
 clock-mult = <1>;
 };
};


&main_pmx0 {
 main_oldi0_pins_default: main-oldi0-pins-default {
 pinctrl-single,pins = <
 AM62X_IOPAD(0x0260, PIN_OUTPUT, 0) /* (AA5) OLDI0_A0N */
 AM62X_IOPAD(0x025c, PIN_OUTPUT, 0) /* (Y6) OLDI0_A0P */
 AM62X_IOPAD(0x0268, PIN_OUTPUT, 0) /* (AD3) OLDI0_A1N */
 AM62X_IOPAD(0x0264, PIN_OUTPUT, 0) /* (AB4) OLDI0_A1P */
 AM62X_IOPAD(0x0270, PIN_OUTPUT, 0) /* (Y8) OLDI0_A2N */
 AM62X_IOPAD(0x026c, PIN_OUTPUT, 0) /* (AA8) OLDI0_A2P */
 AM62X_IOPAD(0x0278, PIN_OUTPUT, 0) /* (AB6) OLDI0_A3N */
 AM62X_IOPAD(0x0274, PIN_OUTPUT, 0) /* (AA7) OLDI0_A3P */
 AM62X_IOPAD(0x0280, PIN_OUTPUT, 0) /* (AC6) OLDI0_A4N */
 AM62X_IOPAD(0x027c, PIN_OUTPUT, 0) /* (AC5) OLDI0_A4P */
 AM62X_IOPAD(0x0288, PIN_OUTPUT, 0) /* (AE5) OLDI0_A5N */
 AM62X_IOPAD(0x0284, PIN_OUTPUT, 0) /* (AD6) OLDI0_A5P */
 AM62X_IOPAD(0x0290, PIN_OUTPUT, 0) /* (AE6) OLDI0_A6N */
 AM62X_IOPAD(0x028c, PIN_OUTPUT, 0) /* (AD7) OLDI0_A6P */
 AM62X_IOPAD(0x0298, PIN_OUTPUT, 0) /* (AD8) OLDI0_A7N */
 AM62X_IOPAD(0x0294, PIN_OUTPUT, 0) /* (AE7) OLDI0_A7P */
 AM62X_IOPAD(0x02a0, PIN_OUTPUT, 0) /* (AD4) OLDI0_CLK0N */
 AM62X_IOPAD(0x029c, PIN_OUTPUT, 0) /* (AE3) OLDI0_CLK0P */
 AM62X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* (AE4) OLDI0_CLK1N */
 AM62X_IOPAD(0x02a4, PIN_OUTPUT, 0) /* (AD5) OLDI0_CLK1P */
 >;
 };
};



&dss0 {
 pinctrl-names = "default";
 pinctrl-0 = <&main_oldi0_pins_default>;
 status = "okay";
};

&oldi0_dss0 {
 status = "okay";
};

&oldi1_dss0 {
 status = "okay";
};

/*

&oldi0_dss0_ports {
 #address-cells = <1>;
 #size-cells = <0>;

 port@0 {
 reg = <0>;

 oldi0_dss0_in: endpoint {
 remote-endpoint = <&dss0_dpi0_out0>;
 };
 };

 port@1 {
 reg = <1>;

 oldi0_dss0_out: endpoint {
 remote-endpoint = <&lcd_in0>;
 };
 };
};

&oldi1_dss0_ports {
 #address-cells = <1>;
 #size-cells = <0>;

 port@0 {
 reg = <0>;

 oldi1_dss0_in: endpoint {
 remote-endpoint = <&dss0_dpi0_out1>;
 };
 };

 port@1 {
 reg = <1>;

 oldi1_dss0_out: endpoint {
 remote-endpoint = <&lcd_in1>;
 };
 };
};*/

&dss0_ports {
 #address-cells = <1>;
 #size-cells = <0>;

 /* VP1: LVDS Output (OLDI TX 0) */
 port@0 {
 reg = <0>;
// #address-cells = <1>;
// #size-cells = <0>;

 oldi_out0: endpoint {
 remote-endpoint = <&lcd_in0>;
 };
 };

 /* VP1: LVDS Output (OLDI TX 1) */
 port@2 {
 reg = <2>;
 // #address-cells = <1>;
 // #size-cells = <0>;

 oldi_out1: endpoint {
 remote-endpoint = <&lcd_in1>;
 };
 };




/* dss0_dpi0_out0: endpoint@0 {
 reg = <0>;
 remote-endpoint = <&oldi0_dss0_in>;
 };

 dss0_dpi0_out1: endpoint@1 {
 reg = <1>;
 remote-endpoint = <&oldi1_dss0_in>;
 };
 };*/
};

Finally, I think the correct kernel options are on:

CONFIG_DRM=y
CONFIG_DRM_KMS_HELPER=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_DISPLAY_HELPER=y
CONFIG_DRM_BRIDGE_CONNECTOR=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER=y
CONFIG_DRM_GEM_DMA_HELPER=y
CONFIG_DRM_PANEL=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_TIDSS=y
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y

  • Thank you. I was eventually able to modify this DTS as an include and for my panel. 

    I have it using compatible = "innolux,zj070na-01p", "panel-simple"; 

    Unclear if this is exactly what we need, but it's 1024x600 - the panel is an AFY1024600A2. I wasn't sure how to translate the timings we had previously in the DTS into the driver values - the mapping is not 1:1. 

    In any case, I was able to pull in the kms++ tools as well:

    # ./fbtest
    /dev/fb0: res 1024x600, virtual 1024x600, line_len 4096
    # ./kmsblank
    Connector 0: blank
    press enter to exit

    # ./kmsprint
    Connector 0 (41) DPI-1 (connected)
    Encoder 0 (40) NONE
    # ./kmsxxtest
    Connector 0/@41: DPI-1
    Crtc 0/@39: 1024x600@60.25 51.501 1024/128/64/128/? 600/16/4/16/? 60 (60.25) P|D
    Plane 0/@32: 0,0-1024x600
    Fb 50 1024x600-XR24
    Atomic test failed: -524

    So something is still amiss here. We are working through some very complex I2C expander issues here for configuration, so these might be conflating things, but any advice appreciated. Thank you so far. 

  • Couple of things I see amiss here:
    1) Is your panel single link LVDS? 
    2) Have you specified the connector type as LVDS in your panel-simple? Panel is getting configured as DPI, which is wrong, please recheck your configs wrt the reference provided.
    3) Please use these formulas to translate the timing parameters:

    hfp = mode->hsync_start - mode->hdisplay;
    hsw = mode->hsync_end - mode->hsync_start;
    hbp = mode->htotal - mode->hsync_end;
    
    vfp = mode->vsync_start - mode->vdisplay;
    vsw = mode->vsync_end - mode->vsync_start;
    vbp = mode->vtotal - mode->vsync_end;

    Have you added your panel node to panel-simple.c?
    4) For I2C related queries, please create a separate thread.

    Please use code blocks to publish code/logs.

  • "1) Is your panel single link LVDS?"

    I assume so, but honestly don't know - the datasheet is pretty terse and focused on mostly electrical setup. What should I change?

    "2) Have you specified the connector type as LVDS in your panel-simple? Panel is getting configured as DPI, which is wrong, please recheck your configs wrt the reference provided."

    Here's what I now have with the math and from the previous mode timings. I don't know where these came from - again, the datasheet is not super helpful here. 

    diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
    index cc05e43670f3..0c4064178e92 100644
    --- a/drivers/gpu/drm/panel/panel-simple.c
    +++ b/drivers/gpu/drm/panel/panel-simple.c
    @@ -1326,6 +1326,36 @@ static const struct panel_desc auo_t215hvn01 = {
     	.connector_type = DRM_MODE_CONNECTOR_LVDS,
     };
     
    +static const struct drm_display_mode orient_display_afy1024600a2_mode = {
    +        .clock = 51200,
    +        .hdisplay = 1024,
    +        .hsync_start = 1024 + 160,
    +        .hsync_end = 1024 + 160 + 70,
    +        .htotal = 1024 + 160 + 70 + 160,
    +        .vdisplay = 600,
    +        .vsync_start = 600 + 12,
    +        .vsync_end = 600 + 12 + 10,
    +        .vtotal = 600 + 12 + 10 + 23,
    +};
    +
    +static const struct panel_desc orient_display_afy1024600a2 = {
    +        .modes = &orient_display_afy1024600a2_mode,
    +        .num_modes = 1,
    +        .bpc = 8,
    +        .size = {
    +                .width = 154,
    +                .height = 90,
    +        },
    +        .delay = {
    +                .prepare = 20,
    +                .enable = 200,
    +                .disable = 200,
    +        },
    +        .bus_flags = DRM_BUS_FLAG_DE_HIGH,
    +        .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
    +        .connector_type = DRM_MODE_CONNECTOR_LVDS,
    +};
    +
     static const struct drm_display_mode avic_tm070ddh03_mode = {
     	.clock = 51200,
     	.hdisplay = 1024,
    @@ -4714,6 +4744,9 @@ static const struct of_device_id platform_of_match[] = {
     	}, {
     		.compatible = "avic,tm070ddh03",
     		.data = &avic_tm070ddh03,
    +        }, {
    +                .compatible = "orient-display,afy1024600a2",
    +                .data = &orient_display_afy1024600a2,
     	}, {
     		.compatible = "bananapi,s070wv20-ct16",
     		.data = &bananapi_s070wv20_ct16,
    

    So the code is now "running", but the display timings are clearly off. I don't know if the other values I have are correct such as other timings or pixel format. I have our hardware team double checking things. This is the datasheet:

    AFY1024600A2-7.0INTH-C

    And here's the output from the tools now:

    ~# kmsprint
    Connector 0 (41) LVDS-1 (connected)
      Encoder 0 (40) NONE
        Crtc 0 (39) 1024x600@56.14 51.200 1024/160/70/160/? 600/12/10/23/? 56 (56.14) P|D
          Plane 0 (32) fb-id: 49 (crtcs: 0) 0,0 1024x600 -> 0,0 1024x600 (AR12 AB12 RA12 RG16 BG16 AR15 AB15 AR24 AB24 RA24 BA24 RG24 BG24 AR30 AB30 XR12 XB12 RX12 XR15 XB15 XR24 XB24 RX24 BX24 XR30 XB30 YUYV UYVY NV12)
            FB 49 1024x600 XR24
            
    # kmsxxtest
    Connector 0/@41: LVDS-1
      Crtc 0/@39: 1024x600@56.14 51.200 1024/160/70/160/? 600/12/10/23/? 56 (56.14) P|D
      Plane 0/@32: 0,0-1024x600
        Fb 51 1024x600-XR24
    press enter to exit
    
    

    "For I2C related queries, please create a separate thread"

    We did, before this was posted, but no one replied:

    (+) AM623: Device tree gpio/i2c dependency - Processors forum - Processors - TI E2E support forums

    We had another post previously about eMMC that we have since resolved, but no one replied to that either. 

  • Are you seeing something on the screen with kmsxxtest? What is the fps that you need? It is getting set at 56, but I assume wanted it to be 60? If so, change the .clock = h_total*v_total*fps

  • Also, to configure single-link, remove 

    dual-lvds-odd-pixels;
    dual-lvds-even-pixels;
    ti,companion-oldi = <&oldi1>;
    ti,secondary-oldi;
    

    from that dtso.

  • Thank you, the display is now nominally working. I'm not 100% sure what the refresh is supposed to be - again, the datasheet is not super clear. The calculation you gave (and / 1000) gives a worse flicker than the value I copied. I ended up setting it at 50000, (which says 54.722) which gives a solid display. I am having my hardware engineer check all the final timings, but this appears good enough.