diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-10-05 19:19:48 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2010-10-05 19:19:48 +0000 |
commit | 37c4252ef75a89e8cb182873fdeac76d3d91418f (patch) | |
tree | 3afd6eb249cef317102a30bf39abcbbf83aa2982 /rayer_spi.c | |
parent | 39dcdece3ad5d629b80958df8f193f0763e878d3 (diff) | |
download | flashrom-37c4252ef75a89e8cb182873fdeac76d3d91418f.tar.gz flashrom-37c4252ef75a89e8cb182873fdeac76d3d91418f.tar.bz2 flashrom-37c4252ef75a89e8cb182873fdeac76d3d91418f.zip |
Speed up RayeR SPIPGM driver by a factor of 2
Allow specification of an alternate base address with
flashrom -p rayer_spi:iobase=0x278
Any base address is allowed as long as it is nonzero, below 65536 and a
multiple of four.
Read speed is now on par with original spipgm.exe.
Corresponding to flashrom svn r1188.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Tested-by: Martin Rehak <rayer@seznam.cz>
Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
Diffstat (limited to 'rayer_spi.c')
-rw-r--r-- | rayer_spi.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/rayer_spi.c b/rayer_spi.c index 722ad147..a01ee801 100644 --- a/rayer_spi.c +++ b/rayer_spi.c @@ -30,6 +30,7 @@ */ #if defined(__i386__) || defined(__x86_64__) +#include <stdlib.h> #include "flash.h" #include "programmer.h" @@ -43,45 +44,33 @@ /* Pins for slave->master direction */ #define SPI_MISO_PIN 6 -static int lpt_iobase; +static uint16_t lpt_iobase; -/* FIXME: All rayer_bitbang_set_* functions could use caching of the value - * stored at port lpt_iobase to avoid unnecessary INB. In theory, only one - * INB(lpt_iobase) would be needed on programmer init to get the initial - * value. - */ +/* Cached value of last byte sent. */ +static uint8_t lpt_outbyte; -void rayer_bitbang_set_cs(int val) +static void rayer_bitbang_set_cs(int val) { - uint8_t tmp; - - tmp = INB(lpt_iobase); - tmp &= ~(1 << SPI_CS_PIN); - tmp |= (val << SPI_CS_PIN); - OUTB(tmp, lpt_iobase); + lpt_outbyte &= ~(1 << SPI_CS_PIN); + lpt_outbyte |= (val << SPI_CS_PIN); + OUTB(lpt_outbyte, lpt_iobase); } -void rayer_bitbang_set_sck(int val) +static void rayer_bitbang_set_sck(int val) { - uint8_t tmp; - - tmp = INB(lpt_iobase); - tmp &= ~(1 << SPI_SCK_PIN); - tmp |= (val << SPI_SCK_PIN); - OUTB(tmp, lpt_iobase); + lpt_outbyte &= ~(1 << SPI_SCK_PIN); + lpt_outbyte |= (val << SPI_SCK_PIN); + OUTB(lpt_outbyte, lpt_iobase); } -void rayer_bitbang_set_mosi(int val) +static void rayer_bitbang_set_mosi(int val) { - uint8_t tmp; - - tmp = INB(lpt_iobase); - tmp &= ~(1 << SPI_MOSI_PIN); - tmp |= (val << SPI_MOSI_PIN); - OUTB(tmp, lpt_iobase); + lpt_outbyte &= ~(1 << SPI_MOSI_PIN); + lpt_outbyte |= (val << SPI_MOSI_PIN); + OUTB(lpt_outbyte, lpt_iobase); } -int rayer_bitbang_get_miso(void) +static int rayer_bitbang_get_miso(void) { uint8_t tmp; @@ -100,16 +89,49 @@ static const struct bitbang_spi_master bitbang_spi_master_rayer = { int rayer_spi_init(void) { - /* Pick a default value for now. */ - lpt_iobase = 0x378; - - msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n", + char *portpos = NULL; + + /* Non-default port requested? */ + portpos = extract_programmer_param("iobase"); + if (portpos) { + char *endptr = NULL; + unsigned long tmp; + tmp = strtoul(portpos, &endptr, 0); + /* Port 0, port >0x10000, unaligned ports and garbage strings + * are rejected. + */ + if (!tmp || (tmp >= 0x10000) || (tmp & 0x3) || + (*endptr != '\0')) { + /* Using ports below 0x100 is a really bad idea, and + * should only be done if no port between 0x100 and + * 0xfffc works due to routing issues. + */ + msg_perr("Error: iobase= specified, but the I/O base " + "given was invalid.\nIt must be a multiple of " + "0x4 and lie between 0x100 and 0xfffc.\n"); + free(portpos); + return 1; + } else { + lpt_iobase = (uint16_t)tmp; + msg_pinfo("Non-default I/O base requested. This will " + "not change the hardware settings.\n"); + } + } else { + /* Pick a default value for the I/O base. */ + lpt_iobase = 0x378; + } + free(portpos); + + msg_pdbg("Using address 0x%x as I/O base for parallel port access.\n", lpt_iobase); get_io_perms(); - /* 1 usec halfperiod delay for now. */ - if (bitbang_spi_init(&bitbang_spi_master_rayer, 1)) + /* Get the initial value before writing to any line. */ + lpt_outbyte = INB(lpt_iobase); + + /* Zero halfperiod delay. */ + if (bitbang_spi_init(&bitbang_spi_master_rayer, 0)) return 1; buses_supported = CHIP_BUSTYPE_SPI; |