1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 23:22:37 +02:00

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>
This commit is contained in:
Carl-Daniel Hailfinger 2010-10-05 19:19:48 +00:00
parent 39dcdece3a
commit 37c4252ef7
2 changed files with 68 additions and 34 deletions

View File

@ -397,7 +397,19 @@ can be any of
(in Hz). The default is the maximum frequency of 8 MHz. (in Hz). The default is the maximum frequency of 8 MHz.
.TP .TP
.BR "rayer_spi " programmer .BR "rayer_spi " programmer
No parameters defined yet. More information about the hardware is available at The default I/O base address used for the parallel port is 0x378 and you can use
the optional
.B iobase
parameter to specify an alternate base I/O address with the
.sp
.B " flashrom \-p rayer_spi:iobase=baseaddr"
.sp
syntax where
.B baseaddr
is base I/O port address of the parallel port, which must be a multiple of
four. Make sure to not forget the "0x" prefix for hexadecimal port addresses.
.sp
More information about the hardware is available at
http://rayer.ic.cz/elektro/spipgm.htm http://rayer.ic.cz/elektro/spipgm.htm
.SH EXIT STATUS .SH EXIT STATUS
flashrom exits with 0 on success, 1 on most failures but with 2 if /dev/mem flashrom exits with 0 on success, 1 on most failures but with 2 if /dev/mem

View File

@ -30,6 +30,7 @@
*/ */
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
#include <stdlib.h>
#include "flash.h" #include "flash.h"
#include "programmer.h" #include "programmer.h"
@ -43,45 +44,33 @@
/* Pins for slave->master direction */ /* Pins for slave->master direction */
#define SPI_MISO_PIN 6 #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 /* Cached value of last byte sent. */
* stored at port lpt_iobase to avoid unnecessary INB. In theory, only one static uint8_t lpt_outbyte;
* INB(lpt_iobase) would be needed on programmer init to get the initial
* value.
*/
void rayer_bitbang_set_cs(int val) static void rayer_bitbang_set_cs(int val)
{ {
uint8_t tmp; lpt_outbyte &= ~(1 << SPI_CS_PIN);
lpt_outbyte |= (val << SPI_CS_PIN);
tmp = INB(lpt_iobase); OUTB(lpt_outbyte, lpt_iobase);
tmp &= ~(1 << SPI_CS_PIN);
tmp |= (val << SPI_CS_PIN);
OUTB(tmp, lpt_iobase);
} }
void rayer_bitbang_set_sck(int val) static void rayer_bitbang_set_sck(int val)
{ {
uint8_t tmp; lpt_outbyte &= ~(1 << SPI_SCK_PIN);
lpt_outbyte |= (val << SPI_SCK_PIN);
tmp = INB(lpt_iobase); OUTB(lpt_outbyte, lpt_iobase);
tmp &= ~(1 << SPI_SCK_PIN);
tmp |= (val << SPI_SCK_PIN);
OUTB(tmp, lpt_iobase);
} }
void rayer_bitbang_set_mosi(int val) static void rayer_bitbang_set_mosi(int val)
{ {
uint8_t tmp; lpt_outbyte &= ~(1 << SPI_MOSI_PIN);
lpt_outbyte |= (val << SPI_MOSI_PIN);
tmp = INB(lpt_iobase); OUTB(lpt_outbyte, lpt_iobase);
tmp &= ~(1 << SPI_MOSI_PIN);
tmp |= (val << SPI_MOSI_PIN);
OUTB(tmp, lpt_iobase);
} }
int rayer_bitbang_get_miso(void) static int rayer_bitbang_get_miso(void)
{ {
uint8_t tmp; uint8_t tmp;
@ -100,16 +89,49 @@ static const struct bitbang_spi_master bitbang_spi_master_rayer = {
int rayer_spi_init(void) int rayer_spi_init(void)
{ {
/* Pick a default value for now. */ char *portpos = NULL;
lpt_iobase = 0x378;
msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n", /* 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); lpt_iobase);
get_io_perms(); get_io_perms();
/* 1 usec halfperiod delay for now. */ /* Get the initial value before writing to any line. */
if (bitbang_spi_init(&bitbang_spi_master_rayer, 1)) lpt_outbyte = INB(lpt_iobase);
/* Zero halfperiod delay. */
if (bitbang_spi_init(&bitbang_spi_master_rayer, 0))
return 1; return 1;
buses_supported = CHIP_BUSTYPE_SPI; buses_supported = CHIP_BUSTYPE_SPI;