HyperPixel 4.0 - High cpu usage from touch driver

Hi Guys,

I have tested this on a Pi Zero and Model B.

Here is the goodix driver:

pi@PiDev:~ $ modinfo goodix
filename:       /lib/modules/4.14.52-v7+/kernel/drivers/input/touchscreen/goodix.ko
license:        GPL v2
description:    Goodix touchscreen driver
author:         Bastien Nocera <hadess@hadess.net>
author:         Benjamin Tissoires <benjamin.tissoires@gmail.com>
srcversion:     35F207673154C81B3E8EBA5
alias:          i2c:GDIX1001:00
alias:          of:N*T*Cgoodix,gt967C*
alias:          of:N*T*Cgoodix,gt967
alias:          of:N*T*Cgoodix,gt928C*
alias:          of:N*T*Cgoodix,gt928
alias:          of:N*T*Cgoodix,gt9271C*
alias:          of:N*T*Cgoodix,gt9271
alias:          of:N*T*Cgoodix,gt927C*
alias:          of:N*T*Cgoodix,gt927
alias:          of:N*T*Cgoodix,gt912C*
alias:          of:N*T*Cgoodix,gt912
alias:          of:N*T*Cgoodix,gt9110C*
alias:          of:N*T*Cgoodix,gt9110
alias:          of:N*T*Cgoodix,gt911C*
alias:          of:N*T*Cgoodix,gt911
depends:        
intree:         Y
name:           goodix
vermagic:       4.14.52-v7+ SMP mod_unload modversions ARMv7 p2v8 

When using the touchscreen this is causing high cpu load (between 20% and 70%) in its ISR (irq/169-gt911).

It is fairly easy to see, run top in a terminal and start moving your finger around on the screen, to see the cpu load get higher move your finger around quicker, now use 2 fingers, then 3 fingers.

Anyone any idea why this might be?

Unfortunately I’ve no clue- it’s an upstream driver so I’ve not had a hand in its creation. It looks like the same driver is used on the GPD Pocket but I can’t find any mention of high CPU usage in relation to it.

It might be worth raising an issue here: https://github.com/raspberrypi/linux/issues

Hi,

Thanks for the info.

Ill raise the issue as you say…

Andy

Edit: Issue raised https://github.com/raspberrypi/linux/issues/2623

Isn’t “some” of the overhead because its done via GPIO instead of say USB?

I’m sure there is overhead because of this, I had a quick look at the driver code before and they use i2c_transfer() which I’m guessing might be where the problem lies.

Still The CPU usage is extremely high.

It uses a bitbanged i2c device running on BCM10/11 also, so this probably doesn’t help.

AH, so it isn’t using the hardware i2c. The plot thickens :)

I had looked up the pinout for the original Hyper Pixel and noticed Touch Data on BCM 10, touch clock on BCM 11 and touch interrupt on BCM 27. I don’t know if the new Hyperpixel is the same or not. For sure its not USB like most DHMI touch screens would do it. It appears, the old Hyperpixel doesn’t use hardware i2c for anything?

Neither the old or new use hardware i2c, since the DPI alt functions of those pins are the completely essential V-SYNC and H-SYNC signals. See: https://pinout.xyz/pinout/dpi

That’s what I thought Phil, thanks for confirming. :)

I looked into this more, the basic problem is that the driver does everything in the IRQ handler and the i2c is slow, both the i2c and the touchscreen drivers use sleeps which cause a cpu spin when used in an IRQ handler.

Changing i2c-gpio,delay-us in the DTS to 2 reduces the cpu load by around a 1/3 (I think, could be wrong as sometimes we still get higher cpu), lowering it further seems to have a detrimental effect.

I have updated the driver to enable you to set the refresh rate of the screen which changed the number of interrupts it generates, this hugely lowers cpu when set to its maximum.

If anyone is suffering cpu load problems the driver is here: https://github.com/AndrewCapon/HyperPixel4TouchScreen/tree/master/driver

1 Like

You’re kinda my hero right now with these driver tweaks! ;D

Thanks :)

For the standard install for users using X I think setting touchscreen-refresh-rate to 15 would be perfect, this really drops the cpu usage, very useful for the slower or single core machines.

I have looked into the cpu load a bit more and changed the driver code to use tasklets where the IRQ request returns immediately and the tasklet is scheduled to run after, outside of interrupt level.

This doesn’t work though, the i2c client is locked/closed when you exit the IRQ request and cannot be used in the tasklet.

What I have learnt though is that the IRQ request in these i2c drivers is not running like a normal IRQ request, it doesn’t run atomically and interrupts are not disabled. So sleeps are allowed and shouldn’t cause spins so I’m guessing the cpu load is fully down to the bit banging of the i2c.