From: Uwe Hermann Date: Thu, 20 Sep 2007 22:13:48 +0000 (+0000) Subject: Fix up and generalize the ITE IT8708F code. It was only working out of X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=0702469f163e69257a7cf079eb40ae99f53c815b;p=coreboot.git Fix up and generalize the ITE IT8708F code. It was only working out of pure luck (and broken code elsewhere). Needs some more fixing. Add more LDN descriptions to various Super I/Os. Signed-off-by: Uwe Hermann Acked-by: Uwe Hermann git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2793 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- diff --git a/util/superiotool/fintek.c b/util/superiotool/fintek.c index 8b5fa5b93..e2f9c2772 100644 --- a/util/superiotool/fintek.c +++ b/util/superiotool/fintek.c @@ -20,6 +20,19 @@ #include "superiotool.h" +#define DEVICE_ID_BYTE1_REG 0x20 +#define DEVICE_ID_BYTE2_REG 0x21 +#define VENDOR_ID_BYTE1_REG 0x23 +#define VENDOR_ID_BYTE2_REG 0x24 + +const static struct superio_registers reg_table[] = { + {0x0604, "F71805", { + {EOT}}}, + {0x4103, "F71872", { + {EOT}}}, + {EOT} +}; + void dump_fintek(uint16_t port, uint16_t did) { switch (did) { @@ -106,38 +119,38 @@ static void exit_conf_mode_fintek(uint16_t port) void probe_idregs_fintek(uint16_t port) { - uint16_t vid, did, success = 0; + uint16_t vid, did, did_ite, success = 0; enter_conf_mode_fintek(port); - outb(0x20, port); - if (inb(port) != 0x20) { + did = regval(port, DEVICE_ID_BYTE1_REG); + did |= (regval(port, DEVICE_ID_BYTE2_REG) << 8); + did_ite = ((did & 0xff) << 8) | ((did & 0xff00) >> 8); + + vid = regval(port, VENDOR_ID_BYTE1_REG); + vid |= (regval(port, VENDOR_ID_BYTE2_REG) << 8); + + /* FIXME */ + if (vid != 0x3419 && did_ite != 0x8708 && did_ite != 0x8710) { no_superio_found(port); + exit_conf_mode_fintek(port); return; } - did = inb(port + 1); - did |= (regval(port, 0x21) << 8); - - vid = regval(port, 0x23); - vid |= (regval(port, 0x24) << 8); - printf("Super I/O found at 0x%02x: vid=0x%04x/did=0x%04x\n", - port, vid, did); - - if (vid == 0xff || vid == 0xffff) + if (did_ite == 0x8708 || did_ite == 0x8701) { + printf("Found ITE IT%04xF (id=0x%04x, rev=0x%01x) at port=0x%x\n", did_ite, did_ite, 0, port); /* FIXME */ + dump_ite(port, did_ite); + regwrite(port, 0x02, 0x02); /* FIXME */ return; - - /* printf("%s\n", familyid[id]); */ - switch (did) { - case 0x0887: /* Pseudoreversed for ITE8708 */ - case 0x1087: /* Pseudoreversed for ITE8710 */ - success = 1; - dump_ite(port, ((did & 0xff) << 8) | ((did & 0xff00) >> 8)); - regwrite(port, 0x02, 0x02); /* Exit MB PnP mode. */ - break; - default: - break; } + + if (vid == 0xff || vid == 0xffff) { + exit_conf_mode_fintek(port); + return; + } + + printf("Found Fintek %s (vid=0x%04x, id=0x%04x) at port=0x%x\n", + get_superio_name(reg_table, did), vid, did, port); switch (vid) { case 0x3419: diff --git a/util/superiotool/ite.c b/util/superiotool/ite.c index fc7c4137d..610516a98 100644 --- a/util/superiotool/ite.c +++ b/util/superiotool/ite.c @@ -21,44 +21,49 @@ #include "superiotool.h" +#define CHIP_ID_BYTE1_REG 0x20 +#define CHIP_ID_BYTE2_REG 0x21 +#define CHIP_VERSION_REG 0x22 + +/* Note: IT8726F has ID 0x8726 (datasheet wrongly says 0x8716). */ const static struct superio_registers reg_table[] = { - {0x8702, "IT8702", { + {0x8702, "IT8702F", { {EOT}}}, - {0x8705, "IT8705 or IT8700", { + {0x8705, "IT8705F or IT8700F", { {EOT}}}, - {0x8708, "IT8708", { + {0x8708, "IT8708F", { {NOLDN, NULL, {0x07,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2a,0x2e,0x2f,EOT}, {NANA,0x87,0x08,0x00,0x00,NANA,0x3f,0x00,0xff,0xff, 0xff,0xff,0x00,0x00,EOT}}, - {0x0, NULL, + {0x0, "Floppy", {0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,EOT}, {0x00,0x03,0xf0,0x06,0x02,0x00,0x00,EOT}}, - {0x1, NULL, + {0x1, "COM1", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0xf8,0x04,0x00,EOT}}, - {0x2, NULL, + {0x2, "COM2", {0x30,0x60,0x61,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, {0x00,0x02,0xf8,0x03,0x00,0x50,0x00,0x7f,EOT}}, - {0x3, NULL, + {0x3, "Parallel port", {0x30,0x60,0x61,0x62,0x63,0x64,0x65,0x70,0x74, 0xf0,EOT}, {0x00,0x03,0x78,0x07,0x78,0x00,0x80,0x07,0x03, 0x03,EOT}}, - {0x4, NULL, + {0x4, "SWC", {0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7, 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,EOT}, {NANA,NANA,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,NANA,NANA,EOT}}, - {0x5, NULL, + {0x5, "Keyboard", /* Note: 0x30 can actually be 0x00 _or_ 0x01. */ {0x30,0x60,0x61,0x62,0x63,0x70,0x71,0xf0,EOT}, {0x01,0x00,0x60,0x00,0x64,0x01,0x02,0x00,EOT}}, - {0x6, NULL, + {0x6, "Mouse", {0x30,0x70,0x71,0xf0,EOT}, {0x00,0x0c,0x02,0x00,EOT}}, - {0x7, NULL, + {0x7, "GPIO", {0x70,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb8,0xb9,0xba, 0xbb,0xbc,0xbd,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc8, 0xc9,0xca,0xcb,0xcc,0xcd,0xd0,0xd1,0xd2,0xd3,0xd4, @@ -71,46 +76,47 @@ const static struct superio_registers reg_table[] = { 0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA, 0x00,EOT}}, - {0x8, NULL, + {0x8, "Game port", {0x30,0x60,0x61,EOT}, {0x00,0x02,0x01,EOT}}, - {0x9, NULL, + {0x9, "Consumer IR", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0x10,0x0b,0x00,EOT}}, - {0xa, NULL, + {0xa, "MIDI port", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0x00,0x0a,0x00,EOT}}, {EOT}}}, - {0x8710, "IT8710", { + {0x8710, "IT8710F", { {EOT}}}, - {0x8712, "IT8712", { + {0x8712, "IT8712F", { {NOLDN, NULL, {0x07,0x20,0x21,0x22,0x23,0x24,0x2b,EOT}, {NANA,0x87,0x12,0x08,0x00,0x00,0x00,EOT}}, - {0x0, NULL, + {0x0, "Floppy", {0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,EOT}, {0x00,0x03,0xf0,0x06,0x02,0x00,0x00,EOT}}, - {0x1, NULL, + {0x1, "COM1", {0x30,0x60,0x61,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, {0x00,0x03,0xf8,0x04,0x00,0x50,0x00,0x7f,EOT}}, - {0x2, NULL, + {0x2, "COM2", {0x30,0x60,0x61,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, {0x00,0x02,0xf8,0x03,0x00,0x50,0x00,0x7f,EOT}}, - {0x3, NULL, + {0x3, "Parallel port", {0x30,0x60,0x61,0x62,0x63,0x70,0x74,0xf0,EOT}, {0x00,0x03,0x78,0x07,0x78,0x07,0x03,0x03,EOT}}, - {0x4, NULL, + {0x4, "Environment controller", {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,EOT}, {0x00,0x02,0x90,0x02,0x30,0x09,0x00,0x00,0x00,0x00, 0x00,NANA,NANA,EOT}}, - {0x5, NULL, + {0x5, "Keyboard", + /* TODO: 0xf0: Error in datasheet? */ {0x30,0x60,0x61,0x62,0x63,0x70,0x71,0xf0,EOT}, {0x01,0x00,0x60,0x00,0x64,0x01,0x02,0x08,EOT}}, - {0x6, NULL, + {0x6, "Mouse", {0x30,0x70,0x71,0xf0,EOT}, {0x00,0x0c,0x02,0x00,EOT}}, - {0x7, NULL, + {0x7, "GPIO", /* TODO: 0x72, 0x73: Errors in datasheet? */ {0x25,0x26,0x27,0x28,0x29,0x2a,0x2c,0x60,0x61,0x62, 0x63,0x64,0x65,0x70,0x71,0x72,0x73,0x74,0xb0,0xb1, 0xb2,0xb3,0xb4,0xb5,0xb8,0xb9,0xba,0xbb,0xbc,0xbd, @@ -118,22 +124,22 @@ const static struct superio_registers reg_table[] = { 0xe0,0xe1,0xe2,0xe3,0xe4,0xf0,0xf1,0xf2,0xf3,0xf4, 0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,EOT}, {0x01,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x30,0x38,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x40,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,0x00,EOT}}, - {0x8, NULL, + {0x8, "MIDI port", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0x00,0x0a,0x00,EOT}}, - {0x9, NULL, + {0x9, "Game port", {0x30,0x60,0x61,EOT}, {0x00,0x02,0x01,EOT}}, - {0xa, NULL, + {0xa, "Consumer IR", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0x10,0x0b,0x00,EOT}}, {EOT}}}, - {0x8716, "IT8716", { + {0x8716, "IT8716F", { {NOLDN, NULL, {0x07,0x20,0x21,0x22,0x23,0x24,0x2b,EOT}, {NANA,0x87,0x16,0x01,0x00,0x00,0x00,EOT}}, @@ -183,52 +189,36 @@ const static struct superio_registers reg_table[] = { {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x00,0x03,0x10,0x0b,0x00,EOT}}, {EOT}}}, - {0x8718, "IT8718", { + {0x8718, "IT8718F", { {EOT}}}, {EOT} }; +/* TODO: Drop this function later. */ void dump_ite(uint16_t port, uint16_t id) { - int i; - - /* TODO: Get datasheets for IT8711 and IT8712. */ - switch (id) { - case 0x8702: - case 0x8705: /* IT8700F or IT8705F */ - case 0x8708: - case 0x8710: - case 0x8712: - case 0x8716: - /* Note: IT8726F has ID 0x8726 (datasheet wrongly says 0x8716). */ - case 0x8718: - dump_superio("ITE", reg_table, port, id); - break; - default: - printf("Unknown ITE chip, id=%04x\n", id); - for (i = 0x20; i <= 0x24; i++) - printf("index %02x=%02x\n", i, regval(port, i)); - break; - } + dump_superio("ITE", reg_table, port, id); } +/** + * Enable configuration sequence (ITE uses this for newer IT87[012]xF). + * + * IT871[01]F uses 0x87, 0x87 -> Fintek detection should handle it + * IT8708F uses 0x87, 0x87 -> Fintek detection should handle it + * IT8761F uses 0x87, 0x61, 0x55, 0x55/0xaa + * IT86xxF series uses different ports + * IT8661F uses 0x86, 0x61, 0x55/0xaa, 0x55/0xaa and 32 more writes + * IT8673F uses 0x86, 0x80, 0x55/0xaa, 0x55/0xaa and 32 more writes + */ static void enter_conf_mode_ite(uint16_t port) { - /* Enable configuration sequence (ITE uses this for newer IT87[012]x) - * IT871[01] uses 0x87, 0x87 -> fintek detection should handle it - * IT8708 uses 0x87, 0x87 -> fintek detection should handle it - * IT8761 uses 0x87, 0x61, 0x55, 0x55/0xaa - * IT86xx series uses different ports - * IT8661 uses 0x86, 0x61, 0x55/0xaa, 0x55/0xaa and 32 more writes - * IT8673 uses 0x86, 0x80, 0x55/0xaa, 0x55/0xaa and 32 more writes - */ outb(0x87, port); outb(0x01, port); outb(0x55, port); if (port == 0x2e) outb(0x55, port); else - outb(0xAA, port); + outb(0xaa, port); } static void exit_conf_mode_ite(uint16_t port) @@ -242,25 +232,20 @@ void probe_idregs_ite(uint16_t port) enter_conf_mode_ite(port); - /* Read Chip ID Byte 1. */ - id = regval(port, 0x20); - if (id != 0x87) { + id = regval(port, CHIP_ID_BYTE1_REG) << 8; + id |= regval(port, CHIP_ID_BYTE2_REG); + chipver = regval(port, CHIP_VERSION_REG) & 0x0f; /* Only bits 3..0 */ + + if (superio_unknown(reg_table, id)) { no_superio_found(port); + exit_conf_mode_ite(port); return; } - id <<= 8; - - /* Read Chip ID Byte 2. */ - id |= regval(port, 0x21); - - /* Read chip version, only bits 3..0 for all IT87xx. */ - chipver = regval(port, 0x22) & 0x0f; - - printf("Super I/O found at 0x%02x: id=0x%04x, chipver=0x%01x\n", - port, id, chipver); + printf("Found ITE %s (id=0x%04x, rev=0x%01x) at port=0x%x\n", + get_superio_name(reg_table, id), id, chipver, port); - dump_ite(port, id); + dump_superio("ITE", reg_table, port, id); exit_conf_mode_ite(port); } diff --git a/util/superiotool/nsc.c b/util/superiotool/nsc.c index c308256e7..ec9b32619 100644 --- a/util/superiotool/nsc.c +++ b/util/superiotool/nsc.c @@ -63,6 +63,7 @@ void probe_idregs_simple(uint16_t port) outb(0x20, port); if (inb(port) != 0x20) { no_superio_found(port); + /* TODO: Exit config mode? */ return; } id = inb(port + 1); diff --git a/util/superiotool/smsc.c b/util/superiotool/smsc.c index 3bfc53661..13ad4a722 100644 --- a/util/superiotool/smsc.c +++ b/util/superiotool/smsc.c @@ -61,6 +61,7 @@ void probe_idregs_smsc(uint16_t port) if (superio_unknown(reg_table, id)) { no_superio_found(port); + exit_conf_mode_smsc(port); return; } diff --git a/util/superiotool/winbond.c b/util/superiotool/winbond.c index 709e7f329..ca2d1db4b 100644 --- a/util/superiotool/winbond.c +++ b/util/superiotool/winbond.c @@ -31,10 +31,9 @@ const static struct superio_registers reg_table[] = { {0x601, "W83697HF/F", { {NOLDN, NULL, - /* TODO: 0x02, 0x07. */ - {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29, + {0x07,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29, 0x2a,EOT}, - {0x60,NANA,0xff,0x00,0x00,0x00,0x00,0x00,0x00, + {NANA,0x60,NANA,0xff,0x00,0x00,0x00,0x00,0x00,0x00, MISC,EOT}}, /* Some register defaults depend on the value of PNPCSV. */ {0x0, "Floppy", @@ -51,18 +50,18 @@ const static struct superio_registers reg_table[] = { {0x3, "COM2", {0x30,0x60,0x61,0x70,0xf0,0xf1,EOT}, {0x01,0x02,0xf8,0x03,0x00,0x00,EOT}}, - {0x6, "CIR", + {0x6, "Consumer IR", {0x30,0x60,0x61,0x70,EOT}, {0x00,0x00,0x00,0x00,EOT}}, - {0x7, "Game port, GPIO port 1", + {0x7, "Game port, GPIO 1", {0x30,0x60,0x61,0x62,0x63,0xf0,0xf1,0xf2,EOT}, {0x00,0x02,0x01,0x00,0x00,0xff,0x00,0x00,EOT}}, - {0x8, "MIDI port, GPIO port 5", + {0x8, "MIDI port, GPIO 5", {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,EOT}, {0x00,0x03,0x30,0x00,0x00,0x09,0xff,0x00,0x00,0x00, 0x00,0x00,EOT}}, - {0x9, "GPIO port 2, 3, and 4", + {0x9, "GPIO 2, GPIO 3, GPIO 4", {0x30,0x60,0x61,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6, 0xf7,0xf8,0xf5,EOT}, {0x00,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff, @@ -80,47 +79,47 @@ const static struct superio_registers reg_table[] = { {NOLDN, NULL, {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,EOT}, - {0x88,NANA,0xff,0x00,MISC,0x00,MISC,RSVD,0x50, + {0x88,MISC,0xff,0x00,MISC,0x00,MISC,RSVD,0x50, 0x04,0x00,RSVD,0x00,0x21,0x00,0x00,EOT}}, - {0x0, NULL, + {0x0, "Floppy", {0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,0xf2,0xf4, 0xf5,EOT}, {0x01,0x03,0xf0,0x06,0x02,0x8e,0x00,0xff,0x00, 0x00,EOT}}, - {0x1, NULL, + {0x1, "Parallel port", {0x30,0x60,0x61,0x70,0x74,0xf0,EOT}, {0x01,0x03,0x78,0x07,0x04,0x3f,EOT}}, - {0x2, NULL, + {0x2, "COM1", {0x30,0x60,0x61,0x70,0xf0,EOT}, {0x01,0x03,0xf8,0x04,0x00,EOT}}, - {0x3, NULL, + {0x3, "COM2", {0x30,0x60,0x61,0x70,0xf0,0xf1,EOT}, {0x01,0x02,0xf8,0x03,0x00,0x00,EOT}}, - {0x5, NULL, + {0x5, "Keyboard", {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,EOT}, {0x01,0x00,0x60,0x00,0x64,0x01,0x0c,0x83,EOT}}, - {0x6, NULL, + {0x6, "Serial flash interface", {0x30,0x62,0x63,EOT}, {0x00,0x00,0x00,EOT}}, - {0x7, NULL, + {0x7, "GPIO 1, GPIO 6, game port, MIDI port", {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7,EOT}, {0x00,0x02,0x01,0x03,0x30,0x09,0xff,0x00,0x00,0x00, 0xff,0x00,0x00,0x00,EOT}}, - {0x8, NULL, + {0x8, "WDTO#, PLED", {0x30,0xf5,0xf6,0xf7,EOT}, {0x00,0x00,0x00,0x00,EOT}}, - {0x9, NULL, + {0x9, "GPIO 2, GPIO 3, GPIO 4, GPIO 5, SUSLED", {0x30,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xf0,0xf1,0xf2, 0xf3,0xf4,0xf5,0xf6,0xf7,EOT}, {0x00,0xff,0x00,0x00,0xff,0x00,0x00,0xff,0x00,0x00, 0x00,0xff,0x00,0x00,0x00,EOT}}, - {0xa, NULL, + {0xa, "ACPI", {0x30,0x70,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7, 0xe8,0xf2,0xf3,0xf4,0xf6,0xf7,EOT}, {0x00,0x00,0x01,0x00,0xff,0x08,0x00,RSVD,0x00,0x00, RSVD,0x7c,0x00,0x00,0x00,0x00,EOT}}, - {0xb, NULL, + {0xb, "Hardware monitor", {0x30,0x60,0x61,0x70,0xf0,0xf1,EOT}, {0x00,0x00,0x00,0x00,0xc1,0x00,EOT}}, {EOT}}}, @@ -153,6 +152,7 @@ void probe_idregs_winbond(uint16_t port) if (superio_unknown(reg_table, id)) { no_superio_found(port); + exit_conf_mode_winbond(port); return; }