Just wanted to let people know where I'm at with the DCON support for X. It's a little ugly, so, those with weak stomachs should read with the 'd' key.
A brief overview. The DCON controls are exposed in sysfs under /sys/devices/platform/dcon. The video driver checks if that path exists, and uses the files therein to do handoff between DCON and GPU ownership of the screen. The X server sets a damage handler on the root window pixmap, and uses that to initiate transition from the DCON back to the GPU. The damage handler also sets a soft timer to expire one frame time in the future; however, this timer is continuously pushed back as more updates come in to the screen, so as long as you keep drawing to the screen, the GPU remains in control. Once the timer fires, the X server tells the kernel to switch to DCON control. (There's a detail or two I'm omitting here, having to do with Xv and with VT switch, but pretend I didn't say anything.) This is about as optimal as we can get on the X side. Note that since the damage handler responds to damage on the root window only, X can still be doing stuff while the DCON is in control - render to offscreen pixmaps, send events and messages, etc. The "one frame time" idle estimate is a bit of a hack, but it seems reasonable so far, we don't have any better way of guessing, and we have to make _some_ guess, since the handoff between the two isn't automatic. The kernel is what implements the actual handoff between GPU and DCON and back. GPU to DCON transition is simple enough: you wiggle a pin on the DCON, which waits for the next full frame from the GPU, loads it into its internal RAM, and then takes over the screen, after which we power down the TFT interface on the GPU. This is non-optimal, frame load and display takeover should be separate operations, but they're not and the silicon ain't about to change for Gen1. Oh well. Works, looks very pretty. Going back the other direction is proving to be challenging. You need to switch sources during the vertical retrace interval, to avoid glitching. But the pixel clocks for the DCON and GPU are not the same and will skew. [1] So you need to get the two clocks to align somehow, at least to the point of both sources clocking out a vsync cycle at the same time. You can't know where you are on the DCON's scanout through the frame, because while we do get an interrupt for any single scanline we want, we can't tell which one we're on _now_. You could take scanline interrupts from the DCON continuously, and interpolate over time, but obviously that's not acceptable for power reasons. And I _think_ you can do multiple scanline interrupts per frame, since that seems like the easy and lazy way of building the hardware, but I'm not sure. On LX and possibly also GX, we can also read which scanline we're on. For LX, we can get interrupts on arbitrary GPU scanline as well. But we have no idea - besides "sometime in the next frame time" - what the interval is between powering up the TFT pixel pump, and when it will hit the next vsync. Also, we can only change timings for the GPU at vsync. And again, we could try to PLL the GPU and DCON clocks together by not powering down the pixel pump on the GPU, taking vblank intervals on both, and shifting them together, but that defeats the whole point of having a DCON. So the idea currently looks like: before sleeping the LX, set it to scan out as tiny of frames as possible, so we'll get lots of fine-grained chances to change timings. When we wake up, set a series of scanline interrupts on the DCON, and measure the timing between the two, so we can figure out both where we are in the frame, and how much the DCON clock is skewed from the GPU clock. At the second measurement, compute a new frame size to scan out that puts the vblank of the DCON and of the GPU at the same time. Set one more DCON scanline interrupt for just before end-of-frame, since it takes time to post the DCONLOAD write through GPIO, such that DCONLOAD is deasserted during the blank interval. And, hopefully, win. It's 1+epsilon frames, but I think that's as good as you can hope for anyway. [1] - They could be tied together, now, maybe, since LX supports genlock but GX didn't. I don't know if we could change that at this point in time, both due to time constraints and because I don't know if the DCON can be made to clock constantly. I think it's built so that when in GPU mode it turns off internal clocking and uses the GPU clock, in which case there's no chance of changing it. But if we can change it, then this whole discussion gets a lot simpler, you just set the scanline interrupt for the right timing to deassert DCONLOAD during blank, and you're done. - ajax _______________________________________________ Devel mailing list [email protected] http://lists.laptop.org/listinfo/devel
