<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">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> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Rex Zhu <Rex.Zhu@amd.com><br>
<b>Sent:</b> Wednesday, June 13, 2018 6:34:44 AM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org<br>
<b>Cc:</b> Zhu, Rex<br>
<b>Subject:</b> [PATCH] drm/amd/pp: Add S3 support for OD feature</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">make custom values survive when S3 sleep transitions.<br>
so not reset the od table if it is not null.<br>
<br>
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com><br>
---<br>
 drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c   | 126 +++++++++++----------<br>
 drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c |  79 +++++++------<br>
 2 files changed, 107 insertions(+), 98 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c<br>
index 00614d0..b73e200 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c<br>
@@ -885,6 +885,60 @@ static void smu7_setup_voltage_range_from_vbios(struct pp_hwmgr *hwmgr)<br>
         data->odn_dpm_table.max_vddc = max_vddc;<br>
 }<br>
 <br>
+static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);<br>
+       struct smu7_odn_dpm_table *odn_table = &(data->odn_dpm_table);<br>
+       struct phm_ppt_v1_information *table_info =<br>
+                       (struct phm_ppt_v1_information *)(hwmgr->pptable);<br>
+       uint32_t i;<br>
+<br>
+       struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;<br>
+       struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;<br>
+<br>
+       if (table_info == NULL)<br>
+               return;<br>
+<br>
+       for (i = 0; i < data->dpm_table.sclk_table.count; i++) {<br>
+               if (odn_table->odn_core_clock_dpm_levels.entries[i].clock !=<br>
+                                       data->dpm_table.sclk_table.dpm_levels[i].value) {<br>
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;<br>
+                       break;<br>
+               }<br>
+       }<br>
+<br>
+       for (i = 0; i < data->dpm_table.mclk_table.count; i++) {<br>
+               if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock !=<br>
+                                       data->dpm_table.mclk_table.dpm_levels[i].value) {<br>
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;<br>
+                       break;<br>
+               }<br>
+       }<br>
+<br>
+       dep_table = table_info->vdd_dep_on_mclk;<br>
+       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk);<br>
+<br>
+       for (i = 0; i < dep_table->count; i++) {<br>
+               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;<br>
+                       return;<br>
+               }<br>
+       }<br>
+<br>
+       dep_table = table_info->vdd_dep_on_sclk;<br>
+       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);<br>
+       for (i = 0; i < dep_table->count; i++) {<br>
+               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;<br>
+                       return;<br>
+               }<br>
+       }<br>
+       if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {<br>
+               data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;<br>
+               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;<br>
+       }<br>
+}<br>
+<br>
 static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)<br>
 {<br>
         struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);<br>
@@ -904,10 +958,13 @@ static int smu7_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)<br>
 <br>
         /* initialize ODN table */<br>
         if (hwmgr->od_enabled) {<br>
-               smu7_setup_voltage_range_from_vbios(hwmgr);<br>
-               smu7_odn_initial_default_setting(hwmgr);<br>
+               if (data->odn_dpm_table.max_vddc) {<br>
+                       smu7_check_dpm_table_updated(hwmgr);<br>
+               } else {<br>
+                       smu7_setup_voltage_range_from_vbios(hwmgr);<br>
+                       smu7_odn_initial_default_setting(hwmgr);<br>
+               }<br>
         }<br>
-<br>
         return 0;<br>
 }<br>
 <br>
@@ -3717,8 +3774,9 @@ static int smu7_trim_single_dpm_states(struct pp_hwmgr *hwmgr,<br>
         uint32_t i;<br>
 <br>
         for (i = 0; i < dpm_table->count; i++) {<br>
-               if ((dpm_table->dpm_levels[i].value < low_limit)<br>
-               || (dpm_table->dpm_levels[i].value > high_limit))<br>
+       /*skip the trim if od is enabled*/<br>
+               if (!hwmgr->od_enabled && (dpm_table->dpm_levels[i].value < low_limit<br>
+                       || dpm_table->dpm_levels[i].value > high_limit))<br>
                         dpm_table->dpm_levels[i].enabled = false;<br>
                 else<br>
                         dpm_table->dpm_levels[i].enabled = true;<br>
@@ -3762,10 +3820,8 @@ static int smu7_generate_dpm_level_enable_mask(<br>
         const struct smu7_power_state *smu7_ps =<br>
                         cast_const_phw_smu7_power_state(states->pnew_state);<br>
 <br>
-       /*skip the trim if od is enabled*/<br>
-       if (!hwmgr->od_enabled)<br>
-               result = smu7_trim_dpm_states(hwmgr, smu7_ps);<br>
 <br>
+       result = smu7_trim_dpm_states(hwmgr, smu7_ps);<br>
         if (result)<br>
                 return result;<br>
 <br>
@@ -4738,60 +4794,6 @@ static bool smu7_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,<br>
         return true;<br>
 }<br>
 <br>
-static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)<br>
-{<br>
-       struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);<br>
-       struct smu7_odn_dpm_table *odn_table = &(data->odn_dpm_table);<br>
-       struct phm_ppt_v1_information *table_info =<br>
-                       (struct phm_ppt_v1_information *)(hwmgr->pptable);<br>
-       uint32_t i;<br>
-<br>
-       struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;<br>
-       struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;<br>
-<br>
-       if (table_info == NULL)<br>
-               return;<br>
-<br>
-       for (i=0; i<data->dpm_table.sclk_table.count; i++) {<br>
-               if (odn_table->odn_core_clock_dpm_levels.entries[i].clock !=<br>
-                                       data->dpm_table.sclk_table.dpm_levels[i].value) {<br>
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;<br>
-                       break;<br>
-               }<br>
-       }<br>
-<br>
-       for (i=0; i<data->dpm_table.mclk_table.count; i++) {<br>
-               if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock !=<br>
-                                       data->dpm_table.mclk_table.dpm_levels[i].value) {<br>
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;<br>
-                       break;<br>
-               }<br>
-       }<br>
-<br>
-       dep_table = table_info->vdd_dep_on_mclk;<br>
-       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk);<br>
-<br>
-       for (i=0; i < dep_table->count; i++) {<br>
-               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;<br>
-                       return;<br>
-               }<br>
-       }<br>
-<br>
-       dep_table = table_info->vdd_dep_on_sclk;<br>
-       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);<br>
-       for (i=0; i < dep_table->count; i++) {<br>
-               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;<br>
-                       return;<br>
-               }<br>
-       }<br>
-       if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {<br>
-               data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;<br>
-               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;<br>
-       }<br>
-}<br>
-<br>
 static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,<br>
                                         enum PP_OD_DPM_TABLE_COMMAND type,<br>
                                         long *input, uint32_t size)<br>
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c<br>
index 3fe2873..3b8d36d 100644<br>
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c<br>
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c<br>
@@ -2414,6 +2414,40 @@ static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)<br>
         return result;<br>
 }<br>
 <br>
