<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
p.msipheaderc10f11a2, li.msipheaderc10f11a2, div.msipheaderc10f11a2
        {mso-style-name:msipheaderc10f11a2;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="msipheaderc10f11a2" style="margin:0in"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:green">[Public]</span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt;background:white"><span style="color:black">> I don't think we want to force the performance level.  This interface<br>
forces various fixed clock configurations for debugging and profiling.</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">Ah got it.</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">>I think what we'd want to select here is the power profile (see<br>
amdgpu_set_pp_power_profile_mode()).  For this interface you can<br>
select various profiles (BOOTUP_DEFAULT, 3D_FULL_SCREEN, POWER_SAVING,<br>
VIDEO, VR, COMPUTE, etc.).  These still use dynamic power management,<br>
but they adjust the heuristics used by the GPU to select power states<br>
so the GPU performance ramps up/down more or less aggressively.</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">Which profile mapping you think make sense?</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">My guess would be:</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">“BOOTUP_DEFAULT” for balanced</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">“POWER_SAVING” for low-power</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">“3D_FULL_SCREEN” for performance</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">Since recently we removed that interface for YC, and some earlier APUs don’t do as much with it.</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">So I wonder if this is only really valuable to do this callback for !APU. 
</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">></span><span style="color:#212121"> I feel it's better to leave to platform vendors. For ex: for APU cases they may have implementations in which their BIOSes talk to PMFW and this might
 be driving something else here.<o:p></o:p></span></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">Even if changing the heuristic for workload as Alex suggested?</span><o:p></o:p></p>
<p class="MsoNormal" style="background:white"><o:p> </o:p></p>
<p class="MsoNormal" style="background:white"><span style="color:black">></span><span style="color:#212121"> Also, not sure how to handle a case like, say a laptop with Intel CPU and AMD dgpu.<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I was actually thinking this approach where there are platform profile callbacks is best because of that specifically.<o:p></o:p></p>
<p class="MsoNormal">It would allow an Intel CPU system to have a platform profile driver implemented by the OEM, but then still notify amdgpu dGPU to tune for power saving or performance workload.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Lazar, Lijo <Lijo.Lazar@amd.com> <br>
<b>Sent:</b> Wednesday, November 10, 2021 10:05<br>
<b>To:</b> Alex Deucher <alexdeucher@gmail.com>; Limonciello, Mario <Mario.Limonciello@amd.com><br>
<b>Cc:</b> amd-gfx list <amd-gfx@lists.freedesktop.org><br>
<b>Subject:</b> Re: [RFC 2/2] drm/amd/pm: Add support for reacting to platform profile notification<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p style="margin:15.0pt"><span style="font-size:10.0pt;font-family:"Arial",sans-serif;color:green">[Public]<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="background:white"><span style="color:#212121">I feel it's better to leave to platform vendors. For ex: for APU cases they may have implementations in which their BIOSes talk to PMFW and this might be driving something else here.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="color:#212121"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="background:white"><span style="color:#212121">Also, not sure how to handle a case like, say a laptop with Intel CPU and AMD dgpu.<o:p></o:p></span></p>
</div>
<div id="ms-outlook-mobile-signature">
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal">Thanks,<br>
Lijo<o:p></o:p></p>
</div>
<div id="id-f61421a9-d54c-4f81-aa61-517d64763a14">
<div>
<p class="MsoNormal"><span style="font-size:13.0pt;font-family:"Arial",sans-serif;color:black"><o:p> </o:p></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="divRplyFwdMsg">
<p class="MsoNormal"><strong><span style="font-family:"Calibri",sans-serif">From:</span></strong> amd-gfx <<a href="mailto:amd-gfx-bounces@lists.freedesktop.org">amd-gfx-bounces@lists.freedesktop.org</a>> on behalf of Alex Deucher <<a href="mailto:alexdeucher@gmail.com">alexdeucher@gmail.com</a>><br>
<strong><span style="font-family:"Calibri",sans-serif">Sent:</span></strong> Wednesday, 10 November 2021, 8:44 pm<br>
<strong><span style="font-family:"Calibri",sans-serif">To:</span></strong> Limonciello, Mario<br>
<strong><span style="font-family:"Calibri",sans-serif">Cc:</span></strong> amd-gfx list<br>
<strong><span style="font-family:"Calibri",sans-serif">Subject:</span></strong> Re: [RFC 2/2] drm/amd/pm: Add support for reacting to platform profile notification<o:p></o:p></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Wed, Nov 10, 2021 at 1:24 AM Mario Limonciello<br>
<<a href="mailto:mario.limonciello@amd.com">mario.limonciello@amd.com</a>> wrote:<br>
><br>
> Various drivers provide platform profile support to let users set a hint<br>
> in their GUI whether they want to run in a high performance, low battery<br>
> life or balanced configuration.<br>
><br>
> Drivers that provide this typically work with the firmware on their system<br>
> to configure hardware.  In the case of AMDGPU however, the notification<br>
> path doesn't come through firmware and can instead be provided directly<br>
> to the driver from a notification chain.<br>
><br>
> Use the information of the newly selected profile to tweak<br>
> `dpm_force_performance_level` to that profile IFF the user hasn't manually<br>
> selected `manual` or any other `profile_*` options.<br>
<br>
I don't think we want to force the performance level.  This interface<br>
forces various fixed clock configurations for debugging and profiling.<br>
I think what we'd want to select here is the power profile (see<br>
amdgpu_set_pp_power_profile_mode()).  For this interface you can<br>
select various profiles (BOOTUP_DEFAULT, 3D_FULL_SCREEN, POWER_SAVING,<br>
VIDEO, VR, COMPUTE, etc.).  These still use dynamic power management,<br>
but they adjust the heuristics used by the GPU to select power states<br>
so the GPU performance ramps up/down more or less aggressively.<br>
<br>
Alex<br>
<br>
><br>
> Signed-off-by: Mario Limonciello <<a href="mailto:mario.limonciello@amd.com">mario.limonciello@amd.com</a>><br>
> ---<br>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h |   3 +<br>
>  drivers/gpu/drm/amd/pm/amdgpu_pm.c  | 105 +++++++++++++++++++++++-----<br>
>  2 files changed, 90 insertions(+), 18 deletions(-)<br>
><br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> index b85b67a88a3d..27b0be23b6ac 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> @@ -1097,6 +1097,9 @@ struct amdgpu_device {<br>
><br>
>         struct amdgpu_reset_control     *reset_cntl;<br>
>         uint32_t                        ip_versions[HW_ID_MAX][HWIP_MAX_INSTANCE];<br>
> +<br>
> +       /* platform profile notifications */<br>
> +       struct notifier_block           platform_profile_notifier;<br>
>  };<br>
><br>
>  static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev)<br>
> diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> index 41472ed99253..33fc52b90d4c 100644<br>
> --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c<br>
> @@ -32,6 +32,7 @@<br>
>  #include <linux/hwmon.h><br>
>  #include <linux/hwmon-sysfs.h><br>
>  #include <linux/nospec.h><br>
> +#include <linux/platform_profile.h><br>
>  #include <linux/pm_runtime.h><br>
>  #include <asm/processor.h><br>
>  #include "hwmgr.h"<br>
> @@ -200,6 +201,33 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev,<br>
>         return count;<br>
>  }<br>
><br>
> +static int amdgpu_get_forced_level(struct device *dev, enum amd_dpm_forced_level *level)<br>
> +{<br>
> +       struct drm_device *ddev = dev_get_drvdata(dev);<br>
> +       struct amdgpu_device *adev = drm_to_adev(ddev);<br>
> +       int ret;<br>
> +<br>
> +       if (amdgpu_in_reset(adev))<br>
> +               return -EPERM;<br>
> +       if (adev->in_suspend && !adev->in_runpm)<br>
> +               return -EPERM;<br>
> +<br>
> +       ret = pm_runtime_get_sync(ddev->dev);<br>
> +       if (ret < 0) {<br>
> +               pm_runtime_put_autosuspend(ddev->dev);<br>
> +               return ret;<br>
> +       }<br>
> +<br>
> +       if (adev->powerplay.pp_funcs->get_performance_level)<br>
> +               *level = amdgpu_dpm_get_performance_level(adev);<br>
> +       else<br>
> +               *level = adev->pm.dpm.forced_level;<br>
> +<br>
> +       pm_runtime_mark_last_busy(ddev->dev);<br>
> +       pm_runtime_put_autosuspend(ddev->dev);<br>
> +<br>
> +       return 0;<br>
> +}<br>
><br>
>  /**<br>
>   * DOC: power_dpm_force_performance_level<br>
> @@ -264,29 +292,13 @@ static ssize_t amdgpu_get_power_dpm_force_performance_level(struct device *dev,<br>
>                                                             struct device_attribute *attr,<br>
>                                                             char *buf)<br>
>  {<br>
> -       struct drm_device *ddev = dev_get_drvdata(dev);<br>
> -       struct amdgpu_device *adev = drm_to_adev(ddev);<br>
>         enum amd_dpm_forced_level level = 0xff;<br>
>         int ret;<br>
><br>
> -       if (amdgpu_in_reset(adev))<br>
> -               return -EPERM;<br>
> -       if (adev->in_suspend && !adev->in_runpm)<br>
> -               return -EPERM;<br>
> +       ret = amdgpu_get_forced_level(dev, &level);<br>
><br>
> -       ret = pm_runtime_get_sync(ddev->dev);<br>
> -       if (ret < 0) {<br>
> -               pm_runtime_put_autosuspend(ddev->dev);<br>
> +       if (ret < 0)<br>
>                 return ret;<br>
> -       }<br>
> -<br>
> -       if (adev->powerplay.pp_funcs->get_performance_level)<br>
> -               level = amdgpu_dpm_get_performance_level(adev);<br>
> -       else<br>
> -               level = adev->pm.dpm.forced_level;<br>
> -<br>
> -       pm_runtime_mark_last_busy(ddev->dev);<br>
> -       pm_runtime_put_autosuspend(ddev->dev);<br>
><br>
>         return sysfs_emit(buf, "%s\n",<br>
>                           (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" :<br>
> @@ -405,6 +417,59 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,<br>
>         return count;<br>
>  }<br>
><br>
> +static void amdgpu_update_profile(struct device *dev, enum platform_profile_option *profile)<br>
> +{<br>
> +       enum amd_dpm_forced_level level;<br>
> +       const char *str;<br>
> +       int ret;<br>
> +<br>
> +       ret = amdgpu_get_forced_level(dev, &level);<br>
> +       if (ret < 0)<br>
> +               return;<br>
> +<br>
> +       /* only update profile if we're in fixed modes right now that need updating */<br>
> +       switch (level) {<br>
> +       case AMD_DPM_FORCED_LEVEL_LOW:<br>
> +               if (*profile < PLATFORM_PROFILE_BALANCED)<br>
> +                       return;<br>
> +               break;<br>
> +       case AMD_DPM_FORCED_LEVEL_HIGH:<br>
> +               if (*profile > PLATFORM_PROFILE_BALANCED)<br>
> +                       return;<br>
> +               break;<br>
> +       case AMD_DPM_FORCED_LEVEL_AUTO:<br>
> +               if (*profile == PLATFORM_PROFILE_BALANCED)<br>
> +                       return;<br>
> +               break;<br>
> +       default:<br>
> +               dev_dbg(dev, "refusing to update amdgpu profile from %d\n", level);<br>
> +               return;<br>
> +       }<br>
> +       if (*profile > PLATFORM_PROFILE_BALANCED)<br>
> +               str = "high";<br>
> +       else if (*profile < PLATFORM_PROFILE_BALANCED)<br>
> +               str = "low";<br>
> +       else<br>
> +               str = "auto";<br>
> +<br>
> +       dev_dbg(dev, "updating platform profile to %s\n", str);<br>
> +       amdgpu_set_power_dpm_force_performance_level(dev, NULL, str, 0);<br>
> +}<br>
> +<br>
> +static int amdgpu_platform_profile_notifier_call(struct notifier_block *nb,<br>
> +                                                 unsigned long action, void *data)<br>
> +{<br>
> +       if (action == PLATFORM_PROFILE_CHANGED) {<br>
> +               enum platform_profile_option *profile = data;<br>
> +               struct amdgpu_device *adev;<br>
> +<br>
> +               adev = container_of(nb, struct amdgpu_device, platform_profile_notifier);<br>
> +               amdgpu_update_profile(adev->dev, profile);<br>
> +       }<br>
> +<br>
> +       return NOTIFY_OK;<br>
> +}<br>
> +<br>
>  static ssize_t amdgpu_get_pp_num_states(struct device *dev,<br>
>                 struct device_attribute *attr,<br>
>                 char *buf)<br>
> @@ -3506,6 +3571,9 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)<br>
>         if (ret)<br>
>                 return ret;<br>
><br>
> +       adev->platform_profile_notifier.notifier_call = amdgpu_platform_profile_notifier_call;<br>
> +       platform_profile_register_notifier(&adev->platform_profile_notifier);<br>
> +<br>
>         adev->pm.sysfs_initialized = true;<br>
><br>
>         return 0;<br>
> @@ -3519,6 +3587,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)<br>
>         if (adev->pm.int_hwmon_dev)<br>
>                 hwmon_device_unregister(adev->pm.int_hwmon_dev);<br>
><br>
> +       platform_profile_unregister_notifier(&adev->platform_profile_notifier);<br>
>         amdgpu_device_attr_remove_groups(adev, &adev->pm.pm_attr_list);<br>
>  }<br>
><br>
> --<br>
> 2.25.1<br>
><o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>