]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/amd/powerplay/smu_v11_0.c
drm/amdgpu/smu11: add support for navi14
[linux.git] / drivers / gpu / drm / amd / powerplay / smu_v11_0.c
index 96719703d7b675ecd4d8d64f7b09cde6dc64dfa8..0e9eead6ad29b6e9b4a7595bf6672c6df7ba373d 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "pp_debug.h"
 #include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "pp_debug.h"
 #include "amdgpu.h"
 #include "amdgpu_smu.h"
 #include "atomfirmware.h"
 #include "amdgpu_atomfirmware.h"
 #include "smu_v11_0.h"
-#include "smu_11_0_driver_if.h"
 #include "soc15_common.h"
 #include "atom.h"
 #include "vega20_ppt.h"
 #include "navi10_ppt.h"
-#include "pp_thermal.h"
 
 #include "asic_reg/thm/thm_11_0_2_offset.h"
 #include "asic_reg/thm/thm_11_0_2_sh_mask.h"
 #include "asic_reg/mp/mp_11_0_offset.h"
 #include "asic_reg/mp/mp_11_0_sh_mask.h"
 #include "asic_reg/nbio/nbio_7_4_offset.h"
+#include "asic_reg/nbio/nbio_7_4_sh_mask.h"
 #include "asic_reg/smuio/smuio_11_0_0_offset.h"
 #include "asic_reg/smuio/smuio_11_0_0_sh_mask.h"
 
 MODULE_FIRMWARE("amdgpu/vega20_smc.bin");
 MODULE_FIRMWARE("amdgpu/navi10_smc.bin");
+MODULE_FIRMWARE("amdgpu/navi14_smc.bin");
 
-#define SMU11_TOOL_SIZE                0x19000
-#define SMU11_THERMAL_MINIMUM_ALERT_TEMP      0
-#define SMU11_THERMAL_MAXIMUM_ALERT_TEMP      255
-
-#define SMU11_TEMPERATURE_UNITS_PER_CENTIGRADES 1000
 #define SMU11_VOLTAGE_SCALE 4
 
