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 */