superio/nuvoton/npcd378: Switch to superio/common
Replace DSDT ACPI code and DSDT injection with a SSDT only solution.
The current implementation shows some issues on current Linux, which
might be due to external ACPI objects, which are then injected into
DSDT or the fact that those objects only use 3 characters.
Replace all the DSDT code with an SSDT generator.
Tested on HP Z220:
Boots into Linux with no ACPI errors. The SSDT can be disassembled.
Change-Id: I41616d9bf320fd2b4d8495892b8190cd2a2d057f
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38862
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
diff --git a/src/mainboard/hp/compaq_8200_elite_sff/acpi/platform.asl b/src/mainboard/hp/compaq_8200_elite_sff/acpi/platform.asl
index 02a1b54..5a861f1 100644
--- a/src/mainboard/hp/compaq_8200_elite_sff/acpi/platform.asl
+++ b/src/mainboard/hp/compaq_8200_elite_sff/acpi/platform.asl
@@ -15,6 +15,7 @@
Method(_WAK, 1, NotSerialized)
{
+ // Generated by SSDT
\_SB.PCI0.LPCB.SIO0.SIOW (Arg0)
Return(Package(){0,0})
@@ -22,5 +23,6 @@
Method(_PTS, 1, NotSerialized)
{
+ // Generated by SSDT
\_SB.PCI0.LPCB.SIO0.SIOS (Arg0)
}
diff --git a/src/mainboard/hp/compaq_8200_elite_sff/acpi/superio.asl b/src/mainboard/hp/compaq_8200_elite_sff/acpi/superio.asl
index 630c5e8..d6acae9 100644
--- a/src/mainboard/hp/compaq_8200_elite_sff/acpi/superio.asl
+++ b/src/mainboard/hp/compaq_8200_elite_sff/acpi/superio.asl
@@ -13,24 +13,10 @@
* GNU General Public License for more details.
*/
-
-#undef SUPERIO_DEV
-#undef SUPERIO_PNP_BASE
-#define SUPERIO_DEV SIO0
-#define SUPERIO_PNP_BASE 0x2e
-
-#define SUPERIO_SHOW_SP2
-#define SUPERIO_SHOW_KBC
-
#include <superio/nuvoton/npcd378/acpi/superio.asl>
Scope (\_GPE)
{
- Method (_L08, 0, NotSerialized)
- {
- \_SB.PCI0.LPCB.SIO0.SIOH ()
- }
-
Method (_L0D, 0, NotSerialized)
{
Notify (\_SB.PCI0.EHC1, 0x02)
diff --git a/src/mainboard/hp/compaq_8200_elite_sff/devicetree.cb b/src/mainboard/hp/compaq_8200_elite_sff/devicetree.cb
index 9dc18be..915f87d 100644
--- a/src/mainboard/hp/compaq_8200_elite_sff/devicetree.cb
+++ b/src/mainboard/hp/compaq_8200_elite_sff/devicetree.cb
@@ -75,100 +75,104 @@
device pci 1d.0 on end # USB2 EHCI #1
device pci 1e.0 on end # PCI bridge
device pci 1f.0 on # LPC bridge PCI-LPC bridge
- chip superio/nuvoton/npcd378
- device pnp 2e.0 off end # Floppy
- device pnp 2e.1 on # Parallel port
- # global
+ chip superio/common
+ device pnp 2e.ff on # passes SIO base addr to SSDT gen
+ chip superio/nuvoton/npcd378
+ device pnp 2e.0 off end # Floppy
+ device pnp 2e.1 on # Parallel port
+ # global
- # serialice: Vendor writes:
- irq 0x14 = 0x9c
- irq 0x1c = 0xa8
- irq 0x1d = 0x08
- irq 0x22 = 0x3f
- irq 0x1a = 0xb0
- # dumped from superiotool:
- irq 0x1b = 0x1e
- irq 0x27 = 0x04
- irq 0x2a = 0x00
- irq 0x2d = 0x01
- # parallel port
- io 0x60 = 0x378
- irq 0x70 = 0x07
- drq 0x74 = 0x01
- end
- device pnp 2e.2 off # COM1
- io 0x60 = 0x2f8
- irq 0x70 = 3
- end
- device pnp 2e.3 on # COM2, IR
- io 0x60 = 0x3f8
- irq 0x70 = 4
- end
- device pnp 2e.4 on # LED control
- io 0x60 = 0x600
- # IOBASE[0h] = bit0 LED red / green
- # IOBASE[0h] = bit1-4 LED PWM duty cycle
- # IOBASE[1h] = bit6 SWCC
+ # serialice: Vendor writes:
+ irq 0x14 = 0x9c
+ irq 0x1c = 0xa8
+ irq 0x1d = 0x08
+ irq 0x22 = 0x3f
+ irq 0x1a = 0xb0
+ # dumped from superiotool:
+ irq 0x1b = 0x1e
+ irq 0x27 = 0x08
+ irq 0x2a = 0x20
+ irq 0x2d = 0x01
+ # parallel port
+ io 0x60 = 0x378
+ irq 0x70 = 0x07
+ drq 0x74 = 0x01
+ end
+ device pnp 2e.2 off # COM1
+ io 0x60 = 0x2f8
+ irq 0x70 = 3
+ end
+ device pnp 2e.3 on # COM2, IR
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+ device pnp 2e.4 on # LED control
+ io 0x60 = 0x600
+ # IOBASE[0h] = bit0 LED red / green
+ # IOBASE[0h] = bit1-4 LED PWM duty cycle
+ # IOBASE[1h] = bit6 SWCC
- io 0x62 = 0x610
- # IOBASE [0h] = GPES
- # IOBASE [1h] = GPEE
- # IOBASE [4h:7h] = 32bit upcounter at 1Mhz
- # IOBASE [8h:bh] = GPS
- # IOBASE [ch:fh] = GPE
- end
- device pnp 2e.5 on # Mouse
- irq 0x70 = 0xc
- end
- device pnp 2e.6 on # Keyboard
- io 0x60 = 0x0060
- io 0x62 = 0x0064
- irq 0x70 = 0x01
- # serialice: Vendor writes:
- drq 0xf0 = 0x40
- end
- device pnp 2e.7 on # WDT ?
- io 0x60 = 0x620
- end
- device pnp 2e.8 on # HWM
- io 0x60 = 0x800
- # IOBASE[0h:feh] HWM page
- # IOBASE[ffh] bit0-bit3 page selector
+ io 0x62 = 0x610
+ # IOBASE [0h] = GPES
+ # IOBASE [1h] = GPEE
+ # IOBASE [4h:7h] = 32bit upcounter at 1Mhz
+ # IOBASE [8h:bh] = GPS
+ # IOBASE [ch:fh] = GPE
+ end
+ device pnp 2e.5 on # Mouse
+ irq 0x70 = 0xc
+ end
+ device pnp 2e.6 on # Keyboard
+ io 0x60 = 0x0060
+ io 0x62 = 0x0064
+ irq 0x70 = 0x01
+ # serialice: Vendor writes:
+ drq 0xf0 = 0x40
+ end
+ device pnp 2e.7 on # WDT ?
+ io 0x60 = 0x620
+ end
+ device pnp 2e.8 on # HWM
+ io 0x60 = 0x800
+ # IOBASE[0h:feh] HWM page
+ # IOBASE[ffh] bit0-bit3 page selector
- drq 0xf0 = 0x20
- drq 0xf1 = 0x01
- drq 0xf2 = 0x40
- drq 0xf3 = 0x01
+ drq 0xf0 = 0x20
+ drq 0xf1 = 0x01
+ drq 0xf2 = 0x40
+ drq 0xf3 = 0x01
- drq 0xf4 = 0x66
- drq 0xf5 = 0x67
- drq 0xf6 = 0x66
- drq 0xf7 = 0x01
- end
- device pnp 2e.f on # GPIO OD ?
- drq 0xf1 = 0x97
- drq 0xf2 = 0x01
- drq 0xf5 = 0x08
- drq 0xfe = 0x80
- end
- device pnp 2e.15 on # BUS ?
- io 0x60 = 0x0680
- io 0x62 = 0x0690
- end
- device pnp 2e.1c on # Suspend Control ?
- io 0x60 = 0x640
- # writing to IOBASE[5h]
- # 0x0: Power off
- # 0x9: Power off and bricked until CMOS battery removed
- end
- device pnp 2e.1e on # GPIO ?
- io 0x60 = 0x660
- drq 0xf4 = 0x01
- # skip the following, as it
- # looks like remapped registers
- #drq 0xf5 = 0x06
- #drq 0xf6 = 0x60
- #drq 0xfe = 0x03
+ drq 0xf4 = 0x66
+ drq 0xf5 = 0x67
+ drq 0xf6 = 0x66
+ drq 0xf7 = 0x01
+ end
+ device pnp 2e.f on # GPIO OD ?
+ drq 0xf1 = 0x97
+ drq 0xf2 = 0x01
+ drq 0xf5 = 0x08
+ drq 0xfe = 0x80
+ end
+ device pnp 2e.15 on # BUS ?
+ io 0x60 = 0x0680
+ io 0x62 = 0x0690
+ end
+ device pnp 2e.1c on # Suspend Control ?
+ io 0x60 = 0x640
+ # writing to IOBASE[5h]
+ # 0x0: Power off
+ # 0x9: Power off and bricked until CMOS battery removed
+ end
+ device pnp 2e.1e on # GPIO ?
+ io 0x60 = 0x660
+ drq 0xf4 = 0x01
+ # skip the following, as it
+ # looks like remapped registers
+ #drq 0xf5 = 0x06
+ #drq 0xf6 = 0x60
+ #drq 0xfe = 0x03
+ end
+ end
end
end
chip drivers/pc80/tpm
diff --git a/src/mainboard/hp/z220_sff_workstation/acpi/platform.asl b/src/mainboard/hp/z220_sff_workstation/acpi/platform.asl
index 02a1b54..5a861f1 100644
--- a/src/mainboard/hp/z220_sff_workstation/acpi/platform.asl
+++ b/src/mainboard/hp/z220_sff_workstation/acpi/platform.asl
@@ -15,6 +15,7 @@
Method(_WAK, 1, NotSerialized)
{
+ // Generated by SSDT
\_SB.PCI0.LPCB.SIO0.SIOW (Arg0)
Return(Package(){0,0})
@@ -22,5 +23,6 @@
Method(_PTS, 1, NotSerialized)
{
+ // Generated by SSDT
\_SB.PCI0.LPCB.SIO0.SIOS (Arg0)
}
diff --git a/src/mainboard/hp/z220_sff_workstation/acpi/superio.asl b/src/mainboard/hp/z220_sff_workstation/acpi/superio.asl
index 630c5e8..d6acae9 100644
--- a/src/mainboard/hp/z220_sff_workstation/acpi/superio.asl
+++ b/src/mainboard/hp/z220_sff_workstation/acpi/superio.asl
@@ -13,24 +13,10 @@
* GNU General Public License for more details.
*/
-
-#undef SUPERIO_DEV
-#undef SUPERIO_PNP_BASE
-#define SUPERIO_DEV SIO0
-#define SUPERIO_PNP_BASE 0x2e
-
-#define SUPERIO_SHOW_SP2
-#define SUPERIO_SHOW_KBC
-
#include <superio/nuvoton/npcd378/acpi/superio.asl>
Scope (\_GPE)
{
- Method (_L08, 0, NotSerialized)
- {
- \_SB.PCI0.LPCB.SIO0.SIOH ()
- }
-
Method (_L0D, 0, NotSerialized)
{
Notify (\_SB.PCI0.EHC1, 0x02)
diff --git a/src/mainboard/hp/z220_sff_workstation/devicetree.cb b/src/mainboard/hp/z220_sff_workstation/devicetree.cb
index ab6ee04..6823c9f 100644
--- a/src/mainboard/hp/z220_sff_workstation/devicetree.cb
+++ b/src/mainboard/hp/z220_sff_workstation/devicetree.cb
@@ -76,100 +76,104 @@
device pci 1d.0 on end # USB2 EHCI #1
device pci 1e.0 on end # PCI bridge
device pci 1f.0 on # LPC bridge PCI-LPC bridge
- chip superio/nuvoton/npcd378
- device pnp 2e.0 off end # Floppy
- device pnp 2e.1 on # Parallel port
- # global
+ chip superio/common
+ device pnp 2e.ff on # passes SIO base addr to SSDT gen
+ chip superio/nuvoton/npcd378
+ device pnp 2e.0 off end # Floppy
+ device pnp 2e.1 on # Parallel port
+ # global
- # serialice: Vendor writes:
- irq 0x14 = 0x9c
- irq 0x1c = 0xa8
- irq 0x1d = 0x08
- irq 0x22 = 0x3f
- irq 0x1a = 0xb0
- # dumped from superiotool:
- irq 0x1b = 0x1e
- irq 0x27 = 0x08
- irq 0x2a = 0x20
- irq 0x2d = 0x01
- # parallel port
- io 0x60 = 0x378
- irq 0x70 = 0x07
- drq 0x74 = 0x01
- end
- device pnp 2e.2 off # COM1
- io 0x60 = 0x2f8
- irq 0x70 = 3
- end
- device pnp 2e.3 on # COM2, IR
- io 0x60 = 0x3f8
- irq 0x70 = 4
- end
- device pnp 2e.4 on # LED control
- io 0x60 = 0x600
- # IOBASE[0h] = bit0 LED red / green
- # IOBASE[0h] = bit1-4 LED PWM duty cycle
- # IOBASE[1h] = bit6 SWCC
+ # serialice: Vendor writes:
+ irq 0x14 = 0x9c
+ irq 0x1c = 0xa8
+ irq 0x1d = 0x08
+ irq 0x22 = 0x3f
+ irq 0x1a = 0xb0
+ # dumped from superiotool:
+ irq 0x1b = 0x1e
+ irq 0x27 = 0x08
+ irq 0x2a = 0x20
+ irq 0x2d = 0x01
+ # parallel port
+ io 0x60 = 0x378
+ irq 0x70 = 0x07
+ drq 0x74 = 0x01
+ end
+ device pnp 2e.2 off # COM1
+ io 0x60 = 0x2f8
+ irq 0x70 = 3
+ end
+ device pnp 2e.3 on # COM2, IR
+ io 0x60 = 0x3f8
+ irq 0x70 = 4
+ end
+ device pnp 2e.4 on # LED control
+ io 0x60 = 0x600
+ # IOBASE[0h] = bit0 LED red / green
+ # IOBASE[0h] = bit1-4 LED PWM duty cycle
+ # IOBASE[1h] = bit6 SWCC
- io 0x62 = 0x610
- # IOBASE [0h] = GPES
- # IOBASE [1h] = GPEE
- # IOBASE [4h:7h] = 32bit upcounter at 1Mhz
- # IOBASE [8h:bh] = GPS
- # IOBASE [ch:fh] = GPE
- end
- device pnp 2e.5 on # Mouse
- irq 0x70 = 0xc
- end
- device pnp 2e.6 on # Keyboard
- io 0x60 = 0x0060
- io 0x62 = 0x0064
- irq 0x70 = 0x01
- # serialice: Vendor writes:
- drq 0xf0 = 0x40
- end
- device pnp 2e.7 on # WDT ?
- io 0x60 = 0x620
- end
- device pnp 2e.8 on # HWM
- io 0x60 = 0x800
- # IOBASE[0h:feh] HWM page
- # IOBASE[ffh] bit0-bit3 page selector
+ io 0x62 = 0x610
+ # IOBASE [0h] = GPES
+ # IOBASE [1h] = GPEE
+ # IOBASE [4h:7h] = 32bit upcounter at 1Mhz
+ # IOBASE [8h:bh] = GPS
+ # IOBASE [ch:fh] = GPE
+ end
+ device pnp 2e.5 on # Mouse
+ irq 0x70 = 0xc
+ end
+ device pnp 2e.6 on # Keyboard
+ io 0x60 = 0x0060
+ io 0x62 = 0x0064
+ irq 0x70 = 0x01
+ # serialice: Vendor writes:
+ drq 0xf0 = 0x40
+ end
+ device pnp 2e.7 on # WDT ?
+ io 0x60 = 0x620
+ end
+ device pnp 2e.8 on # HWM
+ io 0x60 = 0x800
+ # IOBASE[0h:feh] HWM page
+ # IOBASE[ffh] bit0-bit3 page selector
- drq 0xf0 = 0x20
- drq 0xf1 = 0x01
- drq 0xf2 = 0x40
- drq 0xf3 = 0x01
+ drq 0xf0 = 0x20
+ drq 0xf1 = 0x01
+ drq 0xf2 = 0x40
+ drq 0xf3 = 0x01
- drq 0xf4 = 0x66
- drq 0xf5 = 0x67
- drq 0xf6 = 0x66
- drq 0xf7 = 0x01
- end
- device pnp 2e.f on # GPIO OD ?
- drq 0xf1 = 0x97
- drq 0xf2 = 0x01
- drq 0xf5 = 0x08
- drq 0xfe = 0x80
- end
- device pnp 2e.15 on # BUS ?
- io 0x60 = 0x0680
- io 0x62 = 0x0690
- end
- device pnp 2e.1c on # Suspend Control ?
- io 0x60 = 0x640
- # writing to IOBASE[5h]
- # 0x0: Power off
- # 0x9: Power off and bricked until CMOS battery removed
- end
- device pnp 2e.1e on # GPIO ?
- io 0x60 = 0x660
- drq 0xf4 = 0x01
- # skip the following, as it
- # looks like remapped registers
- #drq 0xf5 = 0x06
- #drq 0xf6 = 0x60
- #drq 0xfe = 0x03
+ drq 0xf4 = 0x66
+ drq 0xf5 = 0x67
+ drq 0xf6 = 0x66
+ drq 0xf7 = 0x01
+ end
+ device pnp 2e.f on # GPIO OD ?
+ drq 0xf1 = 0x97
+ drq 0xf2 = 0x01
+ drq 0xf5 = 0x08
+ drq 0xfe = 0x80
+ end
+ device pnp 2e.15 on # BUS ?
+ io 0x60 = 0x0680
+ io 0x62 = 0x0690
+ end
+ device pnp 2e.1c on # Suspend Control ?
+ io 0x60 = 0x640
+ # writing to IOBASE[5h]
+ # 0x0: Power off
+ # 0x9: Power off and bricked until CMOS battery removed
+ end
+ device pnp 2e.1e on # GPIO ?
+ io 0x60 = 0x660
+ drq 0xf4 = 0x01
+ # skip the following, as it
+ # looks like remapped registers
+ #drq 0xf5 = 0x06
+ #drq 0xf6 = 0x60
+ #drq 0xfe = 0x03
+ end
+ end
end
end
chip drivers/pc80/tpm
diff --git a/src/superio/nuvoton/npcd378/Makefile.inc b/src/superio/nuvoton/npcd378/Makefile.inc
index 6dc7626..e70d69b 100644
--- a/src/superio/nuvoton/npcd378/Makefile.inc
+++ b/src/superio/nuvoton/npcd378/Makefile.inc
@@ -2,3 +2,5 @@
# This file is part of the coreboot project.
ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += superio.c
+ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/ssdt.c
+ramstage-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += ../../common/generic.c
diff --git a/src/superio/nuvoton/npcd378/acpi/superio.asl b/src/superio/nuvoton/npcd378/acpi/superio.asl
index 41efb50..cffe33f 100644
--- a/src/superio/nuvoton/npcd378/acpi/superio.asl
+++ b/src/superio/nuvoton/npcd378/acpi/superio.asl
@@ -1,321 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* This file is part of the coreboot project. */
-/*
- * Include this file into a mainboard's DSDT _SB device tree and it will
- * expose the NPCD378 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 KBCK Implemented, untested
- */
-
-#undef SUPERIO_CHIP_NAME
-#define SUPERIO_CHIP_NAME NPCD378
-#include <superio/acpi/pnp.asl>
-
-#undef PNP_DEFAULT_PSC
-#define PNP_DEFAULT_PSC Return (0) /* no power management */
-
-Device(SUPERIO_DEV) {
- Name (_HID, EisaId("PNP0A05"))
- Name (_STR, Unicode("Nuvoton NPCD378 Super I/O"))
- Name (_UID, SUPERIO_UID(SUPERIO_DEV,))
-
- /* SuperIO configuration ports */
- OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02)
- 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 (0x64),
- PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */
- PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */
-
- Offset (0x70),
- PNP_IRQ0, 8, /* First IRQ */
- Offset (0x72),
- PNP_IRQ1, 8, /* Second IRQ */
- }
-
- #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 SUPERIO_SHOW_LPT
- #undef SUPERIO_PNP_HID
- #undef SUPERIO_PNP_LDN
- #undef SUPERIO_PNP_DDN
- #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 SUPERIO_PNP_IRQ1
- #undef SUPERIO_PNP_DMA
- #undef PNP_DEVICE_ACTIVE
- #define PNP_DEVICE_ACTIVE ACT3
- #define SUPERIO_PNP_LDN 1
- #define SUPERIO_PNP_IO0 0x08, 0x08
- #include <superio/acpi/pnp_generic.asl>
-#endif
-
-#ifdef SUPERIO_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 2
- #include <superio/acpi/pnp_uart.asl>
-#endif
-
-#ifdef SUPERIO_SHOW_SP2
- #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 3
- #include <superio/acpi/pnp_uart.asl>
-#endif
-
-#ifdef SUPERIO_SHOW_KBC
- #undef SUPERIO_KBC_LDN
- #undef SUPERIO_KBC_PS2M
- #undef SUPERIO_KBC_PS2LDN
- #define SUPERIO_KBC_PS2LDN 5
- #define SUPERIO_KBC_LDN 6
- #include <superio/acpi/pnp_kbc.asl>
-#endif
-
-#ifdef SUPERIO_SHOW_GPIO
- #undef SUPERIO_PNP_HID
- #undef SUPERIO_PNP_LDN
- #undef SUPERIO_PNP_DDN
- #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
- #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
-
- // generated by SSDT
- External(SWB, IntObj)
- External(SWL, IntObj)
- OperationRegion (SWCR, SystemIO, SWB, SWL)
- Field (SWCR, ByteAcc, NoLock, Preserve)
- {
- LEDC, 8,
- SWCC, 8
- }
-
- // generated by SSDT
- External(RNB, IntObj)
- External(RNL, IntObj)
- OperationRegion (RNTR, SystemIO, RNB, RNL)
- Field (RNTR, ByteAcc, NoLock, Preserve)
- {
- GPES, 8,
- GPEE, 8,
- Offset (0x08),
- GPS0, 8,
- GPS1, 8,
- GPS2, 8,
- GPS3, 8,
- GPE0, 8,
- GPE1, 8,
- GPE2, 8,
- GPE3, 8
- }
-
- Name (MSFG, One)
- Name (KBFG, One)
- Name (PMFG, Zero) // Wake event backup
-
- Method (_CRS, 0, Serialized)
- {
- Name (CRS, ResourceTemplate ()
- {
- FixedIO (SUPERIO_PNP_BASE, 0x02)
- // filled below
- FixedIO (0, 0, CRS1)
- FixedIO (0, 0, CRS2)
- })
-
- CreateWordField (CRS, CRS1._BAS, TMP1)
- Store(SWB, TMP1)
- CreateByteField (CRS, CRS1._LEN, TMP2)
- Store(SWL, TMP2)
-
- CreateWordField (CRS, CRS2._BAS, TMP3)
- Store(RNB, TMP3)
- CreateByteField (CRS, CRS2._LEN, TMP4)
- Store(RNL, TMP4)
-
- /* Announce the used I/O ports to the OS */
- Return (CRS)
- }
-
-#ifdef SUPERIO_SHOW_KBC
-
-#if defined(SUPERIO_KBC_LDN)
-#define _PS2_KB SUPERIO_ID(KBD, SUPERIO_KBC_LDN)
-#else
-#define _PS2_KB PS2K
-#endif
- Scope (_PS2_KB)
- {
- Method (_PSW, 1, NotSerialized)
- {
- KBFG = Arg0
- }
-
- Method (_PRW, 0, NotSerialized)
- {
- Return (Package (0x02) {0x08, 0x03})
- }
- }
-
-#if defined(SUPERIO_KBC_PS2M)
-#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2M)
-#elif defined(SUPERIO_KBC_PS2LDN)
-#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN)
-#else
-#define _PS2_M PS2M
-#endif
- Scope (_PS2_M)
- {
- Method (_PSW, 1, NotSerialized)
- {
- MSFG = Arg0
- }
-
- Method (_PRW, 0, NotSerialized)
- {
- Return (Package (0x02) {0x08, 0x03})
- }
- }
-
- Method (SIOH, 0, NotSerialized)
- {
- If ((PMFG & 0xE8))
- {
- Notify (_PS2_KB, 0x02)
- }
-
- If ((PMFG & 0x10))
- {
- Notify (_PS2_M, 0x02)
- }
- }
-#else
- Method (SIOH, 0, NotSerialized)
- {
- }
-#endif
-
- /* SuperIO sleep method */
- Method (SIOS, 1, NotSerialized)
- {
- If ((0x05 != Arg0))
- {
- /* Set PS/2 powerstate in S3 */
- If (KBFG)
- {
- GPE2 |= 0xE8
- }
- Else
- {
- GPE2 &= 0x17
- }
-
- If (MSFG)
- {
- GPE2 |= 0x10
- }
- Else
- {
- GPE2 &= 0xEF
- }
-
- /* Enable wake on GPE */
- GPEE = One
- If ((0x03 == Arg0))
- {
- /* green LED fading */
- Local1 = LEDC
- Local1 &= 0xE0
- LEDC = (Local1 | 0x1C)
- Local1 = SWCC
- Local1 &= 0xBF
- SWCC = (Local1 | 0x40)
- }
- }
-
- GPE0 = 0x10
- GPE1 = 0x20
- }
-
- /* SuperIO wake method */
- Method (SIOW, 1, NotSerialized)
- {
- /* Store wake status */
- PMFG = GPS2
-
- /* Disable wake on GPE */
- GPEE = Zero
- GPE0 = Zero
- GPE1 = Zero
-
- /* green LED normal */
- Local1 = LEDC
- Local1 &= 0xE0
- LEDC = (Local1 | 0x1E)
- Local1 = SWCC
- SWCC = (Local1 & 0xBF)
- }
-}
+External (\_SB.PCI0.LPCB.SIO0, DeviceObj)
+External (\_SB.PCI0.LPCB.SIO0.SIOS, MethodObj)
+External (\_SB.PCI0.LPCB.SIO0.SIOW, MethodObj)
diff --git a/src/superio/nuvoton/npcd378/superio.c b/src/superio/nuvoton/npcd378/superio.c
index 624c1f08..a07afdc 100644
--- a/src/superio/nuvoton/npcd378/superio.c
+++ b/src/superio/nuvoton/npcd378/superio.c
@@ -10,6 +10,8 @@
#include <superio/conf_mode.h>
#include <arch/acpi.h>
#include <arch/acpigen.h>
+#include <superio/common/ssdt.h>
+#include <stdlib.h>
#include "npcd378.h"
@@ -87,62 +89,351 @@
}
#if CONFIG(HAVE_ACPI_TABLES)
-static void npcd378_ssdt(struct device *dev)
+/* Provide ACPI HIDs for generic Super I/O SSDT */
+static const char *npcd378_acpi_hid(const struct device *dev)
{
- struct resource *res;
+ /* Sanity checks */
+ if (dev->path.type != DEVICE_PATH_PNP)
+ return NULL;
+ if (dev->path.pnp.port == 0)
+ return NULL;
+ if ((dev->path.pnp.device & 0xff) > NPCD378_GPIOA)
+ return NULL;
- const char *scope = acpi_device_path(dev);
- if (!scope) {
- printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(dev));
- return;
- }
-
- switch (dev->path.pnp.device) {
- case NPCD378_PWR: {
- res = find_resource(dev, PNP_IDX_IO0);
- if (!res || !res->base) {
- printk(BIOS_ERR, "NPCD378: LDN%u IOBASE not set.\n",
- NPCD378_PWR);
- break;
- }
-
- acpigen_write_scope(scope);
- acpigen_write_name_integer("SWB", res->base);
- acpigen_write_name_integer("SWL", res->size);
- acpigen_pop_len(); /* pop scope */
-
- res = find_resource(dev, PNP_IDX_IO1);
- if (!res || !res->base) {
- printk(BIOS_ERR, "NPCD378: LDN%u IOBASE2 not set.\n",
- NPCD378_PWR);
- break;
- }
-
- acpigen_write_scope(scope);
- acpigen_write_name_integer("RNB", res->base);
- acpigen_write_name_integer("RNL", res->size);
- acpigen_pop_len(); /* pop scope */
- break;
- }
+ switch (dev->path.pnp.device & 0xff) {
+ case NPCD378_FDC:
+ return ACPI_HID_FDC;
+ case NPCD378_PP:
+ return ACPI_HID_LPT;
+ case NPCD378_SP1: /* fallthrough */
+ case NPCD378_SP2:
+ return ACPI_HID_COM;
+ case NPCD378_AUX:
+ return ACPI_HID_MOUSE;
+ case NPCD378_KBC:
+ return ACPI_HID_KEYBOARD;
+ default:
+ return ACPI_HID_PNP;
}
}
-static const char *npcd378_acpi_name(const struct device *dev)
+static void npcd378_ssdt_aux(struct device *dev)
{
- return "SIO0";
+ /* Scope */
+ acpigen_write_scope(acpi_device_path(dev));
+
+ acpigen_write_method("_PSW", 1);
+ acpigen_write_store();
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_emit_namestring("^^MSFG");
+ acpigen_pop_len(); /* Pop Method */
+
+ acpigen_write_PRW(8, 3);
+
+ acpigen_pop_len(); /* Pop Scope */
+}
+
+static void npcd378_ssdt_kbc(struct device *dev)
+{
+ /* Scope */
+ acpigen_write_scope(acpi_device_path(dev));
+
+ acpigen_write_method("_PSW", 1);
+ acpigen_write_store();
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_emit_namestring("^^KBFG");
+ acpigen_pop_len(); /* Pop Method */
+
+ acpigen_write_PRW(8, 3);
+
+ acpigen_pop_len(); /* Pop Scope */
+}
+
+static void npcd378_ssdt_pwr(struct device *dev)
+{
+ const char *name = acpi_device_path(dev);
+ const char *scope = acpi_device_scope(dev);
+ char *tmp_name;
+
+ /* Scope */
+ acpigen_write_scope(name);
+
+ acpigen_emit_ext_op(OPREGION_OP);
+ acpigen_emit_namestring("SWCR");
+ acpigen_emit_byte(SYSTEMIO);
+ acpigen_emit_namestring("IO0B");
+ acpigen_emit_namestring("IO0S");
+
+ struct fieldlist l1[] = {
+ FIELDLIST_OFFSET(0),
+ FIELDLIST_NAMESTR("LEDC", 8),
+ FIELDLIST_NAMESTR("SWCC", 8),
+ };
+
+ acpigen_write_field("SWCR", l1, ARRAY_SIZE(l1), FIELD_BYTEACC |
+ FIELD_NOLOCK | FIELD_PRESERVE);
+
+ acpigen_emit_ext_op(OPREGION_OP);
+ acpigen_emit_namestring("RNTR");
+ acpigen_emit_byte(SYSTEMIO);
+ acpigen_emit_namestring("IO1B");
+ acpigen_emit_namestring("IO1S");
+
+ struct fieldlist l2[] = {
+ FIELDLIST_OFFSET(0),
+ FIELDLIST_NAMESTR("GPES", 8),
+ FIELDLIST_NAMESTR("GPEE", 8),
+ FIELDLIST_OFFSET(8),
+ FIELDLIST_NAMESTR("GPS0", 8),
+ FIELDLIST_NAMESTR("GPS1", 8),
+ FIELDLIST_NAMESTR("GPS2", 8),
+ FIELDLIST_NAMESTR("GPS3", 8),
+ FIELDLIST_NAMESTR("GPE0", 8),
+ FIELDLIST_NAMESTR("GPE1", 8),
+ FIELDLIST_NAMESTR("GPE2", 8),
+ FIELDLIST_NAMESTR("GPE3", 8),
+ };
+
+ acpigen_write_field("RNTR", l2, ARRAY_SIZE(l2), FIELD_BYTEACC |
+ FIELD_NOLOCK | FIELD_PRESERVE);
+
+ /* Method (SIOW, 1, NotSerialized) */
+ acpigen_write_method("SIOW", 1);
+ acpigen_write_store();
+ acpigen_emit_namestring("^GPS2");
+ acpigen_emit_namestring("^^PMFG");
+
+ acpigen_write_store();
+ acpigen_emit_byte(ZERO_OP);
+ acpigen_emit_namestring("^GPEE");
+
+ acpigen_write_store();
+ acpigen_emit_byte(ZERO_OP);
+ acpigen_emit_namestring("^GPE0");
+
+ acpigen_write_store();
+ acpigen_emit_byte(ZERO_OP);
+ acpigen_emit_namestring("^GPE1");
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^LEDC");
+ acpigen_write_integer(0xE0);
+ acpigen_emit_byte(LOCAL0_OP);
+
+ acpigen_emit_byte(OR_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_write_integer(0x1E);
+ acpigen_emit_namestring("^LEDC");
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^SWCC");
+ acpigen_write_integer(0xBF);
+ acpigen_emit_namestring("^SWCC");
+
+ acpigen_pop_len(); /* SIOW method */
+
+ /* Method (SIOS, 1, NotSerialized) */
+ acpigen_write_method("SIOS", 1);
+
+ acpigen_write_if();
+ acpigen_emit_byte(LNOT_OP);
+ acpigen_emit_byte(LEQUAL_OP);
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_write_integer(5);
+
+ acpigen_write_if();
+ acpigen_emit_byte(LEQUAL_OP);
+ acpigen_emit_namestring("^^KBFG");
+ acpigen_emit_byte(ONE_OP);
+
+ acpigen_emit_byte(OR_OP);
+ acpigen_emit_namestring("^GPE2");
+ acpigen_write_integer(0xE8);
+ acpigen_emit_namestring("^GPE2");
+
+ acpigen_pop_len(); /* Pop If */
+ acpigen_write_else();
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^GPE2");
+ acpigen_write_integer(0x17);
+ acpigen_emit_namestring("^GPE2");
+
+ acpigen_pop_len(); /* Pop Else */
+
+ acpigen_write_if();
+ acpigen_emit_byte(LEQUAL_OP);
+ acpigen_emit_namestring("^^MSFG");
+ acpigen_emit_byte(ONE_OP);
+
+ acpigen_emit_byte(OR_OP);
+ acpigen_emit_namestring("^GPE2");
+ acpigen_write_integer(0x10);
+ acpigen_emit_namestring("^GPE2");
+
+ acpigen_pop_len(); /* Pop If */
+ acpigen_write_else();
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^GPE2");
+ acpigen_write_integer(0xEF);
+ acpigen_emit_namestring("^GPE2");
+
+ acpigen_pop_len(); /* Pop Else */
+
+ /* Enable wake on GPE */
+ acpigen_write_store();
+ acpigen_emit_byte(ONE_OP);
+ acpigen_emit_namestring("^GPEE");
+
+ acpigen_write_if();
+ acpigen_emit_byte(LEQUAL_OP);
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_write_integer(3);
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^LEDC");
+ acpigen_write_integer(0xE0);
+ acpigen_emit_byte(LOCAL0_OP);
+
+ acpigen_emit_byte(OR_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_write_integer(0x1C);
+ acpigen_emit_namestring("^LEDC");
+
+ acpigen_emit_byte(AND_OP);
+ acpigen_emit_namestring("^SWCC");
+ acpigen_write_integer(0xBF);
+ acpigen_emit_byte(LOCAL0_OP);
+
+ acpigen_emit_byte(OR_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_write_integer(0x40);
+ acpigen_emit_namestring("^SWCC");
+
+ acpigen_pop_len(); /* Pop If */
+
+ acpigen_pop_len(); /* Pop If */
+
+ acpigen_write_store();
+ acpigen_write_integer(0x10);
+ acpigen_emit_namestring("^GPE0");
+
+ acpigen_write_store();
+ acpigen_write_integer(0x20);
+ acpigen_emit_namestring("^GPE1");
+
+ acpigen_pop_len(); /* Pop SIOS method */
+
+ acpigen_pop_len(); /* Pop Scope */
+
+ /* Inject into parent: */
+ acpigen_write_scope(acpi_device_scope(dev));
+
+ acpigen_write_name_integer("MSFG", 1);
+ acpigen_write_name_integer("KBFG", 1);
+ acpigen_write_name_integer("PMFG", 0);
+
+ /* DSDT must call SIOW on _WAK */
+ /* Method (SIOW, 1, NotSerialized) */
+ acpigen_write_method("SIOW", 1);
+ acpigen_emit_byte(RETURN_OP);
+ tmp_name = strconcat(name, ".SIOW");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_pop_len();
+
+ /* DSDT must call SIOS on _PTS */
+ /* Method (SIOS, 1, NotSerialized) */
+ acpigen_write_method("SIOS", 1);
+ acpigen_emit_byte(RETURN_OP);
+ tmp_name = strconcat(name, ".SIOS");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_pop_len(); /* Pop Method */
+
+ acpigen_pop_len(); /* Scope */
+
+ acpigen_write_scope("\\_GPE");
+
+ /* Method (SIOH, 0, NotSerialized) */
+ acpigen_write_method("_L08", 0);
+ acpigen_emit_byte(AND_OP);
+ tmp_name = strconcat(scope, ".PMFG");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+ acpigen_write_integer(0xE8);
+ acpigen_emit_byte(LOCAL0_OP);
+
+ acpigen_write_if();
+ acpigen_emit_byte(LGREATER_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_emit_byte(ZERO_OP);
+
+ acpigen_emit_byte(NOTIFY_OP);
+ tmp_name = strconcat(scope, ".L060");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+ acpigen_write_integer(2);
+
+ acpigen_pop_len(); /* Pop If */
+
+ acpigen_emit_byte(AND_OP);
+ tmp_name = strconcat(scope, ".PMFG");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+ acpigen_write_integer(0x10);
+ acpigen_emit_byte(LOCAL0_OP);
+
+ acpigen_write_if();
+ acpigen_emit_byte(LGREATER_OP);
+ acpigen_emit_byte(LOCAL0_OP);
+ acpigen_emit_byte(ZERO_OP);
+
+ acpigen_emit_byte(NOTIFY_OP);
+ tmp_name = strconcat(scope, ".L050");
+ acpigen_emit_namestring(tmp_name);
+ free(tmp_name);
+ acpigen_write_integer(2);
+ acpigen_pop_len(); /* Pop If */
+
+ acpigen_pop_len(); /* Pop Method */
+
+ acpigen_pop_len(); /* Scope */
+}
+
+static void npcd378_fill_ssdt_generator(struct device *dev)
+{
+ superio_common_fill_ssdt_generator(dev);
+
+ switch (dev->path.pnp.device) {
+ case NPCD378_PWR:
+ npcd378_ssdt_pwr(dev);
+ break;
+ case NPCD378_AUX:
+ npcd378_ssdt_aux(dev);
+ break;
+ case NPCD378_KBC:
+ npcd378_ssdt_kbc(dev);
+ break;
+ }
}
#endif
static struct device_operations ops = {
- .read_resources = pnp_read_resources,
- .set_resources = pnp_set_resources,
- .enable_resources = pnp_enable_resources,
- .enable = pnp_alt_enable,
- .init = npcd378_init,
- .ops_pnp_mode = &pnp_conf_mode_8787_aa,
+ .read_resources = pnp_read_resources,
+ .set_resources = pnp_set_resources,
+ .enable_resources = pnp_enable_resources,
+ .enable = pnp_alt_enable,
+ .init = npcd378_init,
+ .ops_pnp_mode = &pnp_conf_mode_8787_aa,
#if CONFIG(HAVE_ACPI_TABLES)
- .acpi_fill_ssdt_generator = npcd378_ssdt,
- .acpi_name = npcd378_acpi_name,
+ .acpi_fill_ssdt_generator = npcd378_fill_ssdt_generator,
+ .acpi_name = superio_common_ldn_acpi_name,
+ .acpi_hid = npcd378_acpi_hid,
#endif
};