display5: Support for the emergency PAD pressing

To enter the special mode, one needs to short cut two pads with e.g. screw
driver.

After power up the SPL will execute u-boot in which proper actions will be
taken.

It is worth noting that we do not alter envs (even the BOOT_FROM variable)
and unconditionally go to recovery.

Signed-off-by: Lukasz Majewski <lukma@denx.de>
diff --git a/board/liebherr/display5/common.c b/board/liebherr/display5/common.c
index 26575f7..4eb86d8 100644
--- a/board/liebherr/display5/common.c
+++ b/board/liebherr/display5/common.c
@@ -34,6 +34,16 @@
 	SETUP_IOMUX_PADS(uart_pads);
 }
 
+iomux_v3_cfg_t const misc_pads_spl[] = {
+	/* Emergency recovery pin */
+	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+void displ5_set_iomux_misc_spl(void)
+{
+	SETUP_IOMUX_PADS(misc_pads_spl);
+}
+
 #ifdef CONFIG_MXC_SPI
 iomux_v3_cfg_t const ecspi_pads[] = {
 	/* SPI3 */
diff --git a/board/liebherr/display5/common.h b/board/liebherr/display5/common.h
index a507ef9..78c64b0 100644
--- a/board/liebherr/display5/common.h
+++ b/board/liebherr/display5/common.h
@@ -37,5 +37,6 @@
 void displ5_set_iomux_ecspi(void);
 void displ5_set_iomux_usdhc_spl(void);
 void displ5_set_iomux_usdhc(void);
+void displ5_set_iomux_misc_spl(void);
 
 #endif /* __DISPL5_COMMON_H_ */
diff --git a/board/liebherr/display5/display5.c b/board/liebherr/display5/display5.c
index ebc643e..4bade47 100644
--- a/board/liebherr/display5/display5.c
+++ b/board/liebherr/display5/display5.c
@@ -44,6 +44,7 @@
 static u32 cpu_id;
 static u32 unit_id;
 
+#define EM_PAD IMX_GPIO_NR(3, 29)
 #define SW0	IMX_GPIO_NR(2, 4)
 #define SW1	IMX_GPIO_NR(2, 5)
 #define SW2	IMX_GPIO_NR(2, 6)
@@ -179,6 +180,9 @@
 
 	/* XTALOSC */
 	MX6_PAD_GPIO_3__XTALOSC_REF_CLK_24M | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* Emergency recovery pin */
+	MX6_PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
 };
 
 #ifdef CONFIG_FSL_ESDHC
@@ -369,7 +373,22 @@
 
 int misc_init_r(void)
 {
+	int ret;
+
 	setup_boot_modes();
+
+	ret = gpio_request(EM_PAD, "Emergency_PAD");
+	if (ret) {
+		printf("Can't request emergency PAD gpio\n");
+		return ret;
+	}
+
+	ret = gpio_direction_input(EM_PAD);
+	if (ret) {
+		printf("Can't set emergency PAD direction\n");
+		return ret;
+	}
+
 	return 0;
 }
 
diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c
index 0d25b0d9..551a143 100644
--- a/board/liebherr/display5/spl.c
+++ b/board/liebherr/display5/spl.c
@@ -16,6 +16,7 @@
 #include <asm/arch/imx-regs.h>
 #include "asm/arch/iomux.h"
 #include <asm/mach-imx/iomux-v3.h>
+#include <asm/gpio.h>
 #include <environment.h>
 #include <fsl_esdhc.h>
 #include <netdev.h>
@@ -194,10 +195,24 @@
 	/* Clear the BSS. */
 	memset(__bss_start, 0, __bss_end - __bss_start);
 
+	displ5_set_iomux_misc_spl();
+
 	/* load/boot image from boot device */
 	board_init_r(NULL, 0);
 }
 
+#define EM_PAD IMX_GPIO_NR(3, 29)
+int board_check_emergency_pad(void)
+{
+	int ret;
+
+	ret = gpio_direction_input(EM_PAD);
+	if (ret)
+		return ret;
+
+	return !gpio_get_value(EM_PAD);
+}
+
 void board_boot_order(u32 *spl_boot_list)
 {
 	/* Default boot sequence SPI -> MMC */
@@ -206,6 +221,13 @@
 	spl_boot_list[2] = BOOT_DEVICE_UART;
 	spl_boot_list[3] = BOOT_DEVICE_NONE;
 
+	/*
+	 * In case of emergency PAD pressed, we always boot
+	 * to proper u-boot and perform recovery tasks there.
+	 */
+	if (board_check_emergency_pad())
+		return;
+
 #ifdef CONFIG_SPL_ENV_SUPPORT
 	/* 'fastboot' */
 	const char *s;