drm/amd/pm: update the cached dpm feature status
authorEvan Quan <evan.quan@amd.com>
Mon, 7 Dec 2020 07:50:08 +0000 (15:50 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 11 Jun 2021 20:02:30 +0000 (16:02 -0400)
For some ASICs, the real dpm feature disablement job is handled by
PMFW during baco reset and custom pptable loading. Cached dpm feature
status need to be updated to pair that.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
drivers/gpu/drm/amd/pm/swsmu/smu_internal.h

index 73fca113f3d9ca58823b45d88c5f216f611fea30..0c06c2f6ea43b0cff2413702b28514bef7e3ede7 100644 (file)
@@ -974,7 +974,9 @@ struct pptable_funcs {
         * @disable_all_features_with_exception: Disable all features with
         *                                       exception to those in &mask.
         */
-       int (*disable_all_features_with_exception)(struct smu_context *smu, enum smu_feature_mask mask);
+       int (*disable_all_features_with_exception)(struct smu_context *smu,
+                                                  bool no_hw_disablement,
+                                                  enum smu_feature_mask mask);
 
        /**
         * @notify_display_change: Enable fast memory clock switching.
index b4ea8b233240cc2f0c1ee89d9cee2bc7e6586974..e6673753595c884608184997b70373df8a013d7d 100644 (file)
@@ -1379,7 +1379,9 @@ static int smu_disable_dpms(struct smu_context *smu)
        if (smu->uploading_custom_pp_table &&
            (adev->asic_type >= CHIP_NAVI10) &&
            (adev->asic_type <= CHIP_DIMGREY_CAVEFISH))
-               return 0;
+               return smu_disable_all_features_with_exception(smu,
+                                                              true,
+                                                              SMU_FEATURE_COUNT);
 
        /*
         * For Sienna_Cichlid, PMFW will handle the features disablement properly
@@ -1387,7 +1389,9 @@ static int smu_disable_dpms(struct smu_context *smu)
         */
        if ((adev->asic_type == CHIP_SIENNA_CICHLID) &&
             use_baco)
-               return 0;
+               return smu_disable_all_features_with_exception(smu,
+                                                              true,
+                                                              SMU_FEATURE_BACO_BIT);
 
        /*
         * For gpu reset, runpm and hibernation through BACO,
@@ -1395,6 +1399,7 @@ static int smu_disable_dpms(struct smu_context *smu)
         */
        if (use_baco && smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) {
                ret = smu_disable_all_features_with_exception(smu,
+                                                             false,
                                                              SMU_FEATURE_BACO_BIT);
                if (ret)
                        dev_err(adev->dev, "Failed to disable smu features except BACO.\n");
index c216d64a1ba499690d33e69120a00bef4d2a46e1..e802f9a95f087a55c0fc336588a6242ccc86835a 100644 (file)
@@ -588,23 +588,52 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu,
        return ret;
 }
 
+/**
+ * smu_cmn_disable_all_features_with_exception - disable all dpm features
+ *                                               except this specified by
+ *                                               @mask
+ *
+ * @smu:               smu_context pointer
+ * @no_hw_disablement: whether real dpm disablement should be performed
+ *                     true: update the cache(about dpm enablement state) only
+ *                     false: real dpm disablement plus cache update
+ * @mask:              the dpm feature which should not be disabled
+ *                     SMU_FEATURE_COUNT: no exception, all dpm features
+ *                     to disable
+ *
+ * Returns:
+ * 0 on success or a negative error code on failure.
+ */
 int smu_cmn_disable_all_features_with_exception(struct smu_context *smu,
+                                               bool no_hw_disablement,
                                                enum smu_feature_mask mask)
 {
+       struct smu_feature *feature = &smu->smu_feature;
        uint64_t features_to_disable = U64_MAX;
        int skipped_feature_id;
 
-       skipped_feature_id = smu_cmn_to_asic_specific_index(smu,
-                                                           CMN2ASIC_MAPPING_FEATURE,
-                                                           mask);
-       if (skipped_feature_id < 0)
-               return -EINVAL;
+       if (mask != SMU_FEATURE_COUNT) {
+               skipped_feature_id = smu_cmn_to_asic_specific_index(smu,
+                                                                   CMN2ASIC_MAPPING_FEATURE,
+                                                                   mask);
+               if (skipped_feature_id < 0)
+                       return -EINVAL;
 
-       features_to_disable &= ~(1ULL << skipped_feature_id);
+               features_to_disable &= ~(1ULL << skipped_feature_id);
+       }
 
-       return smu_cmn_feature_update_enable_state(smu,
-                                                  features_to_disable,
-                                                  0);
+       if (no_hw_disablement) {
+               mutex_lock(&feature->mutex);
+               bitmap_andnot(feature->enabled, feature->enabled,
+                               (unsigned long *)(&features_to_disable), SMU_FEATURE_MAX);
+               mutex_unlock(&feature->mutex);
+
+               return 0;
+       } else {
+               return smu_cmn_feature_update_enable_state(smu,
+                                                          features_to_disable,
+                                                          0);
+       }
 }
 
 int smu_cmn_get_smc_version(struct smu_context *smu,
index c57ce2b2cdc64ecc66a03191c4e542957ccb0be7..9add5f16ff562abcde192a84c3529b529da88ea1 100644 (file)
@@ -79,6 +79,7 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu,
                                uint64_t new_mask);
 
 int smu_cmn_disable_all_features_with_exception(struct smu_context *smu,
+                                               bool no_hw_disablement,
                                                enum smu_feature_mask mask);
 
 int smu_cmn_get_smc_version(struct smu_context *smu,
index 68d9464ababc0b4d83d958ef5fce82b1850793fe..b6d2f2edcd6135f7675ec1bc8a93c585df1ed5ce 100644 (file)
@@ -57,7 +57,7 @@
 #define smu_feature_set_allowed_mask(smu)                              smu_ppt_funcs(set_allowed_mask, 0, smu)
 #define smu_feature_get_enabled_mask(smu, mask, num)                   smu_ppt_funcs(get_enabled_mask, 0, smu, mask, num)
 #define smu_feature_is_enabled(smu, mask)                              smu_ppt_funcs(feature_is_enabled, 0, smu, mask)
-#define smu_disable_all_features_with_exception(smu, mask)             smu_ppt_funcs(disable_all_features_with_exception, 0, smu, mask)
+#define smu_disable_all_features_with_exception(smu, no_hw_disablement, mask)          smu_ppt_funcs(disable_all_features_with_exception, 0, smu, no_hw_disablement, mask)
 #define smu_is_dpm_running(smu)                                                smu_ppt_funcs(is_dpm_running, 0 , smu)
 #define smu_notify_display_change(smu)                                 smu_ppt_funcs(notify_display_change, 0, smu)
 #define smu_populate_umd_state_clk(smu)                                        smu_ppt_funcs(populate_umd_state_clk, 0, smu)