mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	x86: acpi: Add a common routine to write WiFi info
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@chromium.org>
This commit is contained in:
		| @@ -1009,4 +1009,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 | ||||
|   | ||||
| @@ -24,6 +24,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 | ||||
|   | ||||
							
								
								
									
										120
									
								
								arch/x86/cpu/intel_common/generic_wifi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								arch/x86/cpu/intel_common/generic_wifi.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| // 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 <log.h> | ||||
| #include <acpi/acpigen.h> | ||||
| #include <acpi/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_get_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,ddn")); | ||||
|  | ||||
| 	/* 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, "acpi,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) | ||||
| }; | ||||
| @@ -18,6 +18,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_BOOTSTAGE=y | ||||
| CONFIG_SPL_BOOTSTAGE=y | ||||
| CONFIG_TPL_BOOTSTAGE=y | ||||
|   | ||||
		Reference in New Issue
	
	Block a user