Solving i.MX8M MIPI-DSI DCS timeout issue

2023-03-15

When using DSI screen with i.MX8M devices, one may encounter the following issue when trying to write DCS command after the screen has been enabled:

imx_sec_dsim_drv 32e10000.dsi_controller: wait payload tx done time out

For screen that need DCS command for changing the brightness, this would simply mean it's now impossible to change the brightness without first turning off the screen.

MIPI itself multiplexes data and control over the same physical lane with no out-of-band slots, so obviously when it's transmitting image data, it won't be able to transmit other stuff like DCS commands. But it could do so during the Vsync:

/uploads/blog/2023/2023-03-15.jpg

In the datasheet it's clear it's possible to allocate some lines in the Vsync region for transmit LPDT or HSDT commands. This is programmed with CmdAllow bits inside Vporch register:

/uploads/blog/2023/2023-03-15-190325.jpg

However this is hardcoded to disabled in the the driver drivers/gpu/drm/bridge/sec-dsim.c:

    mvporch |= MVPORCH_SET_MAINVBP(vmode->vback_porch)    |
           MVPORCH_SET_STABLEVFP(vmode->vfront_porch) |
           MVPORCH_SET_CMDALLOW(0x0);

Simply change the line to give it some room:

    mvporch |= MVPORCH_SET_MAINVBP(vmode->vback_porch)    |
           MVPORCH_SET_STABLEVFP(vmode->vfront_porch - 15) |
           MVPORCH_SET_CMDALLOW(0xf);

The cmdallow could be anywhere between 0 and 15. Though obviously to allow DCS transfer it should be at least 1. Also need to make sure that VFP is at least cmdallow + 1 (16 in this case).

Another thing to look for is to make sure MIPI_DSI_MODE_VSYNC_FLUSH is being added to dsi->mode_flags when setting mode, typically inside the panel driver.

Then it should just work.