S32G2 ATF GPIO control

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32G2 ATF GPIO control

2,209 Views
petertseng
Contributor IV

Hi, 

I'm trying to port BSP 33.0 to a custom S32G274A board.

And I need to control the GPIO output to drive an external circuit at power on.

So I added in the s32_plat_config_pinctrl function of arm-trusted-firmware_2.5/plat/nxp/s32/s32_pinctrl.c:

#define SIUL2_MSCR_S32_G1_OPEN_DRAIN_GPIO_OUT \
	(SIUL2_MSCR_S32_G1_OBE_EN \
	|SIUL2_MSCR_S32_G1_ODE_EN \
	|SIUL2_MSCR_MUX_MODE_ALT0)

void s32_plat_config_pinctrl(void)
{
	linflex_config_pinctrl(S32_LINFLEX_MODULE);
	sdhc_config_pinctrl();

	/* PJ05: (open drain output gpio) */
	mmio_write_32(SIUL2_0_MSCRn(149), SIUL2_MSCR_S32_G1_OPEN_DRAIN_GPIO_OUT);
	mmio_write_32(SIUL2_0_MSCRn(663), 0x0);

	/* PA06: (open drain output gpio) */
	mmio_write_32(SIUL2_0_MSCRn(6), SIUL2_MSCR_S32_G1_OPEN_DRAIN_GPIO_OUT);
	mmio_write_32(SIUL2_0_MSCRn(667), 0x0);
	
	/* PJ07: (open drain output gpio) */
	mmio_write_32(SIUL2_0_MSCRn(151), SIUL2_MSCR_S32_G1_OPEN_DRAIN_GPIO_OUT);
	mmio_write_32(SIUL2_0_MSCRn(655), 0x0);


}

 

But how to drive the GPIO pin to output HI/LO?

 

Best regards
Peter

0 Kudos
14 Replies

2,151 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

We don't seem to reproduce the behavior you are seeing. Instead of the code you did under "fdts/s32gxxxa-rdb.dtsi", we just add the following:

 

&pfe {
	status = "okay";
};

+&gpio {
+	LED-hog{
+		gpio-hog;
+		gpios = <119 0>;
+		output-low;
+		line-name = "PA_06_LED";
+	};
+};

/* IO Expander  */
&i2c0 {

 

Since PH_07 (GPIO 119) under RDB2 is configured to work under the PFE2 interface, we do not have anything humanly visible to confirm the change. Still, we did use the same code with the difference of selecting "gpios=<6 0>" and we did see the LED turn ON (as seen under the "line-name" property).

On both configurations, we could log into Linux no problem.

Please, let us know.

0 Kudos

2,095 Views
petertseng
Contributor IV

Hi Daniel,

I think it may be an error caused by defined too many GPIO-HOG.
Because when I define only one PH07 no error occurs.

It seems that I need to operate GPIO actions in u-boot's board_late_init()

Do you have any example or good suggestions on GPIO and IOMUX operation under u-boot?

 

Thanks,

Peter

0 Kudos

2,085 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

Thanks for your feedback.

There is no documentation on this regard. The only information is the one provided inside the "doc" folder under the uboot path. Aside from that, nothing else. We do apologize.

Still, if you have questions on why your implementation is not working, we might be able to continue helping.

Please, let us know.

0 Kudos

2,004 Views
petertseng
Contributor IV

Hi Daniel,

The BSP33.0 uses the release/bsp33.0-2020.04 branch version

https://github.com/nxp-auto-linux/u-boot/tree/release/bsp33.0-2020.04

I found that the GPIO number of PH07 in this version is not 119 but 109.

#define SIUL2_0_BASE_ADDR              0x4009C000
#define SIUL2_1_BASE_ADDR              0x44010000
#define SIUL2_0_MSCR_BASE              (SIUL2_0_BASE_ADDR + 0x00000240)
#define SIUL2_1_MSCR_BASE              (SIUL2_1_BASE_ADDR + 0x00000400)
/* gpio output (open drain) */
#define        SIUL2_MSCR_GPIO_OUT_OD  (SIUL2_MSCR_S32_G1_MUX_ID_0 | \
       SIUL2_MSCR_S32_G1_ODE | SIUL2_MSCR_S32_G1_OBE)

