[flashrom] [commit] r1750 - trunk

repository service svn at flashrom.org
Sun Sep 15 16:17:39 CEST 2013


Author: stefanct
Date: Sun Sep 15 16:17:39 2013
New Revision: 1750
URL: http://flashrom.org/trac/flashrom/changeset/1750

Log:
sbxxx: Set SPI clock to 16.5 MHz and disable fast reads.

Do not rely on broken firmware to set up the SPI configuration correctly.
Some boards fail with flashrom because the firmware chose too high speeds
for the alternate SPI mode which flashrom uses. Temporarily change the
clock to the lowest common value of 16.5 MHz.

Also, disable fast reads just to be safe.

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Modified:
   trunk/sb600spi.c

Modified: trunk/sb600spi.c
==============================================================================
--- trunk/sb600spi.c	Sun Sep 15 16:01:06 2013	(r1749)
+++ trunk/sb600spi.c	Sun Sep 15 16:17:39 2013	(r1750)
@@ -272,6 +272,62 @@
 	return 0;
 }
 
+struct spispeed {
+	const char *const name;
+	const uint8_t speed;
+};
+
+static const struct spispeed spispeeds[] = {
+	{ "66 MHz",	0x00 },
+	{ "33 MHz",	0x01 },
+	{ "22 MHz",	0x02 },
+	{ "16.5 MHz",	0x03 },
+};
+
+static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed)
+{
+	bool success = false;
+	uint8_t speed = spispeed->speed;
+
+	msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed);
+	if (amd_gen != CHIPSET_YANGTZE) {
+		rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd);
+		success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3));
+	}
+
+	if (!success) {
+		msg_perr("Setting SPI clock failed.\n");
+		return 1;
+	}
+	return 0;
+}
+
+static int handle_speed(struct pci_dev *dev)
+{
+	uint32_t tmp;
+	int8_t spispeed_idx = 3; /* Default to 16.5 MHz */
+
+	/* See the chipset support matrix for SPI Base_Addr below for an explanation of the symbols used.
+	 * bit   6xx   7xx/SP5100  8xx             9xx  hudson1  hudson234  yangtze
+	 * 18    rsvd  <-          fastReadEnable  ?    <-       ?          SpiReadMode[0]
+	 * 29:30 rsvd  <-          <-              ?    <-       ?          SpiReadMode[2:1]
+	 */
+	if (amd_gen != CHIPSET_YANGTZE) {
+		if (amd_gen >= CHIPSET_SB89XX && amd_gen <= CHIPSET_HUDSON234) {
+			bool fast_read = (mmio_readl(sb600_spibar + 0x00) >> 18) & 0x1;
+			msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis");
+			if (fast_read) {
+				msg_pdbg("Disabling them temporarily.\n");
+				rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18),
+					     sb600_spibar + 0x00);
+			}
+		}
+		tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
+		msg_pdbg("NormSpeed is %s\n", spispeeds[tmp].name);
+	}
+	return set_speed(dev, &spispeeds[spispeed_idx]);
+}
+
 static int sb600_handle_imc(struct pci_dev *dev, bool amd_imc_force)
 {
 	/* Handle IMC everywhere but sb600 which does not have one. */
@@ -322,9 +378,6 @@
 	uint32_t tmp;
 	uint8_t reg;
 	bool amd_imc_force = false;
-	static const char *const speed_names[4] = {
-		"66/reserved", "33", "22", "16.5"
-	};
 
 	char *arg = extract_programmer_param("amd_imc_force");
 	if (arg && !strcmp(arg, "yes")) {
@@ -411,7 +464,7 @@
 	 * See the chipset support matrix for SPI Base_Addr above for an explanation of the symbols used.
 	 * bit   6xx                7xx/SP5100      8xx               9xx  hudson1  hudson2+  yangtze
 	 * 17    rsvd               <-              <-                ?    <-       ?         <-
-	 * 18    rsvd               <-              fastReadEnable<1> ?    <-       ?         SpiReadMode[0]
+	 * 18    rsvd               <-              fastReadEnable<1> ?    <-       ?         SpiReadMode[0]<1>
 	 * 19    SpiArbEnable       <-              <-                ?    <-       ?         <-
 	 * 20    (FifoPtrClr)       <-              <-                ?    <-       ?         <-
 	 * 21    (FifoPtrInc)       <-              <-                ?    <-       ?         IllegalAccess
@@ -420,8 +473,10 @@
 	 * 24:26 ArbWaitCount       <-              <-                ?    <-       ?         <-
 	 * 27    SpiBridgeDisable   <-              <-                ?    <-       ?         rsvd
 	 * 28    rsvd               DropOneClkOnRd  = SPIClkGate      ?    <-       ?         <-
-	 * 29:30 rsvd               <-              <-                ?    <-       ?         SpiReadMode[2:1]
+	 * 29:30 rsvd               <-              <-                ?    <-       ?         SpiReadMode[2:1]<1>
 	 * 31    rsvd               <-              SpiBusy           ?    <-       ?         <-
+	 *
+	 *  <1> see handle_speed
 	 */
 	tmp = mmio_readl(sb600_spibar + 0x00);
 	msg_pdbg("(0x%08" PRIx32 ") SpiArbEnable=%i", tmp, (tmp >> 19) & 0x1);
@@ -447,9 +502,6 @@
 		return ERROR_NONFATAL;
 	}
 
-	tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
-	msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]);
-
 	if (amd_gen >= CHIPSET_SB89XX) {
 		tmp = mmio_readb(sb600_spibar + 0x1D);
 		msg_pdbg("Using SPI_CS%d\n", tmp & 0x3);
@@ -494,6 +546,9 @@
 		return 0;
 	}
 
+	if (handle_speed(dev) != 0)
+		return ERROR_FATAL;
+
 	if (sb600_handle_imc(dev, amd_imc_force) != 0)
 		return ERROR_FATAL;
 




More information about the flashrom mailing list