+static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr)<br>
+{<br>
+       struct vega10_hwmgr *data = hwmgr->backend;<br>
+       struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);<br>
+       struct phm_ppt_v2_information *table_info = hwmgr->pptable;<br>
+       struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;<br>
+       struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;<br>
+       uint32_t i;<br>
+<br>
+       dep_table = table_info->vdd_dep_on_mclk;<br>
+       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk);<br>
+<br>
+       for (i = 0; i < dep_table->count; i++) {<br>
+               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
+                       data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;<br>
+                       return;<br>
+               }<br>
+       }<br>
+<br>
+       dep_table = table_info->vdd_dep_on_sclk;<br>
+       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk);<br>
+       for (i = 0; i < dep_table->count; i++) {<br>
+               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
+                       data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;<br>
+                       return;<br>
+               }<br>
+       }<br>
+<br>
+       if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {<br>
+               data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;<br>
+               data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;<br>
+       }<br>
+}<br>
+<br>
 /**<br>
 * Initializes the SMC table and uploads it<br>
 *<br>
@@ -2430,6 +2464,7 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)<br>
         PPTable_t *pp_table = &(data->smc_state_table.pp_table);<br>
         struct pp_atomfwctrl_voltage_table voltage_table;<br>
         struct pp_atomfwctrl_bios_boot_up_values boot_up_values;<br>
+       struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);<br>
 <br>
         result = vega10_setup_default_dpm_tables(hwmgr);<br>
         PP_ASSERT_WITH_CODE(!result,<br>
@@ -2437,8 +2472,14 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)<br>
                         return result);<br>
 <br>
         /* initialize ODN table */<br>
-       if (hwmgr->od_enabled)<br>
-               vega10_odn_initial_default_setting(hwmgr);<br>
+       if (hwmgr->od_enabled) {<br>
+               if (odn_table->max_vddc) {<br>
+                       data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;<br>
+                       vega10_check_dpm_table_updated(hwmgr);<br>
+               } else {<br>
+                       vega10_odn_initial_default_setting(hwmgr);<br>
+               }<br>
+       }<br>
 <br>
         pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC,<br>
                         VOLTAGE_OBJ_SVID2,  &voltage_table);<br>
@@ -4696,40 +4737,6 @@ static bool vega10_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,<br>
         return true;<br>
 }<br>
 <br>
-static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr)<br>
-{<br>
-       struct vega10_hwmgr *data = hwmgr->backend;<br>
-       struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);<br>
-       struct phm_ppt_v2_information *table_info = hwmgr->pptable;<br>
-       struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;<br>
-       struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;<br>
-       uint32_t i;<br>
-<br>
-       dep_table = table_info->vdd_dep_on_mclk;<br>
-       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk);<br>
-<br>
-       for (i = 0; i < dep_table->count; i++) {<br>
-               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
-                       data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;<br>
-                       return;<br>
-               }<br>
-       }<br>
-<br>
-       dep_table = table_info->vdd_dep_on_sclk;<br>
-       odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk);<br>
-       for (i = 0; i < dep_table->count; i++) {<br>
-               if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {<br>
-                       data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;<br>
-                       return;<br>
-               }<br>
-       }<br>
-<br>
-       if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {<br>
-               data->need_update_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;<br>
-               data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;<br>
-       }<br>
-}<br>
-<br>
 static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr,<br>
                                                 enum PP_OD_DPM_TABLE_COMMAND type)<br>
 {<br>
-- <br>
1.9.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>