dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: "Quan, Evan" <Evan.Quan@amd.com>
To: "Limonciello, Mario" <Mario.Limonciello@amd.com>
Cc: "ryder.lee@mediatek.com" <ryder.lee@mediatek.com>,
	"angelogioacchino.delregno@collabora.com"
	<angelogioacchino.delregno@collabora.com>,
	"rafael@kernel.org" <rafael@kernel.org>,
	"lorenzo@kernel.org" <lorenzo@kernel.org>,
	"kvalo@kernel.org" <kvalo@kernel.org>,
	"Pan, Xinhui" <Xinhui.Pan@amd.com>,
	"linux-wireless@vger.kernel.org" <linux-wireless@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"Lazar, Lijo" <Lijo.Lazar@amd.com>,
	"linux-acpi@vger.kernel.org" <linux-acpi@vger.kernel.org>,
	"shayne.chen@mediatek.com" <shayne.chen@mediatek.com>,
	"matthias.bgg@gmail.com" <matthias.bgg@gmail.com>,
	"amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>,
	"Deucher, Alexander" <Alexander.Deucher@amd.com>,
	"nbd@nbd.name" <nbd@nbd.name>,
	"Koenig, Christian" <Christian.Koenig@amd.com>,
	"sean.wang@mediatek.com" <sean.wang@mediatek.com>,
	"lenb@kernel.org" <lenb@kernel.org>
Subject: RE: [PATCH V3 1/7] drivers/acpi: Add support for Wifi band RF mitigations
Date: Wed, 21 Jun 2023 01:26:05 +0000	[thread overview]
Message-ID: <DM6PR12MB2619C7417A75FCDE99227C6DE45DA@DM6PR12MB2619.namprd12.prod.outlook.com> (raw)
In-Reply-To: <fc055de3-3ff4-c0dc-f48a-9f30a60bfcbf@amd.com>

[AMD Official Use Only - General]

> -----Original Message-----
> From: Limonciello, Mario <Mario.Limonciello@amd.com>
> Sent: Monday, June 19, 2023 10:04 AM
> To: Quan, Evan <Evan.Quan@amd.com>
> Cc: linux-kernel@vger.kernel.org; linux-acpi@vger.kernel.org; amd-
> gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux-
> wireless@vger.kernel.org; rafael@kernel.org; lenb@kernel.org; Deucher,
> Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
> <Christian.Koenig@amd.com>; Pan, Xinhui <Xinhui.Pan@amd.com>;
> airlied@gmail.com; daniel@ffwll.ch; kvalo@kernel.org; nbd@nbd.name;
> lorenzo@kernel.org; ryder.lee@mediatek.com; shayne.chen@mediatek.com;
> sean.wang@mediatek.com; matthias.bgg@gmail.com;
> angelogioacchino.delregno@collabora.com; Lazar, Lijo <Lijo.Lazar@amd.com>
> Subject: Re: [PATCH V3 1/7] drivers/acpi: Add support for Wifi band RF
> mitigations
>
> On 6/16/23 01:57, Evan Quan wrote:
> > From: Mario Limonciello <mario.limonciello@amd.com>
> >
> > Due to electrical and mechanical constraints in certain platform
> > designs there may be likely interference of relatively high-powered
> > harmonics of the (G-)DDR memory clocks with local radio module
> > frequency bands used by Wifi 6/6e/7.
> >
> > To mitigate this, AMD has introduced an ACPI based mechanism that
> > devices can use to notify active use of particular frequencies so that
> > devices can make relative internal adjustments as necessary to avoid
> > this resonance.
> >
> > In order for a device to support this, the expected flow for device
> > driver or subsystems:
> >
> > Drivers/subsystems contributing frequencies:
> >
> > 1) During probe, check `wbrf_supported_producer` to see if WBRF
> supported
> >     for the device.
> > 2) If adding frequencies, then call `wbrf_add_exclusion` with the
> >     start and end ranges of the frequencies.
> > 3) If removing frequencies, then call `wbrf_remove_exclusion` with
> >     start and end ranges of the frequencies.
> >
> > Drivers/subsystems responding to frequencies:
> >
> > 1) During probe, check `wbrf_supported_consumer` to see if WBRF is
> supported
> >     for the device.
> > 2) Call the `wbrf_retrieve_exclusions` to retrieve the current
> >     exclusions on receiving an ACPI notification for a new frequency
> >     change.
> >
> > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
> > Co-developed-by: Evan Quan <evan.quan@amd.com>
> > Signed-off-by: Evan Quan <evan.quan@amd.com>
> > --
> > v1->v2:
> >    - move those wlan specific implementations to net/mac80211(Mario)
> > ---
> >   drivers/acpi/Kconfig     |   7 ++
> >   drivers/acpi/Makefile    |   2 +
> >   drivers/acpi/acpi_wbrf.c | 215
> +++++++++++++++++++++++++++++++++++++++
> >   include/linux/wbrf.h     |  55 ++++++++++
> >   4 files changed, 279 insertions(+)
> >   create mode 100644 drivers/acpi/acpi_wbrf.c
> >   create mode 100644 include/linux/wbrf.h
> >
> > diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index
> > ccbeab9500ec..9ee7c7dcc3e6 100644
> > --- a/drivers/acpi/Kconfig
> > +++ b/drivers/acpi/Kconfig
> > @@ -611,3 +611,10 @@ config X86_PM_TIMER
> >
> >       You should nearly always say Y here because many modern
> >       systems require this timer.
> > +
> > +config ACPI_WBRF
> > +   bool "ACPI Wifi band RF mitigation mechanism"
> > +   help
> > +     Wifi band RF mitigation mechanism allows multiple drivers from
> > +     different domains to notify the frequencies in use so that hardware
> > +     can be reconfigured to avoid harmonic conflicts.
> > \ No newline at end of file
>
> There should be a newline at the end of the Kconfig file.
OK, will add that.

