drivers/wifi/generic: Implement Bluetooth PRR DSM functions

This commit introduces Bluetooth Device-Specific Methods (DSM)
"7266172c-220b-4b29-814f-75e4dd26b5fd" functions 5, 6 and 7, enabling
access to the Power Resource for Reset (PRR) mode, status and reset
delay. It meets the DSM requirements listed in Intel Document number
559910. The Power Resource Advanced Configuration and Power
Interface (ACPI) code was adapted from Panther Lake (PTL) Firmware
Support Package (FSP) revision 3144.01 (IntelBtDsmFunc5.asl,
IntelBtDsmFunc6.asl and IntelBtDsmFunc7.asl).

TEST=The following sequence of acpidbg commands was used to verify
     functions 5, 6 and 7 behavior on a Fatcat device.
     acpidbg -b "evaluate \_SB.PCI0.CNVB._DSM \
           (2c 17 66 72 0b 22 29 4b 81 4f 75 e4 dd 26 b5 fd) \
           0 6 0" # Get PRR mode and status: [0x0 0x0]
     acpidbg -b "evaluate \_SB.PCI0.CNVB._DSM \
           (2c 17 66 72 0b 22 29 4b 81 4f 75 e4 dd 26 b5 fd) \
           0 5 (01 00 01 00)" # Set PRR mode (type) to 0x1
     acpidbg -b "evaluate \_SB.PCI0.CNVB._DSM \
           (2c 17 66 72 0b 22 29 4b 81 4f 75 e4 dd 26 b5 fd) \
           0 6 0" # Get PRR mode and status: [0x1 0x0]
     acpidbg -b 'evaluate \_SB.PCI0.CNVB.BTDL' # 0x32
     acpidbg -b "evaluate \_SB.PCI0.CNVB._DSM \
           (2c 17 66 72 0b 22 29 4b 81 4f 75 e4 dd 26 b5 fd) \
           0 7 60"
     acpidbg -b 'evaluate \_SB.PCI0.CNVB.BTDL' # 0x3C

Change-Id: I3b0a77f3c2b7bec5dcb909a1266c7d5f4d5a8d1e
Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/88115
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Bora Guvendik <bora.guvendik@intel.corp-partner.google.com>
This commit is contained in:
Jeremy Compostella 2025-06-16 15:42:50 -07:00 committed by Jérémy Compostella
commit efa24540b0

View file

@ -362,6 +362,89 @@ static void (*wifi_dsm2_callbacks[])(void *) = {
wifi_dsm_set_prr_reset_delay, /* Function 5 */
};
/*
* Function 5: Set Power Resource for Reset (PRR) mode for Bluetooth
*
* Args3 is a buffer comparable to the following C structure:
* struct pldr_mode {
* uint16_t cmd_type;
* uint16_t cmd_payload;
* };
*
* cmd_type can take one of the following values:
* 1 - Set PRR mode to cmd_payload;
*/
static void bluetooth_dsm_set_power_resource_for_reset(__always_unused void *args)
{
acpigen_write_create_word_field(ARG3_OP, 0, "BCMT");
acpigen_write_create_word_field(ARG3_OP, 2, "BCMP");
/* Set PRR mode */
acpigen_write_if_lequal_namestr_int("BCMT", 1);
{
acpigen_write_if_cond_ref_of("RSTT");
{
acpigen_write_store();
acpigen_emit_namestring("BCMP");
acpigen_emit_namestring("RSTT");
}
acpigen_pop_len();
}
acpigen_pop_len();
acpigen_write_return_integer(0);
}
/*
* Function 6: Get Power Resource for Reset (PRR) mode and status for Bluetooth
*/
static void bluetooth_dsm_get_power_resource_for_reset(__always_unused void *args)
{
/* Get PRR mode and status */
acpigen_write_if_cond_ref_of("RSTT");
{
acpigen_write_if_cond_ref_of("PRRS");
{
acpigen_emit_byte(RETURN_OP);
acpigen_write_package(2);
acpigen_emit_namestring("RSTT");
acpigen_emit_namestring("PRRS");
acpigen_pop_len();
}
acpigen_pop_len();
}
acpigen_pop_len();
acpigen_write_return_integer(0);
}
/*
* Function 7: Set Power Resource for Reset (PRR) reset delay for Bluetooth
*/
static void bluetooth_dsm_set_prr_reset_delay(__always_unused void *args)
{
acpigen_write_if_cond_ref_of("BTDL");
{
acpigen_write_store();
acpigen_emit_byte(ARG3_OP);
acpigen_emit_namestring("BTDL");
}
acpigen_pop_len();
}
static void (*bluetooth_dsm_callbacks[])(void *) = {
NULL, /* Function 0 */
NULL, /* Function 1 */
NULL, /* Function 2 */
NULL, /* Function 3 */
NULL, /* Function 4 */
bluetooth_dsm_set_power_resource_for_reset, /* Function 5 */
bluetooth_dsm_get_power_resource_for_reset, /* Function 6 */
bluetooth_dsm_set_prr_reset_delay, /* Function 7 */
};
static const uint8_t *sar_fetch_set(const struct sar_profile *sar, size_t set_num)
{
const uint8_t *sar_table = &sar->sar_table[0];
@ -1212,7 +1295,7 @@ static void wifi_ssdt_write_properties(const struct device *dev, const char *sco
acpigen_write_scope_end(); /* Scope */
/* Fill Bluetooth companion SAR related ACPI structures */
/* Fill Bluetooth companion SAR related ACPI structures and DSM functions. */
if (sar_loaded && is_dev_enabled(config->bluetooth_companion)) {
const char *path = acpi_device_path(config->bluetooth_companion);
if (path) { /* Bluetooth device under USB Hub scope or PCIe root port */
@ -1226,6 +1309,17 @@ static void wifi_ssdt_write_properties(const struct device *dev, const char *sco
sar_emit_bdmm(sar_limits.bdmm);
sar_emit_ebrd(sar_limits.ebrd);
sar_emit_dsbr(sar_limits.dsbr, DOMAIN_TYPE_BLUETOOTH);
if (config->bluetooth_companion->path.type == DEVICE_PATH_PCI &&
config->bluetooth_companion->vendor == PCI_VID_INTEL) {
struct dsm_uuid bt_dsm_ids = {
.uuid = ACPI_DSM_RFIM_WIFI_UUID,
.callbacks = bluetooth_dsm_callbacks,
.count = ARRAY_SIZE(bluetooth_dsm_callbacks)
};
acpigen_write_dsm_uuid_arr(&bt_dsm_ids, 1);
}
acpigen_write_scope_end();
} else {
printk(BIOS_ERR, "Failed to get %s Bluetooth companion ACPI path\n",