superio/nuvoton: Add NCT5535D

Found on many Asus P8x7x series mainboards, NCT5535D is a 64-pin LPC
super I/O chip with no publicly available datasheet. However, it appears
to share the same silicon as NCT6779D. With only half the pins of 6779,
it does not have parallel port, serial port B, or GPIOs 1 and 6.

This patch adds header and Kconfig option for 5535, and adapts 6779
code to also supply C code to 5535 as well.

asus/p8z77-v_lx2 still builds once modified for this chip, but is not
tested further.

Change-Id: I3fe0dd6fc3010a50b781ca7c5c39ea73b91978a5
Signed-off-by: Keith Hui <buurin@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85834
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Keith Hui 2024-12-29 17:21:28 -05:00 committed by Matt DeVillier
commit 894c8069fc
10 changed files with 300 additions and 40 deletions

View file

@ -6,6 +6,7 @@ romstage-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/early_serial.c
subdirs-$(CONFIG_SUPERIO_NUVOTON_WPCM450) += wpcm450
subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5104D) += nct5104d
subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += nct5535d nct6779d
subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5539D) += nct5539d
subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5572D) += nct5572d
subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6687D) += nct6687d

View file

@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
config SUPERIO_NUVOTON_NCT5535D
bool
select SUPERIO_NUVOTON_COMMON_PRE_RAM
select HAVE_POWER_STATE_AFTER_FAILURE
help
NCT5535D is a cut-down version of NCT6779D and is otherwise supported by
superio/nuvoton/nct6779d, which provides C code for initialization. This directory
only provides consistently-named header and structures.

View file

@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-or-later
ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += nct5535d.c

View file

