From b33ee1da7d35c55a5d88583a96ae036b3cc458a2 Mon Sep 17 00:00:00 2001 From: Michał Żygowski Date: Tue, 26 Apr 2022 17:48:27 +0200 Subject: util/superiotool/nuvoton.c: Add NCT6687D-W register definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on public NCT6686D hardware datasheet revision 0.5 which should be similar to NCT6687D. TEST=Dump NCT6687D, GPIO and EC registers on MSI PRO Z690-A WIFI DDR4 Signed-off-by: Michał Żygowski Change-Id: I38db1de0f3d3b6de14bcb758afc9804c072c1895 Reviewed-on: https://review.coreboot.org/c/coreboot/+/63868 Tested-by: build bot (Jenkins) Reviewed-by: Krystian Hebel --- util/superiotool/nuvoton.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c index dfcbaf76bd..66dcfce9eb 100644 --- a/util/superiotool/nuvoton.c +++ b/util/superiotool/nuvoton.c @@ -5,6 +5,41 @@ #define DEVICE_ID_REG 0x20 /* Super I/O ID (SID) / family */ #define DEVICE_REV_REG 0x27 /* Super I/O revision ID (SRID) */ +static uint8_t regread(uint16_t port, uint8_t reg) +{ + OUTB(reg, port); + return INB(port + 1); +} + +/* For Nuvoton EC space */ +static void set_page(uint16_t port, uint8_t page) +{ + /* + * INDEX reg can be written if PAGE reg is not 0xff + * PAGE reg can be written if value or writing data is 0xff + */ + OUTB(0xff, port); + OUTB(page, port); +} + +static void dump_page_index_data(uint16_t iobase) +{ + uint16_t i,j ; + + for (i = 0; i < 255; i++) { + printf("Page %d:\n", i); + for (j = 0; j < 256; j++) { + if (j % 16 == 0) + printf("\n%02x: ", j); + /* PAGE must be selected before each data read */ + set_page(iobase, i); + printf("%02x ", regread(iobase + 1, j)); + } + printf("\n"); + } + printf("\n"); +} + static const struct superio_registers reg_table[] = { {0xfc, "WPCE775x / NPCE781x", { {NOLDN, NULL, @@ -47,6 +82,73 @@ static const struct superio_registers reg_table[] = { {EOT}}}, {0x1a, "WPCM450", { {EOT}}}, + {0xd592, "NCT6687D-W", { + {NOLDN, "Global Configuration", + {0x10,0x11,0x13,0x14,0x15,0x1a,0x1b,0x1d,0x1e, + 0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2f,EOT}, + {0xff,0xff,0x00,0x00,0x00,0x00,0x10,0x00,0x00, + 0x00,0xd5,0x92,0x00,0x80,0x67,0x01,0x00,0x3e, + 0x00,0x03,0x0f,0x00,0x00,0x00,MISC,EOT}}, + {0x02, "Parallel Port", + {0x30,0x60,0x61,0x70,0x74,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x3f,EOT}}, + {0x02, "UART A", + {0x30,0x60,0x61,0x70,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,EOT}}, + {0x03, "UART B, IR", + {0x30,0x60,0x61,0x70,0xf0,0xf1,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,EOT}}, + {0x05, "Keyboard Controller", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,EOT}}, + {0x06, "CIR", + {0x30,0x60,0x61,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, + {0x00,0x00,0x00,0x00,0x08,0x09,0x32,0x00,EOT}}, + {0x07, "GPIO0-7", + {0x30,0x60,0x61,0x70,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5, + 0xe6,0xe7,0xe8,0xe9,0xeb,0xec,0xed,0xee,0xef,0xf0, + 0xf1,EOT}, + {0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA, + NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA, + 0x01,EOT}}, + {0x08, "PORT80 UART", + {0xe0,0xe1,0xe2,0xe3,0xe4,EOT}, + {0x80,0x00,0x00,0x10,0x00,EOT}}, + {0x09, "GPIO8-9, GPIO1-8 Alternate Function", + {0x30,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8, + 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,EOT}}, + {0x0a, "ACPI", + {0x30,0x60,0x61,0x70,0xe0,0xe1,0xe2,0xe3,0xe4,0xe6, + 0xe7,0xe8,0xea,0xeb,0xec,0xee,0xf0,0xf1,0xf2,0xf3, + 0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,EOT}, + {0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0xef,0x80,0x2e,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + 0x0d,0x0d,0x01,0x00,0x04,0x00,0x00,0x00,0x04,EOT}}, + {0x0b, "EC", + {0x30,0x60,0x61,0x70,0xe0,0xe3,0xe4,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,EOT}}, + {0x0c, "RTC", + {0x30,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8, + 0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,EOT}, + {0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,0x00,0x00, + 0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x80,EOT}}, + {0x0d, "Deep Sleep, Power Fault", + {0x30,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8, + 0xf0,0xf1,0xf3,EOT}, + {0xa0,0x20,0x04,0x05,0x6e,0x00,0x00,0x00,0x88,0x77, + 0x70,0xaa,0x01,EOT}}, + {0x0e, "TACHIN/PWMOUT Assignment", + {0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, + 0xea,0xeb,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,EOT}}, + {0x0f, "Function Register", + {0xe3,0xe4,0xe5,0xe8,0xe9,0xea,EOT}, + {0x80,0x01,0x00,0x00,0x00,0x00,EOT}}, + {EOT}}}, {0xb472, "NCT6775F (A)", { {NOLDN, NULL, {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, @@ -682,6 +784,74 @@ static const struct superio_registers reg_table[] = { {EOT} }; +static void dump_nct6687d_gpios(uint16_t port) +{ + uint8_t group, sel; + + const char *gpio_groups[] ={ + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "Reserved", /* Does not exist */ + "EN0", /* Enhance 0 */ + "EN1", /* Enhance 1 */ + }; + + /* Used by reg at 0xd offset to select which registers to reflect */ + const char *gpio_sel[] ={ + "GPIO Data", + "GPIO Interrupt Enable", + "GPIO Status", + "GPIO I/O Control", + "GPIO Inversion Control", + "GPIO PP/OD Control", + "GPIO Interrupt Type", + "GPIO Output Data Reflection", + "GPIO Internal Pull Down Control", + "GPIO Reset Source Control", + "Reserved", + /* Below are valid only for GPIO Enhance Group 0 and 1 */ + "GPIO De-bounce Clock Option", + "GPIO De-bounce Type 0", + "GPIO De-bounce Type 1", + "GPIO De-bounce Time Option 0", + "GPIO De-bounce Time Option 1", + }; + + enter_conf_mode_winbond_fintek_ite_8787(port); + regwrite(port, LDN_SEL, 0x07); + + printf("\nDumping GPIO configuration...\n\n"); + + printf("%-35s", "GPIO Group"); + for (group = 0; group < ARRAY_SIZE(gpio_groups); group++) { + if (group == 10) + continue; + printf("%-5s", gpio_groups[group]); + } + + printf("\n"); + + for (sel = 0; sel < ARRAY_SIZE(gpio_sel); sel++) { + if (sel == 10) + continue; + printf("%-35s", gpio_sel[sel]); + for (group = 0; group < ARRAY_SIZE(gpio_groups); group++) { + if (group == 10) + continue; + /* Select GPIO group */ + regwrite(port, 0xf0, group); + if (group < 11 && sel > 10) + printf("XX "); + else + /* GPIO registers start at LDN 7 offset 0xe0 */ + printf("%02x ", regval(port, 0xe0 + sel)); + } + printf("\n"); + } + + printf("\n"); + exit_conf_mode_winbond_fintek_ite_8787(port); +} + void probe_idregs_nuvoton(uint16_t port) { uint8_t sid, srid; @@ -758,6 +928,17 @@ extra: for (i = 0; i < 10; i++) dump_data(iobase + 5, i); break; + case 0xd590: /* NCT6687D-W */ + dump_nct6687d_gpios(port); + /* One can use the APCI/BIOS register set, although the + * resulting data is still the same when using software + * register set. + * printf("EC I/O base for ACPI/BIOS: 0x%x\n", iobase); + * dump_page_index_data(iobase); + */ + printf("EC I/O base for software: 0x%x\n", iobase + 4); + dump_page_index_data(iobase + 4); + break; } } } -- cgit v1.2.3