Age | Commit message (Collapse) | Author |
|
The API called to write the name of the child table in the
dp entry (type ACPI_DP_TYPE_CHILD) was not including the
quotes, e.g., it was DAAD and not "DAAD". Thus, the kernel driver
did not get the right information from SSDT.
Change the API to acpigen_write_string() to fix the issue.
Signed-off-by: Harsha Priya <harshapriya.n@intel.com>
Change-Id: Id33ad29e637bf1fe6b02e8a4b0fd9e220e8984e7
Reviewed-on: https://review.coreboot.org/15724
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
There is a second ACPI _DSD document from the UEFI Forum that details
how _DSD style tables can be nested, creating a tree of similarly
formatted tables. This document is linked from acpi_device.h.
In order to support this the device property interface needs to be
more flexible and build up a tree of properties to write all entries
at once instead of writing each entry as it is generated.
In the end this is a more flexible solution that can support drivers
that need child tables like the DA7219 codec, while only requiring
minor changes to the existing drivers that use the device property
interface.
This was tested on reef (apollolake) and chell (skylake) boards to
ensure that there was no change in the generated SSDT AML.
Change-Id: Ia22e3a5fd3982ffa7c324bee1a8d190d49f853dd
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15537
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
Have the different acpi_device_ path functions use a different static
buffer so they can be called interchangeably.
Change-Id: I270a80f66880861d5847bd586a16a73f8f1e2511
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15521
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
|
|
Add a function for an SOC to define that will allow it to map the
SOC-specific gpio_t value into an appropriate ACPI pin. The exact
behavior depends on the GPIO implementation in the SOC, but it can
be used to provide a pin number that is relative to the community or
bank that a GPIO resides in.
Change-Id: Icb97ccf7d6a9034877614d49166bc9e4fe659bcf
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15512
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
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.pdf
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@chromium.org>
Reviewed-on: https://review.coreboot.org/14937
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
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@chromium.org>
Reviewed-on: https://review.coreboot.org/14936
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
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@chromium.org>
Reviewed-on: https://review.coreboot.org/14935
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
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@chromium.org>
Change-Id: Ibf5bab9c4bf6f21252373fb013e78f872550b167
Reviewed-on: https://review.coreboot.org/14934
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
Add definitions for ACPI device extended interrupts and a method to
write an Interrupt() descriptor to the SSDT output stream.
Interrupts are often tied together with other resources and some
configuration items are shared (though not always compatibly) with
other constructs like GPIOs and GPEs.
These will get used by device drivers to write _CRS sections for
devices into the SSDT. One usage is to include a "struct acpi_irq"
inside a config struct for a device so it can be initialized based
on settings in devicetree.
Example usage:
chip.h:
struct drivers_i2c_generic_config {
struct acpi_irq irq;
};
generic.c:
void acpi_fill_ssdt_generator(struct device *dev) {
struct drivers_i2c_generic_config *config = dev->chip_info;
...
acpi_device_write_interrupt(&config->irq);
...
}
devicetree.cb:
device pci 15.0 on
chip drivers/i2c/generic
register "irq" = "IRQ_EDGE_LOW(GPP_E7_IRQ)"
device i2c 10 on end
end
end
SSDT.dsl:
Interrupt (ResourceConsumer, Edge, ActiveLow, Exclusive,,,) { 31 }
Change-Id: I3b64170cc2ebac178e7a17df479eda7670a42703
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/14933
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|
|
Add a function to "struct device_operations" to return the ACPI name
for the device, and helper functions to find this name (either from
the device or its parent) and to build a fully qualified ACPI path
from the root device.
This addition will allow device drivers to generate their ACPI AML in
the SSDT at boot, with customization supplied by devicetree.cb,
instead of needing custom DSDT ASL for every mainboard.
The root device acpi_name is defined as "\\_SB" and is used to start
the path when building a fully qualified name.
This requires SOC support to provide handlers for returning the ACPI
name for devices that it owns, and those names must match the objects
declared in the DSDT. The handler can be done either in each device
driver or with a global handler for the entire SOC.
Simplified example of how this can be used for an i2c device declared
in devicetree.cb with:
chip soc/intel/skylake # "\_SB" (from root device)
device domain 0 on # "PCI0"
device pci 19.2 on # "I2C4"
chip drivers/i2c/test0
device i2c 1a.0 on end # "TST0"
end
end
end
end
And basic SSDT generating code in the device driver:
acpigen_write_scope(acpi_device_scope(dev));
acpigen_write_device(acpi_device_name(dev));
acpigen_write_string("_HID", "TEST0000");
acpigen_write_byte("_UID", 0);
acpigen_pop_len(); /* device */
acpigen_pop_len(); /* scope */
Will produce this ACPI code:
Scope (\_SB.PCI0.I2C4) {
Device (TST0) {
Name (_HID, "TEST0000")
Name (_UID, 0)
}
}
Change-Id: Ie149595aeab96266fa5f006e7934339f0119ac54
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/14840
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
|