-
Notifications
You must be signed in to change notification settings - Fork 8.4k
Description
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_LPwill 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
west build -p always -b mimxrt1160_evk//cm7 samples/modules/lvgl/demos/ -DCONFIG_LV_USE_PERF_MONITOR=y --shield=rk055hdmipi4ma0west flash- Use sample, observe tearing
west build -p always -b mimxrt1160_evk//cm7 samples/modules/lvgl/demos/ -DCONFIG_LV_USE_PERF_MONITOR=y --shield=rk055hdmipi4ma0 -DCONFIG_MCUX_ELCDIF_LP=ywest flash- 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:
zephyr/drivers/display/display_mcux_elcdif.c
Line 318 in 0d1a788
| k_sem_give(&dev_data->sem); |
The issue occurs when the eLCDIF driver checks the frame completion semaphore here:
zephyr/drivers/display/display_mcux_elcdif.c
Line 222 in 0d1a788
| k_sem_take(&dev_data->sem, K_FOREVER); |
There are several failure cases that can occur here:
-
Application calls
display_writeless 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 usingdisplay_write, then immediately send another framebuffer since thedisplay_writecall 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 thedisplay_writecall will return before the display driver has rendered the frame. -
Application calls
display_writeless 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, sincedisplay_writewill 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.