BeagleY-AI: Anyone have overlay/.dts to enable McSPI2 at 50 MHz?

BeagleY-AI: Does anyone have an overlay/.dts for SPI2 (McSPI) working? One that runs at full 50 MHz speed? SPI2 is on hat pins 8,10,11,12,36 which is different from the standard “RPi compatible” bit-banged SPI0 on hat 19,21,23,24,26.

SPI0 works fine, as expected. But at 1.5 MHz max it is not competitive with BBx/BBAI/BBAI-64 which can run McSPI at 48 MHz no problem. I have 10,000 of those deployed in the field and would like to explore using BYAI. But the SPI speed problem needs to be solved.

If you build the 6.1 kernel the McSPI is enabled by default. So it should be just a matter of .dts magic to connect it up. And I have been unsuccessful so far.

Thank you.

This is what Copilot did in 5 seconds:

1 Like

Ha ha, NO. I’m not asking how to construct generic overlay boilerplate. /opt/source/dtb-6.1-Beagle/src/arm64/overlays has all of that you could ever want.

“Copilot” even tells you it’s not answering my question: “You’ll need to adjust the target and pin settings based on the specific hardware configuration and McSPI peripherals on Beagley-Al.” Well, that’s what I need to know. How can I get McSPI2 (&main_spi2) to show up as /dev/spidev2.x given that the existing bit-banged driver appears as /dev/spidev0.x

I’m not even worrying about the overlay aspect yet. I’ve been making changes directly to k3-am67a-beagley-ai.dts just trying to get things to work. No luck so far.

I would try and put spi2 = &main_spi2; inside the aliases clause.
That should move things around.

1 Like

Here’s my walkthrough of figuring out muxing for SPI6_CLK on the BBAI64

Somehow you’re going to have to find the mappings between SoC pads and board header pins. So in my instructions, for BBAI64, I have some spreadsheet. You’ll have to find some alternative source to get the mapping information.

wait…you could just use TI sysconfig and probably be fine. The reason you’ll want to dig into mappings would be to disable SoC pads that share board header pins. You probably can get away with skipping that step

1 Like

@lranders Thank you very much. I was missing that piece. However still doesn’t work.

@kevinacahalan Yes, I had developed something similar for the AI64 SPI6 some years ago. And it’s the basis for what I’m trying to do here.

This is what I’ve added to k3-am67a-beagley-ai.dts so far. I know this is the wrong way to do it and ultimately this probably belongs in an overlay. But I’m just trying to get it working in the simplest way possible.

aliases {
    ...
    spi2 = &main_spi2;
}

&main_pmx0 {
    ...
    
	main_mcspi2_pins_default: main-mcspi2-default-pins {
		pinctrl-single,pins = <
			J722S_IOPAD(0x1B0, PIN_OUTPUT, 1) /* (F24) MCASP0_ACLKR.SPI2_CLK */
			J722S_IOPAD(0x1AC, PIN_OUTPUT, 1) /* (C27) MCASP0_AFSR.SPI2_CS0 */
			J722S_IOPAD(0x198, PIN_OUTPUT, 1) /* (A26) MCASP0_AXR2.SPI2_D1 */
			J722S_IOPAD(0x1A4, PIN_OUTPUT, 1) /* (D25) MCASP0_ACLKX.SPI2_CS1 */
			J722S_IOPAD(0x194, PIN_INPUT, 1)  /* (A25) MCASP0_AXR3.SPI2_D0 */
		>;
	};
};

&main_spi2 {
	status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&main_mcspi2_pins_default>;
    ti,spi-num-cs = <2>;
    ti,pindir-d0-in-d1-out;
    //ti,pindir-d0-out-d1-in;
    num-chipselects = <2>;

    spidev0: spidev@0{
        symlink = "hat/spi/2.0";
        compatible = "spidev";
        reg = <0>;	/* CE0 */
        #address-cells = <1>;
        #size-cells = <0>;
        spi-max-frequency = <50000000>;
    };

    spidev1: spidev@1{
        symlink = "hat/spi/2.1";
        compatible = "spidev";
        reg = <1>;	/* CE1 */
        #address-cells = <1>;
        #size-cells = <0>;
        spi-max-frequency = <50000000>;
    };
};

Use:

compatible = "rohm,dh2228fv";

Vs:

compatible = "spidev";

As compatible spidev throws a runtime error and blocks usage…