-#define SMC_DPM_FEATURE (FEATURE_DPM_PREFETCHER_MASK | \
-                        FEATURE_DPM_GFXCLK_MASK | \
-                        FEATURE_DPM_UCLK_MASK | \
-                        FEATURE_DPM_SOCCLK_MASK | \
-                        FEATURE_DPM_UVD_MASK | \
-                        FEATURE_DPM_VCE_MASK | \
-                        FEATURE_DPM_MP0CLK_MASK | \
-                        FEATURE_DPM_LINK_MASK | \
-                        FEATURE_DPM_DCEFCLK_MASK)
-
 static int smu_v11_0_send_msg_without_waiting(struct smu_context *smu,
                                              uint16_t msg)
 {
@@ -81,9 +69,9 @@ static int smu_v11_0_read_arg(struct smu_context *smu, uint32_t *arg)
 static int smu_v11_0_wait_for_response(struct smu_context *smu)
 {
        struct amdgpu_device *adev = smu->adev;
-       uint32_t cur_value, i;
+       uint32_t cur_value, i, timeout = adev->usec_timeout * 10;
 
-       for (i = 0; i < adev->usec_timeout; i++) {
+       for (i = 0; i < timeout; i++) {
                cur_value = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
                if ((cur_value & MP1_C2PMSG_90__CONTENT_MASK) != 0)
                        break;
@@ -91,7 +79,7 @@ static int smu_v11_0_wait_for_response(struct smu_context *smu)
        }
 
        /* timeout means wrong logic */
-       if (i == adev->usec_timeout)
+       if (i == timeout)
                return -ETIME;
 
        return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90) == 0x1 ? 0 : -EIO;
@@ -153,18 +141,6 @@ smu_v11_0_send_msg_with_param(struct smu_context *smu, uint16_t msg,
        return ret;
 }
 
-static void smu_v11_0_init_smu_ext_microcode(struct smu_context *smu)
-{
-       struct amdgpu_device *adev = smu->adev;
-       const struct smc_firmware_header_v2_0 *v2;
-
-       v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data;
-
-       smu->ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes);
-       smu->ppt_size_bytes = le32_to_cpu(v2->ppt_size_bytes);
-       smu->ppt_start_addr = (uint8_t *)v2 + smu->ppt_offset_bytes;
-}
-
 static int smu_v11_0_init_microcode(struct smu_context *smu)
 {
        struct amdgpu_device *adev = smu->adev;
@@ -174,7 +150,6 @@ static int smu_v11_0_init_microcode(struct smu_context *smu)
        const struct smc_firmware_header_v1_0 *hdr;
        const struct common_firmware_header *header;
        struct amdgpu_firmware_info *ucode = NULL;
-       uint32_t version_major, version_minor;
 
        switch (adev->asic_type) {
        case CHIP_VEGA20:
@@ -183,6 +158,9 @@ static int smu_v11_0_init_microcode(struct smu_context *smu)
        case CHIP_NAVI10:
                chip_name = "navi10";
                break;
+       case CHIP_NAVI14:
+               chip_name = "navi14";
+               break;
        default:
                BUG();
        }
@@ -200,11 +178,6 @@ static int smu_v11_0_init_microcode(struct smu_context *smu)
        amdgpu_ucode_print_smc_hdr(&hdr->header);
        adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
 
-       version_major = le16_to_cpu(hdr->header.header_version_major);
-       version_minor = le16_to_cpu(hdr->header.header_version_minor);
-       if (version_major == 2 && version_minor == 0)
-               smu_v11_0_init_smu_ext_microcode(smu); /* with soft pptable */
-
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
                ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
                ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
@@ -292,33 +265,100 @@ static int smu_v11_0_check_fw_version(struct smu_context *smu)
        smu_minor = (smu_version >> 8) & 0xff;
        smu_debug = (smu_version >> 0) & 0xff;
 
-       pr_info("SMU Driver IF Version = 0x%08x, SMU FW Version = 0x%08x (%d.%d.%d)\n",
-               if_version, smu_version, smu_major, smu_minor, smu_debug);
-
+       /*
+        * 1. if_version mismatch is not critical as our fw is designed
+        * to be backward compatible.
+        * 2. New fw usually brings some optimizations. But that's visible
+        * only on the paired driver.
+        * Considering above, we just leave user a warning message instead
+        * of halt driver loading.
+        */
        if (if_version != smu->smc_if_version) {
-               pr_err("SMU driver if version not matched\n");
-               ret = -EINVAL;
+               pr_info("smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
+                       "smu fw version = 0x%08x (%d.%d.%d)\n",
+                       smu->smc_if_version, if_version,
+                       smu_version, smu_major, smu_minor, smu_debug);
+               pr_warn("SMU driver if version not matched\n");
        }
 
        return ret;
 }
 
-static int smu_v11_0_read_pptable_from_vbios(struct smu_context *smu)
+static int smu_v11_0_set_pptable_v2_0(struct smu_context *smu, void **table, uint32_t *size)
+{
+       struct amdgpu_device *adev = smu->adev;
+       uint32_t ppt_offset_bytes;
+       const struct smc_firmware_header_v2_0 *v2;
+
+       v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data;
+
+       ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes);
+       *size = le32_to_cpu(v2->ppt_size_bytes);
+       *table = (uint8_t *)v2 + ppt_offset_bytes;
+
+       return 0;
+}
+
+static int smu_v11_0_set_pptable_v2_1(struct smu_context *smu, void **table, uint32_t *size, uint32_t pptable_id)
+{
+       struct amdgpu_device *adev = smu->adev;
+       const struct smc_firmware_header_v2_1 *v2_1;
+       struct smc_soft_pptable_entry *entries;
+       uint32_t pptable_count = 0;
+       int i = 0;
+
+       v2_1 = (const struct smc_firmware_header_v2_1 *) adev->pm.fw->data;
+       entries = (struct smc_soft_pptable_entry *)
+               ((uint8_t *)v2_1 + le32_to_cpu(v2_1->pptable_entry_offset));
+       pptable_count = le32_to_cpu(v2_1->pptable_count);
+       for (i = 0; i < pptable_count; i++) {
+               if (le32_to_cpu(entries[i].id) == pptable_id) {
+                       *table = ((uint8_t *)v2_1 + le32_to_cpu(entries[i].ppt_offset_bytes));
+                       *size = le32_to_cpu(entries[i].ppt_size_bytes);
+                       break;
+               }
+       }
+
+       if (i == pptable_count)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int smu_v11_0_setup_pptable(struct smu_context *smu)
 {
+       struct amdgpu_device *adev = smu->adev;
+       const struct smc_firmware_header_v1_0 *hdr;
        int ret, index;
-       uint16_t size;
+       uint32_t size;
        uint8_t frev, crev;
        void *table;
+       uint16_t version_major, version_minor;
+
+       hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
+       version_major = le16_to_cpu(hdr->header.header_version_major);
+       version_minor = le16_to_cpu(hdr->header.header_version_minor);
+       if (version_major == 2 && smu->smu_table.boot_values.pp_table_id > 0) {
+               switch (version_minor) {
+               case 0:
+                       ret = smu_v11_0_set_pptable_v2_0(smu, &table, &size);
+                       break;
+               case 1:
+                       ret = smu_v11_0_set_pptable_v2_1(smu, &table, &size,
+                                                        smu->smu_table.boot_values.pp_table_id);
+                       break;
+               default:
+                       ret = -EINVAL;
+                       break;
+               }
+               if (ret)
+                       return ret;
 
-       if (smu->smu_table.boot_values.pp_table_id > 0 && smu->ppt_start_addr) {
-               /* load soft pptable */
-               table = (void *)smu->ppt_start_addr;
-               size= smu->ppt_size_bytes;
        } else {
                index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
                                                    powerplayinfo);
 
-               ret = smu_get_atom_data_table(smu, index, &size, &frev, &crev,
+               ret = smu_get_atom_data_table(smu, index, (uint16_t *)&size, &frev, &crev,
                                              (uint8_t **)&table);
                if (ret)
                        return ret;
@@ -368,30 +408,19 @@ static int smu_v11_0_init_smc_tables(struct smu_context *smu)
        struct smu_table *tables = NULL;
        int ret = 0;
 
-       if (smu_table->tables || smu_table->table_count != 0)
+       if (smu_table->tables || smu_table->table_count == 0)
                return -EINVAL;
 
-       tables = kcalloc(TABLE_COUNT, sizeof(struct smu_table), GFP_KERNEL);
+       tables = kcalloc(SMU_TABLE_COUNT, sizeof(struct smu_table),
+                        GFP_KERNEL);
        if (!tables)
                return -ENOMEM;
 
        smu_table->tables = tables;
-       smu_table->table_count = TABLE_COUNT;
-
-       SMU_TABLE_INIT(tables, TABLE_PPTABLE, sizeof(PPTable_t),
-                      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
-       SMU_TABLE_INIT(tables, TABLE_WATERMARKS, sizeof(Watermarks_t),
-                      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
-       SMU_TABLE_INIT(tables, TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
-                      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
-       SMU_TABLE_INIT(tables, TABLE_OVERDRIVE, sizeof(OverDriveTable_t),
-                      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
-       SMU_TABLE_INIT(tables, TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE, PAGE_SIZE,
-                      AMDGPU_GEM_DOMAIN_VRAM);
-       SMU_TABLE_INIT(tables, TABLE_ACTIVITY_MONITOR_COEFF,
-                      sizeof(DpmActivityMonitorCoeffInt_t),
-                      PAGE_SIZE,
-                      AMDGPU_GEM_DOMAIN_VRAM);
+
+       ret = smu_tables_init(smu, tables);
+       if (ret)
+               return ret;
 
        ret = smu_v11_0_init_dpm_context(smu);
        if (ret)
@@ -409,8 +438,11 @@ static int smu_v11_0_fini_smc_tables(struct smu_context *smu)
                return -EINVAL;
 
        kfree(smu_table->tables);
+       kfree(smu_table->metrics_table);
        smu_table->tables = NULL;
        smu_table->table_count = 0;
+       smu_table->metrics_table = NULL;
+       smu_table->metrics_time = 0;
 
        ret = smu_v11_0_fini_dpm_context(smu);
        if (ret)
@@ -433,13 +465,6 @@ static int smu_v11_0_init_power(struct smu_context *smu)
                return -ENOMEM;
        smu_power->power_context_size = sizeof(struct smu_11_0_dpm_context);
 
-       smu->metrics_time = 0;
-       smu->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
-       if (!smu->metrics_table) {
-               kfree(smu_power->power_context);
-               return -ENOMEM;
-       }
-
        return 0;
 }
 
@@ -452,9 +477,7 @@ static int smu_v11_0_fini_power(struct smu_context *smu)
        if (!smu_power->power_context || smu_power->power_context_size == 0)
                return -EINVAL;
 
-       kfree(smu->metrics_table);
        kfree(smu_power->power_context);
-       smu->metrics_table = NULL;
        smu_power->power_context = NULL;
        smu_power->power_context_size = 0;
 
@@ -657,11 +680,12 @@ static int smu_v11_0_parse_pptable(struct smu_context *smu)
        int ret;
 
        struct smu_table_context *table_context = &smu->smu_table;
+       struct smu_table *table = &table_context->tables[SMU_TABLE_PPTABLE];
 
        if (table_context->driver_pptable)
                return -EINVAL;
 
-       table_context->driver_pptable = kzalloc(sizeof(PPTable_t), GFP_KERNEL);
+       table_context->driver_pptable = kzalloc(table->size, GFP_KERNEL);
 
        if (!table_context->driver_pptable)
                return -ENOMEM;
@@ -689,15 +713,29 @@ static int smu_v11_0_write_pptable(struct smu_context *smu)
        struct smu_table_context *table_context = &smu->smu_table;
        int ret = 0;
 
-       ret = smu_update_table(smu, TABLE_PPTABLE, table_context->driver_pptable, true);
+       ret = smu_update_table(smu, SMU_TABLE_PPTABLE, 0,
+                              table_context->driver_pptable, true);
 
        return ret;
 }
 
 static int smu_v11_0_write_watermarks_table(struct smu_context *smu)
 {
-       return smu_update_table(smu, TABLE_WATERMARKS,
-                               smu->smu_table.tables[TABLE_WATERMARKS].cpu_addr, true);
+       int ret = 0;
+       struct smu_table_context *smu_table = &smu->smu_table;
+       struct smu_table *table = NULL;
+
+       table = &smu_table->tables[SMU_TABLE_WATERMARKS];
+       if (!table)
+               return -EINVAL;
+
+       if (!table->cpu_addr)
+               return -EINVAL;
+
+       ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr,
+                               true);
+
+       return ret;
 }
 
 static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk)
@@ -728,7 +766,7 @@ static int smu_v11_0_set_min_dcef_deep_sleep(struct smu_context *smu)
 static int smu_v11_0_set_tool_table_location(struct smu_context *smu)
 {
        int ret = 0;
-       struct smu_table *tool_table = &smu->smu_table.tables[TABLE_PMSTATUSLOG];
+       struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG];
 
        if (tool_table->mc_address) {
                ret = smu_send_smc_msg_with_param(smu,
@@ -743,13 +781,14 @@ static int smu_v11_0_set_tool_table_location(struct smu_context *smu)
        return ret;
 }
 
-static int smu_v11_0_init_display(struct smu_context *smu)
+static int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count)
 {
        int ret = 0;
 
        if (!smu->pm_enabled)
                return ret;
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 0);
+
+       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, count);
        return ret;
 }
 
@@ -848,17 +887,6 @@ static int smu_v11_0_get_enabled_mask(struct smu_context *smu,
        return ret;
 }
 
-static bool smu_v11_0_is_dpm_running(struct smu_context *smu)
-{
-       int ret = 0;
-       uint32_t feature_mask[2];
-       unsigned long feature_enabled;
-       ret = smu_v11_0_get_enabled_mask(smu, feature_mask, 2);
-       feature_enabled = (unsigned long)((uint64_t)feature_mask[0] |
-                          ((uint64_t)feature_mask[1] << 32));
-       return !!(feature_enabled & SMC_DPM_FEATURE);
-}
-
 static int smu_v11_0_system_features_control(struct smu_context *smu,
                                             bool en)
 {
@@ -891,22 +919,23 @@ static int smu_v11_0_notify_display_change(struct smu_context *smu)
 
        if (!smu->pm_enabled)
                return ret;
-       if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT))
-           ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1);
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
+           smu->adev->gmc.vram_type == AMDGPU_VRAM_TYPE_HBM)
+               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1);
 
        return ret;
 }
 
 static int
 smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
