LSIO_GPIO0_IO0x toggling on i.MX8QM
Issue customer met:
Customer met LSIO_GPIO0_IO0x not toggling on i.MX8QM, they are working through the software on their board, part of that involves getting a few GPIO pins working.
They have been using several GPIO pins for a while now, we have some simple toggles and some others where we bit bang i2c, all of those have worked fine.
However, They have not been able to get 3 pins to either read or set successfully at all:
LSIO_GPIO0_IO00 (SIM0_CLK)
LSIO_GPIO0_IO01 (SIM0_RST)
LSIO_GPIO0_IO02 (SIM0_IO)
1\ Reproduce on our i.MX8QM EVK board
a. Check the hardware connection
Check the LSIO_GPIO0_IO00 (SIM0_CLK), LSIO_GPIO0_IO01 (SIM0_RST) and LSIO_GPIO0_IO02 (SIM0_IO) connection in our i.MX8QM EVK board.
In the default design in NXP i.MX8QM EVK board, the pins SIM0_CLK, SIM0_RST and SIM0_IO connect to the SIM CARD on the base board.
b. To make these pins work as GPIO pins
In the default pins mux, default pins mux on the SIM0, to make these pins work as GPIO, need to mux them to the GPIO functions.
SIM0_CLK (SIM0_CLK)
SIM0_RST (SIM0_RST)
SIM0_IO (SIM0_IO)
c. In the source code change these pins mux to GPIO configuration:
Defalt setting for these pins :
linux-imx/arch/arm64/boot/dts/freescale/imx8qm-mek.dts at lf-6.12.y · nxp-imx/linux-imx · GitHub
pinctrl_sim0: sim0grp {
fsl,pins = <
IMX8QM_SIM0_CLK_DMA_SIM0_CLK 0xc0000021
IMX8QM_SIM0_IO_DMA_SIM0_IO 0xc2000021
IMX8QM_SIM0_PD_DMA_SIM0_PD 0xc0000021
IMX8QM_SIM0_POWER_EN_DMA_SIM0_POWER_EN 0xc0000021
IMX8QM_SIM0_RST_DMA_SIM0_RST 0xc0000021
>;
};
Linux dts should set them to GPIO0 functions:
IMX8QM_SIM0_CLK_LSIO_GPIO0_IO00 0xc0000021
IMX8QM_SIM0_RST_LSIO_GPIO0_IO01 0xc2000021
IMX8QM_SIM0_IO_LSIO_GPIO0_IO02 0xc0000021
Build the source code, download the images to board, test on the SIM pins to see if these pins can work or not. Test on the J45 pins 3,5,6.
Test the SIM_CLK as an example:
Test commands in Linux
echo 480 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio480/direction
#output high
echo 1 > /sys/class/gpio/gpio480/value
#measure the PINs
#output low
echo 0 > /sys/class/gpio/gpio480/value
#measure the PINs
Found these pins can not toggling well.
2\ Go next further test and consideration
Foud the SCU_GPIO0_00, SCU_GPIO0_01, SCU_GPIO0_02 are also configurate as GPIO function in the SCFW, in the default setting for the SC_P_SCU_GPIO0_00is the function GPIO0_00 , and when setting the SIM0_CLK to GPIO0_00 function then the GPIO0_00 can not work normally.
So if setting the SIM0_CLK as GPIO0_00 function, then we need to set the SC_P_SCU_GPIO0_00 this PIN to others function, so that no conflict of them. Even no use the pin SC_P_SCU_GPIO0_00 in hardware, we also need to set them to others function to avoid the conflict.
SCU_GPIO Pins mux:
SCU_GPIO0_00 (SCU_GPIO0_00)
SCU_GPIO0_01 (SCU_GPIO0_01)
SCU_GPIO0_02 (SCU_GPIO0_02)
Tested the PINs "SIM0_CLK, SIM0_IO, SIM0_RST" on iMX8QM MEK with base board. All of them works fine.
The key points are already listed.
- VDD_SIM0 power should be supplied (It is 3.3V on MEK from PF8100 LDO)
- Linux dts should set them to GPIO0 functions:
IMX8QM_SIM0_CLK_LSIO_GPIO0_IO00 0xc0000021
IMX8QM_SIM0_RST_LSIO_GPIO0_IO01 0xc2000021
IMX8QM_SIM0_IO_LSIO_GPIO0_IO02 0xc0000021
- The default IOMUX for PINs SC_P_SCU_GPIO0_00, SC_P_SCU_GPIO0_01, SC_P_SCU_GPIO0_02 should be changed from 0 to others.
Test on MEK, we used followed codes in SCFW board_init():
else if (phase == BOOT_PHASE_FINAL_INIT)
{
/* Configure SNVS button for rising edge */
SNVS_ConfigButton(SNVS_DRV_BTN_CONFIG_RISINGEDGE, SC_TRUE);
/* Init PMIC if not already done */
pmic_init();
pad_force_mux(SC_P_SCU_GPIO0_00, 2,
SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);
pad_force_mux(SC_P_SCU_GPIO0_01, 2,
SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);
pad_force_mux(SC_P_SCU_GPIO0_02, 2,
SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF);
}
Note:
In SCFW, should also set SC_P_SCU_GPIO0_00, SC_P_SCU_GPIO0_01, SC_P_SCU_GPIO0_02 to other functions, because they are set to GPIO0_0x function default, if two PINs set to the same functions, such as SIM0_CLK_DMA pin and SCU_GPIO0_00 pin are set to GPIO0_00 together, the function will not work correctly.
Test commands in LInux:
echo 480 > /sys/class/gpio/export
echo 481 > /sys/class/gpio/export
echo 482 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio480/direction
echo out > /sys/class/gpio/gpio481/direction
echo out > /sys/class/gpio/gpio482/direction
#output high
echo 1 > /sys/class/gpio/gpio480/value
echo 1 > /sys/class/gpio/gpio481/value
echo 1 > /sys/class/gpio/gpio482/value
#measure the PINs, they are correct high ( 3V )
#output low
echo 0 > /sys/class/gpio/gpio480/value
echo 0 > /sys/class/gpio/gpio481/value
echo 0 > /sys/class/gpio/gpio482/value
#measure the PINs, they are correct low ( 0V )
The test result is based on real measurement on iMX8QM MEK.
Note:
1\In customer's side If still not work, To confirm the issue, please suggest customer build SCFW with parameter "-m", then use followed commands to dump the IOMUX registers:
md 0x41F80000 1
md 0x41F80040 1
md 0x41F80080 1
md 0x41F82140 1
md 0x41F82180 1
md 0x41F83000 1
The "md" command should run from SCFW debug UART, not linux/uboot UART.
2\Make sure the hardware in customer's side VDD_SIM0 power should be supplied .