Jump to content

https://forum.armbian.com/topic/12227-rockpi-4-spi/RockPI 4 SPI


Marko Buršič

Recommended Posts

On 12/16/2019 at 6:27 PM, Marko Buršič said:

And it was working OK. IMO, the good candidate for CS1 is GPIO4_D5 to get SPI1.1 device. So please, don't mess things that are already working properly. I don't understand why user @p-i-u.de messed up with renumbering the SPI channels and it gets /dev/spidev0.0 , SPI0 is already shared with ETH-PHY on RockPi 4.

 

I don't mess something up,  the DTBO which is provided in this post brings up spidev0.1, I just try to help @martinayotte to get the cs-gpio kernel patch to work to help testing the patch with real hardware, that's all.  With this you can have a SPI Bus and multiple GPIOs as chipselect so in other words use more than SPI Device on a single bus. As SPI Devices are common in the industrial field this would enhance the rockchip a lot.

 

Link to comment
Share on other sites

2 hours ago, p-i-u.de said:

I just try to help @martinayotte to get the cs-gpio kernel patch to work to help testing the patch with real hardware

I'm still working on that ! I've just doing a new build with more traces since I got the following error which is a complete "non-sense" since /cpus/cpu@1 is NOT a gpio-controler, and all gpio-controlers have their #gpio-cells property :

[77657.634284] OF: /spi@ff1d0000: could not get #gpio-cells for /cpus/cpu@1
[77657.634295] rockchip-spi ff1d0000.spi: Failed to register master
[77657.634389] rockchip-spi: probe of ff1d0000.spi failed with error -22

EDIT: I think I figured it out : argument os "cs-gpio" is not <gpiobank_number pin_number active_low> but <gpioctl_phandle pin_number active_low> !

So, when I was passing gpiobank_number as 3, 3 was the phandle of /cpus/cpu@1, so, of course, not related ...

Since gpioctl_phandle could vary from one image to another, I can't hard coded in an overlay, I need to figure out a nice way to have such overlay.

Link to comment
Share on other sites

Got it working. I have changed the main .dtb file, but who knows it could be stripped to .dtbo as plugin, since I have manually added phandles, so not best suitable if the software gets updated.

 

The main added nodes are as follows:

 

1. In the pinctrl/spi1 node is added a subnode of definition of GPIO pin spi1/spi1-cs1 0x04 means GPIO4 conteller, 0x1a means pin D2 (therefore GPIO4_D2),  0x00 means a common GPIO (not linked to special functions), 0xb0 means no pull-up/down configured.  A phandle of 0x302 is added by myself manually, I guess a dtbo overlay could do it symbolically.

spi1 {

            spi1-clk {
                rockchip,pins = < 0x01 0x09 0x02 0xb3 >;
                phandle = < 0x4e >;
            };

            spi1-cs0 {
                rockchip,pins = < 0x01 0x0a 0x02 0xb3 >;
                phandle = < 0x51 >;
            };

            spi1-rx {
                rockchip,pins = < 0x01 0x07 0x02 0xb3 >;
                phandle = < 0x50 >;
            };

            spi1-tx {
                rockchip,pins = < 0x01 0x08 0x02 0xb3 >;
                phandle = < 0x4f >;
            };
            spi1-cs1 {
                rockchip,pins = < 0x04 0x1a 0x00 0xb0 >;
                phandle = < 0x302 >;
            };

 

2.  In spi1 controller node (spi@ff1d0000) is added a reference to new CS pin : cs-gpios = <0>, <0x16 0x1a 0x00>; Where <0> is found working experimental, I have no idea what's its meaning, but changing this to <1> throws exception of IRQ, probably links the pin to IRQ controller.  0x16 is a handle to GPIO4 controller, 0x1a is a pin number D2 (so, GPIO4_D2) , 0x00 means ACTIVE_HIGH.

 

Spidev@0 works on hardware CS0 which is GPIO1_B2 (reg=<0>) , meanwhile the spidev@1 works with cs-gpios, GPIO4_D2 (reg=<1>). If enabled flash it would work with CS0, my LCD is still in research phase.

 

I got spidev1.0 and spidev1.1, traced the functionality with DSO, they both seems to work. It has to have newer kernel (mine 5.4.38) and kernel patched with add-csgpio-to-rockchip-spi.patch, the one provided by @martinayotte published in this post.

spi@ff1d0000 {
        compatible = "rockchip,rk3399-spi\0rockchip,rk3066-spi";
        reg = < 0x00 0xff1d0000 0x00 0x1000 >;
        clocks = < 0x08 0x48 0x08 0x15c >;
        clock-names = "spiclk\0apb_pclk";
        interrupts = < 0x00 0x35 0x04 0x00 >;
        dmas = < 0x49 0x0c 0x49 0x0d >;
        dma-names = "tx\0rx";
        pinctrl-names = "default";
        pinctrl-0 = < 0x4e 0x4f 0x50 0x51 0x302>;
        #address-cells = < 0x01 >;
        #size-cells = < 0x00 >;
        status = "okay";
        phandle = < 0xda >;
        cs-gpios = <0>, <0x16 0x1a 0x00>;

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

        spidev@1 {
            compatible = "rockchip,spidev";
            reg = <1>;
            status = "okay";
            spi-max-frequency = < 0x989680 >;
        };

        spiflash@0 {
            compatible = "jedec,spi-nor";
            reg = < 0x00 >;
            spi-max-frequency = < 0x989680 >;
            status = "disabled";
        };
        mytft:mytft@0{
            compatible = "solomon,ssd1322";
            reg = <1>;
            pinctrl-names = "default";
            pinctrl-0 = <0x300 0x301>;
            spi-max-frequency = <1000000>;
            buswidth = <8>;
                    rotate = <0>;
                    bgr = <0>;
                    fps = <20>;
            dc-gpios = <0x16 0x1c 0x00>; // phandle to gpio4=0x16 , pin Nr = D4=0x1c, GPIO_ACTIVE_HIGH = 0x00 
            reset-gpios = <0x16 0x1d 0x00>;    // phandle to gpio4=0x16 , pin Nr = D5=0x1d, GPIO_ACTIVE_HIGH = 0x00 
            debug = <0>;
            status = "disabled";
            };


    };

 

rk3399-rock-pi-4.dts

Link to comment
Share on other sites

Hello, thank you for figuring out how to add the CS-gpio.
I saw a recent work here https://patchwork.kernel.org/project/spi-devel-general/patch/20210621104848.19539-1-jon.lin@rock-chips.com/ which seems to go in the same direction. Do you think it has the same functionality as your patch? 

Is there a way to find a precompiled kernel with your patch or I need to compile it myself?

 

I have a windows workstation with Hyper-V enabled which apparently does not let me install a VirtualBox and the compile.sh script does not seem to like WSL2. So I wanted to ask before diving into this.

 

Link to comment
Share on other sites

Am 14.12.2021 um 09:05 schrieb usual user:

The patch  has been applied for some time, so it should be available out of the box on every kernel version starting with 5.14.0.

with the "linux-image-edge-rockchip64 5.15.5" the spidev overlay does not work at all (no spidev device in /dev) on my rock pi 4b+. So I guess my only option is to rebuild with the current kernel (5.10.63)
 

Link to comment
Share on other sites

2 hours ago, rockynewenthusiast said:

with the "linux-image-edge-rockchip64 5.15.5" the spidev overlay does not work at all

I don't know which overlay you're using, but at least the rockpro-spidev1-1.dts that @martinayotte provides in this thread doesn't match the mainline binding.

Mainline binding is cs-gpios. Other aspects I have not verified.

Link to comment
Share on other sites

vor 18 Stunden schrieb usual user:

I don't know which overlay you're using, but at least the rockpro-spidev1-1.dts that @martinayotte provides in this thread doesn't match the mainline binding.

Mainline binding is cs-gpios. Other aspects I have not verified.

I'm trying to use the default overlay which is build with the armbian images. In my case if I understand correctly the overlays will be taken from the patch:
https://github.com/armbian/build/blob/master/patch/kernel/archive/rockchip64-5.10/general-rockchip-overlays.patch (Line 359)
arch/arm64/boot/dts/rockchip/overlay/rockchip-spi-spidev.dts
and modify it with the changes @Marko Buršič made in order to get the spidev1.1 working.
The overlay framework is new to me, I was hoping not to have to go so deep into the embedded configurations.

Link to comment
Share on other sites

The overlay I am trying to apply now looks like this:
 

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3399";
    fragment@0 {
        target-path = "/spi@ff1d0000";
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            cs-gpios = <0>, <0x16 0x1d 0x00>;
            status = "okay";
           spidev@0 {
                 compatible = "rockchip,spidev";
                 reg = <0>;
                 status = "okay";
                 spi-max-frequency = < 0x989680 >;
            };
           spidev@1 {
                 compatible = "rockchip, spidev";
                 status = "okay";
                 reg = <1>;
                 spi-max-frequency = <10000000>;
            };
           spiflash@0 {
                compatible = "jedec,spi-nor";
                reg = < 0x00 >;
                spi-max-frequency = < 0x989680 >;
                status = "disabled";
            };
        };
    };
};

 

Can you please point help out figuring what I did not get right ?

Link to comment
Share on other sites

3 hours ago, rockynewenthusiast said:
cs-gpios = <0>, <0x16 0x1d 0x00>;

A mainline property name is choosen here, but a u32 value is given as a phandle. So I can't say what kind of node this will point to in the dtb to which this overlay is applied. Phandle values are assignd randomly and may change if the node structure changes by e.g. enabling or disabling a node.
Also, the choosen gpio line is different from the one @martinayotte seems to use and I can't even say if any of them fit your wiring at all.

Link to comment
Share on other sites

Since I never used spidev as a client driver, I wrote rk3399-nanopc-t4-spi.dts out of curiosity for my education:

Spoiler
/dts-v1/;
/plugin/;

/ {
        compatible = "friendlyarm,nanopc-t4";
};

&{/spi@ff1d0000} { /* &spi1 */
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";
        cs-gpios = <0x00>, <&{/pinctrl/gpio@ff790000} 0x15 0x01>;   /* <&gpio4 RK_PC5 GPIO_ACTIVE_LOW>; */

        spidev@0 {
                compatible = "rohm,dh2228fv";
                reg = <0>;
                spi-max-frequency = <10000000>;
        };

        spidev@1 {
                compatible = "lineartechnology,ltc2488";
                reg = <1>;
                spi-max-frequency = <10000000>;
        };
};

 

I used the "absolute path" notation because this requires the least preconditions of the base DTB for its addition. Only the node names of the references must match and can be checked by a simple decompilation of the base DTB if necessary.
Mainline DTC can compile this DTS to a DTBO. But the devicetree framework unfortunately lacks support for full path notion for a reference to another node in a cell array.

With this patch in place the DTBO can be staticly applied.

Running my SBC with rk3399-nanopc-t4-spi.dtb where the overlay is applied via:

fdtoverlay --input rk3399-nanopc-t4.dtb --output rk3399-nanopc-t4-spi.dtb rk3399-nanopc-t4-spi.dtbo

gives me /dev/spidev0.0 and /dev/spidev0.1. The extention connector pin 26 is aquired as CS1 for spi0:

Spoiler
gpiochip4: GPIOs 128-159, parent: platform/ff790000.gpio, gpio4:
 gpio-128 (                    )
 gpio-129 (                    )
 gpio-130 (                    )
 gpio-131 (                    )
 gpio-132 (                    )
 gpio-133 (                    )
 gpio-134 (                    )
 gpio-135 (                    )
 gpio-136 (                    )
 gpio-137 (                    )
 gpio-138 (                    )
 gpio-139 (                    )
 gpio-140 (                    )
 gpio-141 (                    )
 gpio-142 (                    )
 gpio-143 (                    )
 gpio-144 (con1-10             )
 gpio-145 (con1-08             )
 gpio-146 (                    )
 gpio-147 (                    )
 gpio-148 (                    )
 gpio-149 (con1-26             |spi0 CS1            ) out hi ACTIVE LOW
 gpio-150 (                    )
 gpio-151 (                    )
 gpio-152 (                    )
 gpio-153 (                    )
 gpio-154 (                    |vbus-typec          ) out hi
 gpio-155 (                    )
 gpio-156 (                    |Headphone detection ) in  hi
 gpio-157 (                    )
 gpio-158 (                    )
 gpio-159 (                    )

 

You can also use the "label" notation for the overlay DTS, see the comments in my DTS for reference. But this requires a base DTS with matching labels and the base DTB build with the --symbols option. The DTBO can be applied staticly or dynamicly without further patches for the devicetree framework. But it is not guaranteed that a base DTB with an identical label references the same place as the overlay.

 

On 12/16/2021 at 12:14 PM, rockynewenthusiast said:
compatible = "rockchip, spidev";

While I experimented with your client compatible values, I noticed that these are meaningless values and do not reference valid client drivers.

Link to comment
Share on other sites

Hey all!

 

I'm trying to use cs-gpios on a Rock Pi 4B on SPI channel 2, but I have a couple of issues.

Status quo: I'm running an Armbian kernel version 5.10.63, so I assume all required patches should have been applied.

I'm using the following overlay, to both (1) enable SPI 2 and (2) define two GPIOs as CS signals (namely GPIO3_C0 and GPIO4_D6):

 

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3399";
    fragment@0 {
        target-path = "/spi@ff1e0000";
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            cs-gpios = <&gpio3 16 1>, <&gpio4 30 1>;
            status = "okay";
            spidev@0 {
                 compatible = "spidev";
                 status = "okay";
                 reg = <0>;
                 spi-max-frequency = <10000000>;
            };
            spidev@1 {
                 compatible = "spidev";
                 status = "okay";
                 reg = <1>;
                 spi-max-frequency = <10000000>;
            };
        };
    };
};

 

I add the overlay using armbian-add-overlay and I confirmed it is loaded via U-Boot output. I also get corresponding messages in the Kernel log and two SPI devices in Linux:

 

