mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00
ft2232_spi: reintroduce generic GPIOL control
This reintroduces a reworked version of the GPIOL pin control first introduced in commit 3207844 (CB:49637), which was reverted in commit 6518cf3 (CB:55692) due to breakage. This change introduces a new argument `gpiolX` to allow use of the four GPIOL pins either as generic gpios or as additional CS# signal(s). `X` specifies the GPIOL pin (0-3) to be set to one of [HLC] with the following meaning: * H - set the pin as output high * L - set the pin as output low * C - use the pin as additional CS# signal The third value, `C`, aims to replace the parameter `csgpiol`, that is now marked as deprecated and can be removed at some point in the future. `gpiol` and `csgpiol` are mutually exclusive and use of both results in an error. Multiple pins may be set by specifying the parameter multiple times. Documentation was updated/added accordingly. Test: All pin levels/modes have been verified to behave correctly with a logic analyzer. Change-Id: I3989f0f9596c090de52dca67183b1363dae59d3a Signed-off-by: Alan Green <avg@google.com> Signed-off-by: Michael Niewöhner <foss@mniewoehner.de> Reviewed-on: https://review.coreboot.org/c/flashrom/+/57810 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
parent
106f097ef6
commit
7b9c74f496
@ -883,12 +883,42 @@ parameter with the
|
|||||||
syntax.
|
syntax.
|
||||||
.sp
|
.sp
|
||||||
Using the parameter
|
Using the parameter
|
||||||
.B csgpiol
|
.B csgpiol (DEPRECATED - use gpiol instead)
|
||||||
an additional CS# pin can be chosen, where the value can be a number between 0 and 3, denoting GPIOL0-GPIOL3
|
an additional CS# pin can be chosen, where the value can be a number between 0 and 3, denoting GPIOL0-GPIOL3
|
||||||
correspondingly. Example:
|
correspondingly. Example:
|
||||||
.sp
|
.sp
|
||||||
.B " flashrom \-p ft2232_spi:csgpiol=3"
|
.B " flashrom \-p ft2232_spi:csgpiol=3"
|
||||||
.sp
|
.sp
|
||||||
|
The parameter
|
||||||
|
.B gpiolX=[HLC]
|
||||||
|
allows use of the GPIOL pins either as generic gpios with a fixed value during flashing or as addtional CS#
|
||||||
|
signal, where
|
||||||
|
.B X
|
||||||
|
can be a number between 0 and 3, denoting GPIOL0-GPIOL3 correspondingly. The parameter may be specified
|
||||||
|
multiple times, one time per GPIOL pin.
|
||||||
|
Valid values are
|
||||||
|
.B H
|
||||||
|
,
|
||||||
|
.B L
|
||||||
|
and
|
||||||
|
.B C
|
||||||
|
:
|
||||||
|
.br
|
||||||
|
.B " H "
|
||||||
|
- Set GPIOL output high
|
||||||
|
.br
|
||||||
|
.B " L "
|
||||||
|
- Set GPIOL output low
|
||||||
|
.br
|
||||||
|
.B " C "
|
||||||
|
- Use GPIOL as additional CS# output
|
||||||
|
.sp
|
||||||
|
.B Example:
|
||||||
|
.sp
|
||||||
|
.B " flashrom \-p ft2232_spi:gpiol0=H"
|
||||||
|
.sp
|
||||||
|
.B Note
|
||||||
|
that not all GPIOL pins are freely usable with all programmers as some have special functionality.
|
||||||
.SS
|
.SS
|
||||||
.BR "serprog " programmer
|
.BR "serprog " programmer
|
||||||
.IP
|
.IP
|
||||||
|
86
ft2232_spi.c
86
ft2232_spi.c
@ -91,9 +91,10 @@ static const struct dev_entry devs_ft2232spi[] = {
|
|||||||
* to high and will be toggled during SPI transactions. All other
|
* to high and will be toggled during SPI transactions. All other
|
||||||
* output pins will be kept low all the time. For some programmers,
|
* output pins will be kept low all the time. For some programmers,
|
||||||
* some reserved GPIOL* pins are used as outputs. Free GPIOL* pins
|
* some reserved GPIOL* pins are used as outputs. Free GPIOL* pins
|
||||||
* are configured as inputs, while it's possible to use one of them
|
* are configured as inputs, while it's possible to use them either
|
||||||
* as additional CS# signal through the parameter `csgpiol`. On exit,
|
* as generic gpios or as additional CS# signal(s) through the
|
||||||
* all pins will be reconfigured as inputs.
|
* parameter(s) `gpiolX`. On exit, all pins will be reconfigured
|
||||||
|
* as inputs.
|
||||||
*
|
*
|
||||||
* The pin offsets are as follows:
|
* The pin offsets are as follows:
|
||||||
* TCK/SK is bit 0.
|
* TCK/SK is bit 0.
|
||||||
@ -112,6 +113,7 @@ static const struct dev_entry devs_ft2232spi[] = {
|
|||||||
*/
|
*/
|
||||||
struct ft2232_data {
|
struct ft2232_data {
|
||||||
uint8_t cs_bits;
|
uint8_t cs_bits;
|
||||||
|
uint8_t aux_bits;
|
||||||
uint8_t pindir;
|
uint8_t pindir;
|
||||||
struct ftdi_context ftdic_context;
|
struct ftdi_context ftdic_context;
|
||||||
};
|
};
|
||||||
@ -233,7 +235,8 @@ static int ft2232_spi_send_multicommand(const struct flashctx *flash, struct spi
|
|||||||
|
|
||||||
msg_pspew("Assert CS#\n");
|
msg_pspew("Assert CS#\n");
|
||||||
buf[i++] = SET_BITS_LOW;
|
buf[i++] = SET_BITS_LOW;
|
||||||
buf[i++] = 0; /* assert CS# pins, all other output pins stay low */
|
/* assert CS# pins, keep aux_bits, all other output pins stay low */
|
||||||
|
buf[i++] = spi_data->aux_bits;
|
||||||
buf[i++] = spi_data->pindir;
|
buf[i++] = spi_data->pindir;
|
||||||
|
|
||||||
/* WREN, OP(PROGRAM, ERASE), ADDR, DATA */
|
/* WREN, OP(PROGRAM, ERASE), ADDR, DATA */
|
||||||
@ -255,7 +258,7 @@ static int ft2232_spi_send_multicommand(const struct flashctx *flash, struct spi
|
|||||||
/* Add final de-assert CS# */
|
/* Add final de-assert CS# */
|
||||||
msg_pspew("De-assert CS#\n");
|
msg_pspew("De-assert CS#\n");
|
||||||
buf[i++] = SET_BITS_LOW;
|
buf[i++] = SET_BITS_LOW;
|
||||||
buf[i++] = spi_data->cs_bits;
|
buf[i++] = spi_data->cs_bits | spi_data->aux_bits;
|
||||||
buf[i++] = spi_data->pindir;
|
buf[i++] = spi_data->pindir;
|
||||||
|
|
||||||
/* continue if there is no read-cmd and further cmds exist */
|
/* continue if there is no read-cmd and further cmds exist */
|
||||||
@ -325,6 +328,7 @@ static int ft2232_spi_init(void)
|
|||||||
double mpsse_clk;
|
double mpsse_clk;
|
||||||
|
|
||||||
uint8_t cs_bits = 0x08;
|
uint8_t cs_bits = 0x08;
|
||||||
|
uint8_t aux_bits = 0x00;
|
||||||
uint8_t pindir = 0x0b;
|
uint8_t pindir = 0x0b;
|
||||||
struct ftdi_context ftdic;
|
struct ftdi_context ftdic;
|
||||||
struct ft2232_data *spi_data;
|
struct ft2232_data *spi_data;
|
||||||
@ -470,8 +474,13 @@ static int ft2232_spi_init(void)
|
|||||||
}
|
}
|
||||||
free(arg);
|
free(arg);
|
||||||
|
|
||||||
|
bool csgpiol_set = false;
|
||||||
arg = extract_programmer_param("csgpiol");
|
arg = extract_programmer_param("csgpiol");
|
||||||
if (arg) {
|
if (arg) {
|
||||||
|
csgpiol_set = true;
|
||||||
|
msg_pwarn("Deprecation warning: `csgpiol` is deprectated and will be removed "
|
||||||
|
"in the future.\nUse `gpiolX=C` instead.\n");
|
||||||
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
unsigned int temp = strtoul(arg, &endptr, 10);
|
unsigned int temp = strtoul(arg, &endptr, 10);
|
||||||
if (*endptr || endptr == arg || temp > 3) {
|
if (*endptr || endptr == arg || temp > 3) {
|
||||||
@ -480,8 +489,8 @@ static int ft2232_spi_init(void)
|
|||||||
free(arg);
|
free(arg);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
unsigned int pin = temp + 4;
|
|
||||||
|
|
||||||
|
unsigned int pin = temp + 4;
|
||||||
if (rsv_bits & 1 << pin) {
|
if (rsv_bits & 1 << pin) {
|
||||||
msg_perr("Error: Invalid GPIOL specified: \"%s\".\n"
|
msg_perr("Error: Invalid GPIOL specified: \"%s\".\n"
|
||||||
"The pin is reserved on this programmer.\n",
|
"The pin is reserved on this programmer.\n",
|
||||||
@ -491,10 +500,70 @@ static int ft2232_spi_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cs_bits |= 1 << pin;
|
cs_bits |= 1 << pin;
|
||||||
pindir |= 1 << pin;
|
pindir |= 1 << pin;
|
||||||
}
|
}
|
||||||
free(arg);
|
free(arg);
|
||||||
|
|
||||||
|
/* gpiolX */
|
||||||
|
for (int pin = 0; pin < 4; pin++) {
|
||||||
|
char gpiol_param[7];
|
||||||
|
snprintf(gpiol_param, sizeof(gpiol_param), "gpiol%d", pin);
|
||||||
|
arg = extract_programmer_param(gpiol_param);
|
||||||
|
|
||||||
|
if (!arg)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (csgpiol_set) {
|
||||||
|
msg_perr("Error: `csgpiol` and `gpiolX` are mutually exclusive.\n"
|
||||||
|
"Since `csgpiol` is deprecated and will be removed in the "
|
||||||
|
"future, use of `gpiolX=C` is recommended.\n");
|
||||||
|
free(arg);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t bit = 1 << (pin + 4);
|
||||||
|
if (rsv_bits & bit) {
|
||||||
|
msg_perr("Error: Invalid GPIOL specified: \"gpiol%d=%s\".\n"
|
||||||
|
"Pin GPIOL%i is reserved on this programmer.\n",
|
||||||
|
pin, arg, pin);
|
||||||
|
free(arg);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(arg) != 1)
|
||||||
|
goto format_error;
|
||||||
|
|
||||||
|
switch (toupper(arg[0])) {
|
||||||
|
case 'H':
|
||||||
|
aux_bits |= bit;
|
||||||
|
pindir |= bit;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
pindir |= bit;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
cs_bits |= bit;
|
||||||
|
pindir |= bit;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto format_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(arg);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
format_error:
|
||||||
|
msg_perr("Error: Invalid GPIOL specified: \"gpiol%d=%s\".\n"
|
||||||
|
"Valid values are H, L and C.\n"
|
||||||
|
" H - Set GPIOL output high\n"
|
||||||
|
" L - Set GPIOL output low\n"
|
||||||
|
" C - Use GPIOL as additional CS# output\n",
|
||||||
|
pin, arg);
|
||||||
|
|
||||||
|
free(arg);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
@ -577,7 +646,7 @@ static int ft2232_spi_init(void)
|
|||||||
|
|
||||||
msg_pdbg("Set data bits\n");
|
msg_pdbg("Set data bits\n");
|
||||||
buf[0] = SET_BITS_LOW;
|
buf[0] = SET_BITS_LOW;
|
||||||
buf[1] = cs_bits;
|
buf[1] = cs_bits | aux_bits;
|
||||||
buf[2] = pindir;
|
buf[2] = pindir;
|
||||||
if (send_buf(&ftdic, buf, 3)) {
|
if (send_buf(&ftdic, buf, 3)) {
|
||||||
ret = -8;
|
ret = -8;
|
||||||
@ -590,6 +659,7 @@ static int ft2232_spi_init(void)
|
|||||||
return SPI_GENERIC_ERROR;
|
return SPI_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
spi_data->cs_bits = cs_bits;
|
spi_data->cs_bits = cs_bits;
|
||||||
|
spi_data->aux_bits = aux_bits;
|
||||||
spi_data->pindir = pindir;
|
spi_data->pindir = pindir;
|
||||||
spi_data->ftdic_context = ftdic;
|
spi_data->ftdic_context = ftdic;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user