herobrine: Add fingerprint power sequencing

For Herobrine variants that include a finger print sensor, we will
need to power sequence it.  We are using the same FP sensor as
trogdor, so we will follow the timings used for trogdor from
CL:2695676.

BUG=b:198474942
BRANCH=None
TEST=./util/abuild/abuild -p none -t GOOGLE_HEROBRINE -x -a -c max -B

Change-Id: Ica6eafc47cf1b95eeb8d94c6e0a8c88519665e3f
Signed-off-by: Shelley Chen <shchen@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/58021
Reviewed-by: Alexandru Stan <amstan@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/mainboard/google/herobrine/Kconfig b/src/mainboard/google/herobrine/Kconfig
index 3a56fa7..c4c943e 100644
--- a/src/mainboard/google/herobrine/Kconfig
+++ b/src/mainboard/google/herobrine/Kconfig
@@ -3,6 +3,11 @@
 
 if BOARD_GOOGLE_HEROBRINE_COMMON
 
+config HEROBRINE_HAS_FINGERPRINT
+	bool
+	default y if BOARD_GOOGLE_HEROBRINE
+	default n
+
 config BOARD_SPECIFIC_OPTIONS
 	def_bool y
 	select BOARD_ROMSIZE_KB_65536 if BOARD_GOOGLE_PIGLIN || BOARD_GOOGLE_HOGLIN
diff --git a/src/mainboard/google/herobrine/board.h b/src/mainboard/google/herobrine/board.h
index 33c8c7d..0e4a760 100644
--- a/src/mainboard/google/herobrine/board.h
+++ b/src/mainboard/google/herobrine/board.h
@@ -3,6 +3,7 @@
 #ifndef _COREBOOT_SRC_MAINBOARD_GOOGLE_HEROBRINE_BOARD_H_
 #define _COREBOOT_SRC_MAINBOARD_GOOGLE_HEROBRINE_BOARD_H_
 
+#include <assert.h>
 #include <boardid.h>
 #include <gpio.h>
 
@@ -12,6 +13,17 @@
 #define QCOM_SC7280_SKU2 0x1
 #define QCOM_SC7280_SKU3 0x2
 
+/* Fingerprint-specific GPIOs. Only for fingerprint-enabled devices. */
+#if CONFIG(HEROBRINE_HAS_FINGERPRINT)
+#define GPIO_FPMCU_BOOT0	GPIO(77)
+#define GPIO_FP_RST_L		GPIO(78)
+#define GPIO_EN_FP_RAILS	GPIO(42)
+#else
+#define GPIO_FPMCU_BOOT0	dead_code_t(gpio_t)
+#define GPIO_FP_RST_L		dead_code_t(gpio_t)
+#define GPIO_EN_FP_RAILS	dead_code_t(gpio_t)
+#endif
+
 void setup_chromeos_gpios(void);
 
 #endif /* _COREBOOT_SRC_MAINBOARD_GOOGLE_HEROBRINE_BOARD_H_ */
diff --git a/src/mainboard/google/herobrine/chromeos.c b/src/mainboard/google/herobrine/chromeos.c
index 319f929..9faf4ba 100644
--- a/src/mainboard/google/herobrine/chromeos.c
+++ b/src/mainboard/google/herobrine/chromeos.c
@@ -7,6 +7,12 @@
 void setup_chromeos_gpios(void)
 {
 	gpio_input_pullup(GPIO_SD_CD_L);
+
+	if (CONFIG(HEROBRINE_HAS_FINGERPRINT)) {
+		gpio_output(GPIO_FPMCU_BOOT0, 0);
+		gpio_output(GPIO_FP_RST_L, 0);
+		gpio_output(GPIO_EN_FP_RAILS, 0);
+	}
 }
 
 void fill_lb_gpios(struct lb_gpios *gpios)
diff --git a/src/mainboard/google/herobrine/mainboard.c b/src/mainboard/google/herobrine/mainboard.c
index 98e6f5c..ffcd71f 100644
--- a/src/mainboard/google/herobrine/mainboard.c
+++ b/src/mainboard/google/herobrine/mainboard.c
@@ -51,6 +51,12 @@
 	qupv3_se_fw_load_and_init(QUPV3_1_SE4, SE_PROTOCOL_SPI, MIXED);  /* ESIM SPI */
 	qupv3_se_fw_load_and_init(QUPV3_1_SE6, SE_PROTOCOL_SPI, MIXED);  /* Fingerprint SPI */
 #endif
+
+	/* Take FPMCU out of reset. Power was already applied
+	   in romstage and should have stabilized by now. */
+	if (CONFIG(HEROBRINE_HAS_FINGERPRINT))
+		gpio_output(GPIO_FP_RST_L, 1);
+
 }
 
 static void mainboard_enable(struct device *dev)
diff --git a/src/mainboard/google/herobrine/romstage.c b/src/mainboard/google/herobrine/romstage.c
index 8844f18..64aeaaa 100644
--- a/src/mainboard/google/herobrine/romstage.c
+++ b/src/mainboard/google/herobrine/romstage.c
@@ -2,9 +2,16 @@
 
 #include <arch/stages.h>
 #include <soc/qclib_common.h>
+#include "board.h"
 
 void platform_romstage_main(void)
 {
 	/* QCLib: DDR init & train */
 	qclib_load_and_run();
+
+	/* This rail needs to be stable by the time we take the FPMCU out of
+	   reset in ramstage, so already turn it on here. This needs to happen
+	   at least 200ms after this pin was first driven low in the bootblock. */
+	if (CONFIG(HEROBRINE_HAS_FINGERPRINT))
+		gpio_output(GPIO_EN_FP_RAILS, 1);
 }