i.MX8QXP Display Controller Pixel Link to LCDIF Configuration

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX8QXP Display Controller Pixel Link to LCDIF Configuration

Jump to solution
6,890 Views
usr13
Contributor II

Hello,

Im trying to connect the display controller output to the eLCDIF interface in the ADMA subsystem.
The block diagram in section 15.1.1.1 of the reference manual shows a possible connection using the pixel link, but provides no further information.

I have looked at the SDK examples for the i.MX8 but there are noone provided for the eLCDIF interface.
Furthermore the SDK examples for the DPU also dont show how outputting to the eLCDIF interface would be done,  only how to select one of the two lvds channels.

How could I set about to acomplish this? As far as I can tell the so called "pixel link" is a AXI bus, which means there should be a axi master (LCDIF) which I would have to connect with an axi slave (the pixel link of the dc?).

Thanks in advance.

0 Kudos
Reply
1 Solution
6,504 Views
usr13
Contributor II

I found the solution to my issue: after setting up display stream 1, setting the pixel link slave index to 1 and changing the lcdif mux bit 1:0 to 1, you still need to enable the pixel link mux clock to the pixel clock frequency. The eLCDIF module doesnt need to be configured at all.

usr13_0-1646808852931.png

 

View solution in original post

0 Kudos
Reply
10 Replies
6,861 Views
Rita_Wang
NXP TechSupport
NXP TechSupport

Could you tell us which board and which version of BSP are you using?

0 Kudos
Reply
6,855 Views
usr13
Contributor II

Im using a custom in-house carrier board and the BSP Version SDK_2.9.0_MIMX8QX5xxxFZ.

0 Kudos
Reply
6,825 Views
Rita_Wang
NXP TechSupport
NXP TechSupport

Pixel link is dedicated bus used for transferring pixel between master (DISPLAY ) and slave (with fix address. )

The address the master is sending to is configured though SCU FW call.
The document "sc_fw_api_qx_b0.pdf" part of the imx-scfw-porting-kit is describing the API:

b45499_0-1643341161496.png

 

That's what the following chapter is trying to explain in the RM:

b45499_1-1643341161762.png

 

But I would have expected to be find it in the RM chapter:

b45499_2-1643341162352.png

 

Verification on the errata: nothing is preventing to to configure the pixel address.

But looking at the latest internal documentation, it feels like the feature has been de-scoped

0 Kudos
Reply
6,816 Views
usr13
Contributor II

Thanks for the answer.

I'm am still unsure on which value to write to the SC_C_PXL_LINK_MST1_ADDR resource, if I want to use the eLCDIF interface as an output.

Looking at the dpu_character SDK example, it seems like this value is always 0 for LVDS or DSI, the only difference is the DPU display index.

Do I need to take additional steps to output to the eLCDIF or is there a simple address I need to use for the SC_C_PXL_LINK_MST1_ADDR resource?

