U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] toradex: apalis-imx8: Disable PCIe B without on-module Wi-Fi
@ 2026-10-28 10:21 Stefan Eichenberger
  0 siblings, 0 replies; only message in thread
From: Stefan Eichenberger @ 2026-10-28 10:21 UTC (permalink / raw)
  To: francesco.dolcini, sbabic, festevam, uboot-imx, trini,
	stefan.eichenberger, franz.schnyder
  Cc: u-boot

From: Francesco Dolcini <francesco.dolcini@toradex.com>

On Apalis iMX8 the second PCIe controller only connects to the
on-module Wi-Fi, which is assembled on the WB variants only. With the
HSIO configuration "pciea-pcieb-sata", a probed PCIe B without a link
partner keeps its PHY lane and PHYX2_PCLK1 running, and SATA then fails
on the non-WB variants:

  ata1.00: failed to IDENTIFY (I/O error, err_mask=0x40)

The Apalis iMX8 with Wi-Fi has a 10k pull-down connected to
PCIE_CTRL1_PERST_B, use it to detect the variant. Without Wi-Fi the pad
is floating, and with the internal pull disabled its capacitance keeps
the level it was last driven to. Drive the pad high, release it and read
it back: the pull-down brings it low on the Wi-Fi variants, while it
stays high when Wi-Fi is not populated. In that case, disable the PCIe B
node in the kernel device tree.

Tested-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
---
 board/toradex/apalis-imx8/apalis-imx8.c | 55 +++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
index ec30ceb3a68..ba0e05a5e39 100644
--- a/board/toradex/apalis-imx8/apalis-imx8.c
+++ b/board/toradex/apalis-imx8/apalis-imx8.c
@@ -17,6 +17,7 @@
 #include <command.h>
 #include <env.h>
 #include <errno.h>
+#include <fdt_support.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/libfdt.h>
@@ -43,6 +44,14 @@
 				 (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT) | \
 				 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT))
 
+#define WIFI_DETECT_PAD_CTRL	((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \
+				 (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \
+				 (SC_PAD_28FDSOI_PS_NONE << PADRING_PULL_SHIFT) | \
+				 (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT))
+
+#define PCIEB_PERST_GPIO	"GPIO5_0"
+#define PCIEB_BASE_ADDR		0x5f010000
+
 #define TDX_USER_FUSE_BLOCK1_A	276
 #define TDX_USER_FUSE_BLOCK1_B	277
 #define TDX_USER_FUSE_BLOCK2_A	278
@@ -63,6 +72,10 @@ static iomux_cfg_t pcb_vers_default[] = {
 	SC_P_MIPI_DSI0_GPIO0_01 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(PCB_VERS_DEFAULT),
 };
 
+static iomux_cfg_t wifi_detect_pads[] = {
+	SC_P_PCIE_CTRL1_PERST_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(WIFI_DETECT_PAD_CTRL),
+};
+
 static iomux_cfg_t uart1_pads[] = {
 	SC_P_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
 	SC_P_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
@@ -290,9 +303,51 @@ void reset_cpu(void)
 	} while (1);
 }
 
+/*
+ * The on-module Wi-Fi is assembled only on the WB variants, together with
+ * the 10k pull-down on PCIE_CTRL1_PERST_B, a module input the module never
+ * drives. On the other variants the pad is unconnected. The pad is driven
+ * high, released and read right away: an unconnected pad keeps its charge
+ * (leakage is below 1 uA), with the pull-down it is low within
+ * nanoseconds.
+ */
+static bool apalis_imx8_has_wifi(void)
+{
+	struct gpio_desc perst;
+	int val;
+
+	if (dm_gpio_lookup_name(PCIEB_PERST_GPIO, &perst))
+		return true;
+
+	if (dm_gpio_request(&perst, "Wi-Fi detection on PCIE_CTRL1_PERST_B"))
+		return true;
+
+	imx8_iomux_setup_multiple_pads(wifi_detect_pads,
+				       ARRAY_SIZE(wifi_detect_pads));
+
+	dm_gpio_set_dir_flags(&perst, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+	udelay(10);
+	dm_gpio_set_dir_flags(&perst, GPIOD_IS_IN);
+	udelay(2);
+	val = dm_gpio_get_value(&perst);
+
+	dm_gpio_free(perst.dev, &perst);
+
+	return val != 1;
+}
+
 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
 int ft_board_setup(void *blob, struct bd_info *bd)
 {
+	int off;
+
+	if (!apalis_imx8_has_wifi()) {
+		off = fdt_node_offset_by_compat_reg(blob, "fsl,imx8q-pcie",
+						    PCIEB_BASE_ADDR);
+		if (off >= 0)
+			fdt_status_disabled(blob, off);
+	}
+
 	return ft_common_board_setup(blob, bd);
 }
 #endif
-- 
2.56.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-28 13:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-28 10:21 [PATCH v1] toradex: apalis-imx8: Disable PCIe B without on-module Wi-Fi Stefan Eichenberger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox