<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Seems reasonable to me.  With those changes,</p>
<p style="margin-top:0;margin-bottom:0">Reviewed-by: Alex Deucher <alexander.deucher@amd.com><br>
</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Quan, Evan<br>
<b>Sent:</b> Tuesday, January 15, 2019 1:59:42 AM<br>
<b>To:</b> Alex Deucher<br>
<b>Cc:</b> amd-gfx list; Deucher, Alexander<br>
<b>Subject:</b> RE: [PATCH 4/4] drm/amd/powerplay: support retrieving and adjusting dcefclock power levels</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">For ppfeatures, it will be seen only if (adev->asic_type >= CHIP_VEGA10 && !APU).<br>
<br>
Regards,<br>
Evan<br>
> -----Original Message-----<br>
> From: Quan, Evan<br>
> Sent: Tuesday, January 15, 2019 2:44 PM<br>
> To: Alex Deucher <alexdeucher@gmail.com><br>
> Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>; Deucher, Alexander<br>
> <Alexander.Deucher@amd.com><br>
> Subject: RE: [PATCH 4/4] drm/amd/powerplay: support retrieving and<br>
> adjusting dcefclock power levels<br>
> <br>
> I think we can use asic_type to determine whether to expose these new<br>
> interfaces.<br>
> If (adev->asic_type >= CHIP_VEGA10), socclk and dcefclk are OK to expose If<br>
> (adev->asic_type >= CHIP_VEGA20), fclk is OK to expose<br>
> <br>
> Regards,<br>
> Evan<br>
> > -----Original Message-----<br>
> > From: Alex Deucher <alexdeucher@gmail.com><br>
> > Sent: Tuesday, January 15, 2019 1:00 AM<br>
> > To: Quan, Evan <Evan.Quan@amd.com><br>
> > Cc: amd-gfx list <amd-gfx@lists.freedesktop.org>; Deucher, Alexander<br>
> > <Alexander.Deucher@amd.com><br>
> > Subject: Re: [PATCH 4/4] drm/amd/powerplay: support retrieving and<br>
> > adjusting dcefclock power levels<br>
> ><br>
> > On Mon, Jan 14, 2019 at 5:02 AM Evan Quan <evan.quan@amd.com> wrote:<br>
> > ><br>
> > > User can use "pp_dpm_dcefclk" to retrieve and adjust dcefclock power<br>
> > > levels.<br>
> > ><br>
> > > Change-Id: Ia3f61558ca96104c88d129ba5194103b2fe702ec<br>
> > > Signed-off-by: Evan Quan <evan.quan@amd.com><br>
> ><br>
> > We should probably find a way to hide these new files on asics which<br>
> > don't support them.  Other than that, the series looks good to me.<br>
> ><br>
> > Alex<br>
> ><br>
> > > ---<br>
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c        | 53<br>
> > ++++++++++++++++++-<br>
> > >  .../gpu/drm/amd/include/kgd_pp_interface.h    |  1 +<br>
> > >  .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c    | 52<br>
> > +++++++++++++++++-<br>
> > >  3 files changed, 103 insertions(+), 3 deletions(-)<br>
> > ><br>
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> > > b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> > > index f6646a522c06..b7b70f590236 100644<br>
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c<br>
> > > @@ -731,11 +731,13 @@ static ssize_t<br>
> > > amdgpu_get_ppfeature_status(struct device *dev,  }<br>
> > ><br>
> > >  /**<br>
> > > - * DOC: pp_dpm_sclk pp_dpm_mclk pp_dpm_socclk pp_dpm_fclk<br>
> > pp_dpm_pcie<br>
> > > + * DOC: pp_dpm_sclk pp_dpm_mclk pp_dpm_socclk pp_dpm_fclk<br>
> > > + pp_dpm_dcefclk<br>
> > > + * pp_dpm_pcie<br>
> > >   *<br>
> > >   * The amdgpu driver provides a sysfs API for adjusting what power<br>
> levels<br>
> > >   * are enabled for a given power state.  The files pp_dpm_sclk,<br>
> > > pp_dpm_mclk,<br>
> > > - * pp_dpm_socclk, pp_dpm_fclk and pp_dpm_pcie are used for this.<br>
> > > + * pp_dpm_socclk, pp_dpm_fclk, pp_dpm_dcefclk and pp_dpm_pcie<br>
> are<br>
> > > + used for<br>
> > > + * this.<br>
> > >   *<br>
> > >   * Reading back the files will show you the available power levels within<br>
> > >   * the power state and the clock information for those levels.<br>
> > > @@ -745,6 +747,8 @@ static ssize_t<br>
> > > amdgpu_get_ppfeature_status(struct<br>
> > device *dev,<br>
> > >   * Secondly,Enter a new value for each level by inputing a string that<br>
> > >   * contains " echo xx xx xx > pp_dpm_sclk/mclk/pcie"<br>
> > >   * E.g., echo 4 5 6 to > pp_dpm_sclk will enable sclk levels 4, 5, and 6.<br>
> > > + *<br>
> > > + * NOTE: change to the dcefclk max dpm level is not supported now<br>
> > >   */<br>
> > ><br>
> > >  static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, @@ -927,6<br>
> > > +931,42 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,<br>
> > >         return count;<br>
> > >  }<br>
> > ><br>
> > > +static ssize_t amdgpu_get_pp_dpm_dcefclk(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 = ddev->dev_private;<br>
> > > +<br>
> > > +       if (adev->powerplay.pp_funcs->print_clock_levels)<br>
> > > +               return amdgpu_dpm_print_clock_levels(adev, PP_DCEFCLK,<br>
> buf);<br>
> > > +       else<br>
> > > +               return snprintf(buf, PAGE_SIZE, "\n"); }<br>
> > > +<br>
> > > +static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev,<br>
> > > +               struct device_attribute *attr,<br>
> > > +               const char *buf,<br>
> > > +               size_t count)<br>
> > > +{<br>
> > > +       struct drm_device *ddev = dev_get_drvdata(dev);<br>
> > > +       struct amdgpu_device *adev = ddev->dev_private;<br>
> > > +       int ret;<br>
> > > +       uint32_t mask = 0;<br>
> > > +<br>
> > > +       ret = amdgpu_read_mask(buf, count, &mask);<br>
> > > +       if (ret)<br>
> > > +               return ret;<br>
> > > +<br>
> > > +       if (adev->powerplay.pp_funcs->force_clock_level)<br>
> > > +               ret = amdgpu_dpm_force_clock_level(adev, PP_DCEFCLK,<br>
> > > + mask);<br>
> > > +<br>
> > > +       if (ret)<br>
> > > +               return -EINVAL;<br>
> > > +<br>
> > > +       return count;<br>
> > > +}<br>
> > > +<br>
> > >  static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev,<br>
> > >                 struct device_attribute *attr,<br>
> > >                 char *buf)<br>
> > > @@ -1216,6 +1256,9 @@ static DEVICE_ATTR(pp_dpm_socclk, S_IRUGO |<br>
> > > S_IWUSR,  static DEVICE_ATTR(pp_dpm_fclk, S_IRUGO | S_IWUSR,<br>
> > >                 amdgpu_get_pp_dpm_fclk,<br>
> > >                 amdgpu_set_pp_dpm_fclk);<br>
> > > +static DEVICE_ATTR(pp_dpm_dcefclk, S_IRUGO | S_IWUSR,<br>
> > > +               amdgpu_get_pp_dpm_dcefclk,<br>
> > > +               amdgpu_set_pp_dpm_dcefclk);<br>
> > >  static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR,<br>
> > >                 amdgpu_get_pp_dpm_pcie,<br>
> > >                 amdgpu_set_pp_dpm_pcie); @@ -2387,6 +2430,11 @@ int<br>
> > > amdgpu_pm_sysfs_init(struct amdgpu_device *adev)<br>
> > >                 DRM_ERROR("failed to create device file pp_dpm_fclk\n");<br>
> > >                 return ret;<br>
> > >         }<br>
> > > +       ret = device_create_file(adev->dev, &dev_attr_pp_dpm_dcefclk);<br>
> > > +       if (ret) {<br>
> > > +               DRM_ERROR("failed to create device file pp_dpm_dcefclk\n");<br>
> > > +               return ret;<br>
> > > +       }<br>
> > >         ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie);<br>
> > >         if (ret) {<br>
> > >                 DRM_ERROR("failed to create device file<br>
> > > pp_dpm_pcie\n"); @@ -2474,6 +2522,7 @@ void<br>
> > amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)<br>
> > >         device_remove_file(adev->dev, &dev_attr_pp_dpm_socclk);<br>
> > >         device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie);<br>
> > >         device_remove_file(adev->dev, &dev_attr_pp_dpm_fclk);<br>
> > > +       device_remove_file(adev->dev, &dev_attr_pp_dpm_dcefclk);<br>
> > >         device_remove_file(adev->dev, &dev_attr_pp_sclk_od);<br>
> > >         device_remove_file(adev->dev, &dev_attr_pp_mclk_od);<br>
> > >         device_remove_file(adev->dev, diff --git<br>
> > > a/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> > > b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> > > index f82de14f6560..2b579ba9b685 100644<br>
> > > --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> > > +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h<br>
> > > @@ -94,6 +94,7 @@ enum pp_clock_type {<br>
> > >         PP_PCIE,<br>
> > >         PP_SOCCLK,<br>
> > >         PP_FCLK,<br>
> > > +       PP_DCEFCLK,<br>
> > >         OD_SCLK,<br>
> > >         OD_MCLK,<br>
> > >         OD_VDDC_CURVE,<br>
> > > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
> > > b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
> > > index 1832dcb965b1..585046c24925 100644<br>
> > > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
> > > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c<br>
> > > @@ -1746,6 +1746,17 @@ static int<br>
> vega20_upload_dpm_min_level(struct<br>
> > pp_hwmgr *hwmgr, uint32_t feature_<br>
> > >                                         return ret);<br>
> > >         }<br>
> > ><br>
> > > +       if (data->smu_features[GNLD_DPM_DCEFCLK].enabled &&<br>
> > > +          (feature_mask & FEATURE_DPM_DCEFCLK_MASK)) {<br>
> > > +               min_freq =<br>
> > > + data->dpm_table.dcef_table.dpm_state.hard_min_level;<br>
> > > +<br>
> > > +               PP_ASSERT_WITH_CODE(!(ret =<br>
> > smum_send_msg_to_smc_with_parameter(<br>
> > > +                                       hwmgr, PPSMC_MSG_SetHardMinByFreq,<br>
> > > +                                       (PPCLK_DCEFCLK << 16) | (min_freq & 0xffff))),<br>
> > > +                                       "Failed to set hard min dcefclk!",<br>
> > > +                                       return ret);<br>
> > > +       }<br>
> > > +<br>
> > >         return ret;<br>
> > >  }<br>
> > ><br>
> > > @@ -2258,7 +2269,7 @@ static int vega20_force_clock_level(struct<br>
> > pp_hwmgr *hwmgr,<br>
> > >                 enum pp_clock_type type, uint32_t mask)  {<br>
> > >         struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr-<br>
> > >backend);<br>
> > > -       uint32_t soft_min_level, soft_max_level;<br>
> > > +       uint32_t soft_min_level, soft_max_level, hard_min_level;<br>
> > >         int ret = 0;<br>
> > ><br>
> > >         switch (type) {<br>
> > > @@ -2373,6 +2384,28 @@ static int vega20_force_clock_level(struct<br>
> > > pp_hwmgr *hwmgr,<br>
> > ><br>
> > >                 break;<br>
> > ><br>
> > > +       case PP_DCEFCLK:<br>
> > > +               hard_min_level = mask ? (ffs(mask) - 1) : 0;<br>
> > > +<br>
> > > +               if (hard_min_level >= data->dpm_table.dcef_table.count) {<br>
> > > +                       pr_err("Clock level specified %d is over max allowed %d\n",<br>
> > > +                                       hard_min_level,<br>
> > > +                                       data->dpm_table.dcef_table.count - 1);<br>
> > > +                       return -EINVAL;<br>
> > > +               }<br>
> > > +<br>
> > > +               data->dpm_table.dcef_table.dpm_state.hard_min_level<br>
> > > + =<br>
> > > +<br>
> > > + data->dpm_table.dcef_table.dpm_levels[hard_min_level].value;<br>
> > > +<br>
> > > +               ret = vega20_upload_dpm_min_level(hwmgr,<br>
> > FEATURE_DPM_DCEFCLK_MASK);<br>
> > > +               PP_ASSERT_WITH_CODE(!ret,<br>
> > > +                       "Failed to upload boot level to lowest!",<br>
> > > +                       return ret);<br>
> > > +<br>
> > > +               //TODO: Setting DCEFCLK max dpm level is not<br>
> > > + supported<br>
> > > +<br>
> > > +               break;<br>
> > > +<br>
> > >         case PP_PCIE:<br>
> > >                 soft_min_level = mask ? (ffs(mask) - 1) : 0;<br>
> > >                 soft_max_level = mask ? (fls(mask) - 1) : 0; @@<br>
> > > -3039,6 +3072,23 @@ static int vega20_print_clock_levels(struct<br>
> > > pp_hwmgr<br>
> > *hwmgr,<br>
> > >                                 fclk_dpm_table->dpm_levels[i].value == (now / 100) ?<br>
> "*" :<br>
> > "");<br>
> > >                 break;<br>
> > ><br>
> > > +       case PP_DCEFCLK:<br>
> > > +               ret = vega20_get_current_clk_freq(hwmgr,<br>
> > > + PPCLK_DCEFCLK,<br>
> > &now);<br>
> > > +               PP_ASSERT_WITH_CODE(!ret,<br>
> > > +                               "Attempt to get current dcefclk freq Failed!",<br>
> > > +                               return ret);<br>
> > > +<br>
> > > +               ret = vega20_get_dcefclocks(hwmgr, &clocks);<br>
> > > +               PP_ASSERT_WITH_CODE(!ret,<br>
> > > +                               "Attempt to get dcefclk levels Failed!",<br>
> > > +                               return ret);<br>
> > > +<br>
> > > +               for (i = 0; i < clocks.num_levels; i++)<br>
> > > +                       size += sprintf(buf + size, "%d: %uMhz %s\n",<br>
> > > +                               i, clocks.data[i].clocks_in_khz / 1000,<br>
> > > +                               (clocks.data[i].clocks_in_khz == now * 10) ? "*" : "");<br>
> > > +               break;<br>
> > > +<br>
> > >         case PP_PCIE:<br>
> > >                 gen_speed = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &<br>
> > ><br>
> > > PSWUSP0_PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)<br>
> > > --<br>
> > > 2.20.1<br>
> > ><br>
> > > _______________________________________________<br>
> > > amd-gfx mailing list<br>
> > > amd-gfx@lists.freedesktop.org<br>
> > > <a href="https://lists.freedesktop.org/mailman/listinfo/amd-gfx">https://lists.freedesktop.org/mailman/listinfo/amd-gfx</a><br>
</div>
</span></font></div>
</body>
</html>