DTOVERLAY parameters with extlinux.conf

I’m running ArchlinuxArm on a radxa, as such I don’t use a boot.scr u-boot script, but an extlinux.conf file. I’m aware that I can load device-tree overlays with the FDTOVERLAYS line, which works fine ; I already use it for I2C.

Now I need to run an SPI screen. The meson-g12a-spi-spidev overlay has a mandatory argument, param_spidev_spi_bus. Is there a syntax to add it in extlinux.conf ?

Besides, in the hope to have a parameter-free overlay, I tried building an user overlay with the following content :

/dts-v1/;
/plugin/;

&spicc1 {
	#address-cells = <1>;
	#size-cells = <0>;

	spidev@0 {
		compatible = "spidev";
		status = "okay";
		spi-max-frequency = <8000000>;
        reg = <0>;
	};
};

I compiled it with

sudo dtc -@ -I dts -O dtb -o spidev-1.dtbo spidev-1.dts

And added it to /boot/extlinux/extlinux.conf that now reads :

LABEL an Arch Arm
KERNEL /boot/Image
FDT /boot/dtbs/amlogic/meson-g12a-radxa-zero.dtb
FDTOVERLAYS overlay-user/spidev-1.dtbo overlay-user/i2c-3.dtbo
APPEND initrd=/boot/initramfs-linux.img root=LABEL=anArchArm rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 loglevel=5

But there’s still no file named /dev/spidev* in the system. I have logs from u-boot showing it loaded all bootfiles successfuly :

Found /boot/extlinux/extlinux.conf
Retrieving file: /boot/extlinux/extlinux.conf
1:	an Arch Arm
Retrieving file: /boot/initramfs-linux.img
Retrieving file: /boot/Image
append: initrd=/boot/initramfs-linux.img root=LABEL=anArchArm rw console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 loglevel=5
Retrieving file: /boot/dtbs/amlogic/meson-g12a-radxa-zero.dtb
Retrieving file: /boot/overlay-user/spidev-1.dtbo
Retrieving file: /boot/overlay-user/i2c-3.dtbo
Moving Image from 0x8080000 to 0x8200000, end=aa20000
## Flattened Device Tree blob at 08008000
   Booting using the fdt blob at 0x8008000
   Loading Ramdisk to 3f8ff000, end 3fffffae ... OK
   Loading Device Tree to 000000003f8e8000, end 000000003f8fefff ... OK

Starting kernel ...

[    0.448653] SPI driver max3421-hcd has no spi_device_id for maxim,max3421
[    1.386667] dwc2 ff400000.usb: supply vusb_d not found, using dummy regulator
[    1.388283] dwc2 ff400000.usb: supply vusb_a not found, using dummy regulator
[    1.569981] meson-drm ff900000.vpu: Couldnt bind all components
[    3.204832] using random self ethernet address
[    3.204849] using random host ethernet address
[    3.210777] using random self ethernet address
[    3.221832] using random host ethernet address
[    3.310533] systemd-journald[276]: File /var/log/journal/43b6ee3e3a1e4b63be769a8899ad9256/system.journal corrupted or uncleanly shut down, renaming and replacing.
[    4.267421] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[    4.778369] debugfs: Directory 'ff800280.cec' with parent 'regmap' already present!
[    4.921118] meson_vdec: module is from the staging directory, the quality is unknown, you have been warned.
[    5.007951] panfrost ffe40000.gpu: error -ENODEV: dev_pm_opp_set_regulators: no regulator (mali) found
[    5.104684] brcmfmac mmc2:0001:1: Direct firmware load for brcm/brcmfmac43455-sdio.radxa,zero.bin failed with error -2
[    5.123829] brcmfmac mmc2:0001:1: Direct firmware load for brcm/brcmfmac43455-sdio.radxa,zero.txt failed with error -2
[    5.277992] hci_uart_bcm serial0-0: supply vbat not found, using dummy regulator
[    5.309954] hci_uart_bcm serial0-0: supply vddio not found, using dummy regulator
[    5.384331] kauditd_printk_skb: 24 callbacks suppressed
[    5.678762] Bluetooth: hci0: BCM: firmware Patch file not found, tried:
[    5.678776] Bluetooth: hci0: BCM: 'brcm/BCM4345C0.radxa,zero.hcd'
[    5.678779] Bluetooth: hci0: BCM: 'brcm/BCM4345C0.hcd'
[    5.678783] Bluetooth: hci0: BCM: 'brcm/BCM.radxa,zero.hcd'
[    5.678785] Bluetooth: hci0: BCM: 'brcm/BCM.hcd'

