diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2011-04-27 14:34:08 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2011-04-27 14:34:08 +0000 |
commit | bfc8ba124e9bceeb504667397b13b6f7f9125fcd (patch) | |
tree | a54fe83e5bd047ca0ae0af1469973a76acddceb8 /it85spi.c | |
parent | b5e504c5d1ea2949b76f034fc52fcc57705a948d (diff) | |
download | flashrom-bfc8ba124e9bceeb504667397b13b6f7f9125fcd.zip flashrom-bfc8ba124e9bceeb504667397b13b6f7f9125fcd.tar.gz |
Add support for more than one Super I/O or EC per machine
Flashrom currently only supports exactly one Super I/O or Embedded
Controller, and this means quite a few notebooks and a small subset of
desktop/server boards cannot be handled reliably and easily.
Allow detection and initialization of up to 3 Super I/O and/or EC chips.
WARNING! If a Super I/O or EC responds on multiple ports (0x2e and
0x4e), the code will do the wrong thing (namely, initialize the hardware
twice). I have no idea if we should handle such situations, and whether
we should ignore the second chip with identical ID or not. Initializing
the hardware twice for the IT87* family is _not_ a problem, but I don't
know how well IT85* can handle it (and whether IT85* would listen at
more than one port anyway).
Thanks to Thomas Schneider for testing on a board with ITE IT87* SPI.
Test report (success) is here: http://paste.flashrom.org/view.php?id=379
Thanks to David Hendricks for testing on a Google Cr-48 laptop with
ITE IT85* EC SPI. Test report (success) is here:
http://www.flashrom.org/pipermail/flashrom/2011-April/006275.html
Corresponding to flashrom svn r1289.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: David Hendricks <dhendrix@google.com>
Diffstat (limited to 'it85spi.c')
-rw-r--r-- | it85spi.c | 76 |
1 files changed, 8 insertions, 68 deletions
@@ -47,9 +47,6 @@ /* Constants for Logical Device registers */ #define LDNSEL 0x07 -#define CHIP_ID_BYTE1_REG 0x20 -#define CHIP_ID_BYTE2_REG 0x21 -#define CHIP_CHIP_VER_REG 0x22 /* These are standard Super I/O 16-bit base address registers */ #define SHM_IO_BAR0 0x60 /* big-endian, this is high bits */ @@ -86,44 +83,6 @@ unsigned int shm_io_base; unsigned char *ce_high, *ce_low; static int it85xx_scratch_rom_reenter = 0; -uint16_t probe_id_ite85(uint16_t port) -{ - uint16_t id; - - id = sio_read(port, CHIP_ID_BYTE1_REG) << 8 | - sio_read(port, CHIP_ID_BYTE2_REG); - - return id; -} - -struct superio probe_superio_ite85xx(void) -{ - struct superio ret = {}; - uint16_t ite_ports[] = {ITE_SUPERIO_PORT1, ITE_SUPERIO_PORT2, 0}; - uint16_t *i = ite_ports; - - ret.vendor = SUPERIO_VENDOR_ITE; - for (; *i; i++) { - ret.port = *i; - ret.model = probe_id_ite85(ret.port); - switch (ret.model >> 8) { - case 0x85: - msg_pdbg("Found EC: ITE85xx (Vendor:0x%02x,ID:0x%02x," - "Rev:0x%02x) on sio_port:0x%x.\n", - ret.model >> 8, ret.model & 0xff, - sio_read(ret.port, CHIP_CHIP_VER_REG), - ret.port); - return ret; - } - } - - /* No good ID found. */ - ret.vendor = SUPERIO_VENDOR_NONE; - ret.port = 0; - ret.model = 0; - return ret; -} - /* This function will poll the keyboard status register until either * an expected value shows up, or * timeout reaches. @@ -267,20 +226,18 @@ void it85xx_exit_scratch_rom() #endif } -int it85xx_spi_common_init(void) +static int it85xx_spi_common_init(struct superio s) { chipaddr base; msg_pdbg("%s():%d superio.vendor=0x%02x\n", __func__, __LINE__, - superio.vendor); - if (superio.vendor != SUPERIO_VENDOR_ITE) - return 1; + s.vendor); #ifdef LPC_IO /* Get LPCPNP of SHM. That's big-endian */ - sio_write(superio.port, LDNSEL, 0x0F); /* Set LDN to SHM (0x0F) */ - shm_io_base = (sio_read(superio.port, SHM_IO_BAR0) << 8) + - sio_read(superio.port, SHM_IO_BAR1); + sio_write(s.port, LDNSEL, 0x0F); /* Set LDN to SHM (0x0F) */ + shm_io_base = (sio_read(s.port, SHM_IO_BAR0) << 8) + + sio_read(s.port, SHM_IO_BAR1); msg_pdbg("%s():%d shm_io_base=0x%04x\n", __func__, __LINE__, shm_io_base); @@ -311,25 +268,7 @@ int it85xx_spi_common_init(void) return 0; } -/* Called by programmer_entry .init */ -int it85xx_spi_init(void) -{ - int ret; - - get_io_perms(); - /* Probe for the Super I/O chip and fill global struct superio. */ - probe_superio(); - ret = it85xx_spi_common_init(); - if (!ret) { - buses_supported = CHIP_BUSTYPE_SPI; - } else { - buses_supported = CHIP_BUSTYPE_NONE; - } - return ret; -} - -/* Called by internal_init() */ -int it85xx_probe_spi_flash(void) +int it85xx_spi_init(struct superio s) { int ret; @@ -337,13 +276,14 @@ int it85xx_probe_spi_flash(void) msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__); return 1; } - ret = it85xx_spi_common_init(); + ret = it85xx_spi_common_init(s); msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret); if (!ret) { msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__, buses_supported); if (buses_supported & CHIP_BUSTYPE_FWH) msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n"); + /* Really leave FWH enabled? */ buses_supported |= CHIP_BUSTYPE_FWH | CHIP_BUSTYPE_SPI; } return ret; |