Evan
>
> > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index
> > feb36c0b9446..be173e76aa62 100644
> > --- a/drivers/acpi/Makefile
> > +++ b/drivers/acpi/Makefile
> > @@ -131,3 +131,5 @@ obj-y                           += dptf/
> >   obj-$(CONFIG_ARM64)               += arm64/
> >
> >   obj-$(CONFIG_ACPI_VIOT)           += viot.o
> > +
> > +obj-$(CONFIG_ACPI_WBRF)            += acpi_wbrf.o
> > \ No newline at end of file
> > diff --git a/drivers/acpi/acpi_wbrf.c b/drivers/acpi/acpi_wbrf.c new
> > file mode 100644 index 000000000000..8c275998ac29
> > --- /dev/null
> > +++ b/drivers/acpi/acpi_wbrf.c
> > @@ -0,0 +1,215 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * AMD Wifi Band Exclusion Interface
> > + * Copyright (C) 2023 Advanced Micro Devices
> > + *
> > + */
> > +
> > +#include <linux/wbrf.h>
> > +
> > +/* functions */
> > +#define WBRF_RECORD                0x1
> > +#define WBRF_RETRIEVE              0x2
> > +
> > +/* record actions */
> > +#define WBRF_RECORD_ADD            0x0
> > +#define WBRF_RECORD_REMOVE 0x1
> > +
> > +#define WBRF_REVISION              0x1
> > +
> > +static const guid_t wifi_acpi_dsm_guid =
> > +   GUID_INIT(0x7b7656cf, 0xdc3d, 0x4c1c,
> > +             0x83, 0xe9, 0x66, 0xe7, 0x21, 0xde, 0x30, 0x70);
> > +
> > +static int wbrf_dsm(struct acpi_device *adev, u8 fn,
> > +               union acpi_object *argv4,
> > +               union acpi_object **out)
> > +{
> > +   union acpi_object *obj;
> > +   int rc;
> > +
> > +   obj = acpi_evaluate_dsm(adev->handle, &wifi_acpi_dsm_guid,
> > +                           WBRF_REVISION, fn, argv4);
> > +   if (!obj)
> > +           return -ENXIO;
> > +
> > +   switch (obj->type) {
> > +   case ACPI_TYPE_BUFFER:
> > +           if (!*out) {
> > +                   rc = -EINVAL;
> > +                   break;
> > +           }
> > +           *out = obj;
> > +           return 0;
> > +
> > +   case ACPI_TYPE_INTEGER:
> > +           rc =  obj->integer.value ? -EINVAL : 0;
> > +           break;
> > +   default:
> > +           rc = -EOPNOTSUPP;
> > +   }
> > +   ACPI_FREE(obj);
> > +
> > +   return rc;
> > +}
> > +
> > +static int wbrf_record(struct acpi_device *adev, uint8_t action,
> > +                  struct wbrf_ranges_in *in)
> > +{
> > +   union acpi_object *argv4;
> > +   uint32_t num_of_ranges = 0;
> > +   uint32_t arg_idx = 0;
> > +   uint32_t loop_idx;
> > +   int ret;
> > +
> > +   if (!in)
> > +           return -EINVAL;
> > +
> > +   for (loop_idx = 0; loop_idx < ARRAY_SIZE(in->band_list);
> > +        loop_idx++)
> > +           if (in->band_list[loop_idx].start &&
> > +               in->band_list[loop_idx].end)
> > +                   num_of_ranges++;
> > +
> > +   argv4 = kzalloc(sizeof(*argv4) * (2 * num_of_ranges + 2 + 1),
> GFP_KERNEL);
> > +   if (!argv4)
> > +           return -ENOMEM;
> > +
> > +   argv4[arg_idx].package.type = ACPI_TYPE_PACKAGE;
> > +   argv4[arg_idx].package.count = 2 + 2 * num_of_ranges;
> > +   argv4[arg_idx++].package.elements = &argv4[1];
> > +   argv4[arg_idx].integer.type = ACPI_TYPE_INTEGER;
> > +   argv4[arg_idx++].integer.value = num_of_ranges;
> > +   argv4[arg_idx].integer.type = ACPI_TYPE_INTEGER;
> > +   argv4[arg_idx++].integer.value = action;
> > +
> > +   for (loop_idx = 0; loop_idx < ARRAY_SIZE(in->band_list);
> > +        loop_idx++) {
> > +           if (!in->band_list[loop_idx].start ||
> > +               !in->band_list[loop_idx].end)
> > +                   continue;
> > +
> > +           argv4[arg_idx].integer.type = ACPI_TYPE_INTEGER;
> > +           argv4[arg_idx++].integer.value = in->band_list[loop_idx].start;
> > +           argv4[arg_idx].integer.type = ACPI_TYPE_INTEGER;
> > +           argv4[arg_idx++].integer.value = in->band_list[loop_idx].end;
> > +   }
> > +
> > +   ret = wbrf_dsm(adev, WBRF_RECORD, argv4, NULL);
> > +
> > +   kfree(argv4);
> > +
> > +   return ret;
> > +}
> > +
> > +int wbrf_add_exclusion(struct acpi_device *adev,
> > +                  struct wbrf_ranges_in *in)
> > +{
> > +   return wbrf_record(adev, WBRF_RECORD_ADD, in); }
> > +EXPORT_SYMBOL_GPL(wbrf_add_exclusion);
> > +
> > +int wbrf_remove_exclusion(struct acpi_device *adev,
> > +                     struct wbrf_ranges_in *in)
> > +{
> > +   return wbrf_record(adev, WBRF_RECORD_REMOVE, in); }
> > +EXPORT_SYMBOL_GPL(wbrf_remove_exclusion);
> > +
> > +bool wbrf_supported_producer(struct acpi_device *adev) {
> > +   return acpi_check_dsm(adev->handle, &wifi_acpi_dsm_guid,
> > +                         WBRF_REVISION,
> > +                         (1ULL << WBRF_RECORD) | (1ULL <<
> WBRF_RETRIEVE)); }
> > +EXPORT_SYMBOL_GPL(wbrf_supported_producer);
> > +
> > +static union acpi_object *
> > +acpi_evaluate_wbrf(acpi_handle handle, u64 rev, u64 func) {
> > +   acpi_status ret;
> > +   struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
> > +   union acpi_object params[4];
> > +   struct acpi_object_list input = {
> > +           .count = 4,
> > +           .pointer = params,
> > +   };
> > +
> > +   params[0].type = ACPI_TYPE_INTEGER;
> > +   params[0].integer.value = rev;
> > +   params[1].type = ACPI_TYPE_INTEGER;
> > +   params[1].integer.value = func;
> > +   params[2].type = ACPI_TYPE_PACKAGE;
> > +   params[2].package.count = 0;
> > +   params[2].package.elements = NULL;
> > +   params[3].type = ACPI_TYPE_STRING;
> > +   params[3].string.length = 0;
> > +   params[3].string.pointer= NULL;
> > +
> > +   ret = acpi_evaluate_object(handle, "WBRF", &input, &buf);
> > +   if (ACPI_SUCCESS(ret))
> > +           return (union acpi_object *)buf.pointer;
> > +
> > +   if (ret != AE_NOT_FOUND)
> > +           acpi_handle_warn(handle,
> > +                            "failed to evaluate WBRF(0x%x)\n", ret);
> > +
> > +   return NULL;
> > +}
> > +
> > +static bool check_acpi_wbrf(acpi_handle handle, u64 rev, u64 funcs) {
> > +   int i;
> > +   u64 mask = 0;
> > +   union acpi_object *obj;
> > +
> > +   if (funcs == 0)
> > +           return false;
> > +
> > +   obj = acpi_evaluate_wbrf(handle, rev, 0);
> > +   if (!obj)
> > +           return false;
> > +
> > +   if (obj->type != ACPI_TYPE_BUFFER)
> > +           return false;
> > +
> > +   for (i = 0; i < obj->buffer.length && i < 8; i++)
> > +           mask |= (((u64)obj->buffer.pointer[i]) << (i * 8));
> > +   ACPI_FREE(obj);
> > +
> > +   /*
> > +    * Bit 0 indicates whether there's support for any functions other than
> > +    * function 0.
> > +    */
> > +   if ((mask & 0x1) && (mask & funcs) == funcs)
> > +           return true;
> > +
> > +   return false;
> > +}
> > +
> > +bool wbrf_supported_consumer(struct acpi_device *adev) {
> > +   return check_acpi_wbrf(adev->handle,
> > +                          WBRF_REVISION,
> > +                          1ULL << WBRF_RETRIEVE);
> > +}
> > +EXPORT_SYMBOL_GPL(wbrf_supported_consumer);
> > +
> > +int wbrf_retrieve_exclusions(struct acpi_device *adev,
> > +                        struct wbrf_ranges_out *exclusions_out) {
> > +   union acpi_object *obj;
> > +
> > +   obj = acpi_evaluate_wbrf(adev->handle,
> > +                            WBRF_REVISION,
> > +                            WBRF_RETRIEVE);
> > +   if (!obj)
> > +           return -EINVAL;
> > +
> > +   memcpy(exclusions_out, obj->buffer.pointer, obj->buffer.length);
> > +
> > +   ACPI_FREE(obj);
> > +
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(wbrf_retrieve_exclusions);
> > diff --git a/include/linux/wbrf.h b/include/linux/wbrf.h new file mode
> > 100644 index 000000000000..e4c99b69f1d2
> > --- /dev/null
> > +++ b/include/linux/wbrf.h
> > @@ -0,0 +1,55 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * AMD Wifi Band Exclusion Interface
> > + * Copyright (C) 2023 Advanced Micro Devices  */
> > +
> > +#ifndef _LINUX_WBRF_H
> > +#define _LINUX_WBRF_H
> > +
> > +#include <linux/acpi.h>
> > +
> > +/* Maximum number of wbrf ranges */
> > +#define MAX_NUM_OF_WBRF_RANGES             11 > +
> > +struct exclusion_range {
> > +   /* start and end point of the frequency range in Hz */
> > +   uint64_t        start;
> > +   uint64_t        end;
> > +};
> > +
> > +struct wbrf_ranges_in {
> > +   /* valid entry: `start` and `end` filled with non-zero values */
> > +   struct exclusion_range  band_list[MAX_NUM_OF_WBRF_RANGES];
> > +};
> > +
> > +struct wbrf_ranges_out {
> > +   uint32_t                num_of_ranges;
> > +   struct exclusion_range  band_list[MAX_NUM_OF_WBRF_RANGES];
> > +} __attribute__((packed));
> > +
> > +/**
> > + * APIs needed by drivers/subsystems for contributing frequencies:
> > + * During probe, check `wbrf_supported_producer` to see if WBRF is
> supported.
> > + * If adding frequencies, then call `wbrf_add_exclusion` with the
> > + * start and end points specified for the frequency ranges added.
> > + * If removing frequencies, then call `wbrf_remove_exclusion` with
> > + * start and end points specified for the frequency ranges added.
> > + */
> > +bool wbrf_supported_producer(struct acpi_device *adev); int
> > +wbrf_add_exclusion(struct acpi_device *adev,
> > +                  struct wbrf_ranges_in *in);
> > +int wbrf_remove_exclusion(struct acpi_device *adev,
> > +                     struct wbrf_ranges_in *in);
> > +
> > +/**
> > + * APIs needed by drivers/subsystems responding to frequencies:
> > + * During probe, check `wbrf_supported_consumer` to see if WBRF is
> supported.
> > + * When receiving an ACPI notification for some frequencies change,
> > +run
> > + * `wbrf_retrieve_exclusions` to retrieve the latest frequencies ranges.
> > + */
> > +int wbrf_retrieve_exclusions(struct acpi_device *adev,
> > +                        struct wbrf_ranges_out *out); bool
> > +wbrf_supported_consumer(struct acpi_device *adev);
> > +
> > +#endif /* _LINUX_WBRF_H */


  reply	other threads:[~2023-06-21  1:26 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-16  6:57 [PATCH V3 0/7] Support Wifi RFI interference mitigation feature Evan Quan
2023-06-16  6:57 ` [PATCH V3 1/7] drivers/acpi: Add support for Wifi band RF mitigations Evan Quan
2023-06-19  2:04   ` Mario Limonciello
2023-06-21  1:26     ` Quan, Evan [this message]
2023-06-16  6:57 ` [PATCH V3 2/7] wifi: mac80211: Add support for ACPI WBRF Evan Quan
2023-06-19  2:17   ` Mario Limonciello
2023-06-19  8:24     ` Johannes Berg
2023-06-21  1:04       ` Quan, Evan
2023-06-21  1:24     ` Quan, Evan
2023-06-16  6:57 ` [PATCH V3 3/7] drm/amd/pm: update driver_if and ppsmc headers for coming wbrf feature Evan Quan
2023-06-19  2:18   ` Mario Limonciello
2023-06-16  6:57 ` [PATCH V3 4/7] drm/amd/pm: setup the framework to support Wifi RFI mitigation feature Evan Quan
2023-06-19  2:22   ` Mario Limonciello
2023-06-19 14:54   ` Lazar, Lijo
2023-06-21  0:34     ` Quan, Evan
2023-06-16  6:57 ` [PATCH V3 5/7] drm/amd/pm: add flood detection for wbrf events Evan Quan
2023-06-19  2:22   ` Mario Limonciello
2023-06-16  6:57 ` [PATCH V3 6/7] drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.0 Evan Quan
2023-06-19  2:26   ` Mario Limonciello
2023-06-16  6:57 ` [PATCH V3 7/7] drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.7 Evan Quan
2023-06-19  2:27   ` Mario Limonciello

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DM6PR12MB2619C7417A75FCDE99227C6DE45DA@DM6PR12MB2619.namprd12.prod.outlook.com \
    --to=evan.quan@amd.com \
    --cc=Alexander.Deucher@amd.com \
    --cc=Christian.Koenig@amd.com \
    --cc=Lijo.Lazar@amd.com \
    --cc=Mario.Limonciello@amd.com \
    --cc=Xinhui.Pan@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kvalo@kernel.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=lorenzo@kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=nbd@nbd.name \
    --cc=rafael@kernel.org \
    --cc=ryder.lee@mediatek.com \
    --cc=sean.wang@mediatek.com \
    --cc=shayne.chen@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).