util/superiotool/nuvoton.c: Add NCT6687D-W register definitions
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 <michal.zygowski@3mdeb.com>
Change-Id: I38db1de0f3d3b6de14bcb758afc9804c072c1895
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63868
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Krystian Hebel <krystian.hebel@3mdeb.com>
diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c
index dfcbaf7..66dcfce 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 @@
{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 @@
{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 @@
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;
}
}
}