[076/108] x86: acpi: Add a common routine to write WiFi info

Message ID 20200126220508.76.I350ce805b1134011181122f4c297fa3f2ec1dfaa@changeid
State New
Headers show
Series
  • RFC: dm: Add programatic generation of ACPI tables
Related show

Commit Message

Simon Glass Jan. 27, 2020, 5:06 a.m.
Intel WiFi chips can use a common routine to write the information needed
by linux. Add an implementation of this.

Enable it for coral.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 arch/x86/Kconfig                         |   8 ++
 arch/x86/cpu/intel_common/Makefile       |   1 +
 arch/x86/cpu/intel_common/generic_wifi.c | 119 +++++++++++++++++++++++
 configs/chromebook_coral_defconfig       |   3 +-
 4 files changed, 129 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/cpu/intel_common/generic_wifi.c

Patch

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 23d2e04140..61b6b48b81 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -976,4 +976,12 @@  config INTEL_GMA_ACPI
 	  connected to the device. Enable this option to create this
 	  table so that graphics works correctly.
 
+config INTEL_GENERIC_WIFI
+	bool "Enable generation of ACPI tables for Intel WiFi "
+	help
+	  Select this option to provide code to a build generic WiFi ACPI table
+	  for Intel WiFi devices. This is not a WiFi driver and offers no
+	  network functionality. It is only here to generate the ACPI tables
+	  required by Linux.
+
 endmenu
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
index adaf53c35e..084627f21d 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -22,6 +22,7 @@  obj-y += cpu.o
 obj-y += fast_spi.o
 obj-y += lpc.o
 obj-y += lpss.o
+obj-$(CONFIG_INTEL_GENERIC_WIFI) += generic_wifi.o
 ifndef CONFIG_TARGET_EFI_APP
 obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o
 ifndef CONFIG_$(SPL_)X86_64
diff --git a/arch/x86/cpu/intel_common/generic_wifi.c b/arch/x86/cpu/intel_common/generic_wifi.c
new file mode 100644
index 0000000000..a8430fcf3e
--- /dev/null
+++ b/arch/x86/cpu/intel_common/generic_wifi.c
@@ -0,0 +1,119 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Generic WiFi ACPI info
+ *
+ * Copyright 2019 Google LLC
+ * Modified from coreboot src/drivers/wifi/generic.c
+ */
+
+#include <common.h>
+#include <acpigen.h>
+#include <acpi_device.h>
+#include <dm.h>
+#include <dm/acpi.h>
+
+/* WRDS Spec Revision */
+#define WRDS_REVISION 0x0
+
+/* EWRD Spec Revision */
+#define EWRD_REVISION 0x0
+
+/* WRDS Domain type */
+#define WRDS_DOMAIN_TYPE_WIFI 0x7
+
+/* EWRD Domain type */
+#define EWRD_DOMAIN_TYPE_WIFI 0x7
+
+/* WGDS Domain type */
+#define WGDS_DOMAIN_TYPE_WIFI 0x7
+
+/*
+ * WIFI ACPI NAME = "WF" + hex value of last 8 bits of dev_path_encode + '\0'
+ * The above representation returns unique and consistent name every time
+ * generate_wifi_acpi_name is invoked. The last 8 bits of dev_path_encode is
+ * chosen since it contains the bus address of the device.
+ */
+#define WIFI_ACPI_NAME_MAX_LEN 5
+
+/**
+ * struct generic_wifi_config - Data structure to contain common wifi config
+ * @wake: Wake pin for ACPI _PRW
+ * @maxsleep: Maximum sleep state to wake from
+ */
+struct generic_wifi_config {
+	unsigned int wake;
+	unsigned int maxsleep;
+};
+
+static int generic_wifi_fill_ssdt(struct acpi_ctx *ctx,
+				  const struct udevice *dev,
+				  const struct generic_wifi_config *config)
+{
+	char name[ACPI_NAME_MAX];
+	char path[ACPI_PATH_MAX];
+	pci_dev_t bdf;
+	u32 address;
+	int ret;
+
+	ret = acpi_device_path(dev_get_parent(dev), path, sizeof(path));
+	if (ret)
+		return log_msg_ret("path", ret);
+	ret = acpi_device_name(dev, name);
+	if (ret)
+		return log_msg_ret("name", ret);
+
+	/* Device */
+	acpigen_write_scope(ctx, path);
+	acpigen_write_device(ctx, name);
+	acpigen_write_name_integer(ctx, "_UID", 0);
+	acpigen_write_name_string(ctx, "_DDN",
+				  dev_read_string(dev, "acpi,desc"));
+
+	/* Address */
+	bdf = dm_pci_get_bdf(dev);
+	address = (PCI_DEV(bdf) << 16) | PCI_FUNC(bdf);
+	acpigen_write_name_dword(ctx, "_ADR", address);
+
+	/* Wake capabilities */
+	if (config)
+		acpigen_write_prw(ctx, config->wake, config->maxsleep);
+
+	acpigen_pop_len(ctx); /* Device */
+	acpigen_pop_len(ctx); /* Scope */
+
+	return 0;
+}
+
+static int intel_wifi_acpi_fill_ssdt(const struct udevice *dev,
+				     struct acpi_ctx *ctx)
+{
+	struct generic_wifi_config config;
+	bool have_config;
+	int ret;
+
+	ret = dev_read_u32(dev, "gpe-wake", &config.wake);
+	have_config = !ret;
+	/* By default, all intel wifi chips wake from S3 */
+	config.maxsleep = 3;
+	ret = generic_wifi_fill_ssdt(ctx, dev, have_config ? &config : NULL);
+	if (ret)
+		return log_msg_ret("wifi", ret);
+
+	return 0;
+}
+
+struct acpi_ops wifi_acpi_ops = {
+	.fill_ssdt	= intel_wifi_acpi_fill_ssdt,
+};
+
+static const struct udevice_id intel_wifi_ids[] = {
+	{ .compatible = "intel,generic-wifi" },
+	{ }
+};
+
+U_BOOT_DRIVER(intel_wifi) = {
+	.name		= "intel_wifi",
+	.id		= UCLASS_MISC,
+	.of_match	= intel_wifi_ids,
+	acpi_ops_ptr(&wifi_acpi_ops)
+};
diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig
index fcb2952d98..0999fb57c6 100644
--- a/configs/chromebook_coral_defconfig
+++ b/configs/chromebook_coral_defconfig
@@ -15,6 +15,7 @@  CONFIG_HAVE_ACPI_RESUME=y
 CONFIG_INTEL_CAR_CQOS=y
 CONFIG_X86_OFFSET_U_BOOT=0xffe00000
 CONFIG_X86_OFFSET_SPL=0xffe80000
+CONFIG_INTEL_GENERIC_WIFI=y
 CONFIG_SPL_TEXT_BASE=0xfef10000
 CONFIG_BOOTSTAGE=y
 CONFIG_SPL_BOOTSTAGE=y
@@ -41,7 +42,6 @@  CONFIG_SPL_PCI=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_PMC=y
-# CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_I2C=y
 CONFIG_CMD_PART=y
@@ -89,7 +89,6 @@  CONFIG_SOUND_RT5677=y
 CONFIG_SPI=y
 CONFIG_ICH_SPI=y
 CONFIG_TPL_SYSRESET=y
-CONFIG_TPM_TIS_LPC=y
 # CONFIG_TPM_V1 is not set
 CONFIG_TPM2_CR50_I2C=y
 CONFIG_USB_XHCI_HCD=y