What shall I set for enc28j60 on Altera C5 for spi

I want to use the enc28j60, which communicates over spi. I’ve tried to test the usage with rpi and it was ok. Now I want to set it with a rocketboarb Linux for Altera Cyclone V, actually it has a different driver(dts). Our last configuration state:

preloader file socfpfa_common.c:

int board_early_init_f(void)
{

writel(3,SYSMGR_PINMUXGRP_GENERALIO(9)); /* SPIM0_CLK /
writel(3,SYSMGR_PINMUXGRP_GENERALIO(10)); /
SPIM0_MOSI /
writel(3,SYSMGR_PINMUXGRP_GENERALIO(11)); /
SPIM0_MISO /
writel(3,SYSMGR_PINMUXGRP_GENERALIO(12)); /
SPIM0_SS0 /
writel(0,SYSMGR_PINMUXGRP_GENERALIO(13)); /
SPIM INT */

dts file

&spi0 {
status = “okay”;

device@0 {
    compatible = "enc28j60";
    /*spi-chipselect = <0>;*/
    reg = <0>;    /* chip select 0 */
    spi-max-frequency = <12000000>;
    enable-dma = <1>;
};

};

Have somebody experience with SPI and explain me how can I find what am I missing, or where sould I look for a list of dts parameters. I use dizzy:

I have a small succes, I’ve found that a used kernel is not the youngest one. Second I will start just with a spi master.
My dts file looks now:

spi0: spi@fff00000 {
compatible = “snps,dw-apb-ssi”;
reg = <0xfff00000 0x1000>;
interrupts = <0 154 4>;
#address-cells = <1>;
#size-cells = <0>;
num-cs = <1>;
bus-num = <0>;
tx-dma-channel = <&pdma 16>;
rx-dma-channel = <&pdma 17>;
clocks = <&spi_m_clk>;
cs-gpios = <&gpio0 13 0>;

    spidev@0 {
            compatible = "spidev";
            reg = <0>;    /* chip select */
            spi-max-frequency = <12000000>;
            enable-dma = <0>;
        };


And it produces now a following error during a a startup:

/soc/spi@fff00000: could not get #gpio-cells for /soc/gpio@ff708000
/soc/spi@fff00000: could not get #gpio-cells for /soc/gpio@ff708000
spi_master (null): problem registering spi master
dw_spi_mmio: probe of fff00000.spi failed with error -22

What does it mean “could not get #gpio-cells for /soc/gpio@ff708000”?

    /* Basic HW init */
    spi_hw_init(dws);

    ...
    tasklet_init(&dws->pump_transfers, pump_transfers, (unsigned long)dws);
    spi_master_set_devdata(master, dws);
    ret = devm_spi_register_master(dev, master);
    if (ret) {
            dev_err(&master->dev, "problem registering spi master\n");
            goto err_dma_exit;
    }
    ...

I’ve now driver runing with an “ok” dump, but I don’t see anything in /proc/iomem. Why?
I see device now: /dev/spidev0.0

 spi0: spi@fff00000 {
    compatible = "snps,dw-apb-ssi";
    reg = <0xfff00000 0x1000>;
    interrupts = <0 154 4>;
    #address-cells = <1>;
    #size-cells = <0>;
    num-cs = <4>;
    bus-num = <0>;
    tx-dma-channel = <&pdma 16>;
    rx-dma-channel = <&pdma 17>;
    clocks = <&spi_m_clk>;
    cs-gpios = <&portb 2 0>,<0>,<0>,<0>; /*it shall be port B pin 2 - GPIO60 */
                             

    spidev@0 {
            compatible = "spidev";
            reg = <0>;    /* chip select */
            spi-max-frequency = <12000000>;
            enable-dma = <0>;
        };
};

from spi-dw-mmio.c:

static int dw_spi_mmio_probe(struct platform_device *pdev)
{
    struct dw_spi_mmio *dwsmmio;
    struct dw_spi *dws;
    struct resource *mem;
    int ret;
    int num_cs;

    dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
        GFP_KERNEL);
    if (!dwsmmio)
    return -ENOMEM;

    dws = &dwsmmio->dws;

    /* Get basic io resource and map it */
    mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!mem) {
    dev_err(&pdev->dev, "no mem resource?\n");
    return -EINVAL;
    }

    dws->regs = ioremap_nocache(mem->start, resource_size(mem));
    dws->paddr = mem->start;
    if (!dws->regs) {
    dev_err(&pdev->dev, "SPI region already mapped\n");
    return -ENOMEM;
    }

    dws->irq = platform_get_irq(pdev, 0);
    if (dws->irq < 0) {
    dev_err(&pdev->dev, "no irq resource?\n");
    return dws->irq; /* -ENXIO */
    }

    dwsmmio->clk = devm_clk_get(&pdev->dev, NULL);
    if (IS_ERR(dwsmmio->clk))
    return PTR_ERR(dwsmmio->clk);
    ret = clk_prepare_enable(dwsmmio->clk);
    if (ret)
    return ret;

    dws->bus_num = pdev->id;

    dws->max_freq = clk_get_rate(dwsmmio->clk);

    /*num_cs = 1;
    dws->num_cs = num_cs;*/
    num_cs = 4;

    if (pdev->dev.of_node)
    of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);

    dws->num_cs = num_cs;
    printk("half\n");

    if (pdev->dev.of_node) {
    int i;
    for (i = 0; i < dws->num_cs; i++) {
        printk("Loop %d\n", i); 
        printk("T1\n");
        int cs_gpio = of_get_named_gpio(pdev->dev.of_node,
                "cs-gpios", i);
        
        printk("T2 %d\n", cs_gpio);
        if (cs_gpio == -EPROBE_DEFER) {
            ret = cs_gpio;
            printk("G5\n");
            goto out;
        }

        printk("T3 %d\n", gpio_is_valid(cs_gpio));
        if (gpio_is_valid(cs_gpio)) {
            printk("T3.1\n");
            ret = devm_gpio_request(&pdev->dev, cs_gpio,
                    dev_name(&pdev->dev));
            if (ret) {
                printk("G6\n");
                goto out;
            }
        }
    }
    }
