This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM4372: McSPI fails Moving from Linux 4.14 SDK to Yocto Thud Linux 4.19

Part Number: AM4372
Other Parts Discussed in Thread: SN65HVS882,

We are using the McSPI driver.  When we move from TI SDK Linux 4.14 to Yocto thud Linux 4.19, we get all zeros when reading from the SPI bus.  No errors.

We even tried using the original kernel defconfig and device tree binary that worked with the TI SDK and no errors, but it doesn't do anything.  Any ideas on where to look?  The SDK on 4.14 works fine.

  • We have scoped this, and loopback works over SPI with MISO MOSI tied together.

    Data coming from our device is all zeros.  So we are thinking chip select.

  • Hi John,

    I would suggest you to dump AM437x McSPI module and pinmux registers and compare the values between TI SDK Linux and Yocto thud Linux. You can also compare the McSPI driver code - spi-omap2-mcspi.c

    Note that we also have kernel 4.19 that comes with TI PSDK Linux, so you might also try with it.

    Regards,
    Pavel

  • I noticed a difference in the debug file system.  In the file:

    /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pins

    This is the old kernel which displays function and group:

    pin 84 (PIN84): 48030000.spi (GPIO UNCLAIMED) function pinmux_spi0_pins_default group pinmux_spi0_pins_default
    pin 85 (PIN85): 48030000.spi (GPIO UNCLAIMED) function pinmux_spi0_pins_default group pinmux_spi0_pins_default
    pin 86 (PIN86): 48030000.spi (GPIO UNCLAIMED) function pinmux_spi0_pins_default group pinmux_spi0_pins_default
    pin 87 (PIN87): 48030000.spi (GPIO UNCLAIMED) function pinmux_spi0_pins_default group pinmux_spi0_pins_default

    This is the new kernel which does not:

    pin 84 (PIN84) 44e10950 00050000 pinctrl-single
    pin 85 (PIN85) 44e10954 00010000 pinctrl-single
    pin 86 (PIN86) 44e10958 00050000 pinctrl-single
    pin 87 (PIN87) 44e1095c 00010000 pinctrl-single

    I am still looking at the response from Pavel.  Thanks.

  • John,

    Seems that your have different McSPI pinmux configuration in Yocto thud Linux 4.19. McSPI pinmux is done in kernel DTS file. I would suggest you to align your new DTS file with old one.

    For reference, you can also use AM437x IDK DTS file from latest PSDK LInux:

    linux-4.19.38/arch/arm/boot/dts/am437x-idk-evm.dts

    &spi1 {
        status = "okay";
        pinctrl-names = "default", "sleep";
        pinctrl-0 = <&spi1_pins_default>;
        pinctrl-1 = <&spi1_pins_sleep>;
        ti,pindir-d0-out-d1-in;

        sn65hvs882: sn65hvs882@0 {
            compatible = "pisosr-gpio";
            gpio-controller;
            #gpio-cells = <2>;

            load-gpios = <&gpio3 1 GPIO_ACTIVE_LOW>;

            reg = <0>;
            spi-max-frequency = <1000000>;
            spi-cpol;
        };
    };

    spi1_pins_default: spi1_pins_default {
            pinctrl-single,pins = <
                AM4372_IOPAD(0x908, PIN_INPUT | MUX_MODE2)    /* mii1_col.spi1_sclk */
                AM4372_IOPAD(0x910, PIN_INPUT | MUX_MODE2)    /* mii1_rx_er.spi1_d1 */
                AM4372_IOPAD(0x944, PIN_OUTPUT | MUX_MODE2)    /* rmii1_ref_clk.spi1_cs0 */
                AM4372_IOPAD(0x90c, PIN_OUTPUT | MUX_MODE7)    /* mii1_crs.gpio3_1 */
            >;
        };

        spi1_pins_sleep: spi1_pins_sleep {
            pinctrl-single,pins = <
                AM4372_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM4372_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM4372_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM4372_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE7)
            >;
        };

    What else I can suggest you is to dump McSPI pinmux register from userspace with devmem2 or omapconf tool.

    Regards,
    Pavel

  • We found the problem is partly in user space code that was compiled with arago that is working, versus code compiled with yocto thud.  The arago user-space code works on both arago 4.14 and thud 4.19 kernels on the same root otherwise.  I will try strace to see if I can find a difference.  I think the code is dynamically linked, so not sure what is happening.

    We found that using the same exact device tree, yocto thud kernel (4.19) spi data transfer is 13 times slower than 4.14 arago on the SPI data in/data out.  This was observed with a logic analyzer with the same board on the data lines.  I will add a clock test point next.   Next we will try building the 4.14 kernel using yocto to see if the performance issue persists.

    devmem2 does not work.  I have not tried to build omapconf yet.

    devmem2 output:

    mtcdt3:/opt/lora/gateway-utils# devmem2 0x48030000 w
    /dev/mem opened.[  297.239934] Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6ff9000
    [  297.248563] pgd = 2020de6c
    [  297.251294] [b6ff9000] *pgd=fc9ad831
    [  297.255022] ------------[ cut here ]------------
    [  297.259716] WARNING: CPU: 0 PID: 770 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x330/0x380
    ...

    From reverse compile:

    →       →       spi@48030000 {
    →       →       →       compatible = "ti,am4372-mcspi\0ti,omap4-mcspi";
    →       →       →       reg = <0x48030000 0x400>;
    →       →       →       interrupts = <0x00 0x41 0x04>;
    →       →       →       ti,hwmods = "spi0";
    →       →       →       #address-cells = <0x01>;
    →       →       →       #size-cells = <0x00>;
    →       →       →       status = "okay";
    →       →       →       dmas = <0x41 0x10 0x00 0x41 0x11 0x00>;
    →       →       →       dma-names = "tx0\0rx0";
    →       →       →       pinctrl-names = "default\0sleep";
    →       →       →       pinctrl-0 = <0x4e>;
    →       →       →       pinctrl-1 = <0x4f>;
    →       →       →       ti,spi-num-cs = <0x01>;
    →       →       →       ti,pindir-d0-out-d1-in;

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

  • John,

    Seems that McSPI0 module is not enabled in device PRCM, that is why devmem2 tool is not working fine. Please check below register value and compare between TI Linux and your Linux.

    PRCM_CM_PER_SPI0_CLKCTRL/0x44DF8D00

    Regards,
    Pavel

  • We don't know what you mean by:

    PRCM_CM_PER_SPI0_CLKCTRL/0x44DF8D00

    What file is this in?  Could you at least give a name?  We have never seen a syntax with the /.

  • John,

    PRCM_CM_PER_SPI0_CLKCTRL is register at address 0x44DF8D00. For details check AM437x TRM, ch6 PRCM.

    Regards,
    Pavel

  • Both kernels show the same results for address 0x44DF8D00.
    root@am437x-evm:/sys/kernel/debug# devmem2 0x44DF8D00 w
    /dev/mem opened.
    Memory mapped at address 0xb6f8c000.
    Read at address  0x44DF8D00 (0xb6f8cd00): 0x00030000

    mtcdt3:/home/mtadm# devmem2 0x44DF8D00 w
    /dev/mem opened.
    Memory mapped at address 0xb6f5c000.
    Read at address  0x44DF8D00 (0xb6f5cd00): 0x00030000

    The 4.14 arago kernel is much faster with the same working SPI test.

    Both fail when dumping address 0x48030000, the mcspi mux.

  • By monitoring 0x44DF8D00 I see that the spi device is being disabled then enabled.

    I finally probed the clocks of the two kernels.  The speed of the clock is the same, but their are longer intervals between data sets being transferred.

    So I will look at the kernel configuration next to see why on a system with no activity, we see such different speeds.

  • One more thing I noticed.  On the new kernel, there are long pauses of both the data and clock between each byte.  Chip selects last much longer.  That is why the performance is 13 times worse.

  • The extra long chip selects were only in certain cases in PIO mode.  We thought of profiling the kernel, but the TI SDK does not provide Brendan Gregg's perf, and we aren't sure how easy it would be to add.  We did profile the Yocto 4.19 kernel, since Yocto provides perf.

    We found that if DMA is on all the time, some of the worst cases get better, even when writing only 1-3 bytes at a time, however we found cases that some other PIO cases got slightly worse as well.  DMA transfers are the same speed with the old kernel and the new kernel.

    My suspicion is the new 4.19 driver is doing something inefficient when in PIO mode, but we are hoping those cases are not important, so we are leaving this issue for now.