On Wed, Nov 16, 2011 at 6:19 PM, Matthew Garrett mjg59@srcf.ucam.org wrote:
On Thu, Nov 17, 2011 at 01:26:37AM +0100, Mario Kleiner wrote:
On Nov 16, 2011, at 7:48 PM, Matthew Garrett wrote:
For Radeon, I'd have thought you could handle this by scheduling an irq for the beginning of scanout (avivo has a register for that) and delaying the vblank disable until you hit it?
For Radeon there is such an irq, but iirc we had some discussions on this, also with Alex Deucher, a while ago and some irq's weren't considered very reliable, or already used for other stuff. The idea i had goes like this:
Use the crtc scanout position queries together with the vblank counter queries inside some calibration loop, maybe executed after each modeset, to find out the scanline range in which the hardware vblank counter increments -- basically a forbidden range of scanline positions where the race would happen. Then at each vblank off/on, query scanout position before and after the hw vblank counter query. If according to the scanout positions the vblank counter query happened within the forbidden time window, retry the query. With a well working calibration that should add no delay in most cases and a delay to the on/off code of a few dozen microseconds (=duration of a few scanlines) worst case.
Assuming we're sleeping rather than busy-looping, that's certainly ok. My previous experiments with radeon indicated that the scanout irq was certainly not entirely reliable - on the other hand, I was trying to use it for completing memory reclocking within the vblank interval. It was typically still within a few scanlines, so a sanity check there wouldn't pose too much of a problem.
I think there's a simpler fix: just keep the hardware and software counts in sync -- if everything is working correctly (even with all these crazy races), the difference should be constant. Patch coming momentarily.
--Andy