spidev0: spidev@0{

Don’t use spidev0 here, as spidev0 (in dt) might not be spidev0 in userspace… I used channel@0 and channel@1 10 years ago and stuck with it… Or spidev@0 spidev@1 would work perfectly fine too…

Regards,

1 Like

Robert already beat me to the punch and I totally agree with everything he wrote.

One particular piece of information you might appreciate is that a lot of information
can actually be gleaned right off the code itself.
You’d be amazed how much one can learn just from taking a dive in there…

linux/drivers/spi/spidev.c at linux-6.6-mchp · linux4microchip/linux

shows you exactly how Robert came up with that compatible, f. ex.

1 Like

What’s scary, and why rohm… :wink:

https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spidev.c?h=v3.8#n647

Making overlays work on 3.8.x forever! :wink:

Regards,

1 Like

Thanks very much Robert and Lars. Works now. overlays/k3-am67a-beagley-ai-spidev0.dts even says exactly that. I don’t know how I got fixated on specifying spidev.

On to the next level of problems. I can set the SPI clock to 50 MHz and that works fine. But it’s stuck in PIO mode, even for a large 2 kB transfer (160 B is the PIO/DMA switchover threshold). I’ll throw some printfs in spi-omap2-mcspi.c and see what’s happening. Never compiled and run a kernel for BBx before, so should be an interesting learning experience.

Thank you again.

1 Like

Okay, got SPI2 DMA working. Now has the expected 170 ns inter-word gap compared to the 1 us of PIO mode. Working as fast as BBB/G, AI and AI-64 now. I’ll try and submit overlays to DeviceTrees.

// SPDX-License-Identifier: GPL-2.0
/*
 * DT Overlay for spidev2.0 & spidev2.1 (mcspi) on BeagleY-AI board.
 *
 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
 *
 */

/dts-v1/;
/plugin/;

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include "ti/k3-pinctrl.h"

/*
 * Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
 */
&{/chosen} {
	overlays {
		k3-am67a-beagley-ai-spidev2.kernel = __TIMESTAMP__;
	};
};

/ {
    compatible = "beagle,am67a-beagley-ai", "ti,j722s";

    fragment@0 {
        target = <&main_pmx0>;
        __overlay__ {
            overlay_main_mcspi2_pins_default: overlay-main-mcspi2-default-pins {
                pinctrl-single,pins = <
                    J722S_IOPAD(0x1B0, PIN_OUTPUT, 1) /* (F24) MCASP0_ACLKR.SPI2_CLK */
                    J722S_IOPAD(0x1AC, PIN_OUTPUT, 1) /* (C27) MCASP0_AFSR.SPI2_CS0 */
                    J722S_IOPAD(0x198, PIN_INPUT,  1) /* (A26) MCASP0_AXR2.SPI2_D1 */
                    J722S_IOPAD(0x1A4, PIN_OUTPUT, 1) /* (D25) MCASP0_ACLKX.SPI2_CS1 */
                    J722S_IOPAD(0x194, PIN_INPUT,  1) /* (A25) MCASP0_AXR3.SPI2_D0 */
                >;
            };
        };
    };

    fragment@1 {
        target = <&main_spi2>;
        __overlay__ {
            status = "okay";
            #address-cells = <1>;
            #size-cells = <0>;
            pinctrl-names = "default";
            pinctrl-0 = <&overlay_main_mcspi2_pins_default>;
        
            compatible = "ti,am654-mcspi","ti,omap2-mcspi","ti,omap4-mcspi";
            ti,hwmods = "mcspi2";
            ti,spi-num-cs = <2>;
            ti,pindir-d0-in-d1-out;
            //ti,pindir-d0-out-d1-in;
        
            // see k3-psil-am62p.c for tx/rx thread ID values
            // only cs[01] (tx/rx[01]) specified here
            dmas = <&main_pktdma 0xc308 0>, <&main_pktdma 0x4308 0>,
                   <&main_pktdma 0xc309 0>, <&main_pktdma 0x4309 0>;
            dma-names = "tx0", "rx0", "tx1", "rx1";
        
            channel@0 {
                symlink = "hat/spi/2.0";
                compatible = "rohm,dh2228fv";
                reg = <0>;	/* CS0 */
                spi-max-frequency = <50000000>;
            };
        
            channel@1 {
                symlink = "hat/spi/2.1";
                compatible = "rohm,dh2228fv";
                reg = <1>;	/* CS1 */
                spi-max-frequency = <50000000>;
            };
        };
    };
};

2 Likes