When ATOM_PP_PLATFORM_CAP_HARDWAREDC is set,
the SMU has a GPIO pin for detecting AC/DC switch
and everything works automatically.

Otherwise when there is no GPIO pin, the SMU can
automatically detect switching to DC, but needs
to be notified of switching to AC.

Use PPSMC_MSG_RunningOnAC to notify the SMC
when switching to AC.

Signed-off-by: Timur Kristóf <[email protected]>
---
 drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c  | 12 ++++++++++++
 .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c   | 15 +++++++++++++++
 drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h      |  1 +
 3 files changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c 
b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
index 0bbb89788335..19e74baa2b85 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -1550,6 +1550,17 @@ static void pp_pm_compute_clocks(void *handle)
                              NULL);
 }
 
+static void pp_dpm_notify_ac_dc(void *handle)
+{
+       struct pp_hwmgr *hwmgr = handle;
+
+       if (!hwmgr || !hwmgr->pm_en)
+               return;
+
+       if (hwmgr->hwmgr_func->notify_ac_dc)
+               hwmgr->hwmgr_func->notify_ac_dc(hwmgr);
+}
+
 static const struct amd_pm_funcs pp_dpm_funcs = {
        .load_firmware = pp_dpm_load_fw,
        .wait_for_fw_loading_complete = pp_dpm_fw_loading_complete,
@@ -1615,4 +1626,5 @@ static const struct amd_pm_funcs pp_dpm_funcs = {
        .gfx_state_change_set = pp_gfx_state_change_set,
        .get_smu_prv_buf_details = pp_get_prv_buffer_details,
        .pm_compute_clocks = pp_pm_compute_clocks,
+       .notify_ac_dc = pp_dpm_notify_ac_dc,
 };
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c 
b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
index 4436ab2bb51f..416b9380a70e 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -5854,6 +5854,20 @@ static int smu7_power_off_asic(struct pp_hwmgr *hwmgr)
        return result;
 }
 
+static void smu7_notify_ac_dc(struct pp_hwmgr *hwmgr)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
+
+       /* Check if the platform already manages the AC/DC switch via dedicated 
GPIO. */
+       if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
+                           PHM_PlatformCaps_AutomaticDCTransition))
+               return;
+
+       /* The SMU automatically notices DC, but needs to be notified when 
switching to AC. */
+       if (adev->pm.ac_power)
+               smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunningOnAC, NULL);
+}
+
 static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
        .backend_init = &smu7_hwmgr_backend_init,
        .backend_fini = &smu7_hwmgr_backend_fini,
@@ -5916,6 +5930,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
        .get_asic_baco_state = smu7_baco_get_state,
        .set_asic_baco_state = smu7_baco_set_state,
        .power_off_asic = smu7_power_off_asic,
+       .notify_ac_dc = smu7_notify_ac_dc,
 };
 
 uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h 
b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h
index 3ae45eac0c5c..84de2ccad7a3 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h
@@ -364,6 +364,7 @@ struct pp_hwmgr_func {
                                        bool disable);
        ssize_t (*get_gpu_metrics)(struct pp_hwmgr *hwmgr, void **table);
        int (*gfx_state_change)(struct pp_hwmgr *hwmgr, uint32_t state);
+       void (*notify_ac_dc)(struct pp_hwmgr *hwmgr);
 };
 
 struct pp_table_func {
-- 
2.54.0

Reply via email to