drivers: spi_flash: Addressing mode change for SPI NOR

As 4-byte addressing mode is not support in coreboot, change the
addressing mode of SPI NOR from 4-bytes to 3-bytes.

BUG=b:215605946
TEST=Validated on qualcomm sc7280 development board

Signed-off-by: Veerabhadrarao Badiganti <quic_vbadigan@quicinc.com>
Signed-off-by: Shaik Sajida Bhanu <quic_c_sbhanu@quicinc.com>
Change-Id: Ied5b647d0fcc8e3effff3bb7c8680ed5a0c1f3d4
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50586
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Shelley Chen <shchen@google.com>
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index 13a73b8..b7650dd 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -162,6 +162,17 @@
 	  Allows chipset to group write/erase operations under a single volatile
 	  group.
 
+config SPI_FLASH_EXIT_4_BYTE_ADDR_MODE
+	bool
+	default n
+	help
+	  This will send an Exit 4-Byte Address Mode (E9h) command before the first
+	  access to the SPI flash. On some platforms with SPI flashes larger than 32MB,
+	  the SPI flash may power up in 4-byte addressing mode and this command needs
+	  to be sent before coreboot's 3-byte address commands can be interpreted correctly.
+	  On flashes that don't support 4-byte addressing mode or where it is already
+	  disabled, this command should be a no-op.
+
 endif # SPI_FLASH
 
 config HAVE_EM100PRO_SPI_CONSOLE_SUPPORT
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index f3cecd5..ded88ed 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -515,6 +515,10 @@
 			" CONFIG_ROM_SIZE 0x%x!!\n", flash->size,
 			CONFIG_ROM_SIZE);
 	}
+
+	if (CONFIG(SPI_FLASH_EXIT_4_BYTE_ADDR_MODE) && ENV_INITIAL_STAGE)
+		spi_flash_cmd(&flash->spi, CMD_EXIT_4BYTE_ADDR_MODE, NULL, 0);
+
 	return 0;
 }
 
diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h
index 4a7beea..e388311 100644
--- a/src/drivers/spi/spi_flash_internal.h
+++ b/src/drivers/spi/spi_flash_internal.h
@@ -22,6 +22,8 @@
 
 #define CMD_BLOCK_ERASE			0xD8
 
+#define CMD_EXIT_4BYTE_ADDR_MODE	0xe9
+
 /* Common status */
 #define STATUS_WIP			0x01