mirror of
https://review.coreboot.org/flashrom.git
synced 2025-07-01 22:21:16 +02:00
Generify support for ITE IT8705 Super I/O
Autodetect the ITE IT8705 Super I/O and enable flash writes if it performs LPC->Parallel translation. Remove board enables which triggered the IT8705 write enable manually. Change the IT87 SPI special case to cover IT87 LPC->SPI and LPC->Parallel translation. Corresponding to flashrom svn r1073. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Tested on Syntax SV266A. Acked-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested on Shuttle AK38N, all operations work fine. Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
This commit is contained in:
164
it87spi.c
164
it87spi.c
@ -96,90 +96,109 @@ struct superio probe_superio_ite(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t find_ite_spi_flash_port(uint16_t port, uint16_t id)
|
||||
static uint16_t it87spi_probe(uint16_t port)
|
||||
{
|
||||
uint8_t tmp = 0;
|
||||
char *portpos = NULL;
|
||||
uint16_t flashport = 0;
|
||||
|
||||
switch (id) {
|
||||
case 0x8716:
|
||||
case 0x8718:
|
||||
case 0x8720:
|
||||
enter_conf_mode_ite(port);
|
||||
/* NOLDN, reg 0x24, mask out lowest bit (suspend) */
|
||||
tmp = sio_read(port, 0x24) & 0xFE;
|
||||
/* If IT87SPI was not explicitly selected, we want to check
|
||||
* quickly if LPC->SPI translation is active.
|
||||
enter_conf_mode_ite(port);
|
||||
/* NOLDN, reg 0x24, mask out lowest bit (suspend) */
|
||||
tmp = sio_read(port, 0x24) & 0xFE;
|
||||
/* If IT87SPI was not explicitly selected, we want to check
|
||||
* quickly if LPC->SPI translation is active.
|
||||
*/
|
||||
if ((programmer == PROGRAMMER_INTERNAL) && !(tmp & (0x0E))) {
|
||||
msg_pdbg("No IT87* serial flash segment enabled.\n");
|
||||
exit_conf_mode_ite(port);
|
||||
/* Nothing to do. */
|
||||
return 1;
|
||||
}
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis");
|
||||
msg_pdbg("LPC write to serial flash %sabled\n",
|
||||
(tmp & 1 << 4) ? "en" : "dis");
|
||||
/* The LPC->SPI force write enable below only makes sense for
|
||||
* non-programmer mode.
|
||||
*/
|
||||
/* If any serial flash segment is enabled, enable writing. */
|
||||
if ((tmp & 0xe) && (!(tmp & 1 << 4))) {
|
||||
msg_pdbg("Enabling LPC write to serial flash\n");
|
||||
tmp |= 1 << 4;
|
||||
sio_write(port, 0x24, tmp);
|
||||
}
|
||||
msg_pdbg("Serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29);
|
||||
/* LDN 0x7, reg 0x64/0x65 */
|
||||
sio_write(port, 0x07, 0x7);
|
||||
flashport = sio_read(port, 0x64) << 8;
|
||||
flashport |= sio_read(port, 0x65);
|
||||
msg_pdbg("Serial flash port 0x%04x\n", flashport);
|
||||
/* Non-default port requested? */
|
||||
portpos = extract_programmer_param("it87spiport");
|
||||
if (portpos) {
|
||||
char *endptr = NULL;
|
||||
unsigned long forced_flashport;
|
||||
forced_flashport = strtoul(portpos, &endptr, 0);
|
||||
/* Port 0, port >0x1000, unaligned ports and garbage strings
|
||||
* are rejected.
|
||||
*/
|
||||
if ((programmer == PROGRAMMER_INTERNAL) && !(tmp & (0x0E))) {
|
||||
msg_pdbg("No IT87* serial flash segment enabled.\n");
|
||||
exit_conf_mode_ite(port);
|
||||
break;
|
||||
}
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis");
|
||||
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n",
|
||||
0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis");
|
||||
msg_pdbg("LPC write to serial flash %sabled\n",
|
||||
(tmp & 1 << 4) ? "en" : "dis");
|
||||
/* The LPC->SPI force write enable below only makes sense for
|
||||
* non-programmer mode.
|
||||
*/
|
||||
/* If any serial flash segment is enabled, enable writing. */
|
||||
if ((tmp & 0xe) && (!(tmp & 1 << 4))) {
|
||||
msg_pdbg("Enabling LPC write to serial flash\n");
|
||||
tmp |= 1 << 4;
|
||||
sio_write(port, 0x24, tmp);
|
||||
}
|
||||
msg_pdbg("Serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29);
|
||||
/* LDN 0x7, reg 0x64/0x65 */
|
||||
sio_write(port, 0x07, 0x7);
|
||||
flashport = sio_read(port, 0x64) << 8;
|
||||
flashport |= sio_read(port, 0x65);
|
||||
msg_pdbg("Serial flash port 0x%04x\n", flashport);
|
||||
/* Non-default port requested? */
|
||||
portpos = extract_programmer_param("it87spiport");
|
||||
if (portpos && strlen(portpos)) {
|
||||
flashport = strtol(portpos, (char **)NULL, 0);
|
||||
msg_pinfo("Forcing serial flash port 0x%04x\n",
|
||||
flashport);
|
||||
sio_write(port, 0x64, (flashport >> 8));
|
||||
sio_write(port, 0x65, (flashport & 0xff));
|
||||
} else if (portpos) {
|
||||
msg_perr("Error: it87spiport specified, but no port "
|
||||
"given.\n");
|
||||
if (!forced_flashport || (forced_flashport >= 0x1000) ||
|
||||
(forced_flashport & 0x7) || (*endptr != '\0')) {
|
||||
/* Using ports below 0x100 is a really bad idea, and
|
||||
* should only be done if no port between 0x100 and
|
||||
* 0xff8 works due to routing issues.
|
||||
*/
|
||||
msg_perr("Error: it87spiport specified, but no valid "
|
||||
"port specified.\nPort must be a multiple of "
|
||||
"0x8 and lie between 0x100 and 0xff8.\n");
|
||||
free(portpos);
|
||||
/* FIXME: Return failure here once it87spi_common_init()
|
||||
* can handle the return value sanely.
|
||||
*/
|
||||
exit(1);
|
||||
} else {
|
||||
flashport = (uint16_t)forced_flashport;
|
||||
msg_pinfo("Forcing serial flash port 0x%04x\n",
|
||||
flashport);
|
||||
sio_write(port, 0x64, (flashport >> 8));
|
||||
sio_write(port, 0x65, (flashport & 0xff));
|
||||
}
|
||||
free(portpos);
|
||||
exit_conf_mode_ite(port);
|
||||
break;
|
||||
/* TODO: Handle more IT87xx if they support flash translation */
|
||||
default:
|
||||
msg_pdbg("SuperI/O ID %04hx is not on the controller list.\n", id);
|
||||
}
|
||||
return flashport;
|
||||
free(portpos);
|
||||
exit_conf_mode_ite(port);
|
||||
it8716f_flashport = flashport;
|
||||
if (buses_supported & CHIP_BUSTYPE_SPI)
|
||||
msg_pdbg("Overriding chipset SPI with IT87 SPI.\n");
|
||||
spi_controller = SPI_CONTROLLER_IT87XX;
|
||||
buses_supported |= CHIP_BUSTYPE_SPI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int it87spi_common_init(void)
|
||||
int init_superio_ite(void)
|
||||
{
|
||||
if (superio.vendor != SUPERIO_VENDOR_ITE)
|
||||
return 1;
|
||||
|
||||
it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model);
|
||||
|
||||
if (it8716f_flashport)
|
||||
spi_controller = SPI_CONTROLLER_IT87XX;
|
||||
|
||||
return (!it8716f_flashport);
|
||||
switch (superio.model) {
|
||||
case 0x8705:
|
||||
return it8705f_write_enable(superio.port);
|
||||
break;
|
||||
case 0x8716:
|
||||
case 0x8718:
|
||||
case 0x8720:
|
||||
return it87spi_probe(superio.port);
|
||||
break;
|
||||
default:
|
||||
msg_pdbg("Super I/O ID 0x%04hx is not on the list of flash "
|
||||
"capable controllers.\n", superio.model);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -190,7 +209,7 @@ int it87spi_init(void)
|
||||
get_io_perms();
|
||||
/* Probe for the Super I/O chip and fill global struct superio. */
|
||||
probe_superio();
|
||||
ret = it87spi_common_init();
|
||||
ret = init_superio_ite();
|
||||
if (!ret) {
|
||||
buses_supported = CHIP_BUSTYPE_SPI;
|
||||
} else {
|
||||
@ -199,19 +218,6 @@ int it87spi_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int it87xx_probe_spi_flash(const char *name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = it87spi_common_init();
|
||||
if (!ret) {
|
||||
if (buses_supported & CHIP_BUSTYPE_SPI)
|
||||
msg_pdbg("Overriding chipset SPI with IT87 SPI.\n");
|
||||
buses_supported |= CHIP_BUSTYPE_SPI;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The IT8716F only supports commands with length 1,2,4,5 bytes including
|
||||
* command byte and can not read more than 3 bytes from the device.
|
||||
|
Reference in New Issue
Block a user