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(a)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(a)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,
--
To view, visit https://review.coreboot.org/25113
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I33e48e5f5ad595ffa5555a31f171e602ed6c80e2
Gerrit-Change-Number: 25113
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006(a)gmx.net>
Hello Carl-Daniel Hailfinger,
I'd like you to do a code review. Please visit
https://review.coreboot.org/25112
to review the following change.
Change subject: SMSC SuperI/O detection
......................................................................
SMSC SuperI/O detection
Add SMSC SuperI/O detection.
Avoid probing for SuperI/O at a port where we already know the SuperI/O.
Change-Id: I6e9f6d99193ee539e1fcc268dc3b489983052f96
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006(a)gmx.net>
---
M board_enable.c
M internal.c
M it87spi.c
M programmer.h
4 files changed, 86 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/12/25112/1
diff --git a/board_enable.c b/board_enable.c
index 56d3081..370d9aa 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -45,6 +45,13 @@
OUTB(0xAA, port);
}
+void smsc_enter_conf_mode(uint16_t port)
+{
+ /* Most SMSC Super I/Os require only one 0x55, but the second one does not hurt. */
+ OUTB(0x55, port);
+ OUTB(0x55, port);
+}
+
/* Generic Super I/O helper functions */
uint8_t sio_read(uint16_t port, uint8_t reg)
{
@@ -299,7 +306,10 @@
s.vendor = SUPERIO_VENDOR_WINBOND;
for (; *i; i++) {
s.port = *i;
- /* If we're already in Super I/O config more, the W836xx enter sequence won't hurt. */
+ /* Skip if we already know the Super I/O on this port. */
+ if (superio_port_detected(s.port))
+ continue;
+ /* If we're already in Super I/O config mode, the W836xx enter sequence won't hurt. */
w836xx_ext_enter(s.port);
model = sio_read(s.port, 0x20);
/* No response, no point leaving the config mode. */
@@ -582,6 +592,63 @@
return 0;
}
+#define SMSC_SUPERIO_PORT1 0x2e
+#define SMSC_SUPERIO_PORT2 0x4e
+
+enum smsc_id {
+ SMSC_LPC47N217_ID = 0x7a,
+ SMSC_LPC47N227_ID = 0x5a,
+ SMSC_LPC47N237_ID = 0x13,
+};
+
+void probe_superio_smsc(void)
+{
+ struct superio s = {};
+ uint16_t smsc_ports[] = {SMSC_SUPERIO_PORT1, SMSC_SUPERIO_PORT2, 0};
+ uint16_t *i = smsc_ports;
+ uint8_t model1;
+ uint8_t model2;
+
+ s.vendor = SUPERIO_VENDOR_SMSC;
+ for (; *i; i++) {
+ s.port = *i;
+ /* Skip if we already know the Super I/O on this port. */
+ if (superio_port_detected(s.port))
+ continue;
+ /* If we're already in Super I/O config mode, the SMSC enter sequence won't hurt. */
+ smsc_enter_conf_mode(s.port);
+ /* Older SMSC chips have their ID in register 0x0d. */
+ model1 = sio_read(s.port, 0x0d);
+ /* Newer SMSC chips have their ID in register 0x20. */
+ model2 = sio_read(s.port, 0x20);
+ /* No response, no point leaving the config mode. */
+ if ((model1 == 0xff) && (model2 == 0xff))
+ continue;
+ /* Try to leave config mode. If the ID register is still readable, it's not a SMSC chip. */
+ w836xx_ext_leave(s.port);
+ if ((model1 == sio_read(s.port, 0x0d)) && (model2 == sio_read(s.port, 0x20))) {
+ msg_pdbg("SMSC enter config mode worked or we were already in config mode. SMSC "
+ "leave config mode had no effect.\n");
+ continue;
+ }
+ switch (model1) {
+ case SMSC_LPC47N217_ID:
+ case SMSC_LPC47N227_ID:
+ case SMSC_LPC47N237_ID:
+ /* Encode ID register location in the model. */
+ s.model = (0x0d << 8) | model1 ;
+ msg_pdbg("Found SMSC Super I/O, ID 0x%02x (reg %02x) on port 0x%x\n", s.model & 0xff,
+ s.model >> 8, s.port);
+ register_superio(s);
+ continue;
+ break;
+ }
+ msg_pdbg("Found SMSC Super I/O, ID 0x%02x (reg 0x0d), ID 0x%02x (reg 0x20) on port 0x%x\n",
+ model1, model2, s.port);
+ msg_pdbg("Not registering.\n");
+ }
+}
+
/*
* Suited for all boards with ITE IT8705F.
* The SIS950 Super I/O probably requires a similar flash write enable.
diff --git a/internal.c b/internal.c
index 5b24577..9112708 100644
--- a/internal.c
+++ b/internal.c
@@ -107,7 +107,7 @@
* at a given I/O port, do _not_ probe that port with the ITE probe.
* This means SMSC probing must be done before ITE probing.
*/
- //probe_superio_smsc();
+ probe_superio_smsc();
probe_superio_ite();
}
@@ -116,6 +116,17 @@
struct superio superios[SUPERIO_MAX_COUNT];
+/* Check if a Super I/O chip has already been detected on this port. */
+int superio_port_detected(uint16_t port)
+{
+ int i;
+
+ for (i = 0; i < superio_count; i++)
+ if (superios[i].port == port)
+ return 1;
+ return 0;
+}
+
int register_superio(struct superio s)
{
if (superio_count == SUPERIO_MAX_COUNT)
diff --git a/it87spi.c b/it87spi.c
index 8119289..0d9e983 100644
--- a/it87spi.c
+++ b/it87spi.c
@@ -80,6 +80,9 @@
s.vendor = SUPERIO_VENDOR_ITE;
for (; *i; i++) {
s.port = *i;
+ /* Skip if we already know the Super I/O on this port. */
+ if (superio_port_detected(s.port))
+ continue;
s.model = probe_id_ite(s.port);
switch (s.model >> 8) {
case 0x82:
diff --git a/programmer.h b/programmer.h
index 6f9ea8f..718f3fa 100644
--- a/programmer.h
+++ b/programmer.h
@@ -247,6 +247,7 @@
void w836xx_ext_enter(uint16_t port);
void w836xx_ext_leave(uint16_t port);
void probe_superio_winbond(void);
+void probe_superio_smsc(void);
int it8705f_write_enable(uint8_t port);
uint8_t sio_read(uint16_t port, uint8_t reg);
void sio_write(uint16_t port, uint8_t reg, uint8_t data);
@@ -292,6 +293,7 @@
#define SUPERIO_VENDOR_NONE 0x0
#define SUPERIO_VENDOR_ITE 0x1
#define SUPERIO_VENDOR_WINBOND 0x2
+#define SUPERIO_VENDOR_SMSC 0x3
#endif
#if NEED_PCI == 1
struct pci_dev *pci_dev_find_filter(struct pci_filter filter);
@@ -308,6 +310,7 @@
extern int force_boardenable;
extern int force_boardmismatch;
void probe_superio(void);
+int superio_port_detected(uint16_t port);
int register_superio(struct superio s);
extern enum chipbustype internal_buses_supported;
int internal_init(void);
--
To view, visit https://review.coreboot.org/25112
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e9f6d99193ee539e1fcc268dc3b489983052f96
Gerrit-Change-Number: 25112
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006(a)gmx.net>