-                                   PPCLK_e clock_select)
+                                   enum smu_clk_type clock_select)
 {
        int ret = 0;
 
        if (!smu->pm_enabled)
                return ret;
        ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
-                                         clock_select << 16);
+                                         smu_clk_get_index(smu, clock_select) << 16);
        if (ret) {
                pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
                return ret;
@@ -921,7 +950,7 @@ smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
 
        /* if DC limit is zero, return AC limit */
        ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
-                                         clock_select << 16);
+                                         smu_clk_get_index(smu, clock_select) << 16);
        if (ret) {
                pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
                return ret;
@@ -948,10 +977,10 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
        max_sustainable_clocks->phy_clock = 0xFFFFFFFF;
        max_sustainable_clocks->pixel_clock = 0xFFFFFFFF;
 
-       if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->uclock),
-                                                         PPCLK_UCLK);
+                                                         SMU_UCLK);
                if (ret) {
                        pr_err("[%s] failed to get max UCLK from SMC!",
                               __func__);
@@ -959,10 +988,10 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
                }
        }
 
-       if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->soc_clock),
-                                                         PPCLK_SOCCLK);
+                                                         SMU_SOCCLK);
                if (ret) {
                        pr_err("[%s] failed to get max SOCCLK from SMC!",
                               __func__);
@@ -970,10 +999,10 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
                }
        }
 
-       if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->dcef_clock),
-                                                         PPCLK_DCEFCLK);
+                                                         SMU_DCEFCLK);
                if (ret) {
                        pr_err("[%s] failed to get max DCEFCLK from SMC!",
                               __func__);
@@ -982,7 +1011,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
 
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->display_clock),
-                                                         PPCLK_DISPCLK);
+                                                         SMU_DISPCLK);
                if (ret) {
                        pr_err("[%s] failed to get max DISPCLK from SMC!",
                               __func__);
@@ -990,7 +1019,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
                }
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->phy_clock),
-                                                         PPCLK_PHYCLK);
+                                                         SMU_PHYCLK);
                if (ret) {
                        pr_err("[%s] failed to get max PHYCLK from SMC!",
                               __func__);
@@ -998,7 +1027,7 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
                }
                ret = smu_v11_0_get_max_sustainable_clock(smu,
                                                          &(max_sustainable_clocks->pixel_clock),
-                                                         PPCLK_PIXCLK);
+                                                         SMU_PIXCLK);
                if (ret) {
                        pr_err("[%s] failed to get max PIXCLK from SMC!",
                               __func__);
@@ -1028,7 +1057,7 @@ static int smu_v11_0_get_power_limit(struct smu_context *smu,
                mutex_unlock(&smu->mutex);
        } else {
                ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetPptLimit,
-                                                 POWER_SOURCE_AC << 16);
+                       smu_power_get_index(smu, SMU_POWER_SOURCE_AC) << 16);
                if (ret) {
                        pr_err("[%s] get PPT limit failed!", __func__);
                        return ret;
@@ -1055,7 +1084,7 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
                max_power_limit /= 100;
        }
 
-       if (smu_feature_is_enabled(smu, FEATURE_PPT_BIT))
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT))
                ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, n);
        if (ret) {
                pr_err("[%s] Set power limit Failed!", __func__);
@@ -1065,22 +1094,29 @@ static int smu_v11_0_set_power_limit(struct smu_context *smu, uint32_t n)
        return ret;
 }
 
-static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, uint32_t clk_id, uint32_t *value)
+static int smu_v11_0_get_current_clk_freq(struct smu_context *smu,
+                                         enum smu_clk_type clk_id,
+                                         uint32_t *value)
 {
        int ret = 0;
-       uint32_t freq;
+       uint32_t freq = 0;
 
-       if (clk_id >= PPCLK_COUNT || !value)
+       if (clk_id >= SMU_CLK_COUNT || !value)
                return -EINVAL;
 
-       ret = smu_send_smc_msg_with_param(smu,
-                       SMU_MSG_GetDpmClockFreq, (clk_id << 16));
-       if (ret)
-               return ret;
+       /* if don't has GetDpmClockFreq Message, try get current clock by SmuMetrics_t */
+       if (smu_msg_get_index(smu, SMU_MSG_GetDpmClockFreq) == 0)
+               ret =  smu_get_current_clk_freq_by_table(smu, clk_id, &freq);
+       else {
+               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDpmClockFreq,
+                                                 (smu_clk_get_index(smu, clk_id) << 16));
+               if (ret)
+                       return ret;
 
-       ret = smu_read_smc_arg(smu, &freq);
-       if (ret)
-               return ret;
+               ret = smu_read_smc_arg(smu, &freq);
+               if (ret)
+                       return ret;
+       }
 
        freq *= 100;
        *value = freq;
@@ -1088,38 +1124,19 @@ static int smu_v11_0_get_current_clk_freq(struct smu_context *smu, uint32_t clk_
        return ret;
 }
 
-static int smu_v11_0_get_thermal_range(struct smu_context *smu,
-                               struct PP_TemperatureRange *range)
-{
-       PPTable_t *pptable = smu->smu_table.driver_pptable;
-       memcpy(range, &SMU7ThermalWithDelayPolicy[0], sizeof(struct PP_TemperatureRange));
-
-       range->max = pptable->TedgeLimit *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       range->hotspot_crit_max = pptable->ThotspotLimit *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       range->mem_crit_max = pptable->ThbmLimit *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       range->mem_emergency_max = (pptable->ThbmLimit + CTF_OFFSET_HBM)*
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-
-       return 0;
-}
-
 static int smu_v11_0_set_thermal_range(struct smu_context *smu,
-                       struct PP_TemperatureRange *range)
+                                      struct smu_temperature_range *range)
 {
        struct amdgpu_device *adev = smu->adev;
-       int low = SMU11_THERMAL_MINIMUM_ALERT_TEMP *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-       int high = SMU11_THERMAL_MAXIMUM_ALERT_TEMP *
-               PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+       int low = SMU_THERMAL_MINIMUM_ALERT_TEMP *
+               SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
+       int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP *
+               SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
        uint32_t val;
 
+       if (!range)
+               return -EINVAL;
+
        if (low < range->min)
                low = range->min;
        if (high > range->max)
@@ -1131,8 +1148,10 @@ static int smu_v11_0_set_thermal_range(struct smu_context *smu,
        val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
        val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
        val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
-       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
-       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES));
+       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
+       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
+       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES));
+       val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES));
        val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
 
        WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
@@ -1154,22 +1173,10 @@ static int smu_v11_0_enable_thermal_alert(struct smu_context *smu)
        return 0;
 }
 
-static int smu_v11_0_set_thermal_fan_table(struct smu_context *smu)
-{
-       int ret;
-       struct smu_table_context *table_context = &smu->smu_table;
-       PPTable_t *pptable = table_context->driver_pptable;
-
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetFanTemperatureTarget,
-                       (uint32_t)pptable->FanTargetTemperature);
-
-       return ret;
-}
-
 static int smu_v11_0_start_thermal_control(struct smu_context *smu)
 {
        int ret = 0;
-       struct PP_TemperatureRange range = {
+       struct smu_temperature_range range = {
                TEMP_RANGE_MIN,
                TEMP_RANGE_MAX,
                TEMP_RANGE_MAX,
@@ -1183,7 +1190,7 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
 
        if (!smu->pm_enabled)
                return ret;
-       smu_v11_0_get_thermal_range(smu, &range);
+       ret = smu_get_thermal_temperature_range(smu, &range);
 
        if (smu->smu_table.thermal_controller_type) {
                ret = smu_v11_0_set_thermal_range(smu, &range);
@@ -1193,7 +1200,8 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
                ret = smu_v11_0_enable_thermal_alert(smu);
                if (ret)
                        return ret;
-               ret = smu_v11_0_set_thermal_fan_table(smu);
+
+               ret = smu_set_thermal_fan_table(smu);
                if (ret)
                        return ret;
        }
@@ -1211,115 +1219,6 @@ static int smu_v11_0_start_thermal_control(struct smu_context *smu)
        return ret;
 }
 
-static int smu_v11_0_get_metrics_table(struct smu_context *smu,
-               SmuMetrics_t *metrics_table)
-{
-       int ret = 0;
-
-       if (!smu->metrics_time || time_after(jiffies, smu->metrics_time + HZ / 1000)) {
-               ret = smu_update_table(smu, TABLE_SMU_METRICS,
-                               (void *)metrics_table, false);
-               if (ret) {
-                       pr_info("Failed to export SMU metrics table!\n");
-                       return ret;
-               }
-               memcpy(smu->metrics_table, metrics_table, sizeof(SmuMetrics_t));
-               smu->metrics_time = jiffies;
-       } else
-               memcpy(metrics_table, smu->metrics_table, sizeof(SmuMetrics_t));
-
-       return ret;
-}
-
-static int smu_v11_0_get_current_activity_percent(struct smu_context *smu,
-                                                 enum amd_pp_sensors sensor,
-                                                 uint32_t *value)
-{
-       int ret = 0;
-       SmuMetrics_t metrics;
-
-       if (!value)
-               return -EINVAL;
-
-       ret = smu_v11_0_get_metrics_table(smu, &metrics);
-       if (ret)
-               return ret;
-
-       switch (sensor) {
-       case AMDGPU_PP_SENSOR_GPU_LOAD:
-               *value = metrics.AverageGfxActivity;
-               break;
-       case AMDGPU_PP_SENSOR_MEM_LOAD:
-               *value = metrics.AverageUclkActivity;
-               break;
-       default:
-               pr_err("Invalid sensor for retrieving clock activity\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int smu_v11_0_thermal_get_temperature(struct smu_context *smu,
-                                            enum amd_pp_sensors sensor,
-                                            uint32_t *value)
-{
-       struct amdgpu_device *adev = smu->adev;
-       SmuMetrics_t metrics;
-       uint32_t temp = 0;
-       int ret = 0;
-
-       if (!value)
-               return -EINVAL;
-
-       ret = smu_v11_0_get_metrics_table(smu, &metrics);
-       if (ret)
-               return ret;
-
-       switch (sensor) {
-       case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
-               temp = RREG32_SOC15(THM, 0, mmCG_MULT_THERMAL_STATUS);
-               temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
-                               CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
-
-               temp = temp & 0x1ff;
-               temp *= SMU11_TEMPERATURE_UNITS_PER_CENTIGRADES;
-
-               *value = temp;
-               break;
-       case AMDGPU_PP_SENSOR_EDGE_TEMP:
-               *value = metrics.TemperatureEdge *
-                       PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-               break;
-       case AMDGPU_PP_SENSOR_MEM_TEMP:
-               *value = metrics.TemperatureHBM *
-                       PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
-               break;
-       default:
-               pr_err("Invalid sensor for retrieving temp\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int smu_v11_0_get_gpu_power(struct smu_context *smu, uint32_t *value)
-{
-       int ret = 0;
-       SmuMetrics_t metrics;
-
-       if (!value)
-               return -EINVAL;
-
-       ret = smu_v11_0_get_metrics_table(smu, &metrics);
-       if (ret)
-               return ret;
-
-       *value = metrics.CurrSocketPower << 8;
-
-       return 0;
-}
-
 static uint16_t convert_to_vddc(uint8_t vid)
 {
        return (uint16_t) ((6200 - (vid * 25)) / SMU11_VOLTAGE_SCALE);
@@ -1348,60 +1247,33 @@ static int smu_v11_0_read_sensor(struct smu_context *smu,
                                 enum amd_pp_sensors sensor,
                                 void *data, uint32_t *size)
 {
-       struct smu_table_context *table_context = &smu->smu_table;
-       PPTable_t *pptable = table_context->driver_pptable;
        int ret = 0;
        switch (sensor) {
-       case AMDGPU_PP_SENSOR_GPU_LOAD:
-       case AMDGPU_PP_SENSOR_MEM_LOAD:
-               ret = smu_v11_0_get_current_activity_percent(smu,
-                                                            sensor,
-                                                            (uint32_t *)data);
-               *size = 4;
-               break;
        case AMDGPU_PP_SENSOR_GFX_MCLK:
-               ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, (uint32_t *)data);
+               ret = smu_get_current_clk_freq(smu, SMU_UCLK, (uint32_t *)data);
                *size = 4;
                break;
        case AMDGPU_PP_SENSOR_GFX_SCLK:
-               ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, (uint32_t *)data);
-               *size = 4;
-               break;
-       case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
-       case AMDGPU_PP_SENSOR_EDGE_TEMP:
-       case AMDGPU_PP_SENSOR_MEM_TEMP:
-               ret = smu_v11_0_thermal_get_temperature(smu, sensor, (uint32_t *)data);
-               *size = 4;
-               break;
-       case AMDGPU_PP_SENSOR_GPU_POWER:
-               ret = smu_v11_0_get_gpu_power(smu, (uint32_t *)data);
+               ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, (uint32_t *)data);
                *size = 4;
                break;
        case AMDGPU_PP_SENSOR_VDDGFX:
                ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data);
                *size = 4;
                break;
-       case AMDGPU_PP_SENSOR_UVD_POWER:
-               *(uint32_t *)data = smu_feature_is_enabled(smu, FEATURE_DPM_UVD_BIT) ? 1 : 0;
-               *size = 4;
-               break;
-       case AMDGPU_PP_SENSOR_VCE_POWER:
-               *(uint32_t *)data = smu_feature_is_enabled(smu, FEATURE_DPM_VCE_BIT) ? 1 : 0;
-               *size = 4;
-               break;
        case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
                *(uint32_t *)data = 0;
                *size = 4;
                break;
-       case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
-               *(uint32_t *)data = pptable->FanMaximumRpm;
-               *size = 4;
-               break;
        default:
                ret = smu_common_read_sensor(smu, sensor, data, size);
                break;
        }
 
+       /* try get sensor data by asic */
+       if (ret)
+               ret = smu_asic_read_sensor(smu, sensor, data, size);
+
        if (ret)
                *size = 0;
 
@@ -1415,24 +1287,29 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
 {
        enum amd_pp_clock_type clk_type = clock_req->clock_type;
        int ret = 0;
-       PPCLK_e clk_select = 0;
+       enum smu_clk_type clk_select = 0;
        uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
 
        if (!smu->pm_enabled)
                return -EINVAL;
-       if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
+
+       if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) ||
+               smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
                switch (clk_type) {
                case amd_pp_dcef_clock:
-                       clk_select = PPCLK_DCEFCLK;
+                       clk_select = SMU_DCEFCLK;
                        break;
                case amd_pp_disp_clock:
-                       clk_select = PPCLK_DISPCLK;
+                       clk_select = SMU_DISPCLK;
                        break;
                case amd_pp_pixel_clock:
-                       clk_select = PPCLK_PIXCLK;
+                       clk_select = SMU_PIXCLK;
                        break;
                case amd_pp_phy_clock:
-                       clk_select = PPCLK_PHYCLK;
+                       clk_select = SMU_PHYCLK;
+                       break;
+               case amd_pp_mem_clock:
+                       clk_select = SMU_UCLK;
                        break;
                default:
                        pr_info("[%s] Invalid Clock Type!", __func__);
@@ -1443,86 +1320,29 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
                if (ret)
                        goto failed;
 
+               mutex_lock(&smu->mutex);
                ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
-                                                 (clk_select << 16) | clk_freq);
+                       (smu_clk_get_index(smu, clk_select) << 16) | clk_freq);
+               mutex_unlock(&smu->mutex);
        }
 
 failed:
        return ret;
 }
 
-static int smu_v11_0_set_watermarks_table(struct smu_context *smu,
-                                         Watermarks_t *table, struct
-                                         dm_pp_wm_sets_with_clock_ranges_soc15
-                                         *clock_ranges)
-{
-       int i;
-
-       if (!table || !clock_ranges)
-               return -EINVAL;
-
-       if (clock_ranges->num_wm_dmif_sets > 4 ||
-           clock_ranges->num_wm_mcif_sets > 4)
-                return -EINVAL;
-
-        for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
-               table->WatermarkRow[1][i].MinClock =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz /
-                       1000));
-               table->WatermarkRow[1][i].MaxClock =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz /
-                       1000));
-               table->WatermarkRow[1][i].MinUclk =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz /
-                       1000));
-               table->WatermarkRow[1][i].MaxUclk =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz /
-                       1000));
-               table->WatermarkRow[1][i].WmSetting = (uint8_t)
-                               clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
-        }
-
-       for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
-               table->WatermarkRow[0][i].MinClock =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz /
-                       1000));
-               table->WatermarkRow[0][i].MaxClock =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz /
-                       1000));
-               table->WatermarkRow[0][i].MinUclk =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz /
-                       1000));
-               table->WatermarkRow[0][i].MaxUclk =
-                       cpu_to_le16((uint16_t)
-                       (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz /
-                       1000));
-               table->WatermarkRow[0][i].WmSetting = (uint8_t)
-                               clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
-        }
-
-       return 0;
-}
-
 static int
 smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
                                          dm_pp_wm_sets_with_clock_ranges_soc15
                                          *clock_ranges)
 {
        int ret = 0;
-       struct smu_table *watermarks = &smu->smu_table.tables[TABLE_WATERMARKS];
-       Watermarks_t *table = watermarks->cpu_addr;
+       struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS];
+       void *table = watermarks->cpu_addr;
 
        if (!smu->disable_watermark &&
-           smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT) &&
-           smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
-               smu_v11_0_set_watermarks_table(smu, table, clock_ranges);
+           smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
+           smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
+               smu_set_watermarks_table(smu, table, clock_ranges);
                smu->watermarks_bitmap |= WATERMARKS_EXIST;
                smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
        }
