OMAP:DSS: possible bug in WAITFOR_VSYNC ioctl

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

While supporting one of customer I came across one interesting issue and finding with WAITFORVSYNC ioctl - 

Problem Statement - 
-------------------
With WAITFORVSYNC lots of tearing artifacts are visible on LCD output, but WAITFORGO works fine without any issues.

Debugging/Findings - 
--------------------

Technically both, WAITFORVSYNC and WAITFORGO wait on VSYNC interrupt - but there is slight difference in their implementation/processing. 

WAITFORGO ioctl ensures that dirty & shadow_dirty flags (software flag) are cleared, making sure that hardware state and software state always stays in sync. It makes 4 attempts to do so - inside loop it checks for dirty flags and call wait_for_vsync API. In ideal usecase scenario it should come out in single iteration. 

On the other hand WAITFORVSYNC is unconditional wait on VSYNC interrupt. The processing continues with an assumption that HW and SW states are in sync.

Since WAITFORGO ioctl seems to be working in all conditions I started debugging with it and I observed that dirty and shadow_dirty flags are getting cleared on 2nd attempt in some cases. This forced me to think about the window between VFP start and VSYNC.


Root-cause (How the behavior impact software)-
----------------------------------------------

The DSS registers are shadow registers, meaning: after updating the HW registers software must write 1 to GO_LCD bit to indicate that we are finished with register update and HW can now read it on next VFP start (not the vsync). This is the way software and hardware handshaking is done.

In Linux Display driver, we have 2 flags, dirty and shadow_dirty, first one indicates software bookkeeping registers are updated and later indicates that shadow registers are written but DSS HW has not yet read it (which happens on VFP start).

Now, if the PAN ioctl is called in the above mentioned window then DSS hardware is not going to read the shadow register (setting dirty flags), DMA will still happen on old buffer. Then immediately after PAN ioctl we are calling WAITFORVSYNC ioctl, which is unconditional wait for VSYNC interrupt and then application moves on writing to another buffer (which is now same as where DMA is happening). So here we are breaking and going out-of-sync to handle our ping-pong mechanism in application. As soon as the flow breaks, we see the artefacts on screen.

I have created Public Wiki page explaining above issue with more details and pictorial diagrams, you can refer it under http://processors.wiki.ti.com/index.php/OMAP35x_Linux_-_DSS_FAQ


Suggestions/Recommendation - 
--------------------------

>From User application point of view, user won't care about driver internal implementation. Application believes that WAITFORVSYNC will only return after displaying (DMAing) previous buffer and now with addition to FBIO_WAITFORVSYNC standard ioctl interface this is very well expected from user application as a standard behavior.

I would recommend having WAITFORGO like implementation under WAITFORVSYNC, merging WAITFORGO with WAITFORVSYNC, and killing WAITFORGO (since we have FBIO_WAITFORVSYNC standard ioctl). 
Also WAITFORGO ioctl is OMAP specific custom ioctl.  

NOTE: Please note that this issue has been discussed with HW experts here in TI and they have conformed this.

Thanks,
Vaibhav
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux