From: Hans de Goede <hdegoede@redhat.com>
To: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>,
markgross@kernel.org, ilpo.jarvinen@linux.intel.com,
basavaraj.natikar@amd.com, jikos@kernel.org,
benjamin.tissoires@redhat.com
Cc: Patil.Reddy@amd.com, mario.limonciello@amd.com,
platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org
Subject: Re: [PATCH v5 13/17] platform/x86/amd/pmf: Add PMF-AMDGPU get interface
Date: Fri, 17 Nov 2023 11:48:26 +0100 [thread overview]
Message-ID: <80b8c5fe-e81b-4e05-bf21-19351c51d767@redhat.com> (raw)
In-Reply-To: <20231117080747.3643990-14-Shyam-sundar.S-k@amd.com>
Hi Shyam,
On 11/17/23 09:07, Shyam Sundar S K wrote:
> In order to provide GPU inputs to TA for the Smart PC solution to work, we
> need to have interface between the PMF driver and the AMDGPU driver.
>
> Add the initial code path for get interface from AMDGPU.
>
> Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
> ---
> drivers/platform/x86/amd/pmf/core.c | 3 +-
> drivers/platform/x86/amd/pmf/pmf.h | 18 +++++++
> drivers/platform/x86/amd/pmf/spc.c | 41 ++++++++++++++
> drivers/platform/x86/amd/pmf/tee-if.c | 77 +++++++++++++++++++++++++++
> 4 files changed, 138 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c
> index 4b8156033fa6..9b14a997cd48 100644
> --- a/drivers/platform/x86/amd/pmf/core.c
> +++ b/drivers/platform/x86/amd/pmf/core.c
> @@ -411,6 +411,7 @@ static int amd_pmf_probe(struct platform_device *pdev)
> }
>
> dev->cpu_id = rdev->device;
> + dev->root = rdev;
>
> err = amd_smn_read(0, AMD_PMF_BASE_ADDR_LO, &val);
> if (err) {
> @@ -482,4 +483,4 @@ module_platform_driver(amd_pmf_driver);
>
> MODULE_LICENSE("GPL");
> MODULE_DESCRIPTION("AMD Platform Management Framework Driver");
> -MODULE_SOFTDEP("pre: amdtee");
> +MODULE_SOFTDEP("pre: amdtee amdgpu");
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h
> index 8712299ad52b..525308519fa3 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -11,7 +11,11 @@
> #ifndef PMF_H
> #define PMF_H
>
> +#include <acpi/video.h>
> +#include <drm/drm_connector.h>
> #include <linux/acpi.h>
> +#include <linux/backlight.h>
> +#include <linux/pci.h>
> #include <linux/platform_profile.h>
>
> #define POLICY_BUF_MAX_SZ 0x4b000
> @@ -83,6 +87,8 @@
> #define TA_OUTPUT_RESERVED_MEM 906
> #define MAX_OPERATION_PARAMS 4
>
> +#define MAX_SUPPORTED_DISPLAY 4
> +
> /* AMD PMF BIOS interfaces */
> struct apmf_verify_interface {
> u16 size;
> @@ -194,6 +200,15 @@ enum power_modes {
> POWER_MODE_MAX,
> };
>
> +struct amd_gpu_pmf_data {
> + struct pci_dev *gpu_dev;
> + struct backlight_device *raw_bd;
> + struct thermal_cooling_device *cooling_dev;
> + enum drm_connector_status con_status[MAX_SUPPORTED_DISPLAY];
> + int display_count;
> + int connector_type[MAX_SUPPORTED_DISPLAY];
> +};
> +
> struct amd_pmf_dev {
> void __iomem *regbase;
> void __iomem *smu_virt_addr;
> @@ -228,9 +243,12 @@ struct amd_pmf_dev {
> void *shbuf;
> struct delayed_work pb_work;
> struct pmf_action_table *prev_data;
> + struct amd_gpu_pmf_data gfx_data;
> u64 policy_addr;
> void *policy_base;
> bool smart_pc_enabled;
> + struct pci_dev *root;
> + struct drm_device *drm_dev;
> };
>
> struct apmf_sps_prop_granular {
> diff --git a/drivers/platform/x86/amd/pmf/spc.c b/drivers/platform/x86/amd/pmf/spc.c
> index 959146fd483f..47ec563088b8 100644
> --- a/drivers/platform/x86/amd/pmf/spc.c
> +++ b/drivers/platform/x86/amd/pmf/spc.c
> @@ -44,6 +44,10 @@ void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *
> dev_dbg(dev->dev, "Max C0 Residency: %u\n", in->ev_info.max_c0residency);
> dev_dbg(dev->dev, "GFX Busy: %u\n", in->ev_info.gfx_busy);
> dev_dbg(dev->dev, "Connected Display Count: %u\n", in->ev_info.monitor_count);
> + dev_dbg(dev->dev, "Primary Display Type: %s\n",
> + drm_get_connector_type_name(in->ev_info.display_type));
> + dev_dbg(dev->dev, "Primary Display State: %s\n", in->ev_info.display_state ?
> + "Connected" : "disconnected/unknown");
> dev_dbg(dev->dev, "LID State: %s\n", in->ev_info.lid_state ? "close" : "open");
> dev_dbg(dev->dev, "==== TA inputs END ====\n");
> }
> @@ -146,6 +150,41 @@ static int amd_pmf_get_slider_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_
> return 0;
> }
>
> +static int amd_pmf_get_gfx_data(struct amd_pmf_dev *pmf)
> +{
> + struct drm_connector_list_iter iter;
> + struct drm_connector *connector;
> + int i = 0;
> +
> + /* Reset the count to zero */
> + pmf->gfx_data.display_count = 0;
> +
> + drm_connector_list_iter_begin(pmf->drm_dev, &iter);
> + drm_for_each_connector_iter(connector, &iter) {
> + if (connector->status == connector_status_connected)
> + pmf->gfx_data.display_count++;
> + if (connector->status != pmf->gfx_data.con_status[i])
> + pmf->gfx_data.con_status[i] = connector->status;
> + if (connector->connector_type != pmf->gfx_data.connector_type[i])
> + pmf->gfx_data.connector_type[i] = connector->connector_type;
> +
> + i++;
> + if (i >= MAX_SUPPORTED_DISPLAY)
> + break;
> + }
> + drm_connector_list_iter_end(&iter);
> +
> + return 0;
> +}
> +
> +static void amd_pmf_get_gpu_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
> +{
> + amd_pmf_get_gfx_data(dev);
> + in->ev_info.monitor_count = dev->gfx_data.display_count;
> + in->ev_info.display_type = dev->gfx_data.connector_type[0];
> + in->ev_info.display_state = dev->gfx_data.con_status[0];
> +}
> +
> void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in)
> {
> /* TA side lid open is 1 and close is 0, hence the ! here */
> @@ -154,4 +193,6 @@ void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_tab
> amd_pmf_get_smu_info(dev, in);
> amd_pmf_get_battery_info(dev, in);
> amd_pmf_get_slider_info(dev, in);
> + if (dev->drm_dev)
> + amd_pmf_get_gpu_info(dev, in);
> }
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c b/drivers/platform/x86/amd/pmf/tee-if.c
> index 81b1bd356e83..82ee2b1c627f 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -10,6 +10,7 @@
>
> #include <linux/debugfs.h>
> #include <linux/tee_drv.h>
> +#include <linux/thermal.h>
> #include <linux/uuid.h>
> #include "pmf.h"
>
> @@ -422,6 +423,60 @@ static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev)
> tee_client_close_context(dev->tee_ctx);
> }
>
> +static int amd_pmf_gpu_get_cur_state(struct thermal_cooling_device *cooling_dev,
> + unsigned long *state)
> +{
> + struct backlight_device *bd;
> +
> + if (acpi_video_get_backlight_type() != acpi_backlight_native)
> + return -ENODEV;
> +
> + bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!bd)
> + return -ENODEV;
> +
> + *state = backlight_get_brightness(bd);
> +
> + return 0;
> +}
> +
> +static int amd_pmf_gpu_get_max_state(struct thermal_cooling_device *cooling_dev,
> + unsigned long *state)
> +{
> + struct backlight_device *bd;
> +
> + if (acpi_video_get_backlight_type() != acpi_backlight_native)
> + return -ENODEV;
> +
> + bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!bd)
> + return -ENODEV;
> +
> + if (backlight_is_blank(bd))
> + *state = 0;
> + else
> + *state = bd->props.max_brightness;
> +
> + return 0;
> +}
> +
> +static const struct thermal_cooling_device_ops bd_cooling_ops = {
> + .get_max_state = amd_pmf_gpu_get_max_state,
> + .get_cur_state = amd_pmf_gpu_get_cur_state,
> +};
This is still the wrong thing to do. The new PMF code MUST only
be a *consumer* of the thermal_cooling_device API.
The thermal-cooling device for the backlight itself MUST be
registered by the amdgpu driver.
I believe that the correct fix for this is to add a new flag to
the backlight_properties struct;
And then make backlight_device_register() register
a thermal_cooling_device for the backlight when this new flag is set.
This way we get a nice generic way to use backlight class devices
as thermal cooling devices and you can make the amdgpu driver
register the thermal cooling device by simply adding the new flag
to the backlight_properties struct used in the amdgpu driver.
> +static int amd_pmf_get_gpu_handle(struct pci_dev *pdev, void *data)
> +{
> + struct amd_pmf_dev *dev = data;
> +
> + if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->devfn == 0) {
> + dev->gfx_data.gpu_dev = pdev;
> + return 1; /* Stop walking */
> + }
> +
> + return 0; /* Continue walking */
> +}
> +
> int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
> {
> int ret;
> @@ -433,10 +488,30 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
> INIT_DELAYED_WORK(&dev->pb_work, amd_pmf_invoke_cmd);
> amd_pmf_set_dram_addr(dev);
> amd_pmf_get_bios_buffer(dev);
> +
> dev->prev_data = kzalloc(sizeof(*dev->prev_data), GFP_KERNEL);
> if (!dev->prev_data)
> return -ENOMEM;
>
> + pci_walk_bus(dev->root->bus, amd_pmf_get_gpu_handle, dev);
> + if (dev->gfx_data.gpu_dev) {
> + dev->drm_dev = pci_get_drvdata(dev->gfx_data.gpu_dev);
> + if (!dev->drm_dev)
> + return -EINVAL;
You cannot just call pci_get_drvdata() on a device for which you
are not the driver. You have no idea of the lifetime of this device,
the driver may unbind and release the memory pci_get_drvdata()
points to, leaving this code with a dangling pointer which will
crash the kernel the first time you try to use it.
Also since you are not the owner you MUST not assume any specific
type for this memory, you cannot be sure this actually is of
the type drm_device. Basically you MUST not touch another
driver's drvdata *at all*.
The proper way to fix this would be to add some API to the DRM
subsystem to query the information you are looking for form
the DRM subsystem.
Poking directly inside other driver's internals is NOT acceptable,
NACK for this patch.
Regards,
Hans
> +
> + if (acpi_video_get_backlight_type() != acpi_backlight_native)
> + return -ENODEV;
> +
> + dev->gfx_data.raw_bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!dev->gfx_data.raw_bd)
> + return -ENODEV;
> +
> + dev->gfx_data.cooling_dev = thermal_cooling_device_register("pmf_gpu_bd",
> + NULL, &bd_cooling_ops);
> + if (IS_ERR(dev->gfx_data.cooling_dev))
> + return -ENODEV;
> + }
> +
> return dev->smart_pc_enabled;
> }
>
> @@ -448,5 +523,7 @@ void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev)
> kfree(dev->prev_data);
> kfree(dev->policy_buf);
> cancel_delayed_work_sync(&dev->pb_work);
> + if (dev->gfx_data.cooling_dev)
> + thermal_cooling_device_unregister(dev->gfx_data.cooling_dev);
> amd_pmf_tee_deinit(dev);
> }
next prev parent reply other threads:[~2023-11-17 10:48 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-17 8:07 [PATCH v5 00/17] Introduce PMF Smart PC Solution Builder Feature Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 01/17] platform/x86/amd/pmf: Add PMF TEE interface Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 02/17] platform/x86/amd/pmf: Add support for PMF-TA interaction Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 03/17] platform/x86/amd/pmf: Change return type of amd_pmf_set_dram_addr() Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 04/17] platform/x86/amd/pmf: Add support for PMF Policy Binary Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 05/17] platform/x86/amd/pmf: change amd_pmf_init_features() call sequence Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 06/17] platform/x86/amd/pmf: Add support to get inputs from other subsystems Shyam Sundar S K
2023-11-21 12:02 ` Ilpo Järvinen
2023-11-17 8:07 ` [PATCH v5 07/17] platform/x86/amd/pmf: Add support update p3t limit Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 08/17] platform/x86/amd/pmf: Add support to update system state Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 09/17] platform/x86/amd/pmf: Make source_as_str() as non-static Shyam Sundar S K
2023-11-17 22:52 ` Mario Limonciello
2023-11-17 8:07 ` [PATCH v5 10/17] platform/x86/amd/pmf: Add facility to dump TA inputs Shyam Sundar S K
2023-11-21 12:06 ` Ilpo Järvinen
2023-11-17 8:07 ` [PATCH v5 11/17] platform/x86/amd/pmf: Add capability to sideload of policy binary Shyam Sundar S K
2023-11-21 12:17 ` Ilpo Järvinen
2023-12-01 10:29 ` Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 12/17] platform/x86/amd/pmf: dump policy binary data Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 13/17] platform/x86/amd/pmf: Add PMF-AMDGPU get interface Shyam Sundar S K
2023-11-17 10:48 ` Hans de Goede [this message]
2023-11-17 11:08 ` Shyam Sundar S K
2023-11-17 11:31 ` Hans de Goede
2023-11-20 6:42 ` Shyam Sundar S K
2023-11-17 18:13 ` Mario Limonciello
2023-11-20 6:39 ` Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 14/17] platform/x86/amd/pmf: Add PMF-AMDGPU set interface Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 15/17] HID: amd_sfh: rename float_to_int() to amd_sfh_float_to_int() Shyam Sundar S K
2023-11-17 8:07 ` [PATCH v5 16/17] platform/x86/amd/pmf: Add PMF-AMDSFH interface for HPD Shyam Sundar S K
2023-11-17 18:18 ` Mario Limonciello
2023-11-17 8:07 ` [PATCH v5 17/17] platform/x86/amd/pmf: Add PMF-AMDSFH interface for ALS Shyam Sundar S K
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=80b8c5fe-e81b-4e05-bf21-19351c51d767@redhat.com \
--to=hdegoede@redhat.com \
--cc=Patil.Reddy@amd.com \
--cc=Shyam-sundar.S-k@amd.com \
--cc=basavaraj.natikar@amd.com \
--cc=benjamin.tissoires@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=markgross@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/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).