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>
        /* 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)
 
 
        dev_info(adev->dev, "GPU BACO reset\n");
 
+       adev->in_baco_reset = 1;
+
        return 0;
 }
 
 
 #include "vega20_inc.h"
 #include "vega20_ppsmc.h"
 #include "vega20_baco.h"
+#include "vega20_smumgr.h"
 
 
 
 
        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);
+}
 
 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
 
 
 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);
                        "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;
 }
 
 /*
 
 #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;
 
        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;
 
                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