[coreboot-gerrit] New patch to review for coreboot: intel/wifi: Add support for generating SSDT table

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Tue May 31 18:57:48 CEST 2016


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

-gerrit

commit c41106118308a948d9f3a0f7c759f835c40e53ef
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Wed May 11 14:05:07 2016 -0700

    intel/wifi: Add support for generating SSDT table
    
    Intel WiFi devices that support wake-on-wifi need to declare a Power
    Resource for this wake pin.  Typically this has been done with a
    static declaration in the DSDT for each mainboard.  By adding it to
    the existing intel/wifi driver it can be done based on a
    configuration register in the devicetree.
    
    Additionally the WiFi regulatory domain can be set in the SSDT
    directly instead of needing to use NVS to pass the value to the DSDT.
    
    Also add device IDs for Wilkins Peak 2 and Stone Peak 2 devices that
    are found on Chromebooks, and clean up a long line and some comment
    formatting.
    
    This was tested by booting on an HP Chromebook 13 device and comparing
    that the output in the SSDT matches what used to be in the DSDT.  The
    WRDD value is read from VPD, if present, not from devicetree.cb.
    
    devicetree.cb:
      device pci 1c.0 on
        chip drivers/intel/wifi
          register "wake" = "GPE0_DW0_16"
          device pci 00.0 on end
        end
      end
    
    SSDT.dsl:
      Scope (\_SB.PCI0.RP01) {
        Device (WIFI) {
          Name (_UID, Zero)
          Name (_DDN, "Intel WiFi")
          Name (_ADR, 0x00000000)
          Name (_PRW, Package () { 16, 3 })
          Name (WRDD, Package () {
            Zero,
            Package () {
              0x00000007,
              0x00004150
            }
          })
        }
      }
    
    Change-Id: I8b5c916f1a04742507dc1ecc9a20c19d3822b18c
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/drivers/intel/wifi/chip.h |  3 ++
 src/drivers/intel/wifi/wifi.c | 88 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/src/drivers/intel/wifi/chip.h b/src/drivers/intel/wifi/chip.h
new file mode 100644
index 0000000..117d39c
--- /dev/null
+++ b/src/drivers/intel/wifi/chip.h
@@ -0,0 +1,3 @@
+struct drivers_intel_wifi_config {
+	unsigned wake; /* Wake pin for ACPI _PRW */
+};
diff --git a/src/drivers/intel/wifi/wifi.c b/src/drivers/intel/wifi/wifi.c
index 5ae5498..d2def8b 100644
--- a/src/drivers/intel/wifi/wifi.c
+++ b/src/drivers/intel/wifi/wifi.c
@@ -14,12 +14,16 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
 #include <console/console.h>
 #include <device/device.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <smbios.h>
 #include <string.h>
+#include <wrdd.h>
+#include "chip.h"
 
 static int smbios_write_wifi(struct device *dev, int *handle,
 			     unsigned long *current)
@@ -32,15 +36,17 @@ static int smbios_write_wifi(struct device *dev, int *handle,
 		char eos[2];
 	} __attribute__((packed));
 
-	struct smbios_type_intel_wifi *t = (struct smbios_type_intel_wifi *)*current;
+	struct smbios_type_intel_wifi *t =
+		(struct smbios_type_intel_wifi *)*current;
 	int len = sizeof(struct smbios_type_intel_wifi);
 
 	memset(t, 0, sizeof(struct smbios_type_intel_wifi));
 	t->type = 0x85;
 	t->length = len - 2;
 	t->handle = *handle;
-	/* Intel wifi driver expects this string to be in the table 0x85
-	   with PCI IDs enumerated below.
+	/*
+	 * Intel wifi driver expects this string to be in the table 0x85
+	 * with PCI IDs enumerated below.
 	 */
 	t->str = smbios_add_string(t->eos, "KHOIHGIUCCHHII");
 
@@ -50,30 +56,86 @@ static int smbios_write_wifi(struct device *dev, int *handle,
 	return len;
 }
 
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+static void intel_wifi_fill_ssdt(struct device *dev)
+{
+	struct drivers_intel_wifi_config *config = dev->chip_info;
+	const char *path = acpi_device_path(dev->bus->dev);
+	u32 address;
+
+	if (!path)
+		return;
+
+	/* Device */
+	acpigen_write_scope(path);
+	acpigen_write_device(acpi_device_name(dev));
+	acpigen_write_name_integer("_UID", 0);
+	acpigen_write_name_string("_DDN", dev->chip_ops->name);
+
+	/* Address */
+	address = PCI_SLOT(dev->path.pci.devfn) & 0xffff;
+	address <<= 16;
+	address |= PCI_FUNC(dev->path.pci.devfn) & 0xffff;
+	acpigen_write_name_dword("_ADR", address);
+
+	/* Wake capabilities */
+	if (config->wake)
+		acpigen_write_PRW(config->wake, 3);
+
+	/* Fill regulatory domain structure */
+	wifi_regulatory_domain_write_acpi();
+
+	acpigen_pop_len(); /* Device */
+	acpigen_pop_len(); /* Scope */
+
+	printk(BIOS_INFO, "%s.%s: %s %s\n", path, acpi_device_name(dev),
+	       dev->chip_ops->name, dev_path(dev));
+}
+
+static const char *intel_wifi_acpi_name(struct device *dev)
+{
+	return "WIFI";
+}
+#endif
+
 static struct pci_operations pci_ops = {
 	.set_subsystem = pci_dev_set_subsystem,
 };
 
 struct device_operations device_ops = {
-	.read_resources   = pci_dev_read_resources,
-	.set_resources    = pci_dev_set_resources,
-	.enable_resources = pci_dev_enable_resources,
-	.init             = pci_dev_init,
-	.scan_bus         = 0,
-	.enable           = 0,
-	.get_smbios_data  = smbios_write_wifi,
-	.ops_pci          = &pci_ops,
+	.read_resources           = pci_dev_read_resources,
+	.set_resources            = pci_dev_set_resources,
+	.enable_resources         = pci_dev_enable_resources,
+	.init                     = pci_dev_init,
+	.get_smbios_data          = smbios_write_wifi,
+	.ops_pci                  = &pci_ops,
+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
+	.acpi_name                = &intel_wifi_acpi_name,
+	.acpi_fill_ssdt_generator = &intel_wifi_fill_ssdt,
+#endif
 };
 
-
 static const unsigned short pci_device_ids[] = {
 	0x0084, 0x0085, 0x0089, 0x008b, 0x008e, 0x0090,
 	0x0886, 0x0888, 0x0891, 0x0893, 0x0895, 0x088f,
 	0x4236, 0x4237, 0x4238, 0x4239, 0x423b, 0x423d,
-	0 };
+	0x08b1, 0x08b2, /* Wilkins Peak 2 */
+	0x095a, 0x095b, /* Stone Peak 2 */
+	0
+};
 
 static const struct pci_driver pch_intel_wifi __pci_driver = {
 	.ops	 = &device_ops,
 	.vendor	 = PCI_VENDOR_ID_INTEL,
 	.devices = pci_device_ids,
 };
+
+static void intel_wifi_enable(struct device *dev)
+{
+	dev->ops = &device_ops;
+}
+
+struct chip_operations drivers_intel_wifi_ops = {
+	CHIP_NAME("Intel WiFi")
+	.enable_dev = &intel_wifi_enable
+};



More information about the coreboot-gerrit mailing list