Disable SAI pins on A53 core

Hello,

I’m trying to disable the I2S_1 interface on the Verdin-imx8mp 4 GB Quad Core using a device tree overlay. I want to use the SODIMM 30, 32, 34, 36, and 38 pins for GPIO on the M7 core, and not for SAI on the A53 core. On the M7 side I’m initializing the pins in firmware with a IRQ handler, and it seems like the IRQ is triggered when the corresponding button is pushed. However, when a signal is sent from the button to the pin (in this case GPIO3_IO22 / SODIMM 32) the A core (Yocto) crashes, causing it to become unresponsive while the M7 core is still running. After around 1-2 minutes the A core automatically hard resets, causing it to reboot and stop the M7 core.

Is the device tree i have correct for disabling the SAI interface? Am I missing something about disabling modules using device trees? When checking pins in Yocto linux using gpioinfo SODIMM 30, 32, 34, 36, and 38 are all unused, input and active-high.

Below are some code snippets for more context and tdx-info log.

On the M7 side I’m initializing the pins in firmware:

// GPIO3 22 / SODIMM 32 / I2S_1_SYNC => BUTTON1
#define BUTTON1_GPIO GPIO3
#define BUTTON1_GPIO_PIN 22

void BUTTON1_Init(void) {
    GPIO_PinInit(BUTTON1_GPIO, BUTTON1_GPIO_PIN, &s_buttonConfig);
    GPIO_SetPinInterruptConfig(BUTTON1_GPIO, BUTTON1_GPIO_PIN,
                               kGPIO_IntRisingOrFallingEdge);
    GPIO_PortEnableInterrupts(BUTTON1_GPIO, 1U << BUTTON1_GPIO_PIN);

    NVIC_SetPriority(GPIO3_Combined_16_31_IRQn, 5);
    EnableIRQ(GPIO3_Combined_16_31_IRQn);
}

The device tree overlay I’m applying:

/dts-v1/;
/plugin/;

#include "imx8mp-pinfunc.h"

/ {
    compatible = "toradex,verdin-imx8mp";
};

&sai1 {
    status = "disabled";
    pinctrl-names = "default";
    pinctrl-0 = <>;
};

&sai5 {
    status = "disabled";
    pinctrl-names = "default";
    pinctrl-0 = <>;
};

&iomuxc {
    pinctrl_sai1: sai1grp {
        fsl,pins = <>;
    };
};

tdx-info:

Software summary

Bootloader: U-Boot
Kernel version: 5.15.148-6.8.0-devel+git.8c5c2dcbf6ba #1 SMP PREEMPT Tue Aug 6 10:01:59 UTC 2024
Kernel command line: root=PARTUUID=ad0b759c-02 ro rootwait console=tty1 console=ttymxc2,115200 consoleblank=0 earlycon clk-imx8mp.mcore_booted=1
Distro name: NAME=“TDX Wayland with XWayland”
Distro version: VERSION_ID=6.8.0-devel-20250314090650-build.0
Distro variant: -
Hostname: verdin-imx8mp-1550xxxx

Hardware info

HW model: Toradex Verdin iMX8M Plus WB on Verdin Development Board
Toradex version: 0058 V1.1B
Serial number: 1550xxxx
Processor arch: aarch64

Dear @erikr,

To my understanding the interrupts of a single bank can not be shared between both Cortex-A and Cortex-M cores simultaneously, which is likely what is happening in your case. A bank itself I believe could maybe be shared, though I would have to try this out to confirm it.

Best regards,
Collin

1 Like

Hi @collin.tx ,
Did you have the chance to test this out?

Dear @erikr,

Sorry for the late reply. I have not yet tested it, but I have allocated some time tomorrow to try it out.

Best regards,
Collin

1 Like

Dear @erikr,

I have managed to spend quite some time on what you described and tried to replicate it. It seems I may have found what is causing problems here.

I started with a FreeRTOS hello world project and proceeded to build it (simply to get a project on the R7). Following that I took over the relevant parts of your overlay. With that done I started to alter the hello world code to suite the interrupt handling of the GPIO. There were a few things that stood out here. First off, you will likely have to disable the gpio3 as well, since it will otherwise not take over the configurations made further down the line. I presume that this is in fact what is causing the trouble in your case.

looking into the source files used for the device tree I furthermore saw, that the node nau8822_1a needs to be disabled as well as sound.

I had access to both the linux CLI (via ttyUSB3) as well as the serial console of the M7 (via ttyUSB2). This was achieved with the instructions from this developer page in uboot. However, instead of the command:
setenv cm_boot "${load_cm_image}; cp.b ${loadaddr} 0x7e0000 ${cm_image_size}; dcache flush; bootaux 0x7e0000"
I used:
setenv cm_boot 'ext4load mmc 2:2 $ramdisk_addr_r $cm_image; dcache flush; bootaux $ramdisk_addr_r'

