drivers/spi: Add ISSI IS25WP256D flash

datasheet: IS25WP256D Rev A13 (2023-08-03)

tested:
boot SiFive Hifive Unmatched board

Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com>
Change-Id: I655776258cbcf464becf38cbb5045cda5bca711c
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79369
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index 8c251d7..6d161f4 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -155,6 +155,13 @@
 	  Select this option if your chipset driver needs to store certain
 	  data in the SPI flash and your SPI flash is made by Winbond.
 
+config SPI_FLASH_ISSI
+	bool
+	default y if SPI_FLASH_INCLUDE_ALL_DRIVERS
+	help
+	  Select this option if your chipset driver needs to store certain
+	  data in the SPI flash and your SPI flash is made by ISSI.
+
 config SPI_FLASH_HAS_VOLATILE_GROUP
 	bool
 	default n
diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc
index 954eef2..97c3d63 100644
--- a/src/drivers/spi/Makefile.inc
+++ b/src/drivers/spi/Makefile.inc
@@ -30,6 +30,7 @@
 $(1)-$(CONFIG_SPI_FLASH_SST) += sst.c
 $(1)-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c
 $(1)-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c
+$(1)-$(CONFIG_SPI_FLASH_ISSI) += issi.c
 endef
 
 $(eval $(call add_spi_stage,bootblock,_EARLY))
diff --git a/src/drivers/spi/issi.c b/src/drivers/spi/issi.c
new file mode 100644
index 0000000..45fe5a1
--- /dev/null
+++ b/src/drivers/spi/issi.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <console/console.h>
+#include <commonlib/helpers.h>
+#include <spi_flash.h>
+#include <spi-generic.h>
+#include <delay.h>
+#include <lib.h>
+
+#include "spi_flash_internal.h"
+
+static const struct spi_flash_part_id flash_table[] = {
+	{
+		/* IS25WP256D */
+		.id[0]				= 0x7019,
+		.nr_sectors_shift		= 13,
+	},
+};
+
+const struct spi_flash_vendor_info spi_flash_issi_vi = {
+	.id = VENDOR_ID_ISSI,
+	.page_size_shift = 8,        // 256 byte page size
+	.sector_size_kib_shift = 2,  // 4 Kbyte sector size
+	.match_id_mask[0] = 0xffff,
+	.ids = flash_table,
+	.nr_part_ids = ARRAY_SIZE(flash_table),
+	.desc = &spi_flash_pp_0x20_sector_desc,
+	.prot_ops = NULL,
+};
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 7619f64..42952df 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -397,6 +397,9 @@
 #if CONFIG(SPI_FLASH_WINBOND)
 	&spi_flash_winbond_vi,
 #endif
+#if CONFIG(SPI_FLASH_ISSI)
+	&spi_flash_issi_vi,
+#endif
 };
 #define IDCODE_LEN 5
 
diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h
index 6111374..3aea914 100644
--- a/src/drivers/spi/spi_flash_internal.h
+++ b/src/drivers/spi/spi_flash_internal.h
@@ -123,6 +123,7 @@
 extern const struct spi_flash_vendor_info spi_flash_stmicro3_vi;
 extern const struct spi_flash_vendor_info spi_flash_stmicro4_vi;
 extern const struct spi_flash_vendor_info spi_flash_winbond_vi;
+extern const struct spi_flash_vendor_info spi_flash_issi_vi;
 
 /* Page Programming Command Set with 0x20 Sector Erase command. */
 extern const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc;
diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h
index acb22ec..aa28232 100644
--- a/src/include/spi-generic.h
+++ b/src/include/spi-generic.h
@@ -25,6 +25,7 @@
 #define VENDOR_ID_SST				0xbf
 #define VENDOR_ID_STMICRO			0x20
 #define VENDOR_ID_WINBOND			0xef
+#define VENDOR_ID_ISSI				0x9d
 
 /* Controller-specific definitions: */