@@ -1530,393 +1350,31 @@ smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
        return ret;
 }
 
-static int smu_v11_0_get_clock_ranges(struct smu_context *smu,
-                                     uint32_t *clock,
-                                     PPCLK_e clock_select,
-                                     bool max)
+static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
 {
-       int ret;
-       *clock = 0;
-       if (max) {
-               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
-                                           (clock_select << 16));
-               if (ret) {
-                       pr_err("[GetClockRanges] Failed to get max clock from SMC!\n");
-                       return ret;
-               }
-               smu_read_smc_arg(smu, clock);
-       } else {
-               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq,
-                                           (clock_select << 16));
-               if (ret) {
-                       pr_err("[GetClockRanges] Failed to get min clock from SMC!\n");
-                       return ret;
-               }
-               smu_read_smc_arg(smu, clock);
-       }
-
-       return 0;
-}
-
-static uint32_t smu_v11_0_dpm_get_sclk(struct smu_context *smu, bool low)
-{
-       uint32_t gfx_clk;
-       int ret;
-
-       if (!smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) {
-               pr_err("[GetSclks]: gfxclk dpm not enabled!\n");
-               return -EPERM;
-       }
-
-       if (low) {
-               ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, false);
-               if (ret) {
-                       pr_err("[GetSclks]: fail to get min PPCLK_GFXCLK\n");
-                       return ret;
-               }
-       } else {
-               ret = smu_v11_0_get_clock_ranges(smu, &gfx_clk, PPCLK_GFXCLK, true);
-               if (ret) {
-                       pr_err("[GetSclks]: fail to get max PPCLK_GFXCLK\n");
-                       return ret;
-               }
-       }
-
-       return (gfx_clk * 100);
-}
-
-static uint32_t smu_v11_0_dpm_get_mclk(struct smu_context *smu, bool low)
-{
-       uint32_t mem_clk;
-       int ret;
-
-       if (!smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
-               pr_err("[GetMclks]: memclk dpm not enabled!\n");
-               return -EPERM;
-       }
-
-       if (low) {
-               ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_UCLK, false);
-               if (ret) {
-                       pr_err("[GetMclks]: fail to get min PPCLK_UCLK\n");
-                       return ret;
-               }
-       } else {
-               ret = smu_v11_0_get_clock_ranges(smu, &mem_clk, PPCLK_GFXCLK, true);
-               if (ret) {
-                       pr_err("[GetMclks]: fail to get max PPCLK_UCLK\n");
-                       return ret;
-               }
-       }
-
-       return (mem_clk * 100);
-}
-
-static int smu_v11_0_set_od8_default_settings(struct smu_context *smu,
-                                             bool initialize)
-{
-       struct smu_table_context *table_context = &smu->smu_table;
-       int ret;
-
-       if (initialize) {
-               if (table_context->overdrive_table)
-                       return -EINVAL;
-
-               table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
-
-               if (!table_context->overdrive_table)
-                       return -ENOMEM;
-
-               ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
-               if (ret) {
-                       pr_err("Failed to export over drive table!\n");
-                       return ret;
-               }
-
-               smu_set_default_od8_settings(smu);
-       }
-
-       ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
-       if (ret) {
-               pr_err("Failed to import over drive table!\n");
-               return ret;
-       }
-
-       return 0;
-}
+       int ret = 0;
+       struct amdgpu_device *adev = smu->adev;
 
