Verdin iMX8M Plus: Enabling ecspi1 in u-boot

Hello,

We use Verdin iMX8M Plus for our product.
I need to enable spi in u-boot.

I have cloned toradex_imx_v2020.04_5.4.70_2.3.0 branch and added following lines into \arch\arm\dts\imx8mp-verdin.dts:

/* Verdin SPI_1 */
&ecspi1 {
	#address-cells = <1>;
	#size-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi1>;
	cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;    
	status = "okay";  
};

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>, ...

	pinctrl_ecspi1: ecspi1grp {
		fsl,pins = <
			MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK		0x4	/* SODIMM 196 */
			MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI		0x4	/* SODIMM 200 */
			MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO		0x1c4	/* SODIMM 198 */
			MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09		0x1c4	/* SODIMM 202 */
		>;
	};

Then in the configs/verdin-imx8mp_defconfig file, I added:

...
CONFIG_SPI=y
CONFIG_CMD_SPI=y
CONFIG_DM_SPI=y
CONFIG_CMD_SPI=y
CONFIG_DEFAULT_SPI_BUS=0
CONFIG_DEFAULT_SPI_MODE=0
CONFIG_MXC_SPI=y

When I execute sspi command in u-boot, I get bus error:
Invalid bus 0 (err=-19)

Do you know which steps I miss to get spi functional in u-boot?

Thank you.

Hi @Fide !

Could you please elaborate on how exactly you are performing the SPI command on U-Boot?

Also, what is your end objective? To be able to boot via SPI or to be able to simply communicate with another device using SPI?

Best regards,

Hi @henrique.tx,

Final goal is to program an FPGA through an SPI bus. iMX8M-Plus will be a master and FPGA acts as a slave. We could have done this in Linux but not in u-boot. Unfortunately FPGA has to be configured before linux kernel boots. That’s reason why I need ecsp1 module enabled in u-boot.

And for simple testing I use sspi command: sspi 0:0.0 8 55 and got error above.

sspi [<bus>:]<cs>[.<mode>] <bit_len> <dout> - Send and receive bits
<bus> - Identifies the SPI bus
<cs> - Identifies the chip select
<mode> - Identifies the SPI mode to use
<bit_len> - Number of bits to send (base 10)
<dout> - Hexadecimal string that gets sent
<dout> is in hex but without the prefix "0x". All others are in decimal.

Thank you.

Hi @Fide !

I have done several tests regarding ECSPI, the sspi command, and also trying to enable debug prints in U-Boot, but all I get is the same Invalid bus 0 (err=-19) that you are also facing.

I will bring this discussion to the R&D team to find out if I am missing something or even if it is supported at all.

Also, have you tried using the FlexSPI instead of ECSPI?

Best regards,

Hi @henrique.tx,

I managed enabling ecspi1 in the u-boot environment and FPGA configuration worked very well.

  1. I added spi1 = &ecspi1; as alias in imx8mp-verdin.dts. Because alias spi0 is already defined in imx8mp.dtsi as spi0 = &flexspi; This should solve the error you have.

  2. I had to configure pads in the board/toradex/verdin-imx8mp/verdin-imx8mp.c and ecsp1 clocks in drivers/clk/imx/clk-imx8mp.c. I think DTS definitions are ignored in this context, the correct configuration must be in the code.

In verdin-imx8mp.c:

#ifdef CONFIG_MXC_SPI
#define SPI_PAD_CTRL    (PAD_CTL_DSE2 | PAD_CTL_HYS)
static iomux_v3_cfg_t const ecspi1_pads[] = {
        MX8MP_PAD_ECSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX8MP_PAD_ECSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX8MP_PAD_ECSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX8MP_PAD_ECSPI1_SS0__GPIO5_IO09  | MUX_PAD_CTRL(NO_PAD_CTRL),
};

static void setup_spi(void)
{
        imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
        //gpio_request(IMX_GPIO_NR(5, 9), "ECSPI1 CS");

        init_clk_ecspi(0);
}

int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
        return IMX_GPIO_NR(5, 9);
}
#endif

int board_init(void)
{
#ifdef CONFIG_MXC_SPI
	setup_spi();
#endif
..    
..
..
	return 0;
}

In clk-imx8mp.c:

// spi clk def
static const char *imx8mp_ecspi1_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m",
                                          "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
                                          "sys_pll2_250m", "audio_pll2_out", };

static const char *imx8mp_ecspi2_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m",
                                          "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
                                          "sys_pll2_250m", "audio_pll2_out", };

static const char *imx8mp_ecspi3_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m",
                                          "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
                                          "sys_pll2_250m", "audio_pll2_out", };

static int imx8mp_clk_probe(struct udevice *dev)
{
    ..
    ..

    // starts here
	clk_dm(IMX8MP_CLK_ECSPI1, imx8m_clk_composite("ecspi1", imx8mp_ecspi1_sels, base + 0xb280));
	clk_dm(IMX8MP_CLK_ECSPI2, imx8m_clk_composite("ecspi2", imx8mp_ecspi2_sels, base + 0xb300));
	clk_dm(IMX8MP_CLK_ECSPI3, imx8m_clk_composite("ecspi3", imx8mp_ecspi3_sels, base + 0xc180));
	clk_dm(IMX8MP_CLK_ECSPI1_ROOT, imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0));
	clk_dm(IMX8MP_CLK_ECSPI2_ROOT, imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0));
	clk_dm(IMX8MP_CLK_ECSPI3_ROOT, imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0));
}

It worked for us but these changes are not for production. For example when I asked for 60Mhz SPI clock, I got 40Mhz. Above clock settings may not be fully accurate. I expect fully tested accurate patch from Toradex or NXP :slight_smile:

I hope this helps.

Thank you.

Hi @Fide !

Sorry for the delay.

Thanks for sharing your modifications!

Your feature request was escalated.

We will let you know as soon as we have any news.

Also, can you confirm if the 60MHz capability is a requirement for your project?

Best regards,

1 Like

Hi @henrique.tx,

SPI speed directly affects boot time of our device.
FPGA configuration takes 4 secs at 60Mhz. Faster is better, SoM supports up to 80 Mhz (I tested works fine in Linux, but not in u-boot)

Regards,

Hi @Fide,

The SPI at 80MHz is indeed supported and is working on Linux. On U-boot, this feature is for specific usage and will not be supported.

If this feature is critical for your application, we can point you to a partner that will be able to help you with this.

Best regards,