[    3.118032] spi:spi_register_controller: rockchip-spi ff1e0000.spi: registered master spi2
[    3.118265] spi:spi_setup: spi spi2.1: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[    3.119331] spi:spi_add_device: rockchip-spi ff1e0000.spi: registered child spi2.1
[    3.119412] spi:spi_setup: spi spi2.0: setup mode 0, 8 bits/w, 10000000 Hz max --> 0
[    3.120415] spi:spi_add_device: rockchip-spi ff1e0000.spi: registered child spi2.0

 

> ls /dev/spi*
/dev/spidev2.0  /dev/spidev2.1

 

Note, that I enabled additional debug output via dyndbg, so I might have addional messages in my dmesg output that are not "standard".

So far so good.

 

Next, I tested the configuration using spi_test in loopback mode like so:

sudo ./spidev_test --device /dev/spidev2.0 -S 2 --iter 99999 --speed 10000
sudo ./spidev_test --device /dev/spidev2.1 -S 2 --iter 99999 --speed 10000

 

And here the problems start:

 

(1) I noticed, testing spidev2.0, that the hardware CS pin, GPIO2_B4 (aka SPI2_CSn0) toggles inverted to the chip select signal of spidev@0, namely GPIO3_C0, i.e. whenever GPIO3_C0 goes low, GPIO2_B4 goes high and vice-versa. This does not seem to happen if I use spidev@1, aka /dev/spidev2.1. Is this known/intended behaviour? If not, how do I fix it?

(2) I also tried to use the hardware chipselect pin, GPIO2_B4 together with a GPIO pin as chip select, i.e.:

cs-gpios = <0>, <&gpio3 16 1>;

This configuration resulted in spidev2.0 working as expected, but when testing spidev2.1 I got the following error message:

spi mode: 0x4
bits per word: 8
max speed: 10000 Hz (10 kHz)
can't send spi message: Connection timed out

and the following lines were logged to dmesg:

[  326.295637] spidev spi2.1: SPI transfer timed out
[  326.296133] spi_master spi2: failed to transfer one message from queue

What is the issue here? Posts by @martinayotte, @Marko Buršič, and @p-i-u.de made me think that this mode of operation was supported. Or am I still missing kernel patches?

 

I also tried the method of @Marko Buršič adding a spi2_cs1 and then extending pinctrl-0 of spi2 like so:

/dts-v1/;
/plugin/;

/ {
    compatible = "rockchip,rk3399";
    fragment@0 {
        target-path ="/pinctrl/spi2";
        __overlay__ {
             spi2_cs1: spi2-cs1 {
				rockchip,pins = <0x03 0x16 0x02 &pcfg_pull_up>;
	     };
       };
    };
    fragment@1 {
        target-path = "/spi@ff1e0000";
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;
            cs-gpios = <0>, <&gpio3 16 1>;
            pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0 &spi2_cs1>;
            status = "okay";
            spidev@0 {
                 compatible = "spidev";
                 status = "okay";
                 reg = <0>;
                 spi-max-frequency = <10000000>;
            };
            spidev@1 {
                 compatible = "spidev";
                 status = "okay";
                 reg = <1>;
                 spi-max-frequency = <10000000>;
            };

        };
    };
};

But that had the same result of spidev2.0 working and spidev2.1 failing with the "Connection timed out" error message.

 

Does anyone have any suggestion what the issue(s) might be?

 

Thanks in advance!

Link to comment
Share on other sites

So, I got 5.15.18 working (it had an unrelated error in which the included wifi-driver for rtl8821cu was not working for me, so I needed an out-of-tree driver).

 

Good news is that the "Connection timed out"-error disappeared. However the issue remained that the hardware chipselect SPI2_CSn0 on pin GPIO2_B4 continued to toggle regardless if I used spidev2.0 or spidev2.1. This essentially means that

cs-gpios = <0>, <&gpio3 16 1>;

will not work, since the device on CS0 is always selected. The only way I see this working is something like this:

cs-gpios = <&gpio3 16 1>, <gpio4, 30 1>;

and then leaving pin GPIO2_B4 unused and open, thus wasting a pin.

 

Also recognize the significance of @usual user's statement:

Zitat

While I experimented with your client compatible values, I noticed that these are meaningless values and do not reference valid client drivers.

In earlier kernel version you got an error when you used meaningless values but things continued to work. This is not the case anymore in at least 5.15.18. You will not get a device like /dev/spidevX.Y! You will have to enter a valid client driver, however pointless it seems, given that you're not going to use an in-kernel driver. There should exist a dummy value for device node to be created when you want to use userspace drivers. Instead, people are now going to use

compatible = "rohm,dh2228fv";

instead of

compatible = "spidev";

I'm not sure that is going to make things better. But that is another discussion …

 

I have to conclude that cs-gpios does not really work with the Rock Pi hardware (as far as I understand the TRM you have to select either hardware chip select 0 or 1 and the selected line will toggle.)

Instead I'm going to use an external mux and use spi-mux instead.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines