FAILED: patch "[PATCH] drm/amd/pm: preserve committed OD features for SMU 13.0.0/13.0.7" failed to apply to 6.18-stable tree
Sasha Levin
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 6027db7db773714f2e05df82093276f2a52a1fba
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '[email protected]' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Thanks,
Sasha
------------------ original commit in Linus's tree ------------------
From 6027db7db773714f2e05df82093276f2a52a1fba Mon Sep 17 00:00:00 2001
From: Kevin Wang <[email protected]>
Date: Thu, 15 Oct 2026 14:02:09 +0800
Subject: [PATCH] drm/amd/pm: preserve committed OD features for SMU
13.0.0/13.0.7
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PMFW treats FeatureCtrlMask as the complete set of active OD features. Uploads containing only newly edited bits can drop earlier settings.
Fix the OD state handling to:
- preserve committed features across later commits
- keep staged OD settings out of power-cap writes
- update cached state only after successful uploads
- clear restored features only after they return to defaults
- restore PPT for the current AC/DC source after resume
--- .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 193 +++++++++++++----- .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 193 +++++++++++++----- 2 files changed, 293 insertions(+), 93 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +147 -46
@@ -63,6 +63,9 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,int od_feature_bit, int32_t *min, int32_t *max);static int smu_v13_0_0_init_ppt_limits (struct smu_context *smu); +static int +smu_v13_0_0_upload_overdrive_table (struct smu_context *smu, +OverDriveTableExternal_t *od_table);static const struct smu_feature_bits smu_v13_0_0_dpm_features = { .bits = {
@@ -1079,6 +1082,93 @@ static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu,return feature_enabled; } +static u32 +smu_v13_0_0_filter_od_feature_mask (struct smu_context *smu,u32 feature_mask) +{ +PPTable_t *pptable = smu->smu_table.driver_pptable; +u32 supported_mask = + pptable->SkuTable.OverDriveLimitsBasicMax.FeatureCtrlMask; + +return feature_mask & supported_mask; +} + +static bool smu_v13_0_0_fan_is_default (const OverDriveTable_t *od, +const OverDriveTable_t *boot) +{ +return !memcmp (od->FanLinearPwmPoints, boot->FanLinearPwmPoints, +sizeof (od->FanLinearPwmPoints)) && + !memcmp (od->FanLinearTempPoints, boot->FanLinearTempPoints, +sizeof (od->FanLinearTempPoints)) && + od->FanMinimumPwm == boot->FanMinimumPwm && + od->AcousticTargetRpmThreshold == boot->AcousticTargetRpmThreshold && + od->AcousticLimitRpmThreshold == boot->AcousticLimitRpmThreshold && + od->FanTargetTemperature == boot->FanTargetTemperature && + od->FanMode == boot->FanMode; +} + +static bool smu_v13_0_0_zero_fan_is_default (const OverDriveTable_t *od, +const OverDriveTable_t *boot) +{ +return od->FanZeroRpmEnable == boot->FanZeroRpmEnable && + od->FanZeroRpmStopTemp == boot->FanZeroRpmStopTemp; +} + +static u32 smu_v13_0_0_normalize_feature_mask (const OverDriveTable_t *od, +const OverDriveTable_t *boot, +u32 feature_mask) +{ +if (od->GfxclkFmin == boot->GfxclkFmin && + od->GfxclkFmax == boot->GfxclkFmax) + feature_mask &= ~BIT (PP_OD_FEATURE_GFXCLK_BIT ); +if (od->UclkFmin == boot->UclkFmin && + od->UclkFmax == boot->UclkFmax) + feature_mask &= ~BIT (PP_OD_FEATURE_UCLK_BIT ); +if (!memcmp (od->VoltageOffsetPerZoneBoundary, + boot->VoltageOffsetPerZoneBoundary, +sizeof (od->VoltageOffsetPerZoneBoundary))) + feature_mask &= ~BIT (PP_OD_FEATURE_GFX_VF_CURVE_BIT ); +if (smu_v13_0_0_fan_is_default (od, boot)) + feature_mask &= ~BIT (PP_OD_FEATURE_FAN_CURVE_BIT ); +if (smu_v13_0_0_zero_fan_is_default (od, boot)) + feature_mask &= ~BIT (PP_OD_FEATURE_ZERO_FAN_BIT ); +if (!od->Ppt) + feature_mask &= ~BIT (PP_OD_FEATURE_PPT_BIT ); + +return feature_mask; +} + +static int +smu_v13_0_0_upload_ppt_overdrive_table (struct smu_context *smu,s16 ppt) +{ +struct smu_table_context *table_context = &smu->smu_table; +OverDriveTableExternal_t *od_table = table_context->overdrive_table; +OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table; +OverDriveTableExternal_t upload_table; +u32 next_mask = table_context->user_od_feature_mask; +int ret; + +/* Do not commit OD settings staged after the last c operation. */ +memcpy (&upload_table, user_od_table,sizeof (upload_table)); + upload_table.OverDriveTable.Ppt = ppt; +if (ppt) + next_mask |=BIT (PP_OD_FEATURE_PPT_BIT ); +else + next_mask &= ~BIT (PP_OD_FEATURE_PPT_BIT ); + upload_table.OverDriveTable.FeatureCtrlMask = +smu_v13_0_0_filter_od_feature_mask (smu, next_mask); + + ret =smu_v13_0_0_upload_overdrive_table (smu, &upload_table); +if (ret) +return ret; + + table_context->user_od_feature_mask = + upload_table.OverDriveTable.FeatureCtrlMask; + od_table->OverDriveTable.Ppt = ppt; + user_od_table->OverDriveTable.Ppt = ppt; + +return 0 ; +} + static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, int32_t *min,
@@ -1514,41 +1604,30 @@ static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long inp boot_overdrive_table->OverDriveTable.FanLinearPwmPoints[i]; } od_table->OverDriveTable.FanMode =FAN_MODE_AUTO ; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_FAN_CURVE_BIT );break ;case PP_OD_EDIT_ACOUSTIC_LIMIT : od_table->OverDriveTable.AcousticLimitRpmThreshold = boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold; - od_table->OverDriveTable.FanMode =FAN_MODE_AUTO ; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_FAN_CURVE_BIT );break ;case PP_OD_EDIT_ACOUSTIC_TARGET : od_table->OverDriveTable.AcousticTargetRpmThreshold = boot_overdrive_table->OverDriveTable.AcousticTargetRpmThreshold; - od_table->OverDriveTable.FanMode =FAN_MODE_AUTO ; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_FAN_CURVE_BIT );break ;case PP_OD_EDIT_FAN_TARGET_TEMPERATURE : od_table->OverDriveTable.FanTargetTemperature = boot_overdrive_table->OverDriveTable.FanTargetTemperature; - od_table->OverDriveTable.FanMode =FAN_MODE_AUTO ; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_FAN_CURVE_BIT );break ;case PP_OD_EDIT_FAN_MINIMUM_PWM : od_table->OverDriveTable.FanMinimumPwm = boot_overdrive_table->OverDriveTable.FanMinimumPwm; - od_table->OverDriveTable.FanMode =FAN_MODE_AUTO ; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_FAN_CURVE_BIT );break ;case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE : od_table->OverDriveTable.FanZeroRpmEnable = boot_overdrive_table->OverDriveTable.FanZeroRpmEnable; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_ZERO_FAN_BIT );break ;case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP : od_table->OverDriveTable.FanZeroRpmStopTemp = boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp; - od_table->OverDriveTable.FeatureCtrlMask |=BIT (PP_OD_FEATURE_ZERO_FAN_BIT );break ;default :dev_info (adev->dev,"Invalid table index: %ld\n" , input);
@@ -1566,9 +1645,17 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,struct smu_table_context *table_context = &smu->smu_table;OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; +OverDriveTableExternal_t *user_od_table = + (OverDriveTableExternal_t *)table_context->user_overdrive_table; +OverDriveTableExternal_t *boot_od_table = + (OverDriveTableExternal_t *)table_context->boot_overdrive_table; +OverDriveTableExternal_t upload_table; +OverDriveTable_t *od = &od_table->OverDriveTable; +OverDriveTable_t *boot = &boot_od_table->OverDriveTable;struct amdgpu_device *adev = smu->adev;uint32_t offset_of_voltageoffset;int32_t minimum, maximum; +u32 next_mask;int i, ret =0 ;switch (type) {
@@ -1892,36 +1979,41 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, }else {memcpy (od_table, table_context->boot_overdrive_table, -sizeof (OverDriveTableExternal_t)); +sizeof (OverDriveTableExternal_t)); od_table->OverDriveTable.FeatureCtrlMask =0 ; - table_context->user_od_feature_mask =0 ; } fallthrough;case PP_OD_COMMIT_DPM_TABLE : - table_context->user_od_feature_mask = - od_table->OverDriveTable.FeatureCtrlMask; offset_of_voltageoffset = offsetof(OverDriveTable_t , VoltageOffsetPerZoneBoundary); -if (memcmp ((u8 *)od_table + offset_of_voltageoffset, - table_context->user_overdrive_table + offset_of_voltageoffset, -sizeof (OverDriveTableExternal_t) - offset_of_voltageoffset)) { -smu_v13_0_0_dump_od_table (smu, od_table); + next_mask =smu_v13_0_0_filter_od_feature_mask (smu, + table_context->user_od_feature_mask | + od->FeatureCtrlMask); + next_mask =smu_v13_0_0_normalize_feature_mask (od, boot, + next_mask); - ret =smu_v13_0_0_upload_overdrive_table (smu, od_table); +if (memcmp ((u8 *)od_table + offset_of_voltageoffset, + (u8 *)user_od_table + offset_of_voltageoffset, +sizeof (OverDriveTableExternal_t) - offset_of_voltageoffset) || + next_mask != table_context->user_od_feature_mask) { +memcpy (&upload_table, od_table,sizeof (upload_table)); + upload_table.OverDriveTable.FeatureCtrlMask = next_mask; +smu_v13_0_0_dump_od_table (smu, &upload_table); + + ret =smu_v13_0_0_upload_overdrive_table (smu, &upload_table);if (ret) {dev_err (adev->dev,"Failed to upload overdrive table!\n" );return ret; } -memcpy (table_context->user_overdrive_table + offset_of_voltageoffset, + table_context->user_od_feature_mask = next_mask; + od_table->OverDriveTable.FeatureCtrlMask =0 ; +memcpy ((u8 *)user_od_table + offset_of_voltageoffset, (u8 *)od_table + offset_of_voltageoffset,sizeof (OverDriveTableExternal_t) - offset_of_voltageoffset); + user_od_table->OverDriveTable.FeatureCtrlMask =0 ; -if (!memcmp (table_context->user_overdrive_table, - table_context->boot_overdrive_table, -sizeof (OverDriveTableExternal_t))) - smu->user_dpm_profile.user_od = false; -else - smu->user_dpm_profile.user_od = true; + smu->user_dpm_profile.user_od = + !!(next_mask & ~BIT (PP_OD_FEATURE_PPT_BIT )); }break ;
@@ -2184,6 +2276,7 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)memcpy (od_table, boot_od_table,sizeof (OverDriveTableExternal_t)); + od_table->OverDriveTable.FeatureCtrlMask =0 ;/* * For S3/S4/Runpm resume, we need to setup those overdrive tables again,
@@ -2193,6 +2286,7 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)memcpy (user_od_table, boot_od_table,sizeof (OverDriveTableExternal_t)); + user_od_table->OverDriveTable.FeatureCtrlMask =0 ; smu->user_dpm_profile.user_od = false; smu->smu_table.user_od_feature_mask =0 ; }else if (smu->user_dpm_profile.user_od) {
@@ -2231,6 +2325,14 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu) user_od_table_bak.OverDriveTable.FanZeroRpmEnable; user_od_table->OverDriveTable.FanZeroRpmStopTemp = user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp; + user_od_table->OverDriveTable.FanMode = + user_od_table_bak.OverDriveTable.FanMode; + user_od_table->OverDriveTable.FeatureCtrlMask =0 ; + } +if (smu->adev->in_suspend) { + user_od_table->OverDriveTable.Ppt =0 ; + smu->smu_table.user_od_feature_mask &= + ~BIT (PP_OD_FEATURE_PPT_BIT ); }smu_v13_0_0_set_supported_od_feature_mask (smu);
@@ -2243,13 +2345,22 @@ static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu)struct smu_table_context *table_context = &smu->smu_table;OverDriveTableExternal_t *od_table = table_context->overdrive_table;OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table; +OverDriveTableExternal_t upload_table; +u32 next_mask;int res; - user_od_table->OverDriveTable.FeatureCtrlMask = - table_context->user_od_feature_mask; - res =smu_v13_0_0_upload_overdrive_table (smu, user_od_table); - user_od_table->OverDriveTable.FeatureCtrlMask =0 ; -if (res ==0 ) + + next_mask =smu_v13_0_0_filter_od_feature_mask (smu, + table_context->user_od_feature_mask); +memcpy (&upload_table, user_od_table,sizeof (upload_table)); + upload_table.OverDriveTable.FeatureCtrlMask = next_mask; + res =smu_v13_0_0_upload_overdrive_table (smu, &upload_table); +if (res ==0 ) { + table_context->user_od_feature_mask = next_mask; + smu->user_dpm_profile.user_od = + !!(next_mask & ~BIT (PP_OD_FEATURE_PPT_BIT ));memcpy (od_table, user_od_table,sizeof (OverDriveTableExternal_t)); + od_table->OverDriveTable.FeatureCtrlMask =0 ; + }return res; }
@@ -3043,10 +3154,8 @@ static int smu_v13_0_0_set_ppt_limit(struct smu_context *smu,SkuTable_t *skutable = &pptable->SkuTable;uint32_t msg_limit = skutable->MsgLimits.Power [PPT_THROTTLER_PPT0 ][POWER_SOURCE_AC ]; -struct smu_table_context *table_context = &smu->smu_table; -OverDriveTableExternal_t *od_table = - (OverDriveTableExternal_t *)table_context->overdrive_table;OverDriveTableExternal_t current_od_table; +s16 ppt;int ret =0 ;if (limit_type !=SMU_PPT_LIMIT_PPT0 )
@@ -3058,12 +3167,7 @@ static int smu_v13_0_0_set_ppt_limit(struct smu_context *smu,return ret;if (current_od_table.OverDriveTable.Ppt) { - od_table->OverDriveTable.Ppt =0 ; - table_context->user_od_feature_mask &= - ~(1U <<PP_OD_FEATURE_PPT_BIT ); - od_table->OverDriveTable.FeatureCtrlMask = - table_context->user_od_feature_mask; - ret =smu_v13_0_0_upload_overdrive_table (smu, od_table); + ret =smu_v13_0_0_upload_ppt_overdrive_table (smu,0 );if (ret) {dev_err (smu->adev->dev,"Failed to upload overdrive table!\n" );return ret;
@@ -3075,11 +3179,8 @@ static int smu_v13_0_0_set_ppt_limit(struct smu_context *smu,if (ret)return ret; - od_table->OverDriveTable.Ppt = (limit *100 ) / msg_limit -100 ; - table_context->user_od_feature_mask |=1U <<PP_OD_FEATURE_PPT_BIT ; - od_table->OverDriveTable.FeatureCtrlMask = - table_context->user_od_feature_mask; - ret =smu_v13_0_0_upload_overdrive_table (smu, od_table); + ppt = (limit *100 ) / msg_limit -100 ; + ret =smu_v13_0_0_upload_ppt_overdrive_table (smu, ppt);if (ret) {dev_err (smu->adev->dev,"Failed to upload overdrive table!\n" );return ret;
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +146 -47
316 lines not on this page · raw message
Signature · 1 line
2.53.0