@ -0,0 +1,175 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Include this file into a mainboard's DSDT _SB device tree and it will
* expose the NCT5535D SuperIO and some of its functionality.
*
* It allows the change of IO ports, IRQs and DMA settings on logical
* devices, disabling and reenabling logical devices.
*
* LDN State
* 0x2 SP1 Implemented, untested
* 0x5 KBC Implemented, untested
* 0x8 GPIO Implemented, untested
* 0xb HWM Implemented, untested
*
* Controllable through preprocessor defines:
* SUPERIO_DEV Device identifier for this SIO (e.g. SIO0)
* SUPERIO_PNP_BASE I/O address of the first PnP configuration register
* NCT5535D_SHOW_SP1 If defined, Serial Port 1 will be exposed.
* NCT5535D_SHOW_KBC If defined, the Keyboard Controller will be exposed.
* NCT5535D_SHOW_GPIO If defined, GPIO support will be exposed.
* NCT5535D_SHOW_HWM If defined, the Environment Controller will be exposed.
*/
#include <superio/nuvoton/nct5535d/nct5535d.h>
#undef SUPERIO_CHIP_NAME
#define SUPERIO_CHIP_NAME NCT5535D
#include <superio/acpi/pnp.asl>
#undef PNP_DEFAULT_PSC
#define PNP_DEFAULT_PSC Return (0) /* no power management */
#define ENABLE_KEYBOARD_WAKEUP SKWK
#define POWER_LOSS_CONTROL SPWL
Device(SUPERIO_DEV) {
Name (_HID, EisaId("PNP0A05"))
Name (_STR, Unicode("Nuvoton NCT5535D Super I/O"))
Name (_UID, SUPERIO_UID(SUPERIO_DEV,))
/* SuperIO configuration ports */
OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 2)
Field (CREG, ByteAcc, NoLock, Preserve)
{
PNP_ADDR_REG, 8,
PNP_DATA_REG, 8,
}
IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve)
{
Offset (0x07),
PNP_LOGICAL_DEVICE, 8, /* Logical device selector */
Offset (0x30),
PNP_DEVICE_ACTIVE, 1, /* Logical device activation */
ACT1, 1, /* Logical device activation */
ACT2, 1, /* Logical device activation */
ACT3, 1, /* Logical device activation */
ACT4, 1, /* Logical device activation */
ACT5, 1, /* Logical device activation */
ACT6, 1, /* Logical device activation */
ACT7, 1, /* Logical device activation */
Offset (0x60),
PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */
PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */
Offset (0x62),
PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */
PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */
Offset (0x70),
PNP_IRQ0, 8, /* First IRQ */
Offset (0x72),
PNP_IRQ1, 8, /* Second IRQ */
Offset (0x74),
PNP_DMA0, 8, /* DRQ */
Offset (0xe0), /* Config register 0xe0 etc. */
,6,
ENABLE_KEYBOARD_WAKEUP, 1,
Offset (0xe4),
,5,
POWER_LOSS_CONTROL, 2,
}
Method (_CRS)
{
/* Announce the used I/O ports to the OS */
Return (ResourceTemplate () {
IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, 0x01, 0x02)
})
}
Method (SIOS, 1, NotSerialized)
{
if (Arg0 == 5)
{
ENTER_CONFIG_MODE(NCT5535D_ACPI)
ENABLE_KEYBOARD_WAKEUP = 0
EXIT_CONFIG_MODE()
}
}
Method (SIOW, 1, NotSerialized)
{
}
#undef PNP_ENTER_MAGIC_1ST
#undef PNP_ENTER_MAGIC_2ND
#undef PNP_ENTER_MAGIC_3RD
#undef PNP_ENTER_MAGIC_4TH
#undef PNP_EXIT_MAGIC_1ST
#undef PNP_EXIT_SPECIAL_REG
#undef PNP_EXIT_SPECIAL_VAL
#define PNP_ENTER_MAGIC_1ST 0x87
#define PNP_ENTER_MAGIC_2ND 0x87
#define PNP_EXIT_MAGIC_1ST 0xaa
#include <superio/acpi/pnp_config.asl>
#ifdef NCT5535D_SHOW_SP1
#undef SUPERIO_UART_LDN
#undef SUPERIO_UART_DDN
#undef SUPERIO_UART_PM_REG
#undef SUPERIO_UART_PM_VAL
#undef SUPERIO_UART_PM_LDN
#define SUPERIO_UART_LDN NCT5535D_SP1
#include <superio/acpi/pnp_uart.asl>
#endif
#ifdef NCT5535D_SHOW_KBC
#undef SUPERIO_KBC_LDN
#undef SUPERIO_KBC_PS2M
#undef SUPERIO_KBC_PS2LDN
#define SUPERIO_KBC_LDN NCT5535D_KBC
#define SUPERIO_KBC_PS2M
#include <superio/acpi/pnp_kbc.asl>
#endif
#ifdef NCT5535D_SHOW_HWM
#undef SUPERIO_PNP_HID
#undef SUPERIO_PNP_LDN
#undef SUPERIO_PNP_DDN
#undef SUPERIO_PNP_NO_DIS
#undef SUPERIO_PNP_PM_REG
#undef SUPERIO_PNP_PM_VAL
#undef SUPERIO_PNP_PM_LDN
#undef SUPERIO_PNP_IO0
#undef SUPERIO_PNP_IO1
#undef SUPERIO_PNP_IO2
#undef SUPERIO_PNP_IRQ0
#undef SUPERIO_PNP_IRQ1
#undef SUPERIO_PNP_DMA
#define SUPERIO_PNP_LDN NCT5535D_HWM_FPLED
#define SUPERIO_PNP_IO0 0x08, 0x08
#define SUPERIO_PNP_IO1 0x08, 0x08
#define SUPERIO_PNP_IRQ0
#include <superio/acpi/pnp_generic.asl>
#endif
#ifdef NCT5535D_SHOW_GPIO
#undef SUPERIO_PNP_HID
#undef SUPERIO_PNP_LDN
#undef SUPERIO_PNP_DDN
#undef SUPERIO_PNP_NO_DIS
#undef SUPERIO_PNP_PM_REG
#undef SUPERIO_PNP_PM_VAL
#undef SUPERIO_PNP_PM_LDN
#undef SUPERIO_PNP_IO0
#undef SUPERIO_PNP_IO1
#undef SUPERIO_PNP_IRQ0
#undef PNP_DEVICE_ACTIVE
#define PNP_DEVICE_ACTIVE ACT3
#define SUPERIO_PNP_LDN 8
#define SUPERIO_PNP_IO0 0x08, 0x08
#include <superio/acpi/pnp_generic.asl>
#endif
}

