Open ardera opened 4 years ago
Any news on this? Basically every other generic touchscreen is working better right now (both in terms of polling rate and latency) than this officially supported one.
5.4 has adopted the mainline driver from drivers/input/touchscreen/raspberrypi-ts.c rather than the downstream drivers/input/touchscreen/rpi-ft5406.c
It appears to have defined 60fps polling, but it offloads the poll process to the framework by the looks of it.
There is one commit in later kernels (>=5.5) that changes this driver, but I haven't looked to see if the required framework change are in 5.4 or not. https://github.com/raspberrypi/linux/commit/bd88ce25335d23a9967e6d3d1efdc320dbd0a3a4
I can confirm it seems like its the linux-side again, the firmware-side is polling the TS at approx 57Hz according to my i2c sniffer.
The intervals between events are most commonly 30ms, sometimes 60ms and very rarely 40ms. It's kinda strange. The HZ
is 100 so one kernel jiffy is 10ms. The polled_dev is configured with an interval of 17ms, so you'd expect to see either 10ms or 20ms in userspace, maybe 30ms. But that's not the case at all.
There is one commit in later kernels (>=5.5) that changes this driver, but I haven't looked to see if the required framework change are in 5.4 or not. bd88ce2
I did a little bit of research and it seems the actual implementation didn't change much. input_dev_poller
looks basically exactly the same as input_polled_device
(/ input_polldev
). They still use the same mechanism for the delaying the work / polling, and they have exactly the same delay calculation.
While the driver is different, the cause of the slow polling may be the same as https://github.com/raspberrypi/linux/issues/3227#issuecomment-532265372
I've had a very brief look at the framework for input_poller and it looks plausible. It's using queue_delayed_work
to retrigger every poll period.
AFAIK that is accurate at <20ms, although it does appear to be using timers (not hrtimers) for sleeping, so it may well be the same issue. That ought to be reported upstream as it surely affects all input devices using that input-poller mechanism.
That ought to be reported upstream as it surely affects all input devices using that input-poller mechanism.
Do you want to do that? I can do it, if you want me to. I kinda have the feeling though they'll say we should just increase the HZ
.
@pelwell Do you have a feel for the delay accuracy on queue_delayed_work
?
HZ
appears to be set to 100 for our configs, so a 10ms tick. That would give a moderate level of inaccuracy on the polling, but I wouldn't expect so close to 30Hz.
I find it odd that upstream have switched to this polling mechanism on a number of drivers if the accuracy isn't there on the poll rate.
Is there any way the (actual) touchscreen driver can be moved out of the firmware into the linux kernel, and be modified to use interrupts if the user wants so? The delay is pretty bad to be honest, less input lag would make the Raspberry Pi actually very usable for modern UI (using flutter and my flutter-pi project).
There is some work in mainline to write drivers for the Toshiba TC358752 DSI to DPI bridge and the touchscreen controller. One issue is that they share an I2C controller with the camera module, so if you shift the touchscreen to the kernel then you can not use the firmware camera stack (you can use libcamera which is all ARM side).
I'd be tempted to create a delayed_work item that just requeues itself 1 jiffy later for 100 iterations, and log the times.
So, according to this doc on linux work queues, queue_delayed_work
waits for at least delay
jiffies. That means queue_delayed_work
alone is introducing 20-30ms of latency. The polling work is executed right after a kernel tick ocurred, and then queue_delayed_work
with the polling work is executed.
The 17ms is probably rounded up to 2 kernel jiffies as well, and queue_delayed_work
is invoked with a delay of 2 jiffies.
queue_delayed_work
then needs to wait for 3 kernel ticks, since the dt between the invocation of queue_delayed_work
and the 2nd kernel tick is not at least 2 kernel jiffies (= 20ms) (it's probably 19.99ms). That means the delay introduced by queue_delayed_work
alone is most likely closer to 30ms.
I don't know where the other 10ms come from. Maybe the worker thread is not directly woken up by the work being queued after these 20ms, but woken up by the scheduler on the next kernel tick?
Either way, I'm amazed by how inaccurate input_polled_dev
is. I mean not only the problem we have right now, but generally, using relative timing/delays to implement reocurring work is a bad idea. If the actual poll would be a bit more time consuming, the timing would be off. Absolute timing works better in most cases. Or did I miss something?
EDIT: I somehow though queue_delayed_work
was invoked with a delay of 1 jiffy. It's actually 2 jiffies, since the 17ms get rounded up as well. That explains the 30ms delay. I corrected the numbers in the text above.
The kernel devs have been introducing sleep ranges and other "inaccuracies", allowing power savings by batching up activity to increase the length of the low power states. This could be a consequence of those changes.
The kernel devs have been introducing sleep ranges and other "inaccuracies", allowing power savings by batching up activity to increase the length of the low power states. This could be a consequence of those changes.
Could be. Though I just looked it up and input-polldev
was introduced in 2007 in 2.6.22 and hasn't changed much since. I don't know how concerned people were with power management back then.
just for completeness: with the new edt-ft5x06
driver the polling rate is still pretty low, about 33Hz at max:
pi@hpi4:~/devel/evhz $ sudo ./evhz
Press CTRL-C to exit.
event0: Razer Razer Viper
event1: Razer Razer Viper Keyboard
event2: Razer Razer Viper Consumer Control
event3: Razer Razer Viper System Control
event4: Razer Razer Viper
event5: Razer Razer Viper
event6: vc4
event7: vc4
event8: generic ft5x06 (00)
generic ft5x06 (00): Latest 33Hz, Average 0Hz
generic ft5x06 (00): Latest 33Hz, Average 16Hz
generic ft5x06 (00): Latest 33Hz, Average 22Hz
generic ft5x06 (00): Latest 33Hz, Average 24Hz
generic ft5x06 (00): Latest 33Hz, Average 26Hz
generic ft5x06 (00): Latest 33Hz, Average 27Hz
generic ft5x06 (00): Latest 33Hz, Average 28Hz
generic ft5x06 (00): Latest 33Hz, Average 28Hz
generic ft5x06 (00): Latest 16Hz, Average 29Hz
generic ft5x06 (00): Latest 1Hz, Average 28Hz
generic ft5x06 (00): Latest 16Hz, Average 25Hz
generic ft5x06 (00): Latest 33Hz, Average 24Hz
generic ft5x06 (00): Latest 33Hz, Average 25Hz
generic ft5x06 (00): Latest 33Hz, Average 25Hz
generic ft5x06 (00): Latest 33Hz, Average 26Hz
generic ft5x06 (00): Latest 33Hz, Average 26Hz
generic ft5x06 (00): Latest 33Hz, Average 27Hz
generic ft5x06 (00): Latest 33Hz, Average 27Hz
Any updates on this issue? This issue is making it hard to use the pi display for our product. Even button click events cause a lag that is hard to not notice
based on @ardera's comment about rounding up the jiffies I changed RPI_TS_POLL_INTERVAL to 7 in raspberrypi-ts.c for 5.15.32 and got:
raspberrypi-ts: Latest 50Hz, Average 47Hz raspberrypi-ts: Latest 50Hz, Average 47Hz raspberrypi-ts: Latest 25Hz, Average 46Hz raspberrypi-ts: Latest 50Hz, Average 46Hz raspberrypi-ts: Latest 50Hz, Average 47Hz
Then setting HZ to 250 in the config:
raspberrypi-ts: Latest 50Hz, Average 56Hz raspberrypi-ts: Latest 62Hz, Average 56Hz raspberrypi-ts: Latest 62Hz, Average 56Hz raspberrypi-ts: Latest 50Hz, Average 56Hz raspberrypi-ts: Latest 41Hz, Average 56Hz raspberrypi-ts: Latest 83Hz, Average 56Hz raspberrypi-ts: Latest 35Hz, Average 56Hz raspberrypi-ts: Latest 125Hz, Average 57Hz raspberrypi-ts: Latest 50Hz, Average 57Hz
This led to VASTLY improved gesture support on the screen with Qt/QML code
Of course the correct solution is to have the input-poller code get the timing correct but this solution may help others
Describe the bug The rate of input events arriving at userspace when using the Official 7inch touchscreen is too low. Input events arrive at user space at about 33Hz, resulting in perceived lagginess of touch applications, even though the application is running at 60fps.
This bug was present once before, see #3227, so this is kinda a regression. I'm not sure exactly what commit/update caused it to go back down to 33Hz though.
To reproduce See #3227
Expected behaviour Expected is at least 60Hz, possibly even higher (since touchscreen controller seems to support 100Hz, and higher polling rates result in less input lag. All iPhones past iPhone X for example poll at 120Hz, some android gaming phones at 240Hz)
Actual behaviour The frequency of input events arriving at userspace is 33Hz.
System
Logs evhz output:
kinda offtopic Is there any way the (actual) touchscreen driver can be moved out of the firmware into the linux kernel, and be modified to use interrupts if the user wants so? The delay is pretty bad to be honest, less input lag would make the Raspberry Pi actually very usable for modern UI (using flutter and my flutter-pi project).