summaryrefslogtreecommitdiff
path: root/serprog.c
diff options
context:
space:
mode:
authorstefanct <stefanct@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2012-08-13 16:33:04 +0000
committerstefanct <stefanct@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1>2012-08-13 16:33:04 +0000
commitd421f26ca6d6fc0f88f70d828d97028d3b382213 (patch)
tree157aebff0e3bd702eddb8b5b79bd428b02b46a0c /serprog.c
parent0476fe09acd1b4a66613083f12a1b130237c1eaa (diff)
downloadflashrom-d421f26ca6d6fc0f88f70d828d97028d3b382213.tar.gz
serprog: Add support for setting the SPI frequency.
Introduce a new opcode (0x14) that sends the requested frequency as a 32b long value in Hertz to the programmer and receives the frequency eventually chosen by the programmer. The user can specify this with the programmer parameter "spispeed" (named after the similar parameter for the buspirate) including an optional suffix of 'M' or 'k' for specifying megahertz or kilohertz respectively (lowercase suffixes are also accepted). Thanks to Idwer and Uwe (and maybe others) for their feedback especially regarding the unit of frequency to use. Signed-off-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@student.tuwien.ac.at> git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1571 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'serprog.c')
-rw-r--r--serprog.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/serprog.c b/serprog.c
index 3529127..e418c3e 100644
--- a/serprog.c
+++ b/serprog.c
@@ -69,6 +69,7 @@ static int serprog_shutdown(void *data);
#define S_CMD_Q_RDNMAXLEN 0x11 /* Query read-n maximum length */
#define S_CMD_S_BUSTYPE 0x12 /* Set used bustype(s). */
#define S_CMD_O_SPIOP 0x13 /* Perform SPI operation. */
+#define S_CMD_S_SPI_FREQ 0x14 /* Set SPI clock frequency */
static uint16_t sp_device_serbuf_size = 16;
static uint16_t sp_device_opbuf_size = 300;
@@ -482,6 +483,7 @@ int serprog_init(void)
/* Check for the minimum operational set of commands. */
if (serprog_buses_supported & BUS_SPI) {
uint8_t bt = BUS_SPI;
+ char *spispeed;
if (sp_check_commandavail(S_CMD_O_SPIOP) == 0) {
msg_perr("Error: SPI operation not supported while the "
"bustype is SPI\n");
@@ -513,6 +515,51 @@ int serprog_init(void)
spi_programmer_serprog.max_data_read = v;
msg_pdbg(MSGHEADER "Maximum read-n length is %d\n", v);
}
+ spispeed = extract_programmer_param("spispeed");
+ if (spispeed && strlen(spispeed)) {
+ uint32_t f_spi_req, f_spi;
+ uint8_t buf[4];
+ char *f_spi_suffix;
+
+ errno = 0;
+ f_spi_req = strtol(spispeed, &f_spi_suffix, 0);
+ if (errno != 0 || spispeed == f_spi_suffix) {
+ msg_perr("Error: Could not convert 'spispeed'.\n");
+ return 1;
+ }
+ if (strlen(f_spi_suffix) == 1) {
+ if (!strcasecmp(f_spi_suffix, "M"))
+ f_spi_req *= 1000000;
+ else if (!strcasecmp(f_spi_suffix, "k"))
+ f_spi_req *= 1000;
+ else {
+ msg_perr("Error: Garbage following 'spispeed' value.\n");
+ return 1;
+ }
+ } else if (strlen(f_spi_suffix) > 1) {
+ msg_perr("Error: Garbage following 'spispeed' value.\n");
+ return 1;
+ }
+
+ buf[0] = (f_spi_req >> (0 * 8)) & 0xFF;
+ buf[1] = (f_spi_req >> (1 * 8)) & 0xFF;
+ buf[2] = (f_spi_req >> (2 * 8)) & 0xFF;
+ buf[3] = (f_spi_req >> (3 * 8)) & 0xFF;
+
+ if (sp_check_commandavail(S_CMD_S_SPI_FREQ) == 0)
+ msg_perr(MSGHEADER "Warning: Setting the SPI clock rate is not supported!\n");
+ else if (sp_docommand(S_CMD_S_SPI_FREQ, 4, buf, 4, buf)
+ == 0) {
+ f_spi = buf[0];
+ f_spi |= buf[1] << (1 * 8);
+ f_spi |= buf[2] << (2 * 8);
+ f_spi |= buf[3] << (3 * 8);
+ msg_pdbg(MSGHEADER "Requested to set SPI clock frequency to %u Hz. "
+ "It was actually set to %u Hz\n", f_spi_req, f_spi);
+ } else
+ msg_pdbg(MSGHEADER "Setting SPI clock rate to %u Hz failed!\n", f_spi_req);
+ }
+ free(spispeed);
bt = serprog_buses_supported;
if (sp_docommand(S_CMD_S_BUSTYPE, 1, &bt, 0, NULL))
return 1;