Nope. Syslinux doesn’t have support for dt overlay parameters at the moment. You have to bake everything into the overlay. In the case of the spidev overlay, I would use this one: https://github.com/radxa/kernel/blob/linux-5.10.y-radxa-zero/arch/arm64/boot/dts/amlogic/overlay/meson-g12a-spi-spidev.dts

I know the wiki mentions parameters but if you look at the overlay, there’s no mechanism in there for variables or dynamic parameters.

All right, that settles a few things, thank you !

I was able to load successfully the dtbo object made from the dts file you mention. I’m running the latest Ubuntu server image from radxa.com (namely radxa-zero-ubuntu-focal-server-arm64-20221001-0438-mbr.img), to make sure I have something people know of.

On the booted system still no spidev file in /dev. There should be one, right ? I did modprobe spidev in case this module was needed, I’m not even sure of that.

I found that /sys/firmware/devicetree/base/aliases/spi1 contained the address /soc/bus@ffd00000/spi@15000, and tried :

$ cat /sys/firmware/devicetree/base/soc/bus@ffd00000/spi@13000/status
disabled

But that file is read-only. If the param_spidev_spi_bus=0 in uEnv.txt is useless, how do you activate the SPI interface then ?

I’m just a little surprised that the param_* uEnv.txt parameters are unused. Even Armbian docs mention it. And countless posts on this forum.

Found it !

It’s the meson-fixup script that’s responsible for the parameter substitution :

$ cat /boot/dtbs/5.10.69-13-amlogic-g104342c59952/amlogic/overlay/meson-fixup.scr
��������x# overlays fixup script
# implements (or rather substitutes) overlay arguments functionality
# using u-boot scripting, environment variables and "fdt" command

if test -n "${param_spidev_spi_bus}"; then
	test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "soc/bus@ffd00000/spi@13000"
	test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "soc/bus@ffd00000/spi@15000"
	test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "soc/bus@ffd00000/spi@14000"
	fdt set /${tmp_spi_path} status "okay"
	fdt set /${tmp_spi_path}/spidev status "okay"
	if test -n "${param_spidev_max_freq}"; then
		fdt set /${tmp_spi_path}/spidev@0 spi-max-frequency "<${param_spidev_max_freq}>"
	fi
	if test "${param_spidev_spi_cs}" = "1"; then
		fdt set /${tmp_spi_path}/spidev reg "<1>";
	fi
fi

My uEnv.txt file had the wrong overlay_prefix value, which made u-boot’s boot.scr script fail to load that fixup. Now that I’ve set this right, I do get the /dev/spidev0 device file.

To anyone ending down here and wondering if they have the same problem, you need to attach a serial console and check for fixup load errors in U-Boot startup.

Very nice! Does your u-boot load both extlinux.conf and this fixup script?

Well, no, I think u-boot chooses. It always prefers extlinux.conf over boot scripts. They say extlinux.conf is the future, mostly because it’s simpler. I agree, it’s just that DT overlay parameters seem unavoidable ATM. So I suppose they mean that the future is writing more micro-overlays just to say “activate that device”. BTW I found something missing in the dts I gave earlier ; on a working system the &spicc1 node also is status = "okay". So it now reads :

/dts-v1/;
/plugin/;

&spicc1 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	spidev@0 {
		compatible = "spidev";
		status = "okay";
		spi-max-frequency = <8000000>;
        reg = <0>;
	};
};

and I could see on the serial console that it loads fine with both boot processes. But the device is still not there. So I understand the full process but it still fails.

Anyway the question on device-tree overlay parameters is solved.

Well, no, I think u-boot chooses. It always prefers extlinux.conf over boot scripts.

Right! Or am I the only person who cannot boot the latest radxa ubuntu images until their defect extlinux.conf is removed, so that boot.scr gets loaded and uEnv.txt configuration actually applied?

Sorry to reply to this old thread, but I’m experiencing the very same issue.

@la_fleur, did you end up getting SPI to work? If so, how?

Hi ! Yes, using the Radxa kernel, I compiled the DT overlay source above (with the added status = "okay"; line in &spicc1) and had it to load with the extlinux config at the top of this thread. You should see a file at /dev/spidev1,0 on the booted RZ, linking to SPI_B GPIO.

To have access to SPI_A, replace spicc1 with spicc0 in the overlay source file.

Hope that’s clear enough. You tell me !