[coreboot-gerrit] Patch set updated for coreboot: acpi_device: Add support for writing ACPI SPI descriptors

Duncan Laurie (dlaurie@google.com) gerrit at coreboot.org
Sat May 28 03:45:42 CEST 2016


Duncan Laurie (dlaurie at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14936

-gerrit

commit a483b832703923fa7972cffbd2a8f7e7fcdaa21f
Author: Duncan Laurie <dlaurie at 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 at chromium.org>
---
 src/arch/x86/acpi_device.c              | 72 +++++++++++++++++++++++++++++++++
 src/arch/x86/include/arch/acpi_device.h | 44 ++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c
index 3c0230f..073b938 100644
--- a/src/arch/x86/acpi_device.c
+++ b/src/arch/x86/acpi_device.c
@@ -381,3 +381,75 @@ void acpi_device_write_i2c(const struct acpi_i2c *i2c)
 	/* Fill in I2C Descriptor Length */
 	acpi_device_fill_len(desc_length);
 }
+
+/* ACPI 6.1 section 6.4.3.8.2.2 - SpiSerialBus() */
+void acpi_device_write_spi(const struct acpi_spi *spi)
+{
+	void *desc_length, *type_length;
+	uint16_t flags = 0;
+
+	/* Byte 0: Descriptor Type */
+	acpigen_emit_byte(ACPI_DESCRIPTOR_SERIAL_BUS);
+
+	/* Byte 1+2: Length (filled in later) */
+	desc_length = acpi_device_write_zero_len();
+
+	/* Byte 3: Revision ID */
+	acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID);
+
+	/* Byte 4: Resource Source Index is Reserved */
+	acpigen_emit_byte(0);
+
+	/* Byte 5: Serial Bus Type is SPI */
+	acpigen_emit_byte(ACPI_SERIAL_BUS_TYPE_SPI);
+
+	/*
+	 * Byte 6: Flags
+	 *  [7:2]: 0 => Reserved
+	 *    [1]: 1 => ResourceConsumer
+	 *    [0]: 0 => ControllerInitiated
+	 */
+	acpigen_emit_byte(1 << 1);
+
+	/*
+	 * Byte 7-8: Type Specific Flags
+	 *   [15:2]: 0 => Reserved
+	 *      [1]: 0 => ActiveLow, 1 => ActiveHigh
+	 *      [0]: 0 => FourWire, 1 => ThreeWire
+	 */
+	if (spi->wire_mode == SPI_3_WIRE_MODE)
+		flags |= 1 << 0;
+	if (spi->device_select_polarity == SPI_POLARITY_HIGH)
+		flags |= 1 << 1;
+	acpigen_emit_word(flags);
+
+	/* Byte 9: Type Specific Revision ID */
+	acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID);
+
+	/* Byte 10-11: SPI Type Data Length */
+	type_length = acpi_device_write_zero_len();
+
+	/* Byte 12-15: Connection Speed */
+	acpigen_emit_dword(spi->speed);
+
+	/* Byte 16: Data Bit Length */
+	acpigen_emit_byte(spi->data_bit_length);
+
+	/* Byte 17: Clock Phase */
+	acpigen_emit_byte(spi->clock_phase);
+
+	/* Byte 18: Clock Polarity */
+	acpigen_emit_byte(spi->clock_polarity);
+
+	/* Byte 19-20: Device Selection */
+	acpigen_emit_word(spi->device_select);
+
+	/* Fill in Type Data Length */
+	acpi_device_fill_len(type_length);
+
+	/* Byte 21+: ResourceSource String */
+	acpigen_emit_string(spi->resource);
+
+	/* Fill in SPI Descriptor Length */
+	acpi_device_fill_len(desc_length);
+}
diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h
index 7b5001f..dc7f26c 100644
--- a/src/arch/x86/include/arch/acpi_device.h
+++ b/src/arch/x86/include/arch/acpi_device.h
@@ -164,6 +164,7 @@ void acpi_device_write_gpio(const struct acpi_gpio *gpio);
  */
 
 #define ACPI_SERIAL_BUS_TYPE_I2C	1
+#define ACPI_SERIAL_BUS_TYPE_SPI	2
 #define ACPI_SERIAL_BUS_REVISION_ID	1
 
 /*
@@ -184,4 +185,47 @@ struct acpi_i2c {
 /* Write I2cSerialBus() descriptor to SSDT AML output */
 void acpi_device_write_i2c(const struct acpi_i2c *i2c);
 
+/*
+ * ACPI SPI Bus
+ */
+
+enum spi_clock_phase {
+	SPI_CLOCK_PHASE_FIRST,
+	SPI_CLOCK_PHASE_SECOND
+};
+
+/* SPI Flags bit 0 */
+enum spi_wire_mode {
+	SPI_4_WIRE_MODE,
+	SPI_3_WIRE_MODE
+};
+
+/* SPI Flags bit 1 */
+enum spi_polarity {
+	SPI_POLARITY_LOW,
+	SPI_POLARITY_HIGH
+};
+
+struct acpi_spi {
+	/* Device selection */
+	uint16_t device_select;
+	/* Device selection line is active high or low */
+	enum spi_polarity device_select_polarity;
+	/* 3 or 4 wire SPI connection */
+	enum spi_wire_mode wire_mode;
+	/* Connection speed in HZ */
+	unsigned int speed;
+	/* Size in bits of smallest transfer unit */
+	u8 data_bit_length;
+	/* Phase of clock pulse on which to capture data */
+	enum spi_clock_phase clock_phase;
+	/* Indicate if clock is high or low during first phase */
+	enum spi_polarity clock_polarity;
+	/* Reference to SPI controller */
+	const char *resource;
+};
+
+/* Write SPI Bus descriptor to SSDT AML output */
+void acpi_device_write_spi(const struct acpi_spi *spi);
+
 #endif



More information about the coreboot-gerrit mailing list