#ifdef CONFIG_SPI_DW_PL330_DMA
    ret = dw_spi_pl330_init(dws);
    if (ret) {
            printk("G7\n");
    goto out;
    }
#endif

    ret = dw_spi_add_host(&pdev->dev, dws);
    if (ret) {
            printk("G8\n");
    goto out;
    }

    platform_set_drvdata(pdev, dwsmmio);
    printk("ok\n");
    return 0;

out:
    clk_disable_unprepare(dwsmmio->clk);
    return ret;
}

boot messages:

    half
Loop 0
T1
T2 456
T3 1
T3.1
Loop 1
T1
T2 -2
T3 0
Loop 2
T1
T2 -2
T3 0
Loop 3
T1
T2 -2
T3 0
spi_master (null): W1
spi_master (null): W2
ok

I’ve simplified in the first step the SPI test just with a probes directly on SPI_CLK and SPI_MOSI. I don’t have the ENC28J60 yet connected. I assume on this pins some activity if I run a test program (see kernel source code doc/Documentation/spi/spidev_test.c). I don’t see any level changing. The SPI_CLK is on the GPIO57, the SPI_MOSI on the GPIO58. The settings of these pins is done in the function “board_early_init” (see above).

I did not yet reach a step to test ENC28J60. Before we have prooved it on the raspberrypi. But it is a little bit different HW => different settings.

Is there an easy way to read somehow from linux if the pins settings are configured? I assume the spi peripheral is OK, because I see it in the memory map:

root@gateway:~# cat /proc/iomem 
00000000-0dffffff : System RAM
   00008000-0067a06f : Kernel code
   006d0000-0074c333 : Kernel data
ff705000-ff705fff : ff705000.spi
ff708000-ff708fff : /soc/gpio@ff708000
ff709000-ff709fff : /soc/gpio@ff709000
ff70a000-ff70afff : /soc/gpio@ff70a000
ffa00000-ffa00fff : ff705000.spi
ffc00000-ffc00fff : c_can_platform
ffc01000-ffc01fff : c_can_platform
ffc03000-ffc0301f : serial
ffc04000-ffc04fff : /soc/i2c@ffc04000
ffd02000-ffd02fff : /soc/wd@ffd02000
ffe01000-ffe01fff : /soc/amba/pdma@ffe01000
fff00000-fff00fff : fff00000.spi
ffff0000-ffffffff : /soc/sram@ffff0000
root@gateway:~# ls -la /dev/spidev0.0 
crw-------    1 root     root      153,   0 Jan  1  1970 /dev/spidev0.0
root@gateway:~# ./spidev_test -D /dev/spidev0.0 
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF FF FF FF FF 
FF FF 

root@gateway:~# dmesg | grep spi
dw_spi_mmio fff00000.spi: master is unqueued, this is deprecated
spidev spi0.0: setup: unsupported mode bits 4