1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 23:22:37 +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:
Carl-Daniel Hailfinger 2010-07-10 16:56:32 +00:00
parent 2b6dcb36c4
commit 76d4b373dd
4 changed files with 174 additions and 109 deletions

View File

@ -390,31 +390,92 @@ static int w836xx_memw_enable_4e(void)
} }
/** /**
* * Suited for all boards with ITE IT8705F.
* The SIS950 Super I/O probably requires a similar flash write enable.
*/ */
static int it8705f_write_enable(uint8_t port) int it8705f_write_enable(uint8_t port)
{ {
uint8_t tmp;
int ret = 0;
enter_conf_mode_ite(port); enter_conf_mode_ite(port);
sio_mask(port, 0x24, 0x04, 0x04); /* Flash ROM I/F Writes Enable */ tmp = sio_read(port, 0x24);
/* Check if at least one flash segment is enabled. */
if (tmp & 0xf0) {
/* The IT8705F will respond to LPC cycles and translate them. */
buses_supported = CHIP_BUSTYPE_PARALLEL;
/* Flash ROM I/F Writes Enable */
tmp |= 0x04;
msg_pdbg("Enabling IT8705F flash ROM interface write.\n");
if (tmp & 0x02) {
/* The data sheet contradicts itself about max size. */
max_rom_decode.parallel = 1024 * 1024;
msg_pinfo("IT8705F with very unusual settings. Please "
"send the output of \"flashrom -V\" to \n"
"flashrom@flashrom.org to help us finish "
"support for your Super I/O. Thanks.\n");
ret = 1;
} else if (tmp & 0x08) {
max_rom_decode.parallel = 512 * 1024;
} else {
max_rom_decode.parallel = 256 * 1024;
}
/* Safety checks. The data sheet is unclear here: Segments 1+3
* overlap, no segment seems to cover top - 1MB to top - 512kB.
* We assume that certain combinations make no sense.
*/
if (((tmp & 0x02) && !(tmp & 0x08)) || /* 1 MB en, 512 kB dis */
(!(tmp & 0x10)) || /* 128 kB dis */
(!(tmp & 0x40))) { /* 256/512 kB dis */
msg_perr("Inconsistent IT8705F decode size!\n");
ret = 1;
}
if (sio_read(port, 0x25) != 0) {
msg_perr("IT8705F flash data pins disabled!\n");
ret = 1;
}
if (sio_read(port, 0x26) != 0) {
msg_perr("IT8705F flash address pins 0-7 disabled!\n");
ret = 1;
}
if (sio_read(port, 0x27) != 0) {
msg_perr("IT8705F flash address pins 8-15 disabled!\n");
ret = 1;
}
if ((sio_read(port, 0x29) & 0x10) != 0) {
msg_perr("IT8705F flash write enable pin disabled!\n");
ret = 1;
}
if ((sio_read(port, 0x29) & 0x08) != 0) {
msg_perr("IT8705F flash chip select pin disabled!\n");
ret = 1;
}
if ((sio_read(port, 0x29) & 0x04) != 0) {
msg_perr("IT8705F flash read strobe pin disabled!\n");
ret = 1;
}
if ((sio_read(port, 0x29) & 0x03) != 0) {
msg_perr("IT8705F flash address pins 16-17 disabled!\n");
/* Not really an error if you use flash chips smaller
* than 256 kByte, but such a configuration is unlikely.
*/
ret = 1;
}
msg_pdbg("Maximum IT8705F parallel flash decode size is %u.\n",
max_rom_decode.parallel);
if (ret) {
msg_pinfo("Not enabling IT8705F flash write.\n");
} else {
sio_write(port, 0x24, tmp);
}
} else {
msg_pdbg("No IT8705F flash segment enabled.\n");
/* Not sure if this is an error or not. */
ret = 0;
}
exit_conf_mode_ite(port); exit_conf_mode_ite(port);
return 0; return ret;
}
/**
* Suited for:
* - AOpen vKM400Am-S: VIA KM400 + VT8237 + IT8705F.
* - Biostar P4M80-M4: VIA P4M800 + VT8237 + IT8705AF
* - Elitegroup K7S6A: SiS745 + ITE IT8705F
* - Elitegroup K7VTA3: VIA Apollo KT266/A/333 + VIA VT8235 + ITE IT8705F
* - GIGABYTE GA-7VT600: VIA KT600 + VT8237 + IT8705
* - Shuttle AK38N: VIA KT333CF + VIA VT8235 + ITE IT8705F
*
* The SIS950 Super I/O probably requires the same flash write enable.
*/
static int it8705f_write_enable_2e(void)
{
return it8705f_write_enable(0x2e);
} }
static int pc87360_gpio_set(uint8_t gpio, int raise) static int pc87360_gpio_set(uint8_t gpio, int raise)
@ -1590,7 +1651,6 @@ const struct board_pciid_enable board_pciid_enables[] = {
{0x105a, 0x0d30, 0x105a, 0x4d33, 0x8086, 0x1130, 0x8086, 0, NULL, NULL, NULL, "Acorp", "6A815EPD", 0, OK, board_acorp_6a815epd}, {0x105a, 0x0d30, 0x105a, 0x4d33, 0x8086, 0x1130, 0x8086, 0, NULL, NULL, NULL, "Acorp", "6A815EPD", 0, OK, board_acorp_6a815epd},
{0x1022, 0x746B, 0, 0, 0, 0, 0, 0, NULL, "AGAMI", "ARUMA", "agami", "Aruma", 0, OK, w83627hf_gpio24_raise_2e}, {0x1022, 0x746B, 0, 0, 0, 0, 0, 0, NULL, "AGAMI", "ARUMA", "agami", "Aruma", 0, OK, w83627hf_gpio24_raise_2e},
{0x1106, 0x3177, 0x17F2, 0x3177, 0x1106, 0x3148, 0x17F2, 0x3148, NULL, NULL, NULL, "Albatron", "PM266A Pro", 0, OK, w836xx_memw_enable_2e}, {0x1106, 0x3177, 0x17F2, 0x3177, 0x1106, 0x3148, 0x17F2, 0x3148, NULL, NULL, NULL, "Albatron", "PM266A Pro", 0, OK, w836xx_memw_enable_2e},
{0x1106, 0x3205, 0x1106, 0x3205, 0x10EC, 0x8139, 0xA0A0, 0x0477, NULL, NULL, NULL, "AOpen", "vKM400Am-S", 0, OK, it8705f_write_enable_2e},
{0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, NULL, "artecgroup", "dbe61", "Artec Group", "DBE61", 0, OK, board_artecgroup_dbe6x}, {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, NULL, "artecgroup", "dbe61", "Artec Group", "DBE61", 0, OK, board_artecgroup_dbe6x},
{0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, NULL, "artecgroup", "dbe62", "Artec Group", "DBE62", 0, OK, board_artecgroup_dbe6x}, {0x1022, 0x2090, 0, 0, 0x1022, 0x2080, 0, 0, NULL, "artecgroup", "dbe62", "Artec Group", "DBE62", 0, OK, board_artecgroup_dbe6x},
{0x8086, 0x24D4, 0x1849, 0x24D0, 0x8086, 0x24D5, 0x1849, 0x9739, NULL, NULL, NULL, "ASRock", "P4i65GV", 0, OK, intel_ich_gpio23_raise}, {0x8086, 0x24D4, 0x1849, 0x24D0, 0x8086, 0x24D5, 0x1849, 0x9739, NULL, NULL, NULL, "ASRock", "P4i65GV", 0, OK, intel_ich_gpio23_raise},
@ -1611,14 +1671,11 @@ const struct board_pciid_enable board_pciid_enables[] = {
{0x8086, 0x2570, 0x1043, 0x80F2, 0x105A, 0x3373, 0x1043, 0x80F5, NULL, NULL, NULL, "ASUS", "P4P800-E Deluxe", 0, OK, intel_ich_gpio21_raise}, {0x8086, 0x2570, 0x1043, 0x80F2, 0x105A, 0x3373, 0x1043, 0x80F5, NULL, NULL, NULL, "ASUS", "P4P800-E Deluxe", 0, OK, intel_ich_gpio21_raise},
{0x10B9, 0x1541, 0, 0, 0x10B9, 0x1533, 0, 0, "^P5A$", "asus", "p5a", "ASUS", "P5A", 0, OK, board_asus_p5a}, {0x10B9, 0x1541, 0, 0, 0x10B9, 0x1533, 0, 0, "^P5A$", "asus", "p5a", "ASUS", "P5A", 0, OK, board_asus_p5a},
{0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", 0, OK, nvidia_mcp_gpio10_raise}, {0x10DE, 0x0030, 0x1043, 0x818a, 0x8086, 0x100E, 0x1043, 0x80EE, NULL, NULL, NULL, "ASUS", "P5ND2-SLI Deluxe", 0, OK, nvidia_mcp_gpio10_raise},
{0x1106, 0x3149, 0x1565, 0x3206, 0x1106, 0x3344, 0x1565, 0x1202, NULL, NULL, NULL, "Biostar", "P4M80-M4", 0, OK, it8705f_write_enable_2e},
{0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, NULL, NULL, NULL, "Dell", "PowerEdge 1850", 0, OK, intel_ich_gpio23_raise}, {0x8086, 0x3590, 0x1028, 0x016c, 0x1000, 0x0030, 0x1028, 0x016c, NULL, NULL, NULL, "Dell", "PowerEdge 1850", 0, OK, intel_ich_gpio23_raise},
{0x1039, 0x5513, 0x1019, 0x0A41, 0x1039, 0x0018, 0, 0, NULL, NULL, NULL, "Elitegroup", "K7S6A", 0, OK, it8705f_write_enable_2e}, {0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, NULL, NULL, NULL, "Elitegroup", "K7VTA3", 256, OK, NULL},
{0x1106, 0x3038, 0x1019, 0x0996, 0x1106, 0x3177, 0x1019, 0x0996, NULL, NULL, NULL, "Elitegroup", "K7VTA3", 256, OK, it8705f_write_enable_2e},
{0x1106, 0x3177, 0x1106, 0x3177, 0x1106, 0x3059, 0x1695, 0x3005, NULL, NULL, NULL, "EPoX", "EP-8K5A2", 0, OK, w836xx_memw_enable_2e}, {0x1106, 0x3177, 0x1106, 0x3177, 0x1106, 0x3059, 0x1695, 0x3005, NULL, NULL, NULL, "EPoX", "EP-8K5A2", 0, OK, w836xx_memw_enable_2e},
{0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, NULL, NULL, NULL, "EPoX", "EP-8RDA3+", 0, OK, nvidia_mcp_gpio31_raise}, {0x10EC, 0x8139, 0x1695, 0x9001, 0x11C1, 0x5811, 0x1695, 0x9015, NULL, NULL, NULL, "EPoX", "EP-8RDA3+", 0, OK, nvidia_mcp_gpio31_raise},
{0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, NULL, "epox", "ep-bx3", "EPoX", "EP-BX3", 0, OK, board_epox_ep_bx3}, {0x8086, 0x7110, 0, 0, 0x8086, 0x7190, 0, 0, NULL, "epox", "ep-bx3", "EPoX", "EP-BX3", 0, OK, board_epox_ep_bx3},
{0x1106, 0x3227, 0x1458, 0x5001, 0x10ec, 0x8139, 0x1458, 0xe000, NULL, NULL, NULL, "GIGABYTE", "GA-7VT600", 0, OK, it8705f_write_enable_2e},
{0x1106, 0x0686, 0x1106, 0x0686, 0x1106, 0x3058, 0x1458, 0xa000, NULL, NULL, NULL, "GIGABYTE", "GA-7ZM", 512, OK, NULL}, {0x1106, 0x0686, 0x1106, 0x0686, 0x1106, 0x3058, 0x1458, 0xa000, NULL, NULL, NULL, "GIGABYTE", "GA-7ZM", 512, OK, NULL},
{0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, NULL, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, OK, nvidia_mcp_gpio21_raise}, {0x10DE, 0x0050, 0x1458, 0x0C11, 0x10DE, 0x005e, 0x1458, 0x5000, NULL, NULL, NULL, "GIGABYTE", "GA-K8N-SLI", 0, OK, nvidia_mcp_gpio21_raise},
{0x1166, 0x0223, 0x103c, 0x320d, 0x14e4, 0x1678, 0x103c, 0x703e, NULL, "hp", "dl145_g3", "HP", "DL145 G3", 0, OK, board_hp_dl145_g3_enable}, {0x1166, 0x0223, 0x103c, 0x320d, 0x14e4, 0x1678, 0x103c, 0x703e, NULL, "hp", "dl145_g3", "HP", "DL145 G3", 0, OK, board_hp_dl145_g3_enable},
@ -1644,7 +1701,7 @@ const struct board_pciid_enable board_pciid_enables[] = {
{0x10DE, 0x0270, 0x1462, 0x7207, 0x10DE, 0x0264, 0x1462, 0x7207, NULL, NULL, NULL, "MSI", "MS-7207 (K8N GM2-L)", 0, NT, nvidia_mcp_gpio2_raise}, {0x10DE, 0x0270, 0x1462, 0x7207, 0x10DE, 0x0264, 0x1462, 0x7207, NULL, NULL, NULL, "MSI", "MS-7207 (K8N GM2-L)", 0, NT, nvidia_mcp_gpio2_raise},
{0x1011, 0x0019, 0xaa55, 0xaa55, 0x8086, 0x7190, 0, 0, NULL, NULL, NULL, "Nokia", "IP530", 0, OK, fdc37b787_gpio50_raise_3f0}, {0x1011, 0x0019, 0xaa55, 0xaa55, 0x8086, 0x7190, 0, 0, NULL, NULL, NULL, "Nokia", "IP530", 0, OK, fdc37b787_gpio50_raise_3f0},
{0x1106, 0x3099, 0, 0, 0x1106, 0x3074, 0, 0, NULL, "shuttle", "ak31", "Shuttle", "AK31", 0, OK, w836xx_memw_enable_2e}, {0x1106, 0x3099, 0, 0, 0x1106, 0x3074, 0, 0, NULL, "shuttle", "ak31", "Shuttle", "AK31", 0, OK, w836xx_memw_enable_2e},
{0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, NULL, "Shuttle", "AK38N", 256, OK, it8705f_write_enable_2e}, {0x1106, 0x3104, 0x1297, 0xa238, 0x1106, 0x3059, 0x1297, 0xc063, NULL, NULL, NULL, "Shuttle", "AK38N", 256, OK, NULL},
{0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, NULL, NULL, NULL, "Shuttle", "FN25", 0, OK, board_shuttle_fn25}, {0x10DE, 0x0050, 0x1297, 0x5036, 0x1412, 0x1724, 0x1297, 0x5036, NULL, NULL, NULL, "Shuttle", "FN25", 0, OK, board_shuttle_fn25},
{0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, NULL, "Soyo", "SY-7VCA", 0, OK, via_apollo_gpo0_lower}, {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x3058, 0x15DD, 0x7609, NULL, NULL, NULL, "Soyo", "SY-7VCA", 0, OK, via_apollo_gpo0_lower},
{0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x0596, 0x1106, 0, NULL, NULL, NULL, "Tekram", "P6Pro-A5", 256, OK, NULL}, {0x1106, 0x3038, 0x0925, 0x1234, 0x1106, 0x0596, 0x1106, 0, NULL, NULL, NULL, "Tekram", "P6Pro-A5", 256, OK, NULL},

View File

@ -350,6 +350,7 @@ void print_supported_wiki(void);
/* board_enable.c */ /* board_enable.c */
void w836xx_ext_enter(uint16_t port); void w836xx_ext_enter(uint16_t port);
void w836xx_ext_leave(uint16_t port); void w836xx_ext_leave(uint16_t port);
int it8705f_write_enable(uint8_t port);
uint8_t sio_read(uint16_t port, uint8_t reg); uint8_t sio_read(uint16_t port, uint8_t reg);
void sio_write(uint16_t port, uint8_t reg, uint8_t data); void sio_write(uint16_t port, uint8_t reg, uint8_t data);
void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask); void sio_mask(uint16_t port, uint8_t reg, uint8_t data, uint8_t mask);
@ -692,12 +693,11 @@ int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
int ich_spi_send_multicommand(struct spi_command *cmds); int ich_spi_send_multicommand(struct spi_command *cmds);
/* it87spi.c */ /* it87spi.c */
extern uint16_t it8716f_flashport;
void enter_conf_mode_ite(uint16_t port); void enter_conf_mode_ite(uint16_t port);
void exit_conf_mode_ite(uint16_t port); void exit_conf_mode_ite(uint16_t port);
struct superio probe_superio_ite(void); struct superio probe_superio_ite(void);
int init_superio_ite(void);
int it87spi_init(void); int it87spi_init(void);
int it87xx_probe_spi_flash(const char *name);
int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt, int it8716f_spi_send_command(unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr); const unsigned char *writearr, unsigned char *readarr);
int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len); int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);

View File

@ -229,8 +229,10 @@ int internal_init(void)
} }
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
/* Probe for IT87* LPC->SPI translation unconditionally. */ /* Probe unconditionally for IT87* LPC->SPI translation and for
it87xx_probe_spi_flash(NULL); * IT87* Parallel write enable.
*/
init_superio_ite();
#endif #endif
board_flash_enable(lb_vendor, lb_part); board_flash_enable(lb_vendor, lb_part);

164
it87spi.c
View File

@ -96,90 +96,109 @@ struct superio probe_superio_ite(void)
return ret; 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; uint8_t tmp = 0;
char *portpos = NULL; char *portpos = NULL;
uint16_t flashport = 0; uint16_t flashport = 0;
switch (id) { enter_conf_mode_ite(port);
case 0x8716: /* NOLDN, reg 0x24, mask out lowest bit (suspend) */
case 0x8718: tmp = sio_read(port, 0x24) & 0xFE;
case 0x8720: /* If IT87SPI was not explicitly selected, we want to check
enter_conf_mode_ite(port); * quickly if LPC->SPI translation is active.
/* NOLDN, reg 0x24, mask out lowest bit (suspend) */ */
tmp = sio_read(port, 0x24) & 0xFE; if ((programmer == PROGRAMMER_INTERNAL) && !(tmp & (0x0E))) {
/* If IT87SPI was not explicitly selected, we want to check msg_pdbg("No IT87* serial flash segment enabled.\n");
* quickly if LPC->SPI translation is active. 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))) { if (!forced_flashport || (forced_flashport >= 0x1000) ||
msg_pdbg("No IT87* serial flash segment enabled.\n"); (forced_flashport & 0x7) || (*endptr != '\0')) {
exit_conf_mode_ite(port); /* Using ports below 0x100 is a really bad idea, and
break; * should only be done if no port between 0x100 and
} * 0xff8 works due to routing issues.
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", */
0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis"); msg_perr("Error: it87spiport specified, but no valid "
msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", "port specified.\nPort must be a multiple of "
0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis"); "0x8 and lie between 0x100 and 0xff8.\n");
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");
free(portpos); free(portpos);
/* FIXME: Return failure here once it87spi_common_init() /* FIXME: Return failure here once it87spi_common_init()
* can handle the return value sanely. * can handle the return value sanely.
*/ */
exit(1); 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) if (superio.vendor != SUPERIO_VENDOR_ITE)
return 1; return 1;
it8716f_flashport = find_ite_spi_flash_port(superio.port, superio.model); switch (superio.model) {
case 0x8705:
if (it8716f_flashport) return it8705f_write_enable(superio.port);
spi_controller = SPI_CONTROLLER_IT87XX; break;
case 0x8716:
return (!it8716f_flashport); 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(); get_io_perms();
/* Probe for the Super I/O chip and fill global struct superio. */ /* Probe for the Super I/O chip and fill global struct superio. */
probe_superio(); probe_superio();
ret = it87spi_common_init(); ret = init_superio_ite();
if (!ret) { if (!ret) {
buses_supported = CHIP_BUSTYPE_SPI; buses_supported = CHIP_BUSTYPE_SPI;
} else { } else {
@ -199,19 +218,6 @@ int it87spi_init(void)
return ret; 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 * 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. * command byte and can not read more than 3 bytes from the device.