static inline void *s32g2_mscr_reg(void __iomem *base_addr, unsigned int offset)
{
       uintptr_t addr;
       addr = (uintptr_t)base_addr + offset * 4;
       return (void *)addr;
}

/* MSCR 0-101 */
#define SIUL2_0_MSCRn(i)               s32g2_mscr_reg((void __iomem *)SIUL2_0_MSCR_BASE, i)
/* MSCR 112-190 */
#define SIUL2_1_MSCRn(i)               s32g2_mscr_reg((void __iomem *)SIUL2_1_MSCR_BASE, (i-112))

static inline unsigned s32g2_pad_to_gpio(unsigned pad)
{
       if ((pad >=0) && (pad <= 101)) {
               /* PAD 0-101 --> GPIO 0-101 */
               return pad;
       } else if ((pad >=112) && (pad <= 122)) {
               /* PAD 112-122 --> GPIO 102-112 */
               return (pad-10);
       } else if ((pad >=144) && (pad <= 190)) {
               /* PAD 144-190 --> GPIO 113-159 */
               return (pad-31);
       }
       return 200;
}

#define S32G2_GPIO(i)                  s32g2_pad_to_gpio(i)

...

int board_late_init(void)
{
...

       /* PH07 */
       writel(SIUL2_MSCR_GPIO_OUT_OD, SIUL2_0_MSCRn(119));
       gpio_request(S32G2_GPIO(119), "PH07");
       gpio_direction_output(S32G2_GPIO(119), 0);
}

 

If the PH07 pin is not set in U-BOOT, the kernel can boot normally.
But as long as the PH07 pin is set in U-BOOT, it will cause a kernel panic

U-Boot 2020.04+g9cdfca686e (Jun 10 2022 - 11:46:41 +0000)

CPU: NXP S32G274A rev. 2.0
Model: NXP S32G274A-RDB2
DRAM: 3.5 GiB
MMC: FSL_SDHC: 0
Loading Environment from MMC... OK
Using external clock for PCIe0, CRNS
Configuring PCIe0 as RootComplex(x2)
Using external clock for PCIe1, CRNS
Frequency 100Mhz configured for PCIe1
Configuring PCIe1 as RootComplexSGMII(x2) [XPCS0 1G, XPCS1 1G]
ERROR: Invalid XPCS config on PCIe1
XPCS1 power-up failed
Setting PCI Device and Vendor IDs to 0x4002:0x1957
PCIe0: Link up! X1, Gen2
Device 'pcie@44100000': seq 1 is in use by 'pci_0:0.0'
Setting PCI Device and Vendor IDs to 0x4002:0x1957
PCIe1: Link up! X1, Gen3
BusDevFun VendorId DeviceId Device Class Sub-Class
______________________________________________________________________
pcie@40400000 RootComplex
| `-- 00:00.00 0x1957 0x4002 Bridge device 0x04
| |-- 01:00.000x1b4b 0x2b43 Network controller 0x00
| `-- 01:00.010x1b4b 0x2b44 Network controller 0x00
pcie@44100000 RootComplex
| `-- 02:00.00 0x1957 0x4002 Bridge device 0x04
| `-- 03:00.000x1344 0x6001 Mass storage controller 0x08
In: serial@401c8000
Out: serial@401c8000
Err: serial@401c8000
Board revision: RDB2/GLDBOX Revision D
Net: EQOS phy: rgmii @ 3

Warning: eth_eqos (eth0) using random MAC address - 62:91:7d:20:50:f3
eth0: eth_eqosSerDes 0 was not initialized
Emac 2 not initialized
Invalid sgmii configuration for emac index 2

