Hi, we have an AM437x-based board and we're currently trying to use a GPIO to reset an external board. There's a pull-down resistor that pulls the GPIO line to 0V when it's not driven. This line drives a mosfet transistor, which negates the output of the GPIO, causing a 5V signal when GPIO is low.
The problem is that 5V is actually the reset state for the external board and I have to drive the GPIO high (in order to generate a 0V output) on both u-boot/kernel consistently without a glitch so that we don't accidentally trigger a reset during boot-up. So far, I've tried to use led-gpios subsystem, pulling the GPIO low manually in board/ti/am43xx/board.c (sdram_init) and even gpio hogging. Even though I'm able to pull the line low in all the mentioned attempts, GPIO state still goes high until u-boot takes control of the GPIO and during u-boot -> linux transition.
Is there a way to achieve this smoothly without HW modification? I tried playing with the pinmux to set the related GPIO to PIN_OUTPUT_PULLDOWN but it didn't make any difference. The pin in question is gpio5_5:
0x254 (PIN_OUTPUT | MUX_MODE7) /* spi4_d0.gpio5_5 */
Our kernel version is 4.19.59-g5f8c1c6121 and u-boot version is 2019.01
1-) Using led-gpios, I did:
in u-boot:
Index: git/configs/am43xx_evm_defconfig
===================================================================
--- git.orig/configs/am43xx_evm_defconfig
+++ git/configs/am43xx_evm_defconfig
@@ -89,3 +89,7 @@ CONFIG_ZLIB_UNCOMPRESS=y
CONFIG_HW_WATCHDOG=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
CONFIG_OMAP_WATCHDOG=y
+CONFIG_LED=y
+CONFIG_SPL_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_SPL_LED_GPIO=y
Index: git/board/ti/am43xx/board.c
===================================================================
--- git.orig/board/ti/am43xx/board.c
+++ git/board/ti/am43xx/board.c
@@ -748,6 +748,9 @@ int board_late_init(void)
/* Just probe the potentially supported cdce913 device */
uclass_get_device(UCLASS_CLK, 0, &dev);
+ if (IS_ENABLED(CONFIG_LED))
+ led_default_state();
+
return 0;
}
#endif
Index: git/arch/arm/dts/am437x-sk-evm.dts
===================================================================
--- git.orig/arch/arm/dts/am437x-sk-evm.dts
+++ git/arch/arm/dts/am437x-sk-evm.dts
@@ -65,6 +65,13 @@
pinctrl-names = "default";
pinctrl-0 = <&leds_pins>;
+ ctb_reset_led {
+ label = "ctb_reset_led";
+ gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ default-state = "on";
+ };
+
led@0 {
label = "am437x-sk:red:heartbeat";
gpios = <&gpio5 0 GPIO_ACTIVE_HIGH>; /* Bank 5, pin 0 */
in kernel:
Index: kernel-source/arch/arm/boot/dts/am437x-sk-evm.dts
===================================================================
--- kernel-source.orig/arch/arm/boot/dts/am437x-sk-evm.dts
+++ kernel-source/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -53,6 +53,15 @@
};
};
+ initial_gpio_states {
+ compatible = "gpio-leds";
+
+ ctb_reset {
+ gpios = <&gpio5 5 0>;
+ default-state = "keep";
+ };
+ };
+
2-) Attempted call the following function inside board/ti/am43xx/board.c sdram_init:
static void initialize_ctb_reset_pin(void)
{
u32 temp;
temp = readl(AM33XX_GPIO0_BASE + OMAP_GPIO_SETDATAOUT);
temp = temp & ~(GPIO_SETDATAOUT(16));
writel(temp, AM33XX_GPIO0_BASE + OMAP_GPIO_SETDATAOUT);
temp = readl(AM33XX_GPIO0_BASE + OMAP_GPIO_OE);
temp = temp & ~(GPIO_OE_ENABLE(16));
writel(temp, AM33XX_GPIO0_BASE + OMAP_GPIO_OE);
}
Thanks in advance,
Best Regards.