Skip to content

RK055HDMIPI4MA0 display shows tearing on RT1170/RT1160 EVK #80590

@danieldegrasse

Description

@danieldegrasse

Describe the bug
The RK055HDMIPI4MA0 display shows a distinct tearing effect when driven by the RT1170 and RT1160 EVK. This effect is visible within the LVGL samples, but should also appear in any display application. Additionally, the demo application frequency stops responding to touch events when the CPU load is high.

Please also mention any information which could help others to understand
the problem you're facing:

  • What target platform are you using? mimxrt1160_evk//cm7
  • What have you tried to diagnose or workaround this issue? Enabling CONFIG_MCUX_ELCDIF_LP will resolve this issue.
  • Is this a regression? If yes, have you been able to "git bisect" it to a
    specific commit? Yes, the issue was introduced in 2068976

To Reproduce
Steps to reproduce the behavior:

Apply fixes in #80586 to resolve DSI clock issue, otherwise there won't be display output

  1. west build -p always -b mimxrt1160_evk//cm7 samples/modules/lvgl/demos/ -DCONFIG_LV_USE_PERF_MONITOR=y --shield=rk055hdmipi4ma0
  2. west flash
  3. Use sample, observe tearing
  4. west build -p always -b mimxrt1160_evk//cm7 samples/modules/lvgl/demos/ -DCONFIG_LV_USE_PERF_MONITOR=y --shield=rk055hdmipi4ma0 -DCONFIG_MCUX_ELCDIF_LP=y
  5. west flash
  6. Use sample, no more tearing

Expected behavior
There should not be screen tearing.

Impact
Annoyance, I like my screens smooth

Environment (please complete the following information):

  • OS: Ubuntu 22.04 LTS
  • Toolchain Zephyr SDK zephyr-sdk-0.16.5-1
  • Commit SHA or Version used 022c8ee (main)

Additional context
This appears to be caused by the logic present in 2068976. Namely, the eLCDIF IP will set the CUR_FRAME_DONE_IRQ bit each vertical blanking interval. The eLCDIF will continually display the buffer pointed to by CUR_BUF until NEXT_BUF is set. This means that when CONFIG_MCUX_ELCDIF_LP=n, every vertical blanking interval will result in the driver posting to the semaphore used to indicate frame completion here:

k_sem_give(&dev_data->sem);

The issue occurs when the eLCDIF driver checks the frame completion semaphore here:

k_sem_take(&dev_data->sem, K_FOREVER);

There are several failure cases that can occur here:

  1. Application calls display_write less frequently than one vertical sync interval, but can render entire frame within a vertical sync interval
    In this case, the application may write one framebuffer using display_write, then immediately send another framebuffer since the display_write call will return effectively instantly. This may result in some frames being skipped if the new framebuffer is set before the eLCDIF reaches a vertical blanking interval. Another possible failure here is that the application might start rendering into a frame while the eLCDIF is sending it to the display, since the display_write call will return before the display driver has rendered the frame.

  2. Application calls display_write less frequently than one vertical sync interval, and cannot render entire frame within a vertical sync interval
    In this case, other threads may be starved for CPU time. The application will always be able to write a new frame to the eLCDIF, since display_write will always return immediately after taking the semaphore. This means that background threads, like the touch event workqueue, may never be scheduled and touch events may not be processed.

Metadata

Metadata

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions