Jérémy Compostella has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/83200?usp=email )
Change subject: drivers/wifi: Support Bluetooth Regulator Domain Settings ......................................................................
drivers/wifi: Support Bluetooth Regulator Domain Settings
The 'Bluetooth Increased Power Mode - SAR Limitation' feature provides ability to utilize increased device Transmit power capability for Bluetooth applications in coordination with Wi-Fi adhering to product SAR limit when Bluetooth and Wi-Fi run together.
This feature is required for Meteor Lake rex karis variant.
The implementation follow document 559910 Intel Connectivity Platforms BIOS Guideline revision 8.3 specification.
BUG=b:348345301 TEST=BRDS method is added to the CNVW device and return the data supplied by the SAR binary blob
Change-Id: Iebe95815c944d045f4cf686abcd1874a8a45e209 Signed-off-by: Jeremy Compostella jeremy.compostella@intel.com --- M src/drivers/wifi/generic/acpi.c M src/include/sar.h M src/vendorcode/google/chromeos/sar.c 3 files changed, 76 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/00/83200/1
diff --git a/src/drivers/wifi/generic/acpi.c b/src/drivers/wifi/generic/acpi.c index 2d08b87..5eb7a3e 100644 --- a/src/drivers/wifi/generic/acpi.c +++ b/src/drivers/wifi/generic/acpi.c @@ -15,8 +15,9 @@ #include "wifi.h" #include "wifi_private.h"
-/* WIFI Domain type */ +/* Domain type */ #define DOMAIN_TYPE_WIFI 0x7 +#define DOMAIN_TYPE_BLUETOOTH 0x12
/* Maximum number DSM UUID bifurcations in _DSM */ #define MAX_DSM_FUNCS 2 @@ -489,6 +490,55 @@ acpigen_write_package_end(); }
+static void sar_emit_brds(const struct bsar_profile *bsar) +{ + int i; + size_t package_size, table_size; + const uint8_t *set; + + if (bsar == NULL) + return; + + /* + * Name ("BRDS", Package () { + * Revision, + * Package () { + * Domain Type, // 0x12:Bluetooth + * Bluetooth SAR BIOS, // BIOS SAR Enable/disable + * Bluetooth Increase Power Mode // SAR Limitation Enable/disable + * Bluetooth SAR Power Restriction, // 00000000 - 0dBm + * // 11111111 - 31.875dBm + * // (Step 0.125dBm) + * Bluetooth SAR Table // SAR Tx power limit table + * } + * }) + */ + if (bsar->revision != BSAR_REVISION) { + printk(BIOS_ERR, "Unsupported BSAR table revision: %d\n", + bsar->revision); + return; + } + + acpigen_write_name("BRDS"); + acpigen_write_package(2); + acpigen_write_dword(bsar->revision); + + table_size = sizeof(*bsar) - + offsetof(struct bsar_profile, sar_lb_power_restriction); + package_size = 1 + 1 + table_size; + acpigen_write_package(package_size); + acpigen_write_dword(DOMAIN_TYPE_BLUETOOTH); + acpigen_write_dword(1); + acpigen_write_dword(bsar->increased_power_mode_limitation); + + set = (const uint8_t *)&bsar->sar_lb_power_restriction; + for (i = 0; i < table_size; i++) + acpigen_write_byte(set[i]); + + acpigen_write_package_end(); + acpigen_write_package_end(); +} + static void emit_sar_acpi_structures(const struct device *dev, struct dsm_profile *dsm) { union wifi_sar_limits sar_limits = {{NULL, NULL, NULL, NULL, NULL} }; @@ -511,6 +561,7 @@ sar_emit_wgds(sar_limits.wgds); sar_emit_ppag(sar_limits.ppag); sar_emit_wtas(sar_limits.wtas); + sar_emit_brds(sar_limits.bsar);
/* copy the dsm data to be later used for creating _DSM function */ if (sar_limits.dsm != NULL) diff --git a/src/include/sar.h b/src/include/sar.h index c201cea..7c1b95d 100644 --- a/src/include/sar.h +++ b/src/include/sar.h @@ -9,8 +9,9 @@ #define MAX_DENYLIST_ENTRY 16 #define MAX_DSAR_SET_COUNT 3 #define MAX_GEO_OFFSET_REVISION 3 -#define MAX_PROFILE_COUNT 5 +#define MAX_PROFILE_COUNT 6 #define MAX_SAR_REVISION 2 +#define BSAR_REVISION 1 #define REVISION_SIZE 1 #define SAR_REV0_CHAINS_COUNT 2 #define SAR_REV0_SUBBANDS_COUNT 5 @@ -60,6 +61,18 @@ uint32_t enablement_11be; };
+struct bsar_profile { + uint8_t revision; + uint8_t increased_power_mode_limitation; + uint8_t sar_lb_power_restriction; + uint8_t br_modulation; + uint8_t edr2_modulation; + uint8_t edr3_modulation; + uint8_t le_modulation; + uint8_t le2_mhz_modulation; + uint8_t le_lr_modulation; +} __packed; + struct sar_header { char marker[SAR_STR_PREFIX_SIZE]; uint8_t version; @@ -74,6 +87,7 @@ struct gain_profile *ppag; struct avg_profile *wtas; struct dsm_profile *dsm; + struct bsar_profile *bsar; }; void *profile[MAX_PROFILE_COUNT]; }; diff --git a/src/vendorcode/google/chromeos/sar.c b/src/vendorcode/google/chromeos/sar.c index c42bf65..4b5c7e8 100644 --- a/src/vendorcode/google/chromeos/sar.c +++ b/src/vendorcode/google/chromeos/sar.c @@ -94,6 +94,14 @@ return sizeof(struct dsm_profile); }
+static int bsar_table_size(const struct bsar_profile *bsar) +{ + if (bsar == NULL) + return 0; + + return sizeof(struct bsar_profile); +} + static bool valid_legacy_length(size_t bin_len) { if (bin_len == LEGACY_SAR_WGDS_BIN_SIZE) @@ -145,6 +153,7 @@ expected_sar_bin_size += gain_table_size(sar_limits->ppag); expected_sar_bin_size += sar_avg_table_size(sar_limits->wtas); expected_sar_bin_size += dsm_table_size(sar_limits->dsm); + expected_sar_bin_size += bsar_table_size(sar_limits->bsar);
if (sar_bin_size != expected_sar_bin_size) { printk(BIOS_ERR, "Invalid SAR size, expected: %zu, obtained: %zu\n",