-static int smu_v11_0_conv_power_profile_to_pplib_workload(int power_profile)
-{
-       int pplib_workload = 0;
-
-       switch (power_profile) {
-       case PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT:
-            pplib_workload = WORKLOAD_DEFAULT_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_FULLSCREEN3D:
-            pplib_workload = WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_POWERSAVING:
-            pplib_workload = WORKLOAD_PPLIB_POWER_SAVING_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_VIDEO:
-            pplib_workload = WORKLOAD_PPLIB_VIDEO_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_VR:
-            pplib_workload = WORKLOAD_PPLIB_VR_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_COMPUTE:
-            pplib_workload = WORKLOAD_PPLIB_COMPUTE_BIT;
-            break;
-       case PP_SMC_POWER_PROFILE_CUSTOM:
-               pplib_workload = WORKLOAD_PPLIB_CUSTOM_BIT;
+       switch (adev->asic_type) {
+       case CHIP_VEGA20:
+               break;
+       case CHIP_NAVI10:
+               if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
+                       return 0;
+               mutex_lock(&smu->mutex);
+               if (enable)
+                       ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
+               else
+                       ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
+               mutex_unlock(&smu->mutex);
+               break;
+       default:
                break;
        }
 
-       return pplib_workload;
-}
-
-static int smu_v11_0_get_power_profile_mode(struct smu_context *smu, char *buf)
-{
-       DpmActivityMonitorCoeffInt_t activity_monitor;
-       uint32_t i, size = 0;
-       uint16_t workload_type = 0;
-       static const char *profile_name[] = {
-                                       "BOOTUP_DEFAULT",
-                                       "3D_FULL_SCREEN",
-                                       "POWER_SAVING",
-                                       "VIDEO",
-                                       "VR",
-                                       "COMPUTE",
-                                       "CUSTOM"};
-       static const char *title[] = {
-                       "PROFILE_INDEX(NAME)",
-                       "CLOCK_TYPE(NAME)",
-                       "FPS",
-                       "UseRlcBusy",
-                       "MinActiveFreqType",
-                       "MinActiveFreq",
-                       "BoosterFreqType",
-                       "BoosterFreq",
-                       "PD_Data_limit_c",
-                       "PD_Data_error_coeff",
-                       "PD_Data_error_rate_coeff"};
-       int result = 0;
-
-       if (!smu->pm_enabled || !buf)
-               return -EINVAL;
-
-       size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
-                       title[0], title[1], title[2], title[3], title[4], title[5],
-                       title[6], title[7], title[8], title[9], title[10]);
-
-       for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
-               /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
-               workload_type = smu_v11_0_conv_power_profile_to_pplib_workload(i);
-               result = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF,
-                                                  workload_type, &activity_monitor, false);
-               if (result) {
-                       pr_err("[%s] Failed to get activity monitor!", __func__);
-                       return result;
-               }
-
-               size += sprintf(buf + size, "%2d %14s%s:\n",
-                       i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
-
-               size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
-                       " ",
-                       0,
-                       "GFXCLK",
-                       activity_monitor.Gfx_FPS,
-                       activity_monitor.Gfx_UseRlcBusy,
-                       activity_monitor.Gfx_MinActiveFreqType,
-                       activity_monitor.Gfx_MinActiveFreq,
-                       activity_monitor.Gfx_BoosterFreqType,
-                       activity_monitor.Gfx_BoosterFreq,
-                       activity_monitor.Gfx_PD_Data_limit_c,
-                       activity_monitor.Gfx_PD_Data_error_coeff,
-                       activity_monitor.Gfx_PD_Data_error_rate_coeff);
-
-               size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
-                       " ",
-                       1,
-                       "SOCCLK",
-                       activity_monitor.Soc_FPS,
-                       activity_monitor.Soc_UseRlcBusy,
-                       activity_monitor.Soc_MinActiveFreqType,
-                       activity_monitor.Soc_MinActiveFreq,
-                       activity_monitor.Soc_BoosterFreqType,
-                       activity_monitor.Soc_BoosterFreq,
-                       activity_monitor.Soc_PD_Data_limit_c,
-                       activity_monitor.Soc_PD_Data_error_coeff,
-                       activity_monitor.Soc_PD_Data_error_rate_coeff);
-
-               size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
-                       " ",
-                       2,
-                       "UCLK",
-                       activity_monitor.Mem_FPS,
-                       activity_monitor.Mem_UseRlcBusy,
-                       activity_monitor.Mem_MinActiveFreqType,
-                       activity_monitor.Mem_MinActiveFreq,
-                       activity_monitor.Mem_BoosterFreqType,
-                       activity_monitor.Mem_BoosterFreq,
-                       activity_monitor.Mem_PD_Data_limit_c,
-                       activity_monitor.Mem_PD_Data_error_coeff,
-                       activity_monitor.Mem_PD_Data_error_rate_coeff);
-
-               size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
-                       " ",
-                       3,
-                       "FCLK",
-                       activity_monitor.Fclk_FPS,
-                       activity_monitor.Fclk_UseRlcBusy,
-                       activity_monitor.Fclk_MinActiveFreqType,
-                       activity_monitor.Fclk_MinActiveFreq,
-                       activity_monitor.Fclk_BoosterFreqType,
-                       activity_monitor.Fclk_BoosterFreq,
-                       activity_monitor.Fclk_PD_Data_limit_c,
-                       activity_monitor.Fclk_PD_Data_error_coeff,
-                       activity_monitor.Fclk_PD_Data_error_rate_coeff);
-       }
-
-       return size;
-}
-
-static int smu_v11_0_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
-{
-       DpmActivityMonitorCoeffInt_t activity_monitor;
-       int workload_type = 0, ret = 0;
-
-       smu->power_profile_mode = input[size];
-
-       if (!smu->pm_enabled)
-               return ret;
-       if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
-               pr_err("Invalid power profile mode %d\n", smu->power_profile_mode);
-               return -EINVAL;
-       }
-
-       if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
-               ret = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF,
-                                               WORKLOAD_PPLIB_CUSTOM_BIT, &activity_monitor, false);
-               if (ret) {
-                       pr_err("[%s] Failed to get activity monitor!", __func__);
-                       return ret;
-               }
-
-               switch (input[0]) {
-               case 0: /* Gfxclk */
-                       activity_monitor.Gfx_FPS = input[1];
-                       activity_monitor.Gfx_UseRlcBusy = input[2];
-                       activity_monitor.Gfx_MinActiveFreqType = input[3];
-                       activity_monitor.Gfx_MinActiveFreq = input[4];
-                       activity_monitor.Gfx_BoosterFreqType = input[5];
-                       activity_monitor.Gfx_BoosterFreq = input[6];
-                       activity_monitor.Gfx_PD_Data_limit_c = input[7];
-                       activity_monitor.Gfx_PD_Data_error_coeff = input[8];
-                       activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
-                       break;
-               case 1: /* Socclk */
-                       activity_monitor.Soc_FPS = input[1];
-                       activity_monitor.Soc_UseRlcBusy = input[2];
-                       activity_monitor.Soc_MinActiveFreqType = input[3];
-                       activity_monitor.Soc_MinActiveFreq = input[4];
-                       activity_monitor.Soc_BoosterFreqType = input[5];
-                       activity_monitor.Soc_BoosterFreq = input[6];
-                       activity_monitor.Soc_PD_Data_limit_c = input[7];
-                       activity_monitor.Soc_PD_Data_error_coeff = input[8];
-                       activity_monitor.Soc_PD_Data_error_rate_coeff = input[9];
-                       break;
-               case 2: /* Uclk */
-                       activity_monitor.Mem_FPS = input[1];
-                       activity_monitor.Mem_UseRlcBusy = input[2];
-                       activity_monitor.Mem_MinActiveFreqType = input[3];
-                       activity_monitor.Mem_MinActiveFreq = input[4];
-                       activity_monitor.Mem_BoosterFreqType = input[5];
-                       activity_monitor.Mem_BoosterFreq = input[6];
-                       activity_monitor.Mem_PD_Data_limit_c = input[7];
-                       activity_monitor.Mem_PD_Data_error_coeff = input[8];
-                       activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
-                       break;
-               case 3: /* Fclk */
-                       activity_monitor.Fclk_FPS = input[1];
-                       activity_monitor.Fclk_UseRlcBusy = input[2];
-                       activity_monitor.Fclk_MinActiveFreqType = input[3];
-                       activity_monitor.Fclk_MinActiveFreq = input[4];
-                       activity_monitor.Fclk_BoosterFreqType = input[5];
-                       activity_monitor.Fclk_BoosterFreq = input[6];
-                       activity_monitor.Fclk_PD_Data_limit_c = input[7];
-                       activity_monitor.Fclk_PD_Data_error_coeff = input[8];
-                       activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9];
-                       break;
-               }
-
-               ret = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF,
-                                               WORKLOAD_PPLIB_COMPUTE_BIT, &activity_monitor, true);
-               if (ret) {
-                       pr_err("[%s] Failed to set activity monitor!", __func__);
-                       return ret;
-               }
-       }
-
-       /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
-       workload_type =
-               smu_v11_0_conv_power_profile_to_pplib_workload(smu->power_profile_mode);
-       smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
-                                   1 << workload_type);
-
        return ret;
 }
 