View file

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/device.h>
#include <device/pnp.h>
#include "nct5535d.h"
/* Initialization C code is provided by nct6779d */
static struct pnp_info pnp_dev_info[] = {
{ NULL, NCT5535D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT5535D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1,
0x0fff, 0x0fff, },
{ NULL, NCT5535D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0,
0x0ffe, 0x0ffe, },
{ NULL, NCT5535D_GPIOBASE, PNP_IO0, 0x0ff8, },
};
static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &_nuvoton_nct6779d_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}
struct chip_operations superio_nuvoton_nct5535d_ops = {
.name = "NUVOTON NCT5535D Super I/O",
.enable_dev = enable_dev,
};

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef SUPERIO_NUVOTON_NCT5535D_H
#define SUPERIO_NUVOTON_NCT5535D_H
#include "../nct6779d/nct6779d.h"
/* All aliases to NCT6779D numbers. */
#define NCT5535D_SP1 NCT6779D_SP1
#define NCT5535D_KBC NCT6779D_KBC
#define NCT5535D_GPIO78_V NCT6779D_GPIO678_V
#define NCT5535D_WDT1_V NCT6779D_WDT1_GPIO01_V
#define NCT5535D_GPIO_V NCT6779D_GPIO12345678_V
#define NCT5535D_ACPI NCT6779D_ACPI
#define NCT5535D_HWM_FPLED NCT6779D_HWM_FPLED
#define NCT5535D_WDT1_MASK NCT6779D_WDT1
#define NCT5535D_GPIO_PP_OD NCT6779D_GPIO_PP_OD
#define NCT5535D_PRT80 NCT6779D_PRT80
#define NCT5535D_DSLP NCT6779D_DSLP
#ifndef __ACPI__
#define NCT5535D_GPIOBASE ((3 << 8) | NCT5535D_WDT1_V)
#define NCT5535D_WDT1 NCT5535D_WDT1_V
#define NCT5535D_GPIO2 ((2 << 8) | NCT5535D_GPIO_V)
#define NCT5535D_GPIO3 ((3 << 8) | NCT5535D_GPIO_V)
#define NCT5535D_GPIO4 ((4 << 8) | NCT5535D_GPIO_V)
#define NCT5535D_GPIO5 ((5 << 8) | NCT5535D_GPIO_V)
#define NCT5535D_GPIO7 ((7 << 8) | NCT5535D_GPIO_V)
#define NCT5535D_GPIO8 ((0 << 8) | NCT5535D_GPIO_V)
#endif
#endif /* SUPERIO_NUVOTON_NCT5535D_H */

View file

@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-or-later
ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6779D) += superio.c
ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6779D) += superio.c nct6779d.c
ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += superio.c

View file

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/device.h>
#include <device/pnp.h>
#include "nct6779d.h"
static struct pnp_info pnp_dev_info[] = {
{ NULL, NCT6779D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8, },
{ NULL, NCT6779D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1,
0x0fff, 0x0fff, },
{ NULL, NCT6779D_CIR, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_ACPI, PNP_MSC2,},
{ NULL, NCT6779D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0,
0x0ffe, 0x0ffe, },
{ NULL, NCT6779D_WDT1},
{ NULL, NCT6779D_CIRWKUP, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_GPIO_PP_OD},
{ NULL, NCT6779D_PRT80},
{ NULL, NCT6779D_DSLP},
{ NULL, NCT6779D_GPIOBASE, PNP_IO0, 0x0ff8, },
{ NULL, NCT6779D_GPIO0},
{ NULL, NCT6779D_GPIO1},
{ NULL, NCT6779D_GPIO2},
{ NULL, NCT6779D_GPIO3},
{ NULL, NCT6779D_GPIO4},
{ NULL, NCT6779D_GPIO5, PNP_MSC4 | PNP_MSC5},
{ NULL, NCT6779D_GPIO6, PNP_MSC4 | PNP_MSC5},
{ NULL, NCT6779D_GPIO7},
{ NULL, NCT6779D_GPIO8},
};
static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &_nuvoton_nct6779d_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}
struct chip_operations superio_nuvoton_nct6779d_ops = {
.name = "NUVOTON NCT6779D Super I/O",
.enable_dev = enable_dev,
};

