drm/amd/powerplay: add vega12 SMU gfxoff support v3
authorEvan Quan <evan.quan@amd.com>
Wed, 4 Jul 2018 08:44:07 +0000 (16:44 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Jul 2018 19:45:01 +0000 (14:45 -0500)
Export apis for enabling/disabling SMU gfxoff support.

v2: fit the latest gfxoff support framework
v3: add feature_mask control

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Huang Rui <ray.huang at amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h

index ff754bf1875ce7531f291bbd86f39b1a0b63df7a..e6d19e7fbfbda8e9f0c2eef3021aca5034496ac9 100644 (file)
@@ -3769,6 +3769,11 @@ static int gfx_v9_0_set_powergating_state(void *handle,
                /* update mgcg state */
                gfx_v9_0_update_gfx_mg_power_gating(adev, enable);
 
+               /* set gfx off through smu */
+               if (enable && adev->powerplay.pp_funcs->set_powergating_by_smu)
+                       amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true);
+               break;
+       case CHIP_VEGA12:
                /* set gfx off through smu */
                if (enable && adev->powerplay.pp_funcs->set_powergating_by_smu)
                        amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true);
index ed17c560b5ef6b9a36f67426517d970d58dfe8bf..cae76fe6588116c602433a3644850c60d2df9d68 100644 (file)
@@ -423,6 +423,11 @@ static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
                        hwmgr->thermal_controller.advanceFanControlParameters.usFanPWMMinLimit *
                        hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100;
 
+       if (hwmgr->feature_mask & PP_GFXOFF_MASK)
+               data->gfxoff_controlled_by_driver = true;
+       else
+               data->gfxoff_controlled_by_driver = false;
+
        return result;
 }
 
@@ -2328,6 +2333,38 @@ static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
        return 0;
 }
 
+static int vega12_enable_gfx_off(struct pp_hwmgr *hwmgr)
+{
+       struct vega12_hwmgr *data =
+                       (struct vega12_hwmgr *)(hwmgr->backend);
+       int ret = 0;
+
+       if (data->gfxoff_controlled_by_driver)
+               ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_AllowGfxOff);
+
+       return ret;
+}
+
+static int vega12_disable_gfx_off(struct pp_hwmgr *hwmgr)
+{
+       struct vega12_hwmgr *data =
+                       (struct vega12_hwmgr *)(hwmgr->backend);
+       int ret = 0;
+
+       if (data->gfxoff_controlled_by_driver)
+               ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisallowGfxOff);
+
+       return ret;
+}
+
+static int vega12_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
+{
+       if (enable)
+               return vega12_enable_gfx_off(hwmgr);
+       else
+               return vega12_disable_gfx_off(hwmgr);
+}
+
 static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
        .backend_init = vega12_hwmgr_backend_init,
        .backend_fini = vega12_hwmgr_backend_fini,
@@ -2377,6 +2414,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
        .get_thermal_temperature_range = vega12_get_thermal_temperature_range,
        .register_irq_handlers = smu9_register_irq_handlers,
        .start_thermal_controller = vega12_start_thermal_controller,
+       .powergate_gfx = vega12_gfx_off_control,
 };
 
 int vega12_hwmgr_init(struct pp_hwmgr *hwmgr)
index e17237c90eeaaa32fb72d7bb0e9a8125c5a376b4..b3e424d289941aa85d741cc87d09aa541eb524ee 100644 (file)
@@ -393,6 +393,9 @@ struct vega12_hwmgr {
        struct vega12_smc_state_table  smc_state_table;
 
        struct vega12_clock_range      clk_range[PPCLK_COUNT];
+
+       /* ---- Gfxoff ---- */
+       bool                           gfxoff_controlled_by_driver;
 };
 
 #define VEGA12_DPM2_NEAR_TDP_DEC                      10