-static int smu_v11_0_update_od8_settings(struct smu_context *smu,
-                                       uint32_t index,
-                                       uint32_t value)
-{
-       struct smu_table_context *table_context = &smu->smu_table;
-       int ret;
-
-       ret = smu_update_table(smu, TABLE_OVERDRIVE,
-                              table_context->overdrive_table, false);
-       if (ret) {
-               pr_err("Failed to export over drive table!\n");
-               return ret;
-       }
-
-       smu_update_specified_od8_value(smu, index, value);
-
-       ret = smu_update_table(smu, TABLE_OVERDRIVE,
-                              table_context->overdrive_table, true);
-       if (ret) {
-               pr_err("Failed to import over drive table!\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static int smu_v11_0_dpm_set_uvd_enable(struct smu_context *smu, bool enable)
-{
-       if (!smu_feature_is_supported(smu, FEATURE_DPM_UVD_BIT))
-               return 0;
-
-       if (enable == smu_feature_is_enabled(smu, FEATURE_DPM_UVD_BIT))
-               return 0;
-
-       return smu_feature_set_enabled(smu, FEATURE_DPM_UVD_BIT, enable);
-}
-
-static int smu_v11_0_dpm_set_vce_enable(struct smu_context *smu, bool enable)
-{
-       if (!smu_feature_is_supported(smu, FEATURE_DPM_VCE_BIT))
-               return 0;
-
-       if (enable == smu_feature_is_enabled(smu, FEATURE_DPM_VCE_BIT))
-               return 0;
-
-       return smu_feature_set_enabled(smu, FEATURE_DPM_VCE_BIT, enable);
-}
-
 static int smu_v11_0_get_current_rpm(struct smu_context *smu,
                                     uint32_t *current_rpm)
 {
@@ -1937,37 +1395,21 @@ static int smu_v11_0_get_current_rpm(struct smu_context *smu,
 static uint32_t
 smu_v11_0_get_fan_control_mode(struct smu_context *smu)
 {
-       if (!smu_feature_is_enabled(smu, FEATURE_FAN_CONTROL_BIT))
+       if (!smu_feature_is_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT))
                return AMD_FAN_CTRL_MANUAL;
        else
                return AMD_FAN_CTRL_AUTO;
 }
 
-static int
-smu_v11_0_get_fan_speed_percent(struct smu_context *smu,
-                                          uint32_t *speed)
-{
-       int ret = 0;
-       uint32_t percent = 0;
-       uint32_t current_rpm;
-       PPTable_t *pptable = smu->smu_table.driver_pptable;
-
-       ret = smu_v11_0_get_current_rpm(smu, &current_rpm);
-       percent = current_rpm * 100 / pptable->FanMaximumRpm;
-       *speed = percent > 100 ? 100 : percent;
-
-       return ret;
-}
-
 static int
 smu_v11_0_smc_fan_control(struct smu_context *smu, bool start)
 {
        int ret = 0;
 
-       if (smu_feature_is_supported(smu, FEATURE_FAN_CONTROL_BIT))
+       if (smu_feature_is_supported(smu, SMU_FEATURE_FAN_CONTROL_BIT))
                return 0;
 
-       ret = smu_feature_set_enabled(smu, FEATURE_FAN_CONTROL_BIT, start);
+       ret = smu_feature_set_enabled(smu, SMU_FEATURE_FAN_CONTROL_BIT, start);
        if (ret)
                pr_err("[%s]%s smc FAN CONTROL feature failed!",
                       __func__, (start ? "Start" : "Stop"));
@@ -2080,6 +1522,9 @@ static int smu_v11_0_set_fan_speed_rpm(struct smu_context *smu,
        return ret;
 }
 
+#define XGMI_STATE_D0 1
+#define XGMI_STATE_D3 0
+
 static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
                                     uint32_t pstate)
 {
@@ -2092,6 +1537,208 @@ static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
        return ret;
 }
 
+#define THM_11_0__SRCID__THM_DIG_THERM_L2H             0               /* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH  */
+#define THM_11_0__SRCID__THM_DIG_THERM_H2L             1               /* ASIC_TEMP < CG_THERMAL_INT.DIG_THERM_INTL  */
+
+static int smu_v11_0_irq_process(struct amdgpu_device *adev,
+                                struct amdgpu_irq_src *source,
+                                struct amdgpu_iv_entry *entry)
+{
+       uint32_t client_id = entry->client_id;
+       uint32_t src_id = entry->src_id;
+
+       if (client_id == SOC15_IH_CLIENTID_THM) {
+               switch (src_id) {
+               case THM_11_0__SRCID__THM_DIG_THERM_L2H:
+                       pr_warn("GPU over temperature range detected on PCIe %d:%d.%d!\n",
+                               PCI_BUS_NUM(adev->pdev->devfn),
+                               PCI_SLOT(adev->pdev->devfn),
+                               PCI_FUNC(adev->pdev->devfn));
+               break;
+               case THM_11_0__SRCID__THM_DIG_THERM_H2L:
+                       pr_warn("GPU under temperature range detected on PCIe %d:%d.%d!\n",
+                               PCI_BUS_NUM(adev->pdev->devfn),
+                               PCI_SLOT(adev->pdev->devfn),
+                               PCI_FUNC(adev->pdev->devfn));
+               break;
+               default:
+                       pr_warn("GPU under temperature range unknown src id (%d), detected on PCIe %d:%d.%d!\n",
+                               src_id,
+                               PCI_BUS_NUM(adev->pdev->devfn),
+                               PCI_SLOT(adev->pdev->devfn),
+                               PCI_FUNC(adev->pdev->devfn));
+               break;
+
+               }
+       }
+
+       return 0;
+}
+
+static const struct amdgpu_irq_src_funcs smu_v11_0_irq_funcs =
+{
+       .process = smu_v11_0_irq_process,
+};
+
+static int smu_v11_0_register_irq_handler(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       struct amdgpu_irq_src *irq_src = smu->irq_source;
+       int ret = 0;
+
+       /* already register */
+       if (irq_src)
+               return 0;
+
+       irq_src = kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
+       if (!irq_src)
+               return -ENOMEM;
+       smu->irq_source = irq_src;
+
+       irq_src->funcs = &smu_v11_0_irq_funcs;
+
+       ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
+                               THM_11_0__SRCID__THM_DIG_THERM_L2H,
+                               irq_src);
+       if (ret)
+               return ret;
+
+       ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
+                               THM_11_0__SRCID__THM_DIG_THERM_H2L,
+                               irq_src);
+       if (ret)
+               return ret;
+
+       return ret;
+}
+
+static int smu_v11_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
+               struct pp_smu_nv_clock_table *max_clocks)
+{
+       struct smu_table_context *table_context = &smu->smu_table;
+       struct smu_11_0_max_sustainable_clocks *sustainable_clocks = NULL;
+
+       if (!max_clocks || !table_context->max_sustainable_clocks)
+               return -EINVAL;
+
+       sustainable_clocks = table_context->max_sustainable_clocks;
+
+       max_clocks->dcfClockInKhz =
+                       (unsigned int) sustainable_clocks->dcef_clock * 1000;
+       max_clocks->displayClockInKhz =
+                       (unsigned int) sustainable_clocks->display_clock * 1000;
+       max_clocks->phyClockInKhz =
+                       (unsigned int) sustainable_clocks->phy_clock * 1000;
+       max_clocks->pixelClockInKhz =
+                       (unsigned int) sustainable_clocks->pixel_clock * 1000;
+       max_clocks->uClockInKhz =
+                       (unsigned int) sustainable_clocks->uclock * 1000;
+       max_clocks->socClockInKhz =
+                       (unsigned int) sustainable_clocks->soc_clock * 1000;
+       max_clocks->dscClockInKhz = 0;
+       max_clocks->dppClockInKhz = 0;
+       max_clocks->fabricClockInKhz = 0;
+
+       return 0;
+}
+
+static int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
+{
+       int ret = 0;
+
+       mutex_lock(&smu->mutex);
+       ret = smu_send_smc_msg(smu, SMU_MSG_BacoAudioD3PME);
+       mutex_unlock(&smu->mutex);
+
+       return ret;
+}
+
+static int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, enum smu_v11_0_baco_seq baco_seq)
+{
+       return smu_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq);
+}
+
+static bool smu_v11_0_baco_is_support(struct smu_context *smu)
+{
+       struct amdgpu_device *adev = smu->adev;
+       struct smu_baco_context *smu_baco = &smu->smu_baco;
+       uint32_t val;
+       bool baco_support;
+
+       mutex_lock(&smu_baco->mutex);
+       baco_support = smu_baco->platform_support;
+       mutex_unlock(&smu_baco->mutex);
+
+       if (!baco_support)
+               return false;
+
+       if (!smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
+               return false;
+
+       val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
+       if (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK)
+               return true;
+
+       return false;
+}
+
+static enum smu_baco_state smu_v11_0_baco_get_state(struct smu_context *smu)
+{
+       struct smu_baco_context *smu_baco = &smu->smu_baco;
+       enum smu_baco_state baco_state = SMU_BACO_STATE_EXIT;
+
+       mutex_lock(&smu_baco->mutex);
+       baco_state = smu_baco->state;
+       mutex_unlock(&smu_baco->mutex);
+
+       return baco_state;
+}
+
+static int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
+{
+
+       struct smu_baco_context *smu_baco = &smu->smu_baco;
+       int ret = 0;
+
+       if (smu_v11_0_baco_get_state(smu) == state)
+               return 0;
+
+       mutex_lock(&smu_baco->mutex);
+
+       if (state == SMU_BACO_STATE_ENTER)
+               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, BACO_SEQ_BACO);
+       else
+               ret = smu_send_smc_msg(smu, SMU_MSG_ExitBaco);
+       if (ret)
+               goto out;
+
+       smu_baco->state = state;
+out:
+       mutex_unlock(&smu_baco->mutex);
+       return ret;
+}
+
+static int smu_v11_0_baco_reset(struct smu_context *smu)
+{
+       int ret = 0;
+
+       ret = smu_v11_0_baco_set_armd3_sequence(smu, BACO_SEQ_BACO);
+       if (ret)
+               return ret;
+
+       ret = smu_v11_0_baco_set_state(smu, SMU_BACO_STATE_ENTER);
+       if (ret)
+               return ret;
+
+       msleep(10);
+
+       ret = smu_v11_0_baco_set_state(smu, SMU_BACO_STATE_EXIT);
+       if (ret)
+               return ret;
+
+       return ret;
+}
+
 static const struct smu_funcs smu_v11_0_funcs = {
        .init_microcode = smu_v11_0_init_microcode,
        .load_microcode = smu_v11_0_load_microcode,
@@ -2100,7 +1747,6 @@ static const struct smu_funcs smu_v11_0_funcs = {
        .send_smc_msg = smu_v11_0_send_msg,
        .send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
        .read_smc_arg = smu_v11_0_read_arg,
-       .read_pptable_from_vbios = smu_v11_0_read_pptable_from_vbios,
        .setup_pptable = smu_v11_0_setup_pptable,
        .init_smc_tables = smu_v11_0_init_smc_tables,
        .fini_smc_tables = smu_v11_0_fini_smc_tables,
@@ -2116,10 +1762,9 @@ static const struct smu_funcs smu_v11_0_funcs = {
        .write_watermarks_table = smu_v11_0_write_watermarks_table,
        .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
        .set_tool_table_location = smu_v11_0_set_tool_table_location,
-       .init_display = smu_v11_0_init_display,
+       .init_display_count = smu_v11_0_init_display_count,
        .set_allowed_mask = smu_v11_0_set_allowed_mask,
        .get_enabled_mask = smu_v11_0_get_enabled_mask,
-       .is_dpm_running = smu_v11_0_is_dpm_running,
        .system_features_control = smu_v11_0_system_features_control,
        .update_feature_enable_state = smu_v11_0_update_feature_enable_state,
        .notify_display_change = smu_v11_0_notify_display_change,
@@ -2132,22 +1777,20 @@ static const struct smu_funcs smu_v11_0_funcs = {
        .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
        .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
        .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
-       .get_sclk = smu_v11_0_dpm_get_sclk,
-       .get_mclk = smu_v11_0_dpm_get_mclk,
-       .set_od8_default_settings = smu_v11_0_set_od8_default_settings,
-       .conv_power_profile_to_pplib_workload = smu_v11_0_conv_power_profile_to_pplib_workload,
-       .get_power_profile_mode = smu_v11_0_get_power_profile_mode,
-       .set_power_profile_mode = smu_v11_0_set_power_profile_mode,
-       .update_od8_settings = smu_v11_0_update_od8_settings,
-       .dpm_set_uvd_enable = smu_v11_0_dpm_set_uvd_enable,
-       .dpm_set_vce_enable = smu_v11_0_dpm_set_vce_enable,
        .get_current_rpm = smu_v11_0_get_current_rpm,
        .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
        .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
-       .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
        .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
        .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
        .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
+       .gfx_off_control = smu_v11_0_gfx_off_control,
+       .register_irq_handler = smu_v11_0_register_irq_handler,
+       .set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
+       .get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
+       .baco_is_support = smu_v11_0_baco_is_support,
+       .baco_get_state = smu_v11_0_baco_get_state,
+       .baco_set_state = smu_v11_0_baco_set_state,
+       .baco_reset = smu_v11_0_baco_reset,
 };
 
 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
@@ -2160,6 +1803,7 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
                vega20_set_ppt_funcs(smu);
                break;
        case CHIP_NAVI10:
+       case CHIP_NAVI14:
                navi10_set_ppt_funcs(smu);
                break;
        default: