[flashrom] [PATCH 4/4] sbxxx: Add spispeed parameter.

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Fri Aug 9 00:55:02 CEST 2013


TODO: manpage + commit message

Allow to set the SPI clock frequency on SB600 et al. with a programmer
parameter. If the parameter is given (and matches a possible value), the
SPI clock is set temporarily. Both registers are restored on programmer
shutdown.

Example: ./flashrom -p internal:spispeed="33 MHz" -V

Possible values for spispeed are "66/reserved", "33", "22", "16.5".

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 flashrom.8 | 14 ++++++++++++++
 sb600spi.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/flashrom.8 b/flashrom.8
index dccfd1a..8b5e09c 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -345,6 +345,20 @@ syntax. The user is responsible for supplying a suitable image or leaving out th
 a layout file. This limitation might be removed in the future when we understand the details better and have
 received enough feedback from users. Please report the outcome if you had to use this option to write a chip.
 .sp
+An optional
+.B spispeed
+parameter specifies the frequency of the SPI bus where applicable (i.e.\& SB600 or later with SPI flash chip
+directly attached to the chipset).
+Syntax is
+.sp
+.B "  flashrom \-p internal:spispeed=frequency"
+.sp
+where
+.B frequency
+can be
+.BR 16.5 ", " 22 ", " 33 " or " 66/reserved "
+(in MHz). The default is to not change the preset value. The use of this parameter also disables Fast Reads.
+.sp
 .TP
 .B Intel chipsets
 .sp
diff --git a/sb600spi.c b/sb600spi.c
index 98238c2..330ad9a 100644
--- a/sb600spi.c
+++ b/sb600spi.c
@@ -350,6 +350,29 @@ static int handle_speed(struct pci_dev *dev)
 	uint8_t tmp;
 	uint8_t spispeed_idx = 3; /* Default to 16.5 MHz */
 
+	char *spispeed = extract_programmer_param("spispeed");
+	if (spispeed != NULL) {
+		if (strcasecmp(spispeed, "reserved") != 0) {
+			int i;
+			for (i = 0; i < ARRAY_SIZE(spispeeds); i++) {
+				if (strcasecmp(spispeeds[i].name, spispeed) == 0) {
+					spispeed_idx = i;
+					break;
+				}
+			}
+			/* Only Yangtze supports the second half of indices; no 66 MHz before SB8xx. */
+			if ((amd_gen < CHIPSET_YANGTZE && spispeed_idx > 3) ||
+			    (amd_gen < CHIPSET_SB89XX && spispeed_idx == 0))
+				spispeed_idx = -1;
+		}
+		if (spispeed_idx < 0) {
+			msg_perr("Error: Invalid spispeed value: '%s'.\n", spispeed);
+			free(spispeed);
+			return 1;
+		}
+		free(spispeed);
+	}
+
 /* bit   6xx   7xx/SP5100  8xx             9xx  hudson1  hudson234  yangtze
  * 18    rsvd  <-          fastReadEnable  ?    <-       ?          SpiReadMode[0]
  * 29:30 rsvd  <-          <-              ?    <-       ?          SpiReadMode[2:1]
@@ -370,6 +393,15 @@ static int handle_speed(struct pci_dev *dev)
 		msg_pdbg("SpiReadMode=%s (%i)\n", spireadmodes[read_mode], read_mode);
 		tmp = mmio_readb(sb600_spibar + 0x20);
 		msg_pdbg("UseSpi100 is %sabled\n", (tmp & 0x1) ? "en" : "dis");
+		if ((tmp & 0x1) == 0) {
+			mmio_writeb(tmp | 0x1, sb600_spibar + 0x20);
+			tmp = mmio_readb(sb600_spibar + 0x20) & 0x1;
+			if (tmp == 0) {
+				msg_perr("Enabling Spi100 failed.\n");
+				return 1;
+			}
+			msg_pdbg("Enabling Spi100 succeeded.\n");
+		}
 		tmp = mmio_readw(sb600_spibar + 0x22); /* SPI100 Speed Config */
 		msg_pdbg("NormSpeedNew is %s\n", spispeeds[(tmp >> 12) & 0xf].name);
 		msg_pdbg("FastSpeedNew is %s\n", spispeeds[(tmp >> 8) & 0xf].name);
-- 
Kind regards, Stefan Tauner





More information about the flashrom mailing list