Move Intel SPI initialisation to ichspi.c

Smarter version could decide whether SPI is vital or not depending on
straps. Straps are currently implemented for ICH7. EP80579 is in the comment,
PCH of 5 Series/3400 Series has "LPC, reserved, PCI, SPI".

Corresponding to flashrom svn r1098.

Signed-off-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
diff --git a/chipset_enable.c b/chipset_enable.c
index dc0e55f..bb18b4d 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -417,69 +417,15 @@
 
 static int enable_flash_vt8237s_spi(struct pci_dev *dev, const char *name)
 {
-	uint32_t mmio_base;
-
 	/* Do we really need no write enable? */
-	mmio_base = (pci_read_long(dev, 0xbc)) << 8;
-	msg_pdbg("MMIO base at = 0x%x\n", mmio_base);
-	ich_spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
-
-	msg_pdbg("0x6c: 0x%04x     (CLOCK/DEBUG)\n",
-		     mmio_readw(ich_spibar + 0x6c));
-
-	/* Not sure if it speaks all these bus protocols. */
-	buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
-	spi_controller = SPI_CONTROLLER_VIA;
-	ich_init_opcodes();
-
-	return 0;
-}
-
-#define ICH_BMWAG(x) ((x >> 24) & 0xff)
-#define ICH_BMRAG(x) ((x >> 16) & 0xff)
-#define ICH_BRWA(x)  ((x >>  8) & 0xff)
-#define ICH_BRRA(x)  ((x >>  0) & 0xff)
-
-#define ICH_FREG_BASE(x)  ((x >>  0) & 0x1fff)
-#define ICH_FREG_LIMIT(x) ((x >> 16) & 0x1fff)
-
-static void do_ich9_spi_frap(uint32_t frap, int i)
-{
-	const char *access_names[4] = {
-		"locked", "read-only", "write-only", "read-write"
-	};
-	const char *region_names[5] = {
-		"Flash Descriptor", "BIOS", "Management Engine",
-		"Gigabit Ethernet", "Platform Data"
-	};
-	uint32_t base, limit;
-	int rwperms = (((ICH_BRWA(frap) >> i) & 1) << 1) |
-		      (((ICH_BRRA(frap) >> i) & 1) << 0);
-	int offset = 0x54 + i * 4;
-	uint32_t freg = mmio_readl(ich_spibar + offset);
-
-	msg_pdbg("0x%02X: 0x%08x (FREG%i: %s)\n",
-		     offset, freg, i, region_names[i]);
-
-	base  = ICH_FREG_BASE(freg);
-	limit = ICH_FREG_LIMIT(freg);
-	if (base == 0x1fff && limit == 0) {
-		/* this FREG is disabled */
-		msg_pdbg("%s region is unused.\n", region_names[i]);
-		return;
-	}
-
-	msg_pdbg("0x%08x-0x%08x is %s\n",
-		    (base << 12), (limit << 12) | 0x0fff,
-		    access_names[rwperms]);
+	return via_init_spi(dev);
 }
 
 static int enable_flash_ich_dc_spi(struct pci_dev *dev, const char *name,
 				   int ich_generation)
 {
-	int ret, i;
-	uint8_t old, new, bbs, buc;
-	uint16_t spibar_offset, tmp2;
+	int ret;
+	uint8_t bbs, buc;
 	uint32_t tmp, gcs;
 	void *rcrb;
 	//TODO: These names are incorrect for EP80579. For that, the solution would look like the commented line
@@ -512,152 +458,22 @@
 	 * on ICH7 when the southbridge is strapped to LPC
 	 */
 
-	if (ich_generation == 7 && bbs == ICH_STRAP_LPC) {
-		buses_supported = CHIP_BUSTYPE_FWH;
-		/* No further SPI initialization required */
-		return ret;
+	buses_supported = CHIP_BUSTYPE_FWH;
+	if (ich_generation == 7) {
+		if(bbs == ICH_STRAP_LPC) {
+			/* No further SPI initialization required */
+			return ret;
+		}
+		else
+			/* Disable LPC/FWH if strapped to PCI or SPI */
+			buses_supported = 0;
 	}
 
-	switch (ich_generation) {
-	case 7:
-		buses_supported = CHIP_BUSTYPE_SPI;
-		spi_controller = SPI_CONTROLLER_ICH7;
-		spibar_offset = 0x3020;
-		break;
-	case 8:
-		buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
-		spi_controller = SPI_CONTROLLER_ICH9;
-		spibar_offset = 0x3020;
-		break;
-	case 9:
-	case 10:
-	default:		/* Future version might behave the same */
-		buses_supported = CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
-		spi_controller = SPI_CONTROLLER_ICH9;
-		spibar_offset = 0x3800;
-		break;
-	}
-
-	/* SPIBAR is at RCRB+0x3020 for ICH[78] and RCRB+0x3800 for ICH9. */
-	msg_pdbg("SPIBAR = 0x%x + 0x%04x\n", tmp, spibar_offset);
-
-	/* Assign Virtual Address */
-	ich_spibar = rcrb + spibar_offset;
-
-	switch (spi_controller) {
-	case SPI_CONTROLLER_ICH7:
-		msg_pdbg("0x00: 0x%04x     (SPIS)\n",
-			     mmio_readw(ich_spibar + 0));
-		msg_pdbg("0x02: 0x%04x     (SPIC)\n",
-			     mmio_readw(ich_spibar + 2));
-		msg_pdbg("0x04: 0x%08x (SPIA)\n",
-			     mmio_readl(ich_spibar + 4));
-		for (i = 0; i < 8; i++) {
-			int offs;
-			offs = 8 + (i * 8);
-			msg_pdbg("0x%02x: 0x%08x (SPID%d)\n", offs,
-				     mmio_readl(ich_spibar + offs), i);
-			msg_pdbg("0x%02x: 0x%08x (SPID%d+4)\n", offs + 4,
-				     mmio_readl(ich_spibar + offs + 4), i);
-		}
-		ichspi_bbar = mmio_readl(ich_spibar + 0x50);
-		msg_pdbg("0x50: 0x%08x (BBAR)\n",
-			     ichspi_bbar);
-		msg_pdbg("0x54: 0x%04x     (PREOP)\n",
-			     mmio_readw(ich_spibar + 0x54));
-		msg_pdbg("0x56: 0x%04x     (OPTYPE)\n",
-			     mmio_readw(ich_spibar + 0x56));
-		msg_pdbg("0x58: 0x%08x (OPMENU)\n",
-			     mmio_readl(ich_spibar + 0x58));
-		msg_pdbg("0x5c: 0x%08x (OPMENU+4)\n",
-			     mmio_readl(ich_spibar + 0x5c));
-		for (i = 0; i < 4; i++) {
-			int offs;
-			offs = 0x60 + (i * 4);
-			msg_pdbg("0x%02x: 0x%08x (PBR%d)\n", offs,
-				     mmio_readl(ich_spibar + offs), i);
-		}
-		msg_pdbg("\n");
-		if (mmio_readw(ich_spibar) & (1 << 15)) {
-			msg_pinfo("WARNING: SPI Configuration Lockdown activated.\n");
-			ichspi_lock = 1;
-		}
-		ich_init_opcodes();
-		break;
-	case SPI_CONTROLLER_ICH9:
-		tmp2 = mmio_readw(ich_spibar + 4);
-		msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
-		msg_pdbg("FLOCKDN %i, ", (tmp2 >> 15 & 1));
-		msg_pdbg("FDV %i, ", (tmp2 >> 14) & 1);
-		msg_pdbg("FDOPSS %i, ", (tmp2 >> 13) & 1);
-		msg_pdbg("SCIP %i, ", (tmp2 >> 5) & 1);
-		msg_pdbg("BERASE %i, ", (tmp2 >> 3) & 3);
-		msg_pdbg("AEL %i, ", (tmp2 >> 2) & 1);
-		msg_pdbg("FCERR %i, ", (tmp2 >> 1) & 1);
-		msg_pdbg("FDONE %i\n", (tmp2 >> 0) & 1);
-
-		tmp = mmio_readl(ich_spibar + 0x50);
-		msg_pdbg("0x50: 0x%08x (FRAP)\n", tmp);
-		msg_pdbg("BMWAG 0x%02x, ", ICH_BMWAG(tmp));
-		msg_pdbg("BMRAG 0x%02x, ", ICH_BMRAG(tmp));
-		msg_pdbg("BRWA 0x%02x, ", ICH_BRWA(tmp));
-		msg_pdbg("BRRA 0x%02x\n", ICH_BRRA(tmp));
-
-		/* print out the FREGx registers along with FRAP access bits */
-		for(i = 0; i < 5; i++)
-			do_ich9_spi_frap(tmp, i);
-
-		msg_pdbg("0x74: 0x%08x (PR0)\n",
-			     mmio_readl(ich_spibar + 0x74));
-		msg_pdbg("0x78: 0x%08x (PR1)\n",
-			     mmio_readl(ich_spibar + 0x78));
-		msg_pdbg("0x7C: 0x%08x (PR2)\n",
-			     mmio_readl(ich_spibar + 0x7C));
-		msg_pdbg("0x80: 0x%08x (PR3)\n",
-			     mmio_readl(ich_spibar + 0x80));
-		msg_pdbg("0x84: 0x%08x (PR4)\n",
-			     mmio_readl(ich_spibar + 0x84));
-		msg_pdbg("0x90: 0x%08x (SSFS, SSFC)\n",
-			     mmio_readl(ich_spibar + 0x90));
-		msg_pdbg("0x94: 0x%04x     (PREOP)\n",
-			     mmio_readw(ich_spibar + 0x94));
-		msg_pdbg("0x96: 0x%04x     (OPTYPE)\n",
-			     mmio_readw(ich_spibar + 0x96));
-		msg_pdbg("0x98: 0x%08x (OPMENU)\n",
-			     mmio_readl(ich_spibar + 0x98));
-		msg_pdbg("0x9C: 0x%08x (OPMENU+4)\n",
-			     mmio_readl(ich_spibar + 0x9C));
-		ichspi_bbar = mmio_readl(ich_spibar + 0xA0);
-		msg_pdbg("0xA0: 0x%08x (BBAR)\n",
-			     ichspi_bbar);
-		msg_pdbg("0xB0: 0x%08x (FDOC)\n",
-			     mmio_readl(ich_spibar + 0xB0));
-		if (tmp2 & (1 << 15)) {
-			msg_pinfo("WARNING: SPI Configuration Lockdown activated.\n");
-			ichspi_lock = 1;
-		}
-		ich_init_opcodes();
-		break;
-	default:
-		/* Nothing */
-		break;
-	}
-
-	old = pci_read_byte(dev, 0xdc);
-	msg_pdbg("SPI Read Configuration: ");
-	new = (old >> 2) & 0x3;
-	switch (new) {
-	case 0:
-	case 1:
-	case 2:
-		msg_pdbg("prefetching %sabled, caching %sabled, ",
-			     (new & 0x2) ? "en" : "dis",
-			     (new & 0x1) ? "dis" : "en");
-		break;
-	default:
-		msg_pdbg("invalid prefetching/caching settings, ");
-		break;
-	}
+	/* this adds CHIP_BUSTYPE_SPI */
+	if (ich_init_spi(dev, tmp, rcrb, ich_generation) != 0) {
+	        if (!ret)
+		        ret = ERROR_NONFATAL;
+        }
 
 	return ret;
 }
@@ -1546,6 +1362,8 @@
 			msg_pinfo("FAILED!\n");
 		else if(ret == 0)
 			msg_pinfo("OK.\n");
+		else if(ret == ERROR_NONFATAL)
+			msg_pinfo("PROBLEMS, continuing anyway\n");
 	}
 
 	msg_pinfo("This chipset supports the following protocols: %s.\n",
diff --git a/flash.h b/flash.h
index ca3f6f5..1cf333a 100644
--- a/flash.h
+++ b/flash.h
@@ -607,6 +607,9 @@
 #define OK 0
 #define NT 1    /* Not tested */
 
+/* Something happened that shouldn't happen, but we can go on */
+#define ERROR_NONFATAL 0x100
+
 /* cli_output.c */
 /* Let gcc and clang check for correct printf-style format strings. */
 int print(int type, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
@@ -694,10 +697,10 @@
 uint32_t spi_get_valid_read_addr(void);
 
 /* ichspi.c */
-extern int ichspi_lock;
 extern uint32_t ichspi_bbar;
-extern void *ich_spibar;
-int ich_init_opcodes(void);
+int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb,
+		    int ich_generation);
+int via_init_spi(struct pci_dev *dev);
 int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt,
 		    const unsigned char *writearr, unsigned char *readarr);
 int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
diff --git a/ichspi.c b/ichspi.c
index d6f9118..88e993d 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -101,11 +101,11 @@
 #define ICH7_REG_OPMENU                0x58	/* 64 Bits */
 
 /* ICH SPI configuration lock-down. May be set during chipset enabling. */
-int ichspi_lock = 0;
+static int ichspi_lock = 0;
 
 uint32_t ichspi_bbar = 0;
 
-void *ich_spibar = NULL;
+static void *ich_spibar = NULL;
 
 typedef struct _OPCODE {
 	uint8_t opcode;		//This commands spi opcode
@@ -364,7 +364,7 @@
  *
  * It should be called before ICH sends any spi command.
  */
-int ich_init_opcodes(void)
+static int ich_init_opcodes(void)
 {
 	int rc = 0;
 	OPCODES *curopcodes_done;
@@ -863,4 +863,211 @@
 	return ret;
 }
 
+#define ICH_BMWAG(x) ((x >> 24) & 0xff)
+#define ICH_BMRAG(x) ((x >> 16) & 0xff)
+#define ICH_BRWA(x)  ((x >>  8) & 0xff)
+#define ICH_BRRA(x)  ((x >>  0) & 0xff)
+
+#define ICH_FREG_BASE(x)  ((x >>  0) & 0x1fff)
+#define ICH_FREG_LIMIT(x) ((x >> 16) & 0x1fff)
+
+static void do_ich9_spi_frap(uint32_t frap, int i)
+{
+	const char *access_names[4] = {
+		"locked", "read-only", "write-only", "read-write"
+	};
+	const char *region_names[5] = {
+		"Flash Descriptor", "BIOS", "Management Engine",
+		"Gigabit Ethernet", "Platform Data"
+	};
+	uint32_t base, limit;
+	int rwperms = (((ICH_BRWA(frap) >> i) & 1) << 1) |
+		      (((ICH_BRRA(frap) >> i) & 1) << 0);
+	int offset = 0x54 + i * 4;
+	uint32_t freg = mmio_readl(ich_spibar + offset);
+
+	msg_pdbg("0x%02X: 0x%08x (FREG%i: %s)\n",
+		     offset, freg, i, region_names[i]);
+
+	base  = ICH_FREG_BASE(freg);
+	limit = ICH_FREG_LIMIT(freg);
+	if (base == 0x1fff && limit == 0) {
+		/* this FREG is disabled */
+		msg_pdbg("%s region is unused.\n", region_names[i]);
+		return;
+	}
+
+	msg_pdbg("0x%08x-0x%08x is %s\n",
+		    (base << 12), (limit << 12) | 0x0fff,
+		    access_names[rwperms]);
+}
+
+int ich_init_spi(struct pci_dev *dev, uint32_t base, void *rcrb,
+			int ich_generation)
+{
+	int i;
+	uint8_t old, new;
+	uint16_t spibar_offset, tmp2;
+	uint32_t tmp;
+
+	buses_supported |= CHIP_BUSTYPE_SPI;
+	switch (ich_generation) {
+	case 7:
+		spi_controller = SPI_CONTROLLER_ICH7;
+		spibar_offset = 0x3020;
+		break;
+	case 8:
+		spi_controller = SPI_CONTROLLER_ICH9;
+		spibar_offset = 0x3020;
+		break;
+	case 9:
+	case 10:
+	default:		/* Future version might behave the same */
+		spi_controller = SPI_CONTROLLER_ICH9;
+		spibar_offset = 0x3800;
+		break;
+	}
+
+	/* SPIBAR is at RCRB+0x3020 for ICH[78] and RCRB+0x3800 for ICH9. */
+	msg_pdbg("SPIBAR = 0x%x + 0x%04x\n", base, spibar_offset);
+
+	/* Assign Virtual Address */
+	ich_spibar = rcrb + spibar_offset;
+
+	switch (spi_controller) {
+	case SPI_CONTROLLER_ICH7:
+		msg_pdbg("0x00: 0x%04x     (SPIS)\n",
+			     mmio_readw(ich_spibar + 0));
+		msg_pdbg("0x02: 0x%04x     (SPIC)\n",
+			     mmio_readw(ich_spibar + 2));
+		msg_pdbg("0x04: 0x%08x (SPIA)\n",
+			     mmio_readl(ich_spibar + 4));
+		for (i = 0; i < 8; i++) {
+			int offs;
+			offs = 8 + (i * 8);
+			msg_pdbg("0x%02x: 0x%08x (SPID%d)\n", offs,
+				     mmio_readl(ich_spibar + offs), i);
+			msg_pdbg("0x%02x: 0x%08x (SPID%d+4)\n", offs + 4,
+				     mmio_readl(ich_spibar + offs + 4), i);
+		}
+		ichspi_bbar = mmio_readl(ich_spibar + 0x50);
+		msg_pdbg("0x50: 0x%08x (BBAR)\n",
+			     ichspi_bbar);
+		msg_pdbg("0x54: 0x%04x     (PREOP)\n",
+			     mmio_readw(ich_spibar + 0x54));
+		msg_pdbg("0x56: 0x%04x     (OPTYPE)\n",
+			     mmio_readw(ich_spibar + 0x56));
+		msg_pdbg("0x58: 0x%08x (OPMENU)\n",
+			     mmio_readl(ich_spibar + 0x58));
+		msg_pdbg("0x5c: 0x%08x (OPMENU+4)\n",
+			     mmio_readl(ich_spibar + 0x5c));
+		for (i = 0; i < 4; i++) {
+			int offs;
+			offs = 0x60 + (i * 4);
+			msg_pdbg("0x%02x: 0x%08x (PBR%d)\n", offs,
+				     mmio_readl(ich_spibar + offs), i);
+		}
+		msg_pdbg("\n");
+		if (mmio_readw(ich_spibar) & (1 << 15)) {
+			msg_pinfo("WARNING: SPI Configuration Lockdown activated.\n");
+			ichspi_lock = 1;
+		}
+		ich_init_opcodes();
+		break;
+	case SPI_CONTROLLER_ICH9:
+		tmp2 = mmio_readw(ich_spibar + 4);
+		msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
+		msg_pdbg("FLOCKDN %i, ", (tmp2 >> 15 & 1));
+		msg_pdbg("FDV %i, ", (tmp2 >> 14) & 1);
+		msg_pdbg("FDOPSS %i, ", (tmp2 >> 13) & 1);
+		msg_pdbg("SCIP %i, ", (tmp2 >> 5) & 1);
+		msg_pdbg("BERASE %i, ", (tmp2 >> 3) & 3);
+		msg_pdbg("AEL %i, ", (tmp2 >> 2) & 1);
+		msg_pdbg("FCERR %i, ", (tmp2 >> 1) & 1);
+		msg_pdbg("FDONE %i\n", (tmp2 >> 0) & 1);
+
+		tmp = mmio_readl(ich_spibar + 0x50);
+		msg_pdbg("0x50: 0x%08x (FRAP)\n", tmp);
+		msg_pdbg("BMWAG 0x%02x, ", ICH_BMWAG(tmp));
+		msg_pdbg("BMRAG 0x%02x, ", ICH_BMRAG(tmp));
+		msg_pdbg("BRWA 0x%02x, ", ICH_BRWA(tmp));
+		msg_pdbg("BRRA 0x%02x\n", ICH_BRRA(tmp));
+
+		/* print out the FREGx registers along with FRAP access bits */
+		for(i = 0; i < 5; i++)
+			do_ich9_spi_frap(tmp, i);
+
+		msg_pdbg("0x74: 0x%08x (PR0)\n",
+			     mmio_readl(ich_spibar + 0x74));
+		msg_pdbg("0x78: 0x%08x (PR1)\n",
+			     mmio_readl(ich_spibar + 0x78));
+		msg_pdbg("0x7C: 0x%08x (PR2)\n",
+			     mmio_readl(ich_spibar + 0x7C));
+		msg_pdbg("0x80: 0x%08x (PR3)\n",
+			     mmio_readl(ich_spibar + 0x80));
+		msg_pdbg("0x84: 0x%08x (PR4)\n",
+			     mmio_readl(ich_spibar + 0x84));
+		msg_pdbg("0x90: 0x%08x (SSFS, SSFC)\n",
+			     mmio_readl(ich_spibar + 0x90));
+		msg_pdbg("0x94: 0x%04x     (PREOP)\n",
+			     mmio_readw(ich_spibar + 0x94));
+		msg_pdbg("0x96: 0x%04x     (OPTYPE)\n",
+			     mmio_readw(ich_spibar + 0x96));
+		msg_pdbg("0x98: 0x%08x (OPMENU)\n",
+			     mmio_readl(ich_spibar + 0x98));
+		msg_pdbg("0x9C: 0x%08x (OPMENU+4)\n",
+			     mmio_readl(ich_spibar + 0x9C));
+		ichspi_bbar = mmio_readl(ich_spibar + 0xA0);
+		msg_pdbg("0xA0: 0x%08x (BBAR)\n",
+			     ichspi_bbar);
+		msg_pdbg("0xB0: 0x%08x (FDOC)\n",
+			     mmio_readl(ich_spibar + 0xB0));
+		if (tmp2 & (1 << 15)) {
+			msg_pinfo("WARNING: SPI Configuration Lockdown activated.\n");
+			ichspi_lock = 1;
+		}
+		ich_init_opcodes();
+		break;
+	default:
+		/* Nothing */
+		break;
+	}
+
+	old = pci_read_byte(dev, 0xdc);
+	msg_pdbg("SPI Read Configuration: ");
+	new = (old >> 2) & 0x3;
+	switch (new) {
+	case 0:
+	case 1:
+	case 2:
+		msg_pdbg("prefetching %sabled, caching %sabled, ",
+			     (new & 0x2) ? "en" : "dis",
+			     (new & 0x1) ? "dis" : "en");
+		break;
+	default:
+		msg_pdbg("invalid prefetching/caching settings, ");
+		break;
+	}
+	return 0;
+}
+
+int via_init_spi(struct pci_dev *dev)
+{
+	uint32_t mmio_base;
+
+	mmio_base = (pci_read_long(dev, 0xbc)) << 8;
+	msg_pdbg("MMIO base at = 0x%x\n", mmio_base);
+	ich_spibar = physmap("VT8237S MMIO registers", mmio_base, 0x70);
+
+	msg_pdbg("0x6c: 0x%04x     (CLOCK/DEBUG)\n",
+		     mmio_readw(ich_spibar + 0x6c));
+
+	/* Not sure if it speaks all these bus protocols. */
+	buses_supported = CHIP_BUSTYPE_LPC | CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI;
+	spi_controller = SPI_CONTROLLER_VIA;
+	ich_init_opcodes();
+
+	return 0;
+}
+
 #endif