mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00
ft2232_spi.c: add frequency divisor parameter
This adds an optional argument when using the ft2232_spi programmer to set the frequency divisor. The valid values for the divisor is any even integer between 2 and 131072. Corresponding to flashrom svn r1537. Signed-off-by: Samir Ibradžić <sibradzic@gmail.com> Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
This commit is contained in:
parent
901a3ba023
commit
b482c6d5c1
11
flashrom.8
11
flashrom.8
@ -549,6 +549,17 @@ The default model is
|
|||||||
.B 4232H
|
.B 4232H
|
||||||
and the default interface is
|
and the default interface is
|
||||||
.BR B .
|
.BR B .
|
||||||
|
.sp
|
||||||
|
All models supported by the ft2232_spi driver can configure the SPI clock rate by setting a divisor. The
|
||||||
|
expressible divisors are all even numbers between 2 and 2^17 (=131072) resulting in SPI clock frequencies of
|
||||||
|
6 MHz down to about 92 Hz for 12 MHz inputs. The default divisor is set to 2, but you can use another one by
|
||||||
|
specifying the optional
|
||||||
|
.B divisor
|
||||||
|
parameter with the
|
||||||
|
.sp
|
||||||
|
.B " flashrom \-p ft2232_spi:divisor=div"
|
||||||
|
.sp
|
||||||
|
syntax.
|
||||||
.SS
|
.SS
|
||||||
.BR "serprog " programmer
|
.BR "serprog " programmer
|
||||||
A mandatory parameter specifies either a serial
|
A mandatory parameter specifies either a serial
|
||||||
|
54
ft2232_spi.c
54
ft2232_spi.c
@ -64,17 +64,8 @@ const struct usbdev_status devs_ft2232spi[] = {
|
|||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* The 'H' chips can run internally at either 12MHz or 60MHz.
|
|
||||||
* The non-H chips can only run at 12MHz.
|
|
||||||
*/
|
|
||||||
static uint8_t clock_5x = 1;
|
|
||||||
|
|
||||||
/*
|
#define DEFAULT_DIVISOR 2
|
||||||
* In either case, the divisor is a simple integer clock divider.
|
|
||||||
* If clock_5x is set, this divisor divides 30MHz, else it divides 6MHz.
|
|
||||||
*/
|
|
||||||
#define DIVIDE_BY 3 /* e.g. '3' will give either 10MHz or 2MHz SPI clock. */
|
|
||||||
|
|
||||||
#define BITMODE_BITBANG_NORMAL 1
|
#define BITMODE_BITBANG_NORMAL 1
|
||||||
#define BITMODE_BITBANG_SPI 2
|
#define BITMODE_BITBANG_SPI 2
|
||||||
@ -162,12 +153,28 @@ static const struct spi_programmer spi_programmer_ft2232 = {
|
|||||||
/* Returns 0 upon success, a negative number upon errors. */
|
/* Returns 0 upon success, a negative number upon errors. */
|
||||||
int ft2232_spi_init(void)
|
int ft2232_spi_init(void)
|
||||||
{
|
{
|
||||||
int f, ret = 0;
|
int ret = 0;
|
||||||
struct ftdi_context *ftdic = &ftdic_context;
|
struct ftdi_context *ftdic = &ftdic_context;
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
int ft2232_vid = FTDI_VID;
|
int ft2232_vid = FTDI_VID;
|
||||||
int ft2232_type = FTDI_FT4232H_PID;
|
int ft2232_type = FTDI_FT4232H_PID;
|
||||||
enum ftdi_interface ft2232_interface = INTERFACE_B;
|
enum ftdi_interface ft2232_interface = INTERFACE_B;
|
||||||
|
/*
|
||||||
|
* The 'H' chips can run with an internal clock of either 12 MHz or 60 MHz,
|
||||||
|
* but the non-H chips can only run at 12 MHz. We enable the divide-by-5
|
||||||
|
* prescaler on the former to run on the same speed.
|
||||||
|
*/
|
||||||
|
uint8_t clock_5x = 1;
|
||||||
|
/* In addition to the prescaler mentioned above there is also another
|
||||||
|
* configurable one on all versions of the chips. Its divisor div can be
|
||||||
|
* set by a 16 bit value x according to the following formula:
|
||||||
|
* div = (1 + x) * 2 <-> x = div / 2 - 1
|
||||||
|
* Hence the expressible divisors are all even numbers between 2 and
|
||||||
|
* 2^17 (=131072) resulting in SCK frequencies of 6 MHz down to about
|
||||||
|
* 92 Hz for 12 MHz inputs.
|
||||||
|
*/
|
||||||
|
uint32_t divisor = DEFAULT_DIVISOR;
|
||||||
|
int f;
|
||||||
char *arg;
|
char *arg;
|
||||||
double mpsse_clk;
|
double mpsse_clk;
|
||||||
|
|
||||||
@ -243,6 +250,21 @@ int ft2232_spi_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(arg);
|
free(arg);
|
||||||
|
arg = extract_programmer_param("divisor");
|
||||||
|
if (arg && strlen(arg)) {
|
||||||
|
unsigned int temp = 0;
|
||||||
|
char *endptr;
|
||||||
|
temp = strtoul(arg, &endptr, 10);
|
||||||
|
if (*endptr || temp < 2 || temp > 131072 || temp & 0x1) {
|
||||||
|
msg_perr("Error: Invalid SPI frequency divisor specified: \"%s\".\n"
|
||||||
|
"Valid are even values between 2 and 131072.\n", arg);
|
||||||
|
free(arg);
|
||||||
|
return -2;
|
||||||
|
} else {
|
||||||
|
divisor = (uint32_t)temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(arg);
|
||||||
msg_pdbg("Using device type %s %s ",
|
msg_pdbg("Using device type %s %s ",
|
||||||
get_ft2232_vendorname(ft2232_vid, ft2232_type),
|
get_ft2232_vendorname(ft2232_vid, ft2232_type),
|
||||||
get_ft2232_devicename(ft2232_vid, ft2232_type));
|
get_ft2232_devicename(ft2232_vid, ft2232_type));
|
||||||
@ -303,17 +325,15 @@ int ft2232_spi_init(void)
|
|||||||
|
|
||||||
msg_pdbg("Set clock divisor\n");
|
msg_pdbg("Set clock divisor\n");
|
||||||
buf[0] = 0x86; /* command "set divisor" */
|
buf[0] = 0x86; /* command "set divisor" */
|
||||||
/* valueL/valueH are (desired_divisor - 1) */
|
|
||||||
buf[1] = (DIVIDE_BY - 1) & 0xff;
|
|
||||||
buf[2] = ((DIVIDE_BY - 1) >> 8) & 0xff;
|
|
||||||
if (send_buf(ftdic, buf, 3)) {
|
if (send_buf(ftdic, buf, 3)) {
|
||||||
ret = -6;
|
ret = -6;
|
||||||
goto ftdi_err;
|
goto ftdi_err;
|
||||||
}
|
}
|
||||||
|
buf[1] = (divisor / 2 - 1) & 0xff;
|
||||||
|
buf[2] = ((divisor / 2 - 1) >> 8) & 0xff;
|
||||||
|
|
||||||
msg_pdbg("MPSSE clock: %f MHz divisor: %d "
|
msg_pdbg("MPSSE clock: %f MHz, divisor: %u, SPI clock: %f MHz\n",
|
||||||
"SPI clock: %f MHz\n", mpsse_clk, DIVIDE_BY,
|
mpsse_clk, divisor, (double)(mpsse_clk / divisor));
|
||||||
(double)(mpsse_clk / (((DIVIDE_BY - 1) + 1) * 2)));
|
|
||||||
|
|
||||||
/* Disconnect TDI/DO to TDO/DI for loopback. */
|
/* Disconnect TDI/DO to TDO/DI for loopback. */
|
||||||
msg_pdbg("No loopback of TDI/DO TDO/DI\n");
|
msg_pdbg("No loopback of TDI/DO TDO/DI\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user