Shaunak Saha (shaunak.saha(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14967
-gerrit
commit 0e62ca610b5c684dacf491c12c775228dee14efb
Author: Shaunak Saha <shaunak.saha(a)intel.com>
Date: Wed May 25 11:34:43 2016 -0700
[intel/apollolake]: Add support to enable google ChromeEC
ChromeEC is needed for EC controlled features to work properly.
This patch adds neccessary support in soc/intel so that mainboard
asl files can include the ChromeEC e.g. PNOT method and
LPCB and also the nvs fields.
BUG = 53096
TEST = This patch is needed by the mainboard specific ASL change to include
src/ec/google/chromeec/acpi/ec.asl
Change-Id: Icecc437df05cd3efb41579317a353fd22526e0c9
Signed-off-by: Shaunak Saha <shaunak.saha(a)intel.com>
---
src/soc/intel/apollolake/acpi/cpu.asl | 118 ++++++++++++++++++++++++++
src/soc/intel/apollolake/acpi/globalnvs.asl | 7 +-
src/soc/intel/apollolake/acpi/lpc.asl | 23 +++++
src/soc/intel/apollolake/acpi/southbridge.asl | 3 +
src/soc/intel/apollolake/include/soc/nvs.h | 7 +-
5 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/src/soc/intel/apollolake/acpi/cpu.asl b/src/soc/intel/apollolake/acpi/cpu.asl
new file mode 100644
index 0000000..a202ceb
--- /dev/null
+++ b/src/soc/intel/apollolake/acpi/cpu.asl
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* These devices are created at runtime */
+External (\_PR.CP00, DeviceObj)
+External (\_PR.CP01, DeviceObj)
+External (\_PR.CP02, DeviceObj)
+External (\_PR.CP03, DeviceObj)
+External (\_PR.CP04, DeviceObj)
+External (\_PR.CP05, DeviceObj)
+External (\_PR.CP06, DeviceObj)
+External (\_PR.CP07, DeviceObj)
+
+/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
+Method (PNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x81) // _CST
+ Notify (\_PR.CP01, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x81) // _CST
+ Notify (\_PR.CP03, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x81) // _CST
+ Notify (\_PR.CP05, 0x81) // _CST
+ Notify (\_PR.CP06, 0x81) // _CST
+ Notify (\_PR.CP07, 0x81) // _CST
+ }
+}
+
+/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
+Method (PPCN)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x80) // _PPC
+ Notify (\_PR.CP01, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x80) // _PPC
+ Notify (\_PR.CP03, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x80) // _PPC
+ Notify (\_PR.CP05, 0x80) // _PPC
+ Notify (\_PR.CP06, 0x80) // _PPC
+ Notify (\_PR.CP07, 0x80) // _PPC
+ }
+}
+
+/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
+Method (TNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x82) // _TPC
+ Notify (\_PR.CP01, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x82) // _TPC
+ Notify (\_PR.CP03, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x82) // _TPC
+ Notify (\_PR.CP05, 0x82) // _TPC
+ Notify (\_PR.CP06, 0x82) // _TPC
+ Notify (\_PR.CP07, 0x82) // _TPC
+ }
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+ If (LGreaterEqual (\PCNT, 8)) {
+ Return (Package()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03,
+ \_PR.CP04,
+ \_PR.CP05,
+ \_PR.CP06,
+ \_PR.CP07
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 4)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 2)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01
+ })
+ } Else {
+ Return (Package ()
+ {
+ \_PR.CP00
+ })
+ }
+}
diff --git a/src/soc/intel/apollolake/acpi/globalnvs.asl b/src/soc/intel/apollolake/acpi/globalnvs.asl
index 2ef5031..e081dcb 100644
--- a/src/soc/intel/apollolake/acpi/globalnvs.asl
+++ b/src/soc/intel/apollolake/acpi/globalnvs.asl
@@ -26,8 +26,13 @@ External (NVSA)
OperationRegion (GNVS, SystemMemory, NVSA, 0x1000)
Field (GNVS, ByteAcc, NoLock, Preserve)
{
- /* Nothing here yet, folks */
+ /* Miscellaneous */
Offset (0x00),
+ PCNT, 8, // 0x01 - Processor Count
+ PPCM, 8, // 0x02 - Max PPC State
+ LIDS, 8, // 0x03 - LID State
+ PWRS, 8, // 0x04 - AC Power State
+ DPTE, 8, // 0x05 - Enable DPTF
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
Offset (0x100),
diff --git a/src/soc/intel/apollolake/acpi/lpc.asl b/src/soc/intel/apollolake/acpi/lpc.asl
new file mode 100644
index 0000000..749daf7
--- /dev/null
+++ b/src/soc/intel/apollolake/acpi/lpc.asl
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Intel LPC Bus Device - 0:1f.0 */
+
+Device (LPCB)
+{
+ Name (_ADR, 0x001f0000)
+}
diff --git a/src/soc/intel/apollolake/acpi/southbridge.asl b/src/soc/intel/apollolake/acpi/southbridge.asl
index 9409d5e..44c440e 100644
--- a/src/soc/intel/apollolake/acpi/southbridge.asl
+++ b/src/soc/intel/apollolake/acpi/southbridge.asl
@@ -27,3 +27,6 @@
#include "gpio.asl"
#include "xhci.asl"
+
+/* LPC */
+#include "lpc.asl"
diff --git a/src/soc/intel/apollolake/include/soc/nvs.h b/src/soc/intel/apollolake/include/soc/nvs.h
index 8b3a3af..4768aaa 100644
--- a/src/soc/intel/apollolake/include/soc/nvs.h
+++ b/src/soc/intel/apollolake/include/soc/nvs.h
@@ -28,7 +28,12 @@
struct global_nvs_t {
/* Miscellaneous */
- uint8_t unused[256];
+ uint8_t pcnt; /* 0x01 - Processor Count */
+ uint8_t ppcm; /* 0x02 - Max PPC State */
+ uint8_t lids; /* 0x03 - LID State */
+ uint8_t pwrs; /* 0x04 - AC Power State */
+ uint8_t dpte; /* 0x05 - Enable DPTF */
+ uint8_t unused[251];
/* ChromeOS specific (0x100 - 0xfff) */
chromeos_acpi_t chromeos;
Shaunak Saha (shaunak.saha(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14967
-gerrit
commit 5a8c7a397fc23b705494ecb8afe7ef570833e859
Author: Shaunak Saha <shaunak.saha(a)intel.com>
Date: Wed May 25 11:34:43 2016 -0700
[intel/apollolake]: Add support to enable google ChromeEC
ChromeEC is needed for EC controlled features to work properly.
This patch adds neccessary support in soc/intel so that mainboard
asl files can include the ChromeEC e.g. PNOT method and
LPCB and also the nvs fields.
BUG = 53096
TEST = This patch is needed by the mainboard specific ASL change to include
src/ec/google/chromeec/acpi/ec.asl
Change-Id: Icecc437df05cd3efb41579317a353fd22526e0c9
Signed-off-by: Shaunak Saha <shaunak.saha(a)intel.com>
---
src/soc/intel/apollolake/acpi/cpu.asl | 118 ++++++++++++++++++++++++++
src/soc/intel/apollolake/acpi/globalnvs.asl | 7 +-
src/soc/intel/apollolake/acpi/lpc.asl | 23 +++++
src/soc/intel/apollolake/acpi/southbridge.asl | 3 +
src/soc/intel/apollolake/include/soc/nvs.h | 7 +-
5 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/src/soc/intel/apollolake/acpi/cpu.asl b/src/soc/intel/apollolake/acpi/cpu.asl
new file mode 100644
index 0000000..a202ceb
--- /dev/null
+++ b/src/soc/intel/apollolake/acpi/cpu.asl
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* These devices are created at runtime */
+External (\_PR.CP00, DeviceObj)
+External (\_PR.CP01, DeviceObj)
+External (\_PR.CP02, DeviceObj)
+External (\_PR.CP03, DeviceObj)
+External (\_PR.CP04, DeviceObj)
+External (\_PR.CP05, DeviceObj)
+External (\_PR.CP06, DeviceObj)
+External (\_PR.CP07, DeviceObj)
+
+/* Notify OS to re-read CPU tables, assuming ^2 CPU count */
+Method (PNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x81) // _CST
+ Notify (\_PR.CP01, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x81) // _CST
+ Notify (\_PR.CP03, 0x81) // _CST
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x81) // _CST
+ Notify (\_PR.CP05, 0x81) // _CST
+ Notify (\_PR.CP06, 0x81) // _CST
+ Notify (\_PR.CP07, 0x81) // _CST
+ }
+}
+
+/* Notify OS to re-read CPU _PPC limit, assuming ^2 CPU count */
+Method (PPCN)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x80) // _PPC
+ Notify (\_PR.CP01, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x80) // _PPC
+ Notify (\_PR.CP03, 0x80) // _PPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x80) // _PPC
+ Notify (\_PR.CP05, 0x80) // _PPC
+ Notify (\_PR.CP06, 0x80) // _PPC
+ Notify (\_PR.CP07, 0x80) // _PPC
+ }
+}
+
+/* Notify OS to re-read Throttle Limit tables, assuming ^2 CPU count */
+Method (TNOT)
+{
+ If (LGreaterEqual (\PCNT, 2)) {
+ Notify (\_PR.CP00, 0x82) // _TPC
+ Notify (\_PR.CP01, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 4)) {
+ Notify (\_PR.CP02, 0x82) // _TPC
+ Notify (\_PR.CP03, 0x82) // _TPC
+ }
+ If (LGreaterEqual (\PCNT, 8)) {
+ Notify (\_PR.CP04, 0x82) // _TPC
+ Notify (\_PR.CP05, 0x82) // _TPC
+ Notify (\_PR.CP06, 0x82) // _TPC
+ Notify (\_PR.CP07, 0x82) // _TPC
+ }
+}
+
+/* Return a package containing enabled processor entries */
+Method (PPKG)
+{
+ If (LGreaterEqual (\PCNT, 8)) {
+ Return (Package()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03,
+ \_PR.CP04,
+ \_PR.CP05,
+ \_PR.CP06,
+ \_PR.CP07
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 4)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01,
+ \_PR.CP02,
+ \_PR.CP03
+ })
+ } ElseIf (LGreaterEqual (\PCNT, 2)) {
+ Return (Package ()
+ {
+ \_PR.CP00,
+ \_PR.CP01
+ })
+ } Else {
+ Return (Package ()
+ {
+ \_PR.CP00
+ })
+ }
+}
diff --git a/src/soc/intel/apollolake/acpi/globalnvs.asl b/src/soc/intel/apollolake/acpi/globalnvs.asl
index 2ef5031..6a8a7dd 100644
--- a/src/soc/intel/apollolake/acpi/globalnvs.asl
+++ b/src/soc/intel/apollolake/acpi/globalnvs.asl
@@ -26,8 +26,13 @@ External (NVSA)
OperationRegion (GNVS, SystemMemory, NVSA, 0x1000)
Field (GNVS, ByteAcc, NoLock, Preserve)
{
- /* Nothing here yet, folks */
+ /* Miscellaneous */
Offset (0x00),
+ PCNT, 8, // 0x01 - Processor Count
+ PPCM, 8, // 0x02 - Max PPC State
+ LIDS, 8, // 0x03 - LID State
+ PWRS, 8, // 0x04 - AC Power State
+ DPTE, 8, // 0x05 - Enable DPTF
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
Offset (0x100),
diff --git a/src/soc/intel/apollolake/acpi/lpc.asl b/src/soc/intel/apollolake/acpi/lpc.asl
new file mode 100644
index 0000000..749daf7
--- /dev/null
+++ b/src/soc/intel/apollolake/acpi/lpc.asl
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Intel LPC Bus Device - 0:1f.0 */
+
+Device (LPCB)
+{
+ Name (_ADR, 0x001f0000)
+}
diff --git a/src/soc/intel/apollolake/acpi/southbridge.asl b/src/soc/intel/apollolake/acpi/southbridge.asl
index 9409d5e..44c440e 100644
--- a/src/soc/intel/apollolake/acpi/southbridge.asl
+++ b/src/soc/intel/apollolake/acpi/southbridge.asl
@@ -27,3 +27,6 @@
#include "gpio.asl"
#include "xhci.asl"
+
+/* LPC */
+#include "lpc.asl"
diff --git a/src/soc/intel/apollolake/include/soc/nvs.h b/src/soc/intel/apollolake/include/soc/nvs.h
index 8b3a3af..4768aaa 100644
--- a/src/soc/intel/apollolake/include/soc/nvs.h
+++ b/src/soc/intel/apollolake/include/soc/nvs.h
@@ -28,7 +28,12 @@
struct global_nvs_t {
/* Miscellaneous */
- uint8_t unused[256];
+ uint8_t pcnt; /* 0x01 - Processor Count */
+ uint8_t ppcm; /* 0x02 - Max PPC State */
+ uint8_t lids; /* 0x03 - LID State */
+ uint8_t pwrs; /* 0x04 - AC Power State */
+ uint8_t dpte; /* 0x05 - Enable DPTF */
+ uint8_t unused[251];
/* ChromeOS specific (0x100 - 0xfff) */
chromeos_acpi_t chromeos;
the following patch was just integrated into master:
commit 559e947306d9a8684f7c0879c122a9b3b3f87c16
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue May 10 13:18:17 2016 -0700
acpi_device: Add support for writing ACPI Device Properties
The recent ACPI specification extensions have formally defined a
method for describing device information with a key=value format that
is modeled after the Devicetree/DTS format using a special crafted
object named _DSD with a specific UUID for this format.
There are three defined Device Property types: Integers, Strings, and
References. It is also possible to have arrays of these properties
under one key=value pair. Strings and References are both represented
as character arrays but result in different generated ACPI OpCodes.
Various helpers are provided for writing the Device Property header
(to fill in the object name and UUID) and footer (to fill in the
property count and device length values) as well as for writing the
different Device Property types. A specific helper is provided for
writing the defined GPIO binding Device Property that is used to allow
GPIOs to be referred to by name rather than resource index.
This is all documented in the _DSD Device Properties UUID document:
http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
This will be used by device drivers to provide device properties that
are consumed by the operating system. Devicetree bindings are often
described in the linux kernel at Documentation/devicetree/bindings/
A sample driver here has an input GPIO that it needs to describe to
the kernel driver:
chip.h:
struct drivers_generic_sample_config {
struct acpi_gpio mode_gpio;
};
sample.c:
static void acpi_fill_ssdt_generator(struct device *dev) {
struct drivers_generic_sample_config *config = dev->chip_info;
const char *path = acpi_device_path(dev);
...
acpi_device_write_gpio(&config->mode_gpio);
...
acpi_dp_write_header();
acpi_dp_write_gpio("mode-gpio", path, 0, 0, 0);
acpi_dp_write_footer();
...
}
devicetree.cb:
device pci 1f.0 on
chip drivers/generic/sample
register "mode_gpio" = "ACPI_GPIO_INPUT(GPP_B1)"
device generic 0 on end
end
end
SSDT.dsl:
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionInputOnly,
"\\_SB.PCI0.GPIO", 0, ResourceConsumer) { 25 }
})
Name (_DSD, Package () {
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"mode-gpio", Package () { \_SB.PCI0.LPCB, 0, 0, 1 }}
}
})
Change-Id: I93ffd09e59d05c09e38693e221a87085469be3ad
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://review.coreboot.org/14937
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/14937 for details.
-gerrit
the following patch was just integrated into master:
commit 70c86d9b265a7ea821fcd1b0684d60393d9908c1
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue May 10 07:26:34 2016 -0700
acpi_device: Add support for writing ACPI SPI descriptors
Add required definitions to describe an ACPI SPI bus and a method to
write the SpiSerialBus() descriptor to the SSDT.
This will be used by device drivers to describe their SPI resources to
the OS. SPI devices are not currently enumerated in the devicetree but
can be enumerated by device drivers directly.
generic.c:
void acpi_fill_ssdt_generator(struct device *dev) {
struct acpi_spi spi = {
.device_select = dev->path->generic.device.id,
.device_select_polarity = SPI_POLARITY_LOW,
.spi_wire_mode = SPI_4_WIRE_MODE,
.speed = 1000 * 1000; /* 1 mHz */
.data_bit_length = 8,
.clock_phase = SPI_CLOCK_PHASE_FIRST,
.clock_polarity = SPI_POLARITY_LOW,
.resource = acpi_device_path(dev->bus->dev)
};
...
acpi_device_write_spi(&spi);
...
}
devicetree.cb:
device pci 1e.2 on
chip drivers/spi/generic
device generic 0 on end
end
end
SSDT.dsl:
SpiSerialBus (0, PolarityLow, FourWireMode, 8, ControllerInitiated,
1000000, ClockPolarityLow, ClockPhaseFirst,
"\\_SB.PCI0.SPI0", 0, ResourceConsumer)
Change-Id: I0ef83dc111ac6c19d68872ab64e1e5e3a7756cae
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://review.coreboot.org/14936
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/14936 for details.
-gerrit
the following patch was just integrated into master:
commit 1010b4aeacd709500e31ec10d96187f8835a4f2d
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Mon May 9 20:10:47 2016 -0700
acpi_device: Add support for writing ACPI I2C descriptors
Add required definitions to describe an ACPI I2C bus and a method to
write the I2cSerialBus() descriptor to the SSDT.
This will be used by device drivers to describe their I2C resources to
the OS. The devicetree i2c device can supply the address and 7 or 10
bit mode as well as indicate the GPIO controller device, and the bus
speed can be fixed or configured by the driver.
chip.h:
struct drivers_i2c_generic_config {
enum i2c_speed bus_speed;
};
generic.c:
void acpi_fill_ssdt_generator(struct device *dev) {
struct drivers_i2c_generic_config *config = dev->chip_info;
struct acpi_i2c i2c = {
.address = dev->path->i2c.device,
.mode_10bit = dev->path.i2c.mode_10bit,
.speed = config->bus_speed ? : I2C_SPEED_FAST,
.resource = acpi_device_path(dev->bus->dev)
};
...
acpi_device_write_i2c(&i2c);
...
}
devicetree.cb:
device pci 15.0 on
chip drivers/i2c/generic
device i2c 10.0 on end
end
end
SSDT.dsl:
I2cSerialBus (0x10, ControllerInitiated, 400000, AddressingMode7Bit,
"\\_SB.PCI0.I2C0", 0, ResourceConsumer)
Change-Id: I598401ac81a92c72f19da0271af1e218580a6c49
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Reviewed-on: https://review.coreboot.org/14935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/14935 for details.
-gerrit
the following patch was just integrated into master:
commit cfb6ea7e659be66c90a94841a33e69afa8163eab
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Mon May 9 17:08:38 2016 -0700
acpi_device: Add support for writing ACPI GPIO descriptors
Add definitions to describe GPIOs in generated ACPI objects and a
method to write a GpioIo() or GpioInt() descriptor to the SSDT.
ACPI GPIOs have many possible configuration options and a structure
is created to describe it accurately in ACPI terms. There are many
shared descriptor fields between GpioIo() and GpioInt() so the same
function can write both types.
GpioInt shares many properties with ACPI Interrupts and the same types
are re-used here where possible. One addition is that GpioInt can be
configured to trigger on both low and high edge transitions.
One descriptor can describe multiple GPIO pins (limited to 8 in this
implementation) that all share configuration and controller and are
used by the same device scope.
Accurately referring to the GPIO controller that this pin is connected
to requires the SoC/board to implement a function handler for
acpi_gpio_path(), or for the caller to provide this directly as a
string in the acpi_gpio->reference variable.
This will get used by device drivers to describe their resources in
the SSDT. Here is a sample for a Maxim 98357A I2S codec which has a
GPIO for power and channel selection called "sdmode".
chip.h:
struct drivers_generic_max98357a_config {
struct acpi_gpio sdmode_gpio;
};
max98357a.c:
void acpi_fill_ssdt_generator(struct device *dev) {
struct drivers_generic_max98357a_config *config = dev->chip_info;
...
acpi_device_write_gpio(&config->sdmode_gpio);
...
}
devicetree.cb:
device pci 1f.3 on
chip drivers/generic/max98357a
register "sdmode_gpio" = "ACPI_GPIO_OUTPUT(GPP_C5)"
device generic 0 on end
end
end
SSDT.dsl:
GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly,
"\\_SB.PCI0.GPIO", 0, ResourceConsumer, ,) { 53 }
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
Change-Id: Ibf5bab9c4bf6f21252373fb013e78f872550b167
Reviewed-on: https://review.coreboot.org/14934
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/14934 for details.
-gerrit
Duncan Laurie (dlaurie(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14937
-gerrit
commit a06bd2613ab28aec7e00aa8b9e1a82354ebdc67d
Author: Duncan Laurie <dlaurie(a)chromium.org>
Date: Tue May 10 13:18:17 2016 -0700
acpi_device: Add support for writing ACPI Device Properties
The recent ACPI specification extensions have formally defined a
method for describing device information with a key=value format that
is modeled after the Devicetree/DTS format using a special crafted
object named _DSD with a specific UUID for this format.
There are three defined Device Property types: Integers, Strings, and
References. It is also possible to have arrays of these properties
under one key=value pair. Strings and References are both represented
as character arrays but result in different generated ACPI OpCodes.
Various helpers are provided for writing the Device Property header
(to fill in the object name and UUID) and footer (to fill in the
property count and device length values) as well as for writing the
different Device Property types. A specific helper is provided for
writing the defined GPIO binding Device Property that is used to allow
GPIOs to be referred to by name rather than resource index.
This is all documented in the _DSD Device Properties UUID document:
http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
This will be used by device drivers to provide device properties that
are consumed by the operating system. Devicetree bindings are often
described in the linux kernel at Documentation/devicetree/bindings/
A sample driver here has an input GPIO that it needs to describe to
the kernel driver:
chip.h:
struct drivers_generic_sample_config {
struct acpi_gpio mode_gpio;
};
sample.c:
static void acpi_fill_ssdt_generator(struct device *dev) {
struct drivers_generic_sample_config *config = dev->chip_info;
const char *path = acpi_device_path(dev);
...
acpi_device_write_gpio(&config->mode_gpio);
...
acpi_dp_write_header();
acpi_dp_write_gpio("mode-gpio", path, 0, 0, 0);
acpi_dp_write_footer();
...
}
devicetree.cb:
device pci 1f.0 on
chip drivers/generic/sample
register "mode_gpio" = "ACPI_GPIO_INPUT(GPP_B1)"
device generic 0 on end
end
end
SSDT.dsl:
Name (_CRS, ResourceTemplate () {
GpioIo (Exclusive, PullDefault, 0, 0, IoRestrictionInputOnly,
"\\_SB.PCI0.GPIO", 0, ResourceConsumer) { 25 }
})
Name (_DSD, Package () {
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"mode-gpio", Package () { \_SB.PCI0.LPCB, 0, 0, 1 }}
}
})
Change-Id: I93ffd09e59d05c09e38693e221a87085469be3ad
Signed-off-by: Duncan Laurie <dlaurie(a)chromium.org>
---
src/arch/x86/acpi_device.c | 135 ++++++++++++++++++++++++++++++++
src/arch/x86/include/arch/acpi_device.h | 60 ++++++++++++++
2 files changed, 195 insertions(+)
diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c
index 073b938..69d44f3 100644
--- a/src/arch/x86/acpi_device.c
+++ b/src/arch/x86/acpi_device.c
@@ -24,6 +24,15 @@
#include <gpio.h>
#endif
+/*
+ * Pointer to length field in device properties package
+ * Location is set in dp_header() and length filled in by dp_footer()
+ */
+static char *dp_count_ptr;
+
+/* Count of the number of device properties in the current set */
+static char dp_count;
+
/* Write empty word value and return pointer to it */
static void *acpi_device_write_zero_len(void)
{
@@ -453,3 +462,129 @@ void acpi_device_write_spi(const struct acpi_spi *spi)
/* Fill in SPI Descriptor Length */
acpi_device_fill_len(desc_length);
}
+
+/* Write a header for using _DSD to export Device Properties */
+void acpi_dp_write_header(void)
+{
+ /* Name (_DSD) */
+ acpigen_write_name("_DSD");
+
+ /* Package (2) */
+ acpigen_write_package(2);
+
+ /* ToUUID (ACPI_DP_UUID) */
+ acpigen_write_uuid(ACPI_DP_UUID);
+
+ /* Package (X) */
+ acpigen_emit_byte(0x12);
+ acpigen_write_len_f();
+ dp_count_ptr = acpigen_get_current();
+ acpigen_emit_byte(0); /* Number of elements, filled by dp_footer */
+
+ /* Reset element counter */
+ dp_count = 0;
+}
+
+/* Fill in length values from writing Device Properties */
+void acpi_dp_write_footer(void)
+{
+ /* Patch device property element count */
+ *dp_count_ptr = dp_count;
+
+ acpigen_pop_len(); /* Inner package length */
+ acpigen_pop_len(); /* Outer package length */
+}
+
+void acpi_dp_write_value(const struct acpi_dp *prop)
+{
+ switch (prop->type) {
+ case ACPI_DP_TYPE_INTEGER:
+ acpigen_write_integer(prop->integer);
+ break;
+ case ACPI_DP_TYPE_STRING:
+ acpigen_write_string(prop->string);
+ break;
+ case ACPI_DP_TYPE_REFERENCE:
+ acpigen_emit_namestring(prop->string);
+ break;
+ }
+}
+
+/* Write Device Property key with value as an integer */
+void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop)
+{
+ acpigen_write_package(2);
+ acpigen_write_string(key);
+ acpi_dp_write_value(prop);
+ acpigen_pop_len();
+ dp_count++;
+}
+
+/* Write Device Property key with value as an integer */
+void acpi_dp_write_integer(const char *key, uint64_t value)
+{
+ const struct acpi_dp prop = ACPI_DP_INTEGER(value);
+ acpi_dp_write_keyval(key, &prop);
+}
+
+/* Write Device Property key with value as a string */
+void acpi_dp_write_string(const char *key, const char *value)
+{
+ const struct acpi_dp prop = ACPI_DP_STRING(value);
+ acpi_dp_write_keyval(key, &prop);
+}
+
+/* Write Device Property key with value as a reference */
+void acpi_dp_write_reference(const char *key, const char *value)
+{
+ const struct acpi_dp prop = ACPI_DP_REFERENCE(value);
+ acpi_dp_write_keyval(key, &prop);
+}
+
+/* Write array of Device Properties */
+void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len)
+{
+ int i;
+ acpigen_write_package(2);
+ acpigen_write_string(key);
+ acpigen_write_package(len);
+ for (i = 0; i < len; i++)
+ acpi_dp_write_value(&array[i]);
+ acpigen_pop_len();
+ acpigen_pop_len();
+ dp_count++;
+}
+
+/* Write array of Device Properties with values as integers */
+void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len)
+{
+ int i;
+ acpigen_write_package(2);
+ acpigen_write_string(key);
+ acpigen_write_package(len);
+ for (i = 0; i < len; i++)
+ acpigen_write_integer(array[i]);
+ acpigen_pop_len();
+ acpigen_pop_len();
+ dp_count++;
+}
+
+/*
+ * Device Properties for GPIO binding
+ * linux/Documentation/acpi/gpio-properties.txt
+ */
+void acpi_dp_write_gpio(const char *key, const char *ref, int index,
+ int pin, int active_low)
+{
+ const struct acpi_dp gpio_prop[] = {
+ /* The device that has _CRS containing GpioIo()/GpioInt() */
+ ACPI_DP_REFERENCE(ref),
+ /* Index of the GPIO resource in _CRS starting from zero */
+ ACPI_DP_INTEGER(index),
+ /* Pin in the GPIO resource, typically zero */
+ ACPI_DP_INTEGER(pin),
+ /* Set if pin is active low */
+ ACPI_DP_INTEGER(active_low)
+ };
+ acpi_dp_write_array(key, gpio_prop, ARRAY_SIZE(gpio_prop));
+}
diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h
index dc7f26c..65f49b2 100644
--- a/src/arch/x86/include/arch/acpi_device.h
+++ b/src/arch/x86/include/arch/acpi_device.h
@@ -228,4 +228,64 @@ struct acpi_spi {
/* Write SPI Bus descriptor to SSDT AML output */
void acpi_device_write_spi(const struct acpi_spi *spi);
+/*
+ * Device Properties with _DSD
+ * http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.p…
+ */
+
+#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
+
+enum acpi_dp_type {
+ ACPI_DP_TYPE_INTEGER,
+ ACPI_DP_TYPE_STRING,
+ ACPI_DP_TYPE_REFERENCE,
+};
+
+struct acpi_dp {
+ enum acpi_dp_type type;
+ union {
+ uint64_t integer;
+ const char *string;
+ };
+};
+
+#define ACPI_DP_INTEGER(x) { .type = ACPI_DP_TYPE_INTEGER, .integer = x }
+#define ACPI_DP_STRING(x) { .type = ACPI_DP_TYPE_STRING, .string = x }
+#define ACPI_DP_REFERENCE(x) { .type = ACPI_DP_TYPE_REFERENCE, .string = x }
+
+/*
+ * Writing Device Properties objects via _DSD
+ */
+
+/* Start a set of Device Properties with _DSD and UUID */
+void acpi_dp_write_header(void);
+
+/* End the Device Properties set and fill in length values */
+void acpi_dp_write_footer(void);
+
+/* Write a Device Property value, but not the key */
+void acpi_dp_write_value(const struct acpi_dp *prop);
+
+/* Write a Device Property, both key and value */
+void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop);
+
+/* Write an integer as a Device Property */
+void acpi_dp_write_integer(const char *key, uint64_t value);
+
+/* Write a string as a Device Property */
+void acpi_dp_write_string(const char *key, const char *value);
+
+/* Write an ACPI reference as a Device Property */
+void acpi_dp_write_reference(const char *key, const char *value);
+
+/* Write an array of Device Properties */
+void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len);
+
+/* Write an array of integers as Device Properties */
+void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len);
+
+/* Write a GPIO binding Device Property */
+void acpi_dp_write_gpio(const char *key, const char *ref, int index,
+ int pin, int active_low);
+
#endif