#if (DPU_EXAMPLE_DI == DPU_DI_MIPI)
status_t SOC_SetDpuMipiDsiPixelLink(sc_ipc_t ipc, IRIS_MVPL_Type *dpu, uint8_t displayIndex, MIPI_DSI_HOST_Type *dsi)
{
    /*
     * Pixel link setting.
     *
     * DPU 0 display0 is connected to MIPI DSI 0 using address 0.
     * DPU 0 display1 is connected to MIPI DSI 1 using address 0.
     *
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_ADDR   Master 1 pixel link address
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_ENB    Master 1 pixel link enable
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_VLD    Master 1 pixel link valid
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_ADDR   Master 2 pixel link address
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_ENB    Master 2 pixel link enable
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_VLD    Master 2 pixel link valid
     * SC_R_DC_0    SC_C_SYNC_CTRL0           PL sync ctrl 0
     * SC_R_DC_0    SC_C_SYNC_CTRL1           PL sync ctrl 1
     */
    uint8_t pixelLinkAddr = 0;
    uint32_t i;
    sc_err_t err = SC_ERR_NONE;

    const dpu_mipi_pl_addr_t dpuMipiPlAddrs[] = {
        {
            .dpu             = DC__IRIS_MVPL,
            .dpuDisplayIndex = 0,
            .dsi             = DI_MIPI_DSI_LVDS_0__MIPI_DSI_HOST,
            .plAddr          = 0,
        },
        {
            .dpu             = DC__IRIS_MVPL,
            .dpuDisplayIndex = 1,
            .dsi             = DI_MIPI_DSI_LVDS_1__MIPI_DSI_HOST,
            .plAddr          = 0,
        },
    };

    const sc_ctrl_t pixelLinkCtrl[][4] = {
        {
            SC_C_PXL_LINK_MST1_ADDR,
            SC_C_PXL_LINK_MST1_ENB,
            SC_C_PXL_LINK_MST1_VLD,
            SC_C_SYNC_CTRL0,
        },
        {
            SC_C_PXL_LINK_MST2_ADDR,
            SC_C_PXL_LINK_MST2_ENB,
            SC_C_PXL_LINK_MST2_VLD,
            SC_C_SYNC_CTRL1,
        },
    };

    /* Get the pixel link address. */
    for (i = 0; i < ARRAY_SIZE(dpuMipiPlAddrs); i++)
    {
        if ((dpu == dpuMipiPlAddrs[i].dpu) && (displayIndex == dpuMipiPlAddrs[i].dpuDisplayIndex) &&
            (dsi == dpuMipiPlAddrs[i].dsi))
        {
            pixelLinkAddr = dpuMipiPlAddrs[i].plAddr;
            break;
        }
    }

    if (ARRAY_SIZE(dpuMipiPlAddrs) <= i)
    {
        PRINTF("ERROR: This DPU to MIPI DSI path is not supported.\r\n");
        return kStatus_Fail;
    }

    /* Set address. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][0], pixelLinkAddr);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Pull down sync control. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][3], 0);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Enable pixel link. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][1], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Delay at least 3 pixel clock. */
    for (volatile uint32_t i = 0; i < 0x100000; i++)
    {
    }

    /* Valid pixel link. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][2], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Pull up sync control. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][3], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    return kStatus_Success;
}
#elif (DPU_EXAMPLE_DI == DPU_DI_LVDS)
status_t SOC_SetDpuLdbPixelLink(sc_ipc_t ipc, IRIS_MVPL_Type *dpu, uint8_t displayIndex, LDB_Type *ldb)
{
    /*
     * Pixel link setting.
     *
     * DPU 0 display1 is connected to LDB 0 using address 0.
     * DPU 1 display1 is connected to LDB 1 using address 0.
     *
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_ADDR   Master 1 pixel link address
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_ENB    Master 1 pixel link enable
     * SC_R_DC_0    SC_C_PXL_LINK_MST1_VLD    Master 1 pixel link valid
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_ADDR   Master 2 pixel link address
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_ENB    Master 2 pixel link enable
     * SC_R_DC_0    SC_C_PXL_LINK_MST2_VLD    Master 2 pixel link valid
     * SC_R_DC_0    SC_C_SYNC_CTRL0           PL sync ctrl 0
     * SC_R_DC_0    SC_C_SYNC_CTRL1           PL sync ctrl 1
     */
    uint8_t pixelLinkAddr = 0;
    uint32_t i;
    sc_err_t err = SC_ERR_NONE;

    const dpu_ldb_pl_addr_t dpuLdbPlAddrs[] = {
        {
            .dpu             = DC__IRIS_MVPL,
            .dpuDisplayIndex = 0,
            .ldb             = MIPI_DSI_LVDS_COMBO0_CSR,
            .plAddr          = 0,
        },
        {
            .dpu             = DC__IRIS_MVPL,
            .dpuDisplayIndex = 1,
            .ldb             = MIPI_DSI_LVDS_COMBO1_CSR,
            .plAddr          = 0,
        },
    };

    const sc_ctrl_t pixelLinkCtrl[][4] = {
        {
            SC_C_PXL_LINK_MST1_ADDR,
            SC_C_PXL_LINK_MST1_ENB,
            SC_C_PXL_LINK_MST1_VLD,
            SC_C_SYNC_CTRL0,
        },
        {
            SC_C_PXL_LINK_MST2_ADDR,
            SC_C_PXL_LINK_MST2_ENB,
            SC_C_PXL_LINK_MST2_VLD,
            SC_C_SYNC_CTRL1,
        },
    };

    /* Get the pixel link address. */
    for (i = 0; i < ARRAY_SIZE(dpuLdbPlAddrs); i++)
    {
        if ((dpu == dpuLdbPlAddrs[i].dpu) && (displayIndex == dpuLdbPlAddrs[i].dpuDisplayIndex) &&
            (ldb == dpuLdbPlAddrs[i].ldb))
        {
            pixelLinkAddr = dpuLdbPlAddrs[i].plAddr;
            break;
        }
    }

    if (ARRAY_SIZE(dpuLdbPlAddrs) <= i)
    {
        PRINTF("ERROR: This DPU to LDB path is not supported.\r\n");
        return kStatus_Fail;
    }

    /* 8QX uses combo PHY, configure to LVDS here. */
    err = sc_misc_set_control(ipc, MIPI_DSI_RSRC, SC_C_MODE, 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    err = sc_misc_set_control(ipc, MIPI_DSI_RSRC, SC_C_DUAL_MODE, 0);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    err = sc_misc_set_control(ipc, MIPI_DSI_RSRC, SC_C_PXL_LINK_SEL, 0);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Set address. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][0], pixelLinkAddr);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Pull down sync control. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][3], 0);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Enable pixel link. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][1], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Delay at least 3 pixel clock. */
    for (volatile uint32_t i = 0; i < 0x100000; i++)
    {
    }

    /* Valid pixel link. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][2], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    /* Pull up sync control. */
    err = sc_misc_set_control(ipc, DC_RSRC, pixelLinkCtrl[displayIndex][3], 1);
    if (SC_ERR_NONE != err)
    {
        assert(false);
    }

    return kStatus_Success;
}

