Radxa CM3 sodimm + enc28j60

Hello everyone!
I have a trouble communicating with enc28j60 from a CM3 sodimm module:

  • CM3 is running Radxa Ubuntu 22.04.2 LTS (GNU/Linux 4.19.193-3-rk356x aarch64)
  • CM3 is placed in a custom board (replacing RPI CM3) with soldered enc28j60, spi lanes are routed to DIMM socket pins 27, 29, 33, 35 (GPIO4_A6 GPIO4_B0 GPIO4_B2 GPIO4_B3 ), interrupt lane is routed to pin 83 (GPIO0_C5)
  • There is no pre-built DT overlay for such configuration, so out-of-the-box it does not work ((

Using dtс I decompiled rk3568-spi3-m1-cs0-enc28j60.dtbo and rk3568-spi3-m0-cs0-spidev.dtbo and built my own radxa-cm3-sodimm-io-enc28j60-spi3-m0-cs0.dts :

/dts-v1/;

/ {

    metadata {
            title = "Enable ENC28J60 on SPI3-M0 CS0";
            compatible = "radxa,radxa-cm3-sodimm-io";
            category = "misc";
            exclusive = "GPIO4_B3\0GPIO4_B2\0GPIO4_B0\0GPIO4_A6\0GPIO0_C5";
            description = "Enable Microchip ENC28J60 SPI Ethernet controller on SPI3-M0 CS0.\nINT=22";
    };

    fragment@0 {
            target = <0xffffffff>;

            __overlay__ {
                    status = "okay";
                    #address-cells = <0x01>;
                    #size-cells = <0x00>;
                    pinctrl-names = "default\0high_speed";
                    pinctrl-0 = <0xffffffff 0xffffffff>;
                    pinctrl-1 = <0xffffffff 0xffffffff>;
                    max-freq = <0x2faf080>;

                    enc28j60@0 {
                            compatible = "microchip,enc28j60";
                            reg = <0x00>;
                            spi-max-frequency = <0x1312d00>;
                            pinctrl-names = "default";
                            pinctrl-0 = <0x01>;
                            interrupt-parent = <0xffffffff>;
                            interrupts = <0x11 0x02>;
                            phandle = <0x02>;
                    };
            };
    };

    fragment@1 {
            target = <0xffffffff>;

            __overlay__ {

                    enc28j60 {

                            enc28j60-int-pins {
                                    rockchip,pins = <0x03 0x15 0x00 0xffffffff>;
                                    phandle = <0x01>;
                            };
                    };
            };
    };

    __symbols__ {
            ethernet = "/fragment@0/__overlay__/enc28j60@0";
            enc28j60_int_pins = "/fragment@1/__overlay__/enc28j60/enc28j60-int-pins";
    };

    __fixups__ {
            spi3 = "/fragment@0:target:0";
            spi3m0_cs0 = "/fragment@0/__overlay__:pinctrl-0:0\0/fragment@0/__overlay__:pinctrl-1:0";
            spi3m0_pins = "/fragment@0/__overlay__:pinctrl-0:4";
            spi3m0_pins_hs = "/fragment@0/__overlay__:pinctrl-1:4";
            gpio3 = "/fragment@0/__overlay__/enc28j60@0:interrupt-parent:0";
            pinctrl = "/fragment@1:target:0";
            pcfg_pull_none = "/fragment@1/__overlay__/enc28j60/enc28j60-int-pins:rockchip,pins:12";
    };

    __local_fixups__ {

            fragment@0 {

                    __overlay__ {

                            enc28j60@0 {
                                    pinctrl-0 = <0x00>;
                            };
                    };
            };
    };

};

The resulting dtbo is loaded OK, the kernel module is loaded also, saying

[ 5.740330] enc28j60 spi3.0: enc28j60 Ethernet driver 1.02 loaded
[ 5.746126] net eth0: enc28j60 driver registered

and device is present in the system:

2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether f6:6a:e5:64:6f:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.1.101/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever

But there is no ethernet communication over eth0, and actually, while eth0 is up, USB ethernet (eth1) is also unresposive.

My guess is that interrupt lane is misconfigured in my dtbo, but i cannot figure out, how to calculate the correct value.

I would greatly appreciate any help on that issue. Thanks in advance! ))

Try taking the dts file from GitHub rather than using the decompiled option and see if that makes a difference.

Thank you for reply, I used that dts as a reference, but it is used for enc28j60 on spi3-m1-cs0, and my board is fixed for it on spi3-m0-cs0. Are you sure that enc28j60-int-pins from original dts will be the same?
If not, then what value should I use for
enc28j60-int-pins {rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>}
in order to make it use GPIO0_C5 (sodimm pin 83)?

No best check. You can readily change this to suit your design.

interrupt-parent = <&gpio3>;
interrupts = <RK_PC1 IRQ_TYPE_EDGE_FALLING>;

That dts has interrupt pin set at GPIO3_C1 (pin 8 on the J1 100 pin connector).

Similarly, you’ll also need to change this to point to the correct m0 pins

	pinctrl-0 = <&spi3m1_cs0 &spi3m1_pins>;
	pinctrl-1 = <&spi3m1_cs0 &spi3m1_pins_hs>;

Thanks, GoGerriko, got it working. If anyone needs, here is a modified overlay for connecting enc28j60 just the same way (pin-to pin), as for RPI :

cat ./radxa-cm3-sodimm-io-spi3-m0-cs0-enc28j60.dts
/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/interrupt-controller/irq.h>

/ {
metadata {
title = “Enable ENC28J60 on SPI3-M1 CS0”;
compatible = “radxa”, “radxa-cm3-sodimm-io”;
category = “misc”;
exclusive = “GPIO4_B3”, “GPIO4_B2”, “GPIO4_B0”, “GPIO4_A6”, “GPIO0_C5”;
description = “Enable Microchip ENC28J60 SPI Ethernet controller on SPI3-M0 CS0.\nINT=22”;
};

    fragment@0 {
            target = <&spi3>;
            __overlay__ {
                    status = "okay";
                    #address-cells = <1>;
                    #size-cells = <0>;
                    pinctrl-names = "default", "high_speed";
                    pinctrl-0 = <&spi3m0_cs0 &spi3m0_pins>;
                    pinctrl-1 = <&spi3m0_cs0 &spi3m0_pins_hs>;
                    max-freq = <50000000>;

                    ethernet: enc28j60@0 {
                            compatible = "microchip,enc28j60";
                            reg = <0>;
                            spi-max-frequency = <20000000>;

                            pinctrl-names = "default";
                            pinctrl-0 = <&enc28j60_int_pins>;

                            interrupt-parent = <&gpio0>;
                            interrupts = <RK_PC5 IRQ_TYPE_EDGE_FALLING>;
                    };
            };
    };

    fragment@1 {
            target = <&pinctrl>;
            __overlay__ {
                    enc28j60 {
                            enc28j60_int_pins: enc28j60-int-pins {
                                    rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
                            };
                    };
            };
    };

};

1 Like