Hello Carl-Daniel Hailfinger,
I'd like you to do a code review. Please visit
https://review.coreboot.org/25113
to review the following change.
Change subject: Fintek SPI driver, based off it87spi ......................................................................
Fintek SPI driver, based off it87spi
Updated Fintek Super I/O detection/handling code.
Note: This code contains no SPI support whatsoever, that will happen in a followup patch.
A verbose log would be appreciated.
TODO: - Kill duplicated code (conf mode enter/exit) - File name: fintek_spi.c, sio_fintek.c, f718xx_spi.c, ...? - Should we check for known IDs in probe_superio_fintek() as well even though we're 100% sure about the vendor? What about Fintek devices which are attached to the LPC bus but are not Super I/Os? - Ask Hans de Goede for a F71889E datasheet.
Change-Id: I33e48e5f5ad595ffa5555a31f171e602ed6c80e2 Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net --- M Makefile A fintek_spi.c M internal.c M programmer.h 4 files changed, 153 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/13/25113/1
diff --git a/Makefile b/Makefile index 9309ce5..5d964dd 100644 --- a/Makefile +++ b/Makefile @@ -404,7 +404,7 @@ PROGRAMMER_OBJS += processor_enable.o chipset_enable.o board_enable.o cbtable.o dmi.o internal.o ifeq ($(ARCH), x86) PROGRAMMER_OBJS += it87spi.o it85spi.o sb600spi.o wbsio_spi.o mcp6x_spi.o -PROGRAMMER_OBJS += ichspi.o ich_descriptors.o +PROGRAMMER_OBJS += ichspi.o ich_descriptors.o fintek_spi.o else endif NEED_PCI := yes diff --git a/fintek_spi.c b/fintek_spi.c new file mode 100644 index 0000000..d0054bd --- /dev/null +++ b/fintek_spi.c @@ -0,0 +1,141 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 Sean Nelson audiohacked@gmail.com + * Copyright (C) 2011,2012 Carl-Daniel Hailfinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Contains the Fintek F7188x SPI specific routines + * + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include <string.h> +#include <stdlib.h> +#include "flash.h" +#include "chipdrivers.h" +#include "programmer.h" +#include "hwaccess.h" + +#define FINTEK_SUPERIO_PORT1 0x2e +#define FINTEK_SUPERIO_PORT2 0x4e + +/* Helper functions for Fintek F7188x Super I/O chips */ +#define DEVICE_ID_BYTE1_REG 0x20 +#define DEVICE_ID_BYTE2_REG 0x21 + +#define VENDOR_ID_BYTE1_REG 0x23 +#define VENDOR_ID_BYTE2_REG 0x24 + +#define FINTEK_VENDOR_ID 0x1934 + +void enter_conf_mode_fintek_ite_8787(uint16_t port) +{ + OUTB(0x87, port); + OUTB(0x87, port); +} + +void exit_conf_mode_winbond_fintek_ite_8787(uint16_t port) +{ + OUTB(0xaa, port); +} + +uint16_t probe_vid_fintek(uint16_t port) +{ + uint16_t id; + + enter_conf_mode_fintek_ite_8787(port); + id = sio_read(port, VENDOR_ID_BYTE1_REG) << 8; + id |= sio_read(port, VENDOR_ID_BYTE2_REG); + exit_conf_mode_winbond_fintek_ite_8787(port); + return id; +} + +uint16_t probe_id_fintek(uint16_t port) +{ + uint16_t id; + + enter_conf_mode_fintek_ite_8787(port); + id = sio_read(port, DEVICE_ID_BYTE1_REG) << 8; + id |= sio_read(port, DEVICE_ID_BYTE2_REG); + exit_conf_mode_winbond_fintek_ite_8787(port); + return id; +} + +void probe_superio_fintek(void) +{ + struct superio s = {}; + uint16_t fintek_ports[] = {FINTEK_SUPERIO_PORT1, FINTEK_SUPERIO_PORT2, 0}; + uint16_t *i = fintek_ports; + + s.vendor = SUPERIO_VENDOR_FINTEK; + for (; *i; i++) { + s.port = *i; + if (probe_vid_fintek(s.port) != FINTEK_VENDOR_ID) + continue; + s.model = probe_id_fintek(s.port); + // FIXME: Should we explicitly check for known IDs? + msg_pinfo("Found Fintek Super I/O, ID 0x%04hx.\n", s.model); + register_superio(s); + break; + } + + return; +} + + +int init_superio_fintek(void) +{ + int i; + int ret = 0; + + for (i = 0; i < superio_count; i++) { + if (superios[i].vendor != SUPERIO_VENDOR_FINTEK) + continue; + + switch (superios[i].model) { + case 0x0601: /* F71862FG / F71863FG */ + case 0x0541: /* F71882F / F71883F / F71887 */ + case 0x0723: /* F71889F */ + case 0x0704: /* F81865F */ + msg_pdbg("Super I/O ID 0x%04hx is SPI capable. TODO: Check if SPI is active.\n", + superios[i].model); + break; + case 0x0909: /* F71889E, only known person with datasheet is Hans de Goede */ + case 0x1010: /* F81867, seems to have builtin flash, but SPI is only slave functionality. */ + /* Characteristics unknown. */ + msg_pdbg("Super I/O ID 0x%04hx may be SPI capable. TODO: Find a datasheet.\n", + superios[i].model); + break; + case 0x1001: /* F71808A */ + case 0x0901: /* F71808E */ + case 0x0507: /* F71858DG */ + case 0x0814: /* F71869F */ + case 0x0719: /* F71869A */ + case 0x0341: /* F71872F */ + case 0x1005: /* F71889A */ + /* Known not to have any flash translation features. */ + default: + msg_pdbg("Super I/O ID 0x%04hx is not on the list of flash capable controllers.\n", + superios[i].model); + } + } + return ret; +} + +#endif diff --git a/internal.c b/internal.c index 3ecc348..9450d18 100644 --- a/internal.c +++ b/internal.c @@ -110,6 +110,7 @@ */ //probe_superio_smsc(); probe_superio_ite(); + probe_superio_fintek(); }
int superio_count = 0; @@ -319,6 +320,7 @@ * IT87* Parallel write enable. */ init_superio_ite(); + init_superio_fintek(); #endif
board_flash_enable(lb_vendor, lb_part); diff --git a/programmer.h b/programmer.h index 7d06be3..78da23f 100644 --- a/programmer.h +++ b/programmer.h @@ -295,6 +295,7 @@ #define SUPERIO_VENDOR_NONE 0x0 #define SUPERIO_VENDOR_ITE 0x1 #define SUPERIO_VENDOR_WINBOND 0x2 +#define SUPERIO_VENDOR_FINTEK 0x4 #endif #if NEED_PCI == 1 struct pci_filter; @@ -542,6 +543,14 @@ int default_spi_write_aai(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int register_spi_programmer(const struct spi_programmer *programmer);
+/* fintek_spi.c */ +#if CONFIG_INTERNAL == 1 +void enter_conf_mode_fintek_ite_8787(uint16_t port); +void exit_conf_mode_winbond_fintek_ite_8787(uint16_t port); +void probe_superio_fintek(void); +int init_superio_fintek(void); +#endif + /* The following enum is needed by ich_descriptor_tool and ich* code. */ enum ich_chipset { CHIPSET_ICH_UNKNOWN,