drm/amd/powerplay: apply Vega20 BACO workaround
authorEvan Quan <evan.quan@amd.com>
Thu, 7 Mar 2019 02:20:12 +0000 (10:20 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Mar 2019 20:36:49 +0000 (15:36 -0500)
Applied vdci flush workaround for Vega20 BACO.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.h
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/vega20_ppsmc.h
drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.h

index baad21e8e8f2de4a9c177455c515482cfa64f1fc..60c0601429df675c2799b22e3ccd7292991ab600 100644 (file)
@@ -929,6 +929,7 @@ struct amdgpu_device {
        /* counter of mapped memory through xgmi */
        atomic_t                        xgmi_map_counter;
 
+       bool                            in_baco_reset;
 };
 
 static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_bo_device *bdev)
index e172114460cc752f495a76ae31cc1746e21e049f..77493a0f5e7ed4760349be9fd87a0537304d92d7 100644 (file)
@@ -452,6 +452,8 @@ static int soc15_asic_baco_reset(struct amdgpu_device *adev)
 
        dev_info(adev->dev, "GPU BACO reset\n");
 
+       adev->in_baco_reset = 1;
+
        return 0;
 }
 
index 5e8602a79b1c30d0a63bd97e7485740884e1a875..df6ff92524011d9480149c26c4466f9bd69a9374 100644 (file)
@@ -27,6 +27,7 @@
 #include "vega20_inc.h"
 #include "vega20_ppsmc.h"
 #include "vega20_baco.h"
+#include "vega20_smumgr.h"
 
 
 
@@ -101,3 +102,14 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state)
 
        return 0;
 }
+
+int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr)
+{
+       int ret = 0;
+
+       ret = vega20_set_pptable_driver_address(hwmgr);
+       if (ret)
+               return ret;
+
+       return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_BacoWorkAroundFlushVDCI);
+}
index 51c7f83929254832e6f6aaa87902e140fd959c0e..f06471e712dcba646a7a00eb5327217d0ac5a60b 100644 (file)
@@ -28,5 +28,6 @@
 extern int vega20_baco_get_capability(struct pp_hwmgr *hwmgr, bool *cap);
 extern int vega20_baco_get_state(struct pp_hwmgr *hwmgr, enum BACO_STATE *state);
 extern int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state);
+extern int vega20_baco_apply_vdci_flush_workaround(struct pp_hwmgr *hwmgr);
 
 #endif
index 9aa7bec1b5fe6f3aeb67da66d4b88b2e16966bbb..664544e7fcdc7623a7ce059fb952f51000bc38c1 100644 (file)
@@ -443,6 +443,7 @@ static int vega20_init_sclk_threshold(struct pp_hwmgr *hwmgr)
 
 static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr)
 {
+       struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
        int ret = 0;
 
        ret = vega20_init_sclk_threshold(hwmgr);
@@ -450,7 +451,15 @@ static int vega20_setup_asic_task(struct pp_hwmgr *hwmgr)
                        "Failed to init sclk threshold!",
                        return ret);
 
-       return 0;
+       if (adev->in_baco_reset) {
+               adev->in_baco_reset = 0;
+
+               ret = vega20_baco_apply_vdci_flush_workaround(hwmgr);
+               if (ret)
+                       pr_err("Failed to apply vega20 baco workaround!\n");
+       }
+
+       return ret;
 }
 
 /*
index 4f63a736ea0e7371b6f09b26ea8cc55ec6b9bdd0..a0883038f3c3fabdada19def4571591a3ea97c22 100644 (file)
 #define PPSMC_MSG_PrepareMp1ForShutdown          0x5A
 #define PPSMC_MSG_SetMGpuFanBoostLimitRpm        0x5D
 #define PPSMC_MSG_GetAVFSVoltageByDpm            0x5F
-#define PPSMC_Message_Count                      0x60
+#define PPSMC_MSG_BacoWorkAroundFlushVDCI        0x60
+#define PPSMC_Message_Count                      0x61
 
 typedef uint32_t PPSMC_Result;
 typedef uint32_t PPSMC_Msg;
index ba00744c3413f53e03db1aa9c91226ed9ddc5c6a..f301a73f6df1b9890926816f12eab57aa45c2713 100644 (file)
@@ -367,6 +367,26 @@ static int vega20_set_tools_address(struct pp_hwmgr *hwmgr)
        return ret;
 }
 
+int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr)
+{
+       struct vega20_smumgr *priv =
+                       (struct vega20_smumgr *)(hwmgr->smu_backend);
+       int ret = 0;
+
+       PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+                       PPSMC_MSG_SetDriverDramAddrHigh,
+                       upper_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr))) == 0,
+                       "[SetPPtabeDriverAddress] Attempt to Set Dram Addr High Failed!",
+                       return ret);
+       PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
+                       PPSMC_MSG_SetDriverDramAddrLow,
+                       lower_32_bits(priv->smu_tables.entry[TABLE_PPTABLE].mc_addr))) == 0,
+                       "[SetPPtabeDriverAddress] Attempt to Set Dram Addr Low Failed!",
+                       return ret);
+
+       return ret;
+}
+
 static int vega20_smu_init(struct pp_hwmgr *hwmgr)
 {
        struct vega20_smumgr *priv;
index 77349c3f016281aba01eae62c2cdfda753e6b7e7..ec953ab13e87c1e478c8321f32e24b1af35c6f78 100644 (file)
@@ -55,6 +55,7 @@ int vega20_set_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
                uint8_t *table, uint16_t workload_type);
 int vega20_get_activity_monitor_coeff(struct pp_hwmgr *hwmgr,
                uint8_t *table, uint16_t workload_type);
+int vega20_set_pptable_driver_address(struct pp_hwmgr *hwmgr);
 
 #endif