To get the serial console running while Linux was booted I used this command:
setenv tdxargs clk-imx8mp.mcore_booted=1

With all that said, here is what my overlay looks like:

/dts-v1/;
/plugin/;

/ {
    compatible = "toradex,verdin-imx8mp";
};

&sai1 {
    status = "disabled";
};

&sai5 {
    status = "disabled";
};

&gpio3 {
    status = "disabled";
};

&nau8822_1a {
    status = "disabled";
};

&{/sound} {
    status = "disabled";
};

Finally here is the altered hello world I used to test the gpio you mentioned:

/*
 * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2017, 2024 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_common_arm.h"
#include "fsl_gpio.h"
#include "board.h"
#include "app.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
// GPIO3 22 / SODIMM 32 / I2S_1_SYNC => BUTTON1
#define BUTTON1_GPIO GPIO3
#define BUTTON1_GPIO_PIN 22
/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */

void GPIO3_Combined_16_31_IRQHandler(void)
{
    PRINTF("IRQ Handler\r\n");
    IRQ_ClearPendingIRQ(GPIO3_Combined_16_31_IRQn);
    GPIO_PortClearInterruptFlags(BUTTON1_GPIO, GPIO_PortGetInterruptFlags(BUTTON1_GPIO));
    PRINTF("Button State: %d\r\n", GPIO_PinRead(BUTTON1_GPIO, BUTTON1_GPIO_PIN));
    PRINTF("IRQ Handler done\r\n");
    SDK_ISR_EXIT_BARRIER;
}

void BUTTON1_Init(void) {
    PRINTF("Button init\r\n");
    gpio_pin_config_t gpio_config = {kGPIO_DigitalInput, 0, kGPIO_IntRisingOrFallingEdge};
    GPIO_PinInit(BUTTON1_GPIO, BUTTON1_GPIO_PIN, &gpio_config);
    GPIO_SetPinInterruptConfig(BUTTON1_GPIO, BUTTON1_GPIO_PIN, kGPIO_IntRisingOrFallingEdge);
    GPIO_PortEnableInterrupts(BUTTON1_GPIO, 1U << BUTTON1_GPIO_PIN);

    NVIC_SetPriority(GPIO3_Combined_16_31_IRQn, 5);
    EnableIRQ(GPIO3_Combined_16_31_IRQn);

    PRINTF("Button init done\r\n");
}

int main(void)
{
    char ch;

    /* Init board hardware. */
    BOARD_InitHardware();
    BUTTON1_Init();
    PRINTF("Button State: %d\r\n", GPIO_PinRead(BUTTON1_GPIO, BUTTON1_GPIO_PIN));

    PRINTF("hello world.\r\n");

    while (1)
    {
        ch = GETCHAR();
        PUTCHAR(ch);
    }
}

Please let me know if this approach works for you as well.

Best regards,
Collin

1 Like

Hi @collin.tx ,

Thank you for the time spent and this detailed answer!

We will do some more testing on our side after the Easter holyday here in Norway.

1 Like

Hello @collin.tx ,

I’ve have tested the same overlay you tested with, and I can confirm that interrupts on GPIO3 bank is working fine, and it looks like this was causing the issue indeed. I also tested interrupts on GPIO4 with the new overlay, and this works fine too. Thank you for the device tree example you shared.

However, I’m running into a different problem;

I’m planning to use the HDMI connector on the Mallow carrier board, and I’ve found its definition in the device tree:

hdmi_connector: hdmi-connector {
		compatible = "hdmi-connector";
		ddc-i2c-bus = <&i2c2>;
		/* Verdin PWM_3_DSI (SODIMM 19) */
		hpd-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
		label = "hdmi";
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_pwm_3_dsi_hpd_gpio>;
		type = "a";
		status = "disabled";
};

, which looks like its using GPIO3. Disabling GPIO3 in the device tree is causing the HDMI (OUT) not to work. Is there any way to change what GPIO bank the HDMI connector is using, or is this impossible due to hardware?

Best regards,
Erik

Hello @erikr,

Let me give some pointers here as Collin is on vacation this week.

On the Mallow Carrier Board the HPD pin of the HDMI is connected to SODIMM 19, which is only capable of working as a GPIO as part of Bank 3.
On a custom carrier board, another GPIO could be used.

With the Mallow board, you could also check if other banks could fulfill your requirements, such as bank 1, 4 or 5, depending on how many pins you need and which other you plan to use.

Best Regards,
Bruno

@bruno.tx Thank you, I think we got what we need for moving forwards now!

1 Like