Hit any key to stop autoboot: 0
SerDes 0 was not initialized
Emac 2 not initialized
Invalid sgmii configuration for emac index 2
switch to partitions #0, OK
mmc0 is current device
13824008 bytes read in 610 ms (21.6 MiB/s)
Booting from mmc ...
44079 bytes read in 18 ms (2.3 MiB/s)
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Using Device Tree in place at 0000000083000000, end 000000008300dc2e
Invalid PCIe1 lanes config
Failed to set mode for PCIe1
Invalid SerDes1 mode
Failed to set mode for SerDes1
SerDes 0 was not initialized
Emac 2 not initialized
Invalid sgmii configuration for emac index 2
DT: Disabling PFE

Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.10.109-rt65+g0bace7fde5f5 (oe-user@oe-host) (aarch64-fsl-linux-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #1 SMP PREEMPT Fri Jun 24 15:01:08 UTC 2022
[ 0.000000] Machine model: NXP S32G274A-RDB2
[ 0.000000] earlycon: linflex0 at MMIO 0x00000000401c8000 (options '115200n8')
[ 0.000000] printk: bootconsole [linflex0] enabled
[ 0.000000] SError Interrupt on CPU0, code 0xbf000002 -- SError
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.10.109-rt65+g0bace7fde5f5 #1
[ 0.000000] Hardware name: NXP S32G274A-RDB2 (DT)
[ 0.000000] pstate: 60000085 (nZCv daIf -PAN -UAO -TCO BTYPE=--)
[ 0.000000] pc : setup_arch+0x164/0x58c
[ 0.000000] lr : setup_arch+0x15c/0x58c
[ 0.000000] sp : ffffffc010c93ef0
[ 0.000000] x29: ffffffc010c93ef0 x28: 0000000080b40018
[ 0.000000] x27: 00000000ffaa27f0 x26: 0000000000000000
[ 0.000000] x25: 00000000ffb2f400 x24: 00000000ffdf1298
[ 0.000000] x23: ffffffc010d33000 x22: ffffffc010c9e380
[ 0.000000] x21: fffffffefe600094 x20: ffffffc010ce7088
[ 0.000000] x19: ffffffc010000000 x18: 0000000000000030
[ 0.000000] x17: 0000000000001800 x16: 0000000000000000
[ 0.000000] x15: ffffffc010c9e7e8 x14: ffffffffffffffff
[ 0.000000] x13: 0000000000000000 x12: 0000000000000028
[ 0.000000] x11: 0000000000000015 x10: 0101010101010101
[ 0.000000] x9 : 3334ff6b6e6e6f5e x8 : 7f7f7f7f7f7f7f7f
[ 0.000000] x7 : 736d647164676e62 x6 : 000006161d090b74
[ 0.000000] x5 : 740b091d16060000 x4 : 0000000000000000
[ 0.000000] x3 : ce6ded8ca0000000 x2 : 000000000000000c
[ 0.000000] x1 : 0000000000000000 x0 : 0000000000000080
[ 0.000000] Kernel panic - not syncing:
[ 0.000000] Asynchronous SError Interrupt
[ 0.000000] ---[ end Kernel panic - not syncing: Asynchronous SError Interrupt ]---

 

What could be the reason for this?

Thanks,

Peter

0 Kudos

1,960 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

We cannot replicate the exact issue you are seeing on your setup.

We have configured both PA06 and PH07 on our board under BSP33.0 as follows:

arm-trusted-firmware\fdts\s32gxxxa-rdb.dtsi

DanielAguirre_0-1687211115082.png

When we see the status under u-boot, we have the following:

DanielAguirre_1-1687211150174.png

What we are seeing is that you are setting PH07 under SIUL2_0, which is incorrect, since PH07 corresponds to SIUL2_1. As for the number, it is the assigned logical number, but referring to PH07 as 119 should be the correct way.

Please, let us know.

0 Kudos

1,922 Views
petertseng
Contributor IV

Hi Daniel,

Good jobs!

When I set setting PH07 under SIUL2_1 it does alleviate the kernel panic issue.

 

But when setting both PJ07(#151) and PH07(#119) with gpio-hog.

I found that the <pinctrl_offset> value returned by s32cc_get_pinctrl_offset() is the same (=119).

 

Is this caused by the lack of adding <range->gpio_offset> in s32cc_gpio_get_xlate()?

diff --git a/drivers/gpio/gpio-s32cc.c b/drivers/gpio/gpio-s32cc.c
index 4863c1af..966e87f2 100644
--- a/drivers/gpio/gpio-s32cc.c
+++ b/drivers/gpio/gpio-s32cc.c
@@ -203,8 +205,9 @@ static int s32cc_gpio_get_xlate(struct udevice *dev, struct gpio_desc *desc,
 		range = &priv->valid_ranges[i];
 		range_begin = range->pinctrl_offset;
 		range_end = range_begin + range->cnt;
 		if (args->args[0] >= range_begin && args->args[0] < range_end) {
-			desc->offset += args->args[0] - range_begin;
+			desc->offset = args->args[0] - range_begin + range->gpio_offset;
 			break;
 		}
 	}

 

Thanks,

Peter

0 Kudos

1,908 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

We may not understand the comment "found that the <pinctrl_offset> value returned by s32cc_get_pinctrl_offset() is the same (=119).". For both PJ07 and PH07 it returns the same value?

How and when are you calling the function?

Please, let us know.

0 Kudos

1,847 Views
petertseng
Contributor IV

Hi Daniel,

If you debug both PH07 and PJ07 in s32gxxxa-rdb.dtsi, you will get probe error message.

But debugging one of the GPIOs alone and tracking the <pinctrl_offset> value returned by s32cc_get_pinctrl_offset() in s32cc_gpio_direction_output() will get the same result (=119)

u-boot_2020.4/drivers/gpio/gpio-s32cc.c

@@ -124,6 +129,7 @@ static int s32cc_gpio_direction_output(struct udevice *dev, unsigned int offset,
        int ret;
 
        ret = s32cc_get_pinctrl_offset(priv, offset, &pinctrl_offset);
+       printf(":%s: offset=%d, pinctrl=%d (ret=%d)\n", __func__, offset, pinctrl_offset, ret);
        if (ret)
                return ret;

 

I think the reason for the probe error is that the last <desc->offset> values generated by the two GPIOs when calling s32cc_gpio_get_xlate() are the same as 7.

PJ07:  desc->offset = 151 - 144 = 7

PH07: desc->offset = 119 - 112 = 7

 

Thanks,

Peter

0 Kudos

1,823 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

Thanks for your feedback.

It does indeed seem to be a bug under the driver. We could replicate the issue you were seeing.

It does seems that since PH07 and PJ07 have the same offset (but on different ranges) the PJ07 (gpio 151) hog was being put under the PH07 address (gpio 119), shown below:

DanielAguirre_0-1687807300467.png

Where PJ07 should be under "siul2-gpio118", instead of "siul2-gpio17".

By applying the patch under the xlate function that you have provided we can see both PH07 and PJ07 under the correct address, as shown below:

DanielAguirre_1-1687807392992.png

Also, after the patch, there was no probe error message.

Please, let us know.

0 Kudos

1,777 Views
petertseng
Contributor IV

Hi Daniel,

Thanks for your reply

Please let me know if there is a follow-up update on this part of the patch

 

Peter

0 Kudos

1,760 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

Since the development team is dedicated to the newer releases, could be a time for when the update is provided under the BSP33.0 version.

Still, we will provide this information to the development team.

Please, let us know.

0 Kudos

1,061 Views
petertseng
Contributor IV

Hi Daniel,

Thanks for your reply

Peter

0 Kudos

2,185 Views
Daniel-Aguirre
NXP TechSupport
NXP TechSupport

Hi,

We may not understand the overall scope of your application, but you can set/clear a GPIO directly from the uboot terminal, if it is feasible under your application flow. You can set/clear a GPIO (i.e. PA_06) doing the following command:

  • Set: gpio set siul2-gpio06
  • Clear: gpio clear siul2-gpio06

As for the code method, you need to write to the needed GPDOn register (or PGPDOn, if you want to). Below will be the code method (with GPDOn) for clearing PA_06 (since LED_BLUE is connected under RDB2, we can see the result as the LED turning ON):

 

#define SIUL2_0_GPDO_BASE	(SIUL2_0_BASE_ADDR + 0x00001300)
#define SIUL2_0_GPDO_6_BASE	(SIUL2_0_GPDO_BASE + 0x00000005)
#define SIUL2_MSCR_S32_G1_SRE_7            		(7 << 14)

#define SIUL2_MSCR_S32G_G2_PORT_CTRL_OBE_P_P	\
	(SIUL2_MSCR_S32_G1_SRE_7 | 	\
	 SIUL2_MSCR_S32_G1_OBE_EN)

#define SIUL2_MSCR_S32G_G2_PORT_CTRL_OBE_O_D	\
	(SIUL2_MSCR_S32_G1_SRE_7 | 	\
	 SIUL2_MSCR_S32_G1_OBE_EN |	\
	 SIUL2_MSCR_S32_G1_ODE_EN)

void gpio_config_pinctrl(void){
	/* PA06 pad: GPIO[6] GPO */
	mmio_write_32(SIUL2_0_MSCRn(6), SIUL2_MSCR_S32G_G2_PORT_CTRL_OBE_P_P);
}

void gpio_set_state(int lvl){
	mmio_write_8(SIUL2_0_GPDO_6_BASE, lvl ? 0x1 : 0x0);
}

void s32_plat_config_pinctrl(void)
{
	linflex_config_pinctrl(S32_LINFLEX_MODULE);
	sdhc_config_pinctrl();
	gpio_config_pinctrl();
	gpio_set_state(0);
}

 

Since we only modified ATF, once we enter Linux itself we lose control over the GPIO, since the BSP configures the same pin with a different function. Beware of this. 

Please, let us know.

0 Kudos

2,158 Views
petertseng
Contributor IV

Hi Daniel,

Thanks for your reply.

I also tried to define the PH07 pin using gpio-hog

u-boot_2020.4/configs/s32g274ardb2_defconfig

--- a/configs/s32g274ardb2_defconfig
+++ b/configs/s32g274ardb2_defconfig
@@ -2,3 +2,4 @@ CONFIG_ARM=y
 CONFIG_ARCH_S32G2=y
 # CONFIG_SPI_FLASH_BAR is not set
 CONFIG_SD_BOOT=y
+CONFIG_GPIO_HOG=y


arm-trusted-firmware_2.5/fdts/s32gxxxa-rdb.dtsi

--- a/fdts/s32gxxxa-rdb.dtsi
+++ b/fdts/s32gxxxa-rdb.dtsi

+/* GPIO1 */
+&gpio1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl1_gpio_hog>;
+
+	/* PH07 */
+	PH07 {
+		gpio-hog;
+		gpios = <119 0>;
+		output-low;
+		line-name = "PV4_EN";
+	};
+};


+		pinctrl1_gpio_hog: pinctrl1_gpio_hog {
+			fsl,pins = <PH07_MSCR_S32G SIUL2_MSCR_GPIO>;
+ 		};

 

but get the error

U-Boot 2020.04+g9cdfca686e (Jun 10 2022 - 11:46:41 +0000)

CPU: NXP S32G274A rev. 2.0
Model: NXP S32G274A-RDB2
DRAM: 3.5 GiB
MMC: FSL_SDHC: 0
Loading Environment from MMC... OK
Using external clock for PCIe0, CRNS
Configuring PCIe0 as RootComplex(x2)
Using external clock for PCIe1, CRNS
Frequency 125Mhz configured for PCIe1
Configuring PCIe1 as SGMII(x2) [XPCS0 2.5G, XPCS1 OFF]
Setting PCI Device and Vendor IDs to 0x4002:0x1957
PCIe0: Failed to get link up
Pcie0: LINK_DBG_1: 0x00000000, LINK_DBG_2: 0x00000800 (expected 0x000000d1)
DEBUG_R0: 0x0043f300, DEBUG_R1: 0x08200000
PCI: Failed autoconfig bar 20
PCI: Failed autoconfig bar 24
PCIe1: Not configuring PCIe, PHY not configured
In: serial@401c8000
Out: serial@401c8000
Err: serial@401c8000
Failed to probe device PV4_EN err: -16
initcall sequence 00000000ffb2a408 failed at call 00000000ffad43e4 (err=-16)
### ERROR ### Please RESET the board ###

 

I try to replace PJ05 or PJ11, it can be started normally, but PH07 will have an error.

Is there a special for the PH07 pins?

Thanks,

Peter

 

0 Kudos