View file

@ -3,8 +3,10 @@
#ifndef SUPERIO_NUVOTON_NCT6779D_H
#define SUPERIO_NUVOTON_NCT6779D_H
#include <device/device.h>
/* Logical Device Numbers (LDN). */
#define NCT6779D_PP 0x01 /* Parallel port */
#define NCT6779D_PP 0x01 /* Parallel port */
#define NCT6779D_SP1 0x02 /* Com1 */
#define NCT6779D_SP2 0x03 /* Com2 & IR */
#define NCT6779D_KBC 0x05 /* PS/2 keyboard and mouse */
@ -34,4 +36,6 @@
#define NCT6779D_GPIO7 ((7 << 8) | NCT6779D_GPIO12345678_V)
#define NCT6779D_GPIO8 ((0 << 8) | NCT6779D_GPIO12345678_V)
extern struct device_operations _nuvoton_nct6779d_ops;
#endif /* SUPERIO_NUVOTON_NCT6779D_H */

View file

@ -8,6 +8,8 @@
#include "nct6779d.h"
/* C code shared by NCT6779D and NCT5535D */
#define MAINBOARD_POWER_OFF 0
#define MAINBOARD_POWER_ON 1
#define MAINBOARD_POWER_KEEP 2
@ -42,7 +44,7 @@ static void nct6779d_init(struct device *dev)
}
}
static struct device_operations ops = {
struct device_operations _nuvoton_nct6779d_ops = {
.read_resources = pnp_read_resources,
.set_resources = pnp_set_resources,
.enable_resources = pnp_enable_resources,
@ -50,40 +52,3 @@ static struct device_operations ops = {
.init = nct6779d_init,
.ops_pnp_mode = &pnp_conf_mode_8787_aa,
};
static struct pnp_info pnp_dev_info[] = {
{ NULL, NCT6779D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8, },
{ NULL, NCT6779D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1,
0x0fff, 0x0fff, },
{ NULL, NCT6779D_CIR, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_ACPI, PNP_MSC2,},
{ NULL, NCT6779D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0,
0x0ffe, 0x0ffe, },
{ NULL, NCT6779D_WDT1},
{ NULL, NCT6779D_CIRWKUP, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
{ NULL, NCT6779D_GPIO_PP_OD},
{ NULL, NCT6779D_PRT80},
{ NULL, NCT6779D_DSLP},
{ NULL, NCT6779D_GPIOBASE, PNP_IO0, 0x0ff8, },
{ NULL, NCT6779D_GPIO0},
{ NULL, NCT6779D_GPIO1},
{ NULL, NCT6779D_GPIO2},
{ NULL, NCT6779D_GPIO3},
{ NULL, NCT6779D_GPIO4},
{ NULL, NCT6779D_GPIO5, PNP_MSC4 | PNP_MSC5},
{ NULL, NCT6779D_GPIO6, PNP_MSC4 | PNP_MSC5},
{ NULL, NCT6779D_GPIO7},
{ NULL, NCT6779D_GPIO8},
};
static void enable_dev(struct device *dev)
{
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
}
struct chip_operations superio_nuvoton_nct6779d_ops = {
.name = "NUVOTON NCT6779D Super I/O",
.enable_dev = enable_dev,
};