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>
This commit is contained in:
Michał Żygowski 2022-04-26 17:48:27 +02:00
parent c28302fdda
commit b33ee1da7d
1 changed files with 181 additions and 0 deletions

View File

@ -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;
}
}
}