enable smart shift on dGPU if it is part of HG system and
the platform supports ATCS method to handle power shift.

V2: avoid psc updates in baco enter and exit (Lijo)
    fix alignment (Shashank)
V3: rebased on unified ATCS handling. (Alex)
V4: check for return value and warn on failed update (Shashank)
    return 0 if device does not support smart shift.  (Lizo)
V5: rebased on ATPX/ATCS structures global (Alex)

Signed-off-by: Sathishkumar S <sathishkumar.sundarar...@amd.com>
Reviewed-by: Lijo Lazar <lijo.la...@amd.com>
Reviewed-by: Shashank Sharma <shashank.sha...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h        | 18 ++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c   | 49 ++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 24 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  6 +++
 4 files changed, 97 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 0ea2ed3a55f1..827533a543c6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -130,6 +130,13 @@ struct amdgpu_mgpu_info
        bool                            pending_reset;
 };
 
+enum amdgpu_ss {
+       AMDGPU_SS_DRV_LOAD,
+       AMDGPU_SS_DEV_D0,
+       AMDGPU_SS_DEV_D3,
+       AMDGPU_SS_DRV_UNLOAD
+};
+
 struct amdgpu_watchdog_timer
 {
        bool timeout_fatal_disable;
@@ -1267,6 +1274,7 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev);
 bool amdgpu_device_supports_atpx(struct drm_device *dev);
 bool amdgpu_device_supports_px(struct drm_device *dev);
 bool amdgpu_device_supports_boco(struct drm_device *dev);
+bool amdgpu_device_supports_smart_shift(struct drm_device *dev);
 bool amdgpu_device_supports_baco(struct drm_device *dev);
 bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev,
                                      struct amdgpu_device *peer_adev);
@@ -1339,6 +1347,13 @@ struct amdgpu_afmt_acr {
 struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock);
 
 /* amdgpu_acpi.c */
+
+/* ATCS Device/Driver State */
+#define AMDGPU_ATCS_PSC_DEV_STATE_D0           0
+#define AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT       3
+#define AMDGPU_ATCS_PSC_DRV_STATE_OPR          0
+#define AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR      1
+
 #if defined(CONFIG_ACPI)
 int amdgpu_acpi_init(struct amdgpu_device *adev);
 void amdgpu_acpi_fini(struct amdgpu_device *adev);
@@ -1348,6 +1363,7 @@ int amdgpu_acpi_pcie_performance_request(struct 
amdgpu_device *adev,
                                                u8 perf_req, bool advertise);
 int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
                                    u8 dev_state, bool drv_state);
+int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss 
ss_state);
 int amdgpu_acpi_pcie_notify_device_ready(struct amdgpu_device *adev);
 
 void amdgpu_acpi_get_backlight_caps(struct amdgpu_dm_backlight_caps *caps);
@@ -1361,6 +1377,8 @@ static inline void amdgpu_acpi_detect(void) { }
 static inline bool amdgpu_acpi_is_power_shift_control_supported(void) { return 
false; }
 static inline int amdgpu_acpi_power_shift_control(struct amdgpu_device *adev,
                                                  u8 dev_state, bool drv_state) 
{ return 0; }
+static inline int amdgpu_acpi_smart_shift_update(struct drm_device *dev,
+                                                enum amdgpu_ss ss_state) { 
return 0; }
 #endif
 
 int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index b631316bfe5b..84a1b4bc9bb4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -754,6 +754,55 @@ int amdgpu_acpi_power_shift_control(struct amdgpu_device 
*adev,
        return 0;
 }
 
+/**
+ * amdgpu_acpi_smart_shift_update - update dGPU device state to SBIOS
+ *
+ * @dev: drm_device pointer
+ * @ss_state: current smart shift event
+ *
+ * returns 0 on success,
+ * otherwise return error number.
+ */
+int amdgpu_acpi_smart_shift_update(struct drm_device *dev, enum amdgpu_ss 
ss_state)
+{
+       struct amdgpu_device *adev = drm_to_adev(dev);
+       int r;
+
+       if (!amdgpu_device_supports_smart_shift(dev))
+               return 0;
+
+       switch (ss_state) {
+       /* SBIOS trigger “stop”, “enable” and “start” at D0, Driver Operational.
+        * SBIOS trigger “stop” at D3, Driver Not Operational.
+        * SBIOS trigger “stop” and “disable” at D0, Driver NOT operational.
+        */
+       case AMDGPU_SS_DRV_LOAD:
+               r = amdgpu_acpi_power_shift_control(adev,
+                                                   
AMDGPU_ATCS_PSC_DEV_STATE_D0,
+                                                   
AMDGPU_ATCS_PSC_DRV_STATE_OPR);
+               break;
+       case AMDGPU_SS_DEV_D0:
+               r = amdgpu_acpi_power_shift_control(adev,
+                                                   
AMDGPU_ATCS_PSC_DEV_STATE_D0,
+                                                   
AMDGPU_ATCS_PSC_DRV_STATE_OPR);
+               break;
+       case AMDGPU_SS_DEV_D3:
+               r = amdgpu_acpi_power_shift_control(adev,
+                                                   
AMDGPU_ATCS_PSC_DEV_STATE_D3_HOT,
+                                                   
AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
+               break;
+       case AMDGPU_SS_DRV_UNLOAD:
+               r = amdgpu_acpi_power_shift_control(adev,
+                                                   
AMDGPU_ATCS_PSC_DEV_STATE_D0,
+                                                   
AMDGPU_ATCS_PSC_DRV_STATE_NOT_OPR);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return r;
+}
+
 /**
  * amdgpu_acpi_event - handle notify events
  *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d1521e498e40..5c465db47aff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -263,6 +263,21 @@ bool amdgpu_device_supports_baco(struct drm_device *dev)
        return amdgpu_asic_supports_baco(adev);
 }
 
+/**
+ * amdgpu_device_supports_smart_shift - Is the device dGPU with
+ * smart shift support
+ *
+ * @dev: drm_device pointer
+ *
+ * Returns true if the device is a dGPU with Smart Shift support,
+ * otherwise returns false.
+ */
+bool amdgpu_device_supports_smart_shift(struct drm_device *dev)
+{
+       return (amdgpu_device_supports_boco(dev) &&
+               amdgpu_acpi_is_power_shift_control_supported());
+}
+
 /*
  * VRAM access helper functions
  */
@@ -3750,6 +3765,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool 
fbcon)
                return 0;
 
        adev->in_suspend = true;
+
+       if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D3))
+               DRM_WARN("smart shift update failed\n");
+
        drm_kms_helper_poll_disable(dev);
 
        if (fbcon)
@@ -3859,6 +3878,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool 
fbcon)
 #endif
        adev->in_suspend = false;
 
+       if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
+               DRM_WARN("smart shift update failed\n");
+
        return 0;
 }
 
@@ -4938,6 +4960,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
                        amdgpu_vf_error_put(tmp_adev, 
AMDGIM_ERROR_VF_GPU_RESET_FAIL, 0, r);
                } else {
                        dev_info(tmp_adev->dev, "GPU reset(%d) succeeded!\n", 
atomic_read(&tmp_adev->gpu_reset_counter));
+                       if 
(amdgpu_acpi_smart_shift_update(adev_to_drm(tmp_adev), AMDGPU_SS_DEV_D0))
+                               DRM_WARN("smart shift update failed\n");
                }
        }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 524e4fe5efe8..c354ffa62483 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -91,6 +91,9 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
                pm_runtime_forbid(dev->dev);
        }
 
+       if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD))
+               DRM_WARN("smart shift update failed\n");
+
        amdgpu_acpi_fini(adev);
        amdgpu_device_fini(adev);
 }
@@ -214,6 +217,9 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, 
unsigned long flags)
                pm_runtime_put_autosuspend(dev->dev);
        }
 
+       if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
+               DRM_WARN("smart shift update failed\n");
+
 out:
        if (r) {
                /* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to