#endif /* DPU_EXAMPLE_DI */

 

0 Kudos
Reply
6,740 Views
Rita_Wang
NXP TechSupport
NXP TechSupport

We have been informed that the feature should be enable in our latest BSP:

Looking a code aurora, we can see that the pixel link mux is declared in the DTB

https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8qxp-ss-a...

DTB for configuring the feature in linux.

https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8x-mek-dp...

 

0 Kudos
Reply
6,741 Views
Rita_Wang
NXP TechSupport
NXP TechSupport

Pixel link slave address will be 1.
Additional "pixel link mux" should be configured at 0x5A170000

b45499_0-1644386205857.png

 

(personal drawing, this is not coming from any documentation.)

Even if the address is described as "reserved", it controls the pixel link mux internal to the LCDIF module.

b45499_1-1644386205830.png

 

There might be requirement for the clocking that I still need to clarify.
If I understood correctly the slice of the LCDIF should be configured to use the bypass input when using the Pixel link input.

6,544 Views
usr13
Contributor II

How do I need to configure the eLCDIF display module? Your drawing makes it look like the module is bypassed altogheter, and changing *0x5A170000 = 1/2/3 is all I need to do.

Looking at the eLCDIF subsystem overview:Unbenannt.PNG

It still seems like I still have to configure the LCD Interface to drive the LCD pins. Do I have to configure the eLCDIF Interface to be in e.g. DOTCLK mode? Looking at the startup sequence of the pixel link, I still need to power on the reciever (the lcdif mux, which I have not found the right resource for).

Is there some documentation on this lcdif mux that I can get my hands on? As far as I can see its not documented in the eLCDIF chapter or the pixel link chapter. Its rather frustrating having to wait for your answers, instead of looking up things myself.

Thanks in Advance

 

0 Kudos
Reply
6,505 Views
usr13
Contributor II

I found the solution to my issue: after setting up display stream 1, setting the pixel link slave index to 1 and changing the lcdif mux bit 1:0 to 1, you still need to enable the pixel link mux clock to the pixel clock frequency. The eLCDIF module doesnt need to be configured at all.

usr13_0-1646808852931.png

 

0 Kudos
Reply
6,499 Views
Rita_Wang
NXP TechSupport
NXP TechSupport
Good news it works, thanks a lot for you kindly sharing. Wish you have a nice day
0 Kudos
Reply
6,833 Views
Rita_Wang
NXP TechSupport
NXP TechSupport

I will confirm it for you, As we Chinese will have the Spring Festival holiday and will back to office on the 7th Feb,Thanks a lot for your kindly understandings.

0 Kudos
Reply