Is there a way to increase SPI clock speed?

Hi,

I’ve attached a SPI LCD display (ST7789 - 240x240 pixels) on the zero board.
It work fine but it’s limited to less than one frame per seconde probably because the SPI device is limited to :
param_spidev_max_freq=10000000

So what i did:

  • change param_spidev_max_freq in /boot/uEnv.txt
    overlays=meson-g12a-spi-spidev
    param_spidev_spi_bus=1
    param_spidev_max_freq=120000000

  • recompile and install the kernel and especialy meson-g12a-spi-spidev.dts file :

root@debian:/home/papy/radxa-zero-sdk/kernel# cat ./arch/arm64/boot/dts/amlogic/overlay/meson-g12a-spi-spidev.dts
/dts-v1/;
/plugin/;

/ {
	compatible = "radxa,zero", "amlogic,g12a";

	fragment@0 {
		target = <&spicc0>;
		__overlay__ {
			pinctrl-0 = <&spicc0_x_pins &spicc0_ss0_x_pins>;
			pinctrl-names = "default";
			#address-cells = <1>;
			#size-cells = <0>;
			spidev@0 {
				compatible = "spidev";
				status = "disabled";
				reg = <0>;
				spi-max-frequency = <120000000>;
			};
		};
	};

	fragment@1 {
		target = <&spicc1>;
		__overlay__ {
			pinctrl-0 = <&spicc1_pins &spicc1_ss0_pins>;
			pinctrl-names = "default";
			#address-cells = <1>;
			#size-cells = <0>;
			spidev@0 {
				compatible = "spidev";
				status = "disabled";
				reg = <0>;
				spi-max-frequency = <120000000>;
			};
		};
	};
};

But the display is still limited to less than 1 frame per second. I don’t have an oscilloscope to check the SPI clock speed but it always seems limited to a very low speed

Is there a way to increase the SPI clock (maybe I use a bad multipler)?

Thanks in advance

I go further in my search. If I look at https://wiki.radxa.com/Device-tree-overlays :

param_spidev_max_freq (int)
Maximum SPIdev frequency
Optional
Default: 10000000
Range: 3000 - 100000000

So, I can apparently set the clock up to 100 Mhz, but even after a recompile and even if I can see that spi.max_speed_hz is well set to 100 Mhz in spidev (I also check that it’s well set with “dtc -I fs /sys/firmware/devicetree/base”), the SPI is still very low (probably 10 Mhz). I’ve tested on both spi on 2 different Radxa Zero.

Do you have any idea? Is there a hardware clock limit to only 10Mhz ?

I found an interesting error that I miss previously in “dmes” when I activate SPI.
I have the same error log on 2 different Zero SBC.
I’ve tested with 2 debian raw images (one from january and the last one) and I even rebuild the kernel and I’ve always the same problem. To reproduce this kernel error, you juste have to activate spidev in /boot/uEnv.txt

overlays=meson-g12a-spi-spidev
param_spidev_spi_bus=1
param_spidev_max_freq=10000000

I suspect that the limited SPI clock speed is related to this problem

The log is bellow:

[    2.318384] random: fast init done
[    2.425063] meson-vrtc ff8000a8.rtc: registered as rtc0
[    2.425136] meson-vrtc ff8000a8.rtc: setting system clock to 1970-01-01T00:00:02 UTC (2)
[    2.441078] ------------[ cut here ]------------
[    2.441120] /soc/bus@ffd00000/spi@15000/spidev@0: buggy DT: spidev listed directly in DT
[    2.441208] WARNING: CPU: 2 PID: 1384 at drivers/spi/spidev.c:742 spidev_probe+0x144/0x268 [spidev]
[    2.441220] Modules linked in: spidev(+) rtc_meson_vrtc axg_audio(+) sclk_div clk_phase
[    2.441251] CPU: 2 PID: 1384 Comm: systemd-udevd Not tainted 5.10.69-10-amlogic-g617a45dd0fce #amlogic
[    2.441262] Hardware name: Radxa Zero (DT)
[    2.441271] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[    2.441283] pc : spidev_probe+0x144/0x268 [spidev]
[    2.441294] lr : spidev_probe+0x144/0x268 [spidev]
[    2.441301] sp : ffff8000140e3900
[    2.441307] x29: ffff8000140e3900 x28: 0000000000000100
[    2.441317] x27: ffff0000038db000 x26: 0000000000000001
[    2.441328] x25: 0000000000000019 x24: ffff800011771000
[    2.441338] x23: ffff800008e5c058 x22: 0000000000000000
[    2.441348] x21: ffff000000828800 x20: ffff000000828800
[    2.441359] x19: ffff800008e5c038 x18: ffffffffffffffff
[    2.441369] x17: 0000000000000000 x16: 0000000000000000
[    2.441379] x15: ffff80001166e948 x14: 000000000000012a
[    2.441390] x13: ffff8000140e35a0 x12: 00000000ffffffea
[    2.441400] x11: ffff8000116fb270 x10: ffff8000116e3230
[    2.441410] x9 : ffff8000116e3288 x8 : 0000000000017fe8
[    2.441422] x7 : c0000000ffffefff x6 : 0000000000000001
[    2.441432] x5 : 0000000000000000 x4 : 0000000000000000
[    2.441442] x3 : 00000000ffffffff x2 : ffff80001168b200
[    2.441452] x1 : fc3801c1fb1f1a00 x0 : 0000000000000000
[    2.441464] Call trace:
[    2.441474]  spidev_probe+0x144/0x268 [spidev]
[    2.441489]  spi_drv_probe+0x84/0xe8
[    2.441500]  really_probe+0x114/0x500
[    2.441509]  driver_probe_device+0xfc/0x168
[    2.441519]  device_driver_attach+0x74/0x80
[    2.441527]  __driver_attach+0xb8/0x168
[    2.441535]  bus_for_each_dev+0x7c/0xd8
[    2.441544]  driver_attach+0x24/0x30
[    2.441552]  bus_add_driver+0x15c/0x240
[    2.441560]  driver_register+0x64/0x120
[    2.441568]  __spi_register_driver+0x4c/0x58
[    2.441579]  spidev_init+0xa4/0x1000 [spidev]
[    2.441590]  do_one_initcall+0x60/0x1d8
[    2.441601]  do_init_module+0x58/0x1f8
[    2.441613]  load_module+0x21ec/0x26e8
[    2.441621]  __do_sys_finit_module+0xc0/0x128
[    2.441630]  __arm64_sys_finit_module+0x20/0x30
[    2.441641]  el0_svc_common.constprop.4+0x70/0x1d0
[    2.441650]  do_el0_svc+0x24/0x90
[    2.441661]  el0_svc+0x14/0x20
[    2.441669]  el0_sync_handler+0x90/0xb8
[    2.441677]  el0_sync+0x180/0x1c0
[    2.441685] ---[ end trace a2f9de1855f57e5d ]---
[    3.102288] usb 2-1: new SuperSpeed Gen 1 USB device number 2 using xhci-hcd

I got a good fps on my ST7735s lcd, although when i try to run large videos and scaled down to 128x128, i tends to get choked on cpu since it tries to downscale it and write to framebuffer.
But for relatively small resolution video / display, it can be handled ok.

I’ve make a bench raspberry vs Raxda zero on the same SPI display 256x256 :
Raspberry can display 500 frames in 37 seconds (and It could be probably be improved)
Raxda zero can display 500 frames in 154 seconds

It’s insufficient to display animations on Raxda

As you can see on my video, the Raxda zero (at the bottom) display blinks a lot more compared to Raspberry (at the top)

If we look at “Meson G12A Available Overlay” here :
https://wiki.radxa.com/Device-tree-overlays
We can see that the max SPI clock is 100Mhz :

 param_spidev_max_freq (int)

        Maximum SPIdev frequency
        Optional
        Default: 10000000
        Range: 3000 - 100000000

But In my experience, it’s only limited to 12Mhz maximum (the frame rate is reduced if I set param_spidev_max_freq bellow 12 000 000 but It does not increase if I set above 12Mhz)

I’ve try to modify the SPI clock (spicc1: spi@15000 {}) in meson-g12-common.dtsi but without success. I don’t know if we can increase the clock or even if we can use an other clock for SPI

I use a 256x256 display, it’s 4 time more data to transfer vs 128x128.

Could you got solution?

I got same issue.
I have a 0.96inch(160*80) screen,using python language to write screen program.
before find your problem I thought problem in python mraa library because use raspberry B+ didn`t have this issue

No, I didn’f found a solution. I’ve search for weeks but the frame rate is always slow.
I suspect the spi clock is not well assigned.

In meson-g12-common.dtsi, we have :

spicc1: spi@15000 {
			compatible = "amlogic,meson-g12a-spicc";
			reg = <0x0 0x15000 0x0 0x44>;
				interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&clkc CLKID_SPICC1>,
					 <&clkc CLKID_SPICC1_SCLK>;
				clock-names = "core", "pclk";
				#address-cells = <1>;
				#size-cells = <0>;
				status = "disabled";
			}; 

The clock “pclk” is probably limited to something like 20 mhz, resulting in a low spi data rate

maybe we should also modify spi-meson-spicc.c to assign a good spi clock rate but I did not suceed.
Maybe radxa team has a line of thought

Thank you for your reply.
last night , I reseach this document https://github.com/HejinYo/ss/blob/master/doc/radxa/radxa-zero-spi-led.md

  • I think the key point is probably in this article

In this document ,you can see this log .

[ 7.871224] graphics fb1: fb_st7789v frame buffer, 240x135, 63 KiB video memory, 4 KiB buffer memory, fps=62, spi1.0 at 10 MHz

This shows that it also works on 10Mhz So the point probably not at frequency.

I’ve make some benchmarks, I found that spi data rate is approximately 8 time slower in radxa zero compared with raspberry pi 4, resulting in a low frame rate.

It’s realy the spi bus which is the bottelneck and probably because the spi clock rate is too low (I can’t be very assertive because I don’t have an oscilloscope to check the clock rate). It’s still low if you increase param_spidev_max_freq or spi.max_speed_hz (in spidev)

You can maybe improve the smoothness of your screen if you use the linux “fb” frame buffer (fbtft) instead of directly drawing your screen with Python (PIL wich don’t use fbtft if used with spidev) because it’s possible that the linux “fb” only refresh the tiny screen portion which differs from the previous frame instead of refreshing the whole screen (that’s probably the reason why you could have a good frame rate with a low frequency if you have only tiny difference between each frame )

my observation is that spi rate is to low to properly display video/animation/gif/transition effect on a 240x240 diplay on radxa zero. It could probably be acceptable with a lower screen resolution : it’s almost smooth if I only use half of the display (240x128) and probably even better with your resolution (160x80)

I have a oscilloscope but I’m not very skilled with it. Here is my results.


As you have said ,it only 6MHz.
I try to use spidev but the library will report segmentation fault Error without other messages. so i abandoned the library.
libmraa library Spi Instance writeByte function what each loop write only one byte.so this is another reason why my screen is solw .

The picture aboves is of measuring clock pin

just now I’m retry the spidev library, it run the program successful, Turns out I was using it the wrong way.

  • Much faster than before :joy: