aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 239bf2a4b3c6..790fd5408ddf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -26,9 +26,44 @@
#include "amdgpu.h"
#include "amdgpu_gfx.h"
+/* delay 0.1 second to enable gfx off feature */
+#define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100)
+
/*
- * GPU scratch registers helpers function.
+ * GPU GFX IP block helpers function.
*/
+
+int amdgpu_gfx_queue_to_bit(struct amdgpu_device *adev, int mec,
+ int pipe, int queue)
+{
+ int bit = 0;
+
+ bit += mec * adev->gfx.mec.num_pipe_per_mec
+ * adev->gfx.mec.num_queue_per_pipe;
+ bit += pipe * adev->gfx.mec.num_queue_per_pipe;
+ bit += queue;
+
+ return bit;
+}
+
+void amdgpu_gfx_bit_to_queue(struct amdgpu_device *adev, int bit,
+ int *mec, int *pipe, int *queue)
+{
+ *queue = bit % adev->gfx.mec.num_queue_per_pipe;
+ *pipe = (bit / adev->gfx.mec.num_queue_per_pipe)
+ % adev->gfx.mec.num_pipe_per_mec;
+ *mec = (bit / adev->gfx.mec.num_queue_per_pipe)
+ / adev->gfx.mec.num_pipe_per_mec;
+
+}
+
+bool amdgpu_gfx_is_mec_queue_enabled(struct amdgpu_device *adev,
+ int mec, int pipe, int queue)
+{
+ return test_bit(amdgpu_gfx_queue_to_bit(adev, mec, pipe, queue),
+ adev->gfx.mec.queue_bitmap);
+}
+
/**
* amdgpu_gfx_scratch_get - Allocate a scratch register
*
@@ -340,3 +375,40 @@ void amdgpu_gfx_compute_mqd_sw_fini(struct amdgpu_device *adev)
&ring->mqd_gpu_addr,
&ring->mqd_ptr);
}
+
+/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable
+ *
+ * @adev: amdgpu_device pointer
+ * @bool enable true: enable gfx off feature, false: disable gfx off feature
+ *
+ * 1. gfx off feature will be enabled by gfx ip after gfx cg gp enabled.
+ * 2. other client can send request to disable gfx off feature, the request should be honored.
+ * 3. other client can cancel their request of disable gfx off feature
+ * 4. other client should not send request to enable gfx off feature before disable gfx off feature.
+ */
+
+void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
+{
+ if (!(adev->powerplay.pp_feature & PP_GFXOFF_MASK))
+ return;
+
+ if (!adev->powerplay.pp_funcs->set_powergating_by_smu)
+ return;
+
+
+ mutex_lock(&adev->gfx.gfx_off_mutex);
+
+ if (!enable)
+ adev->gfx.gfx_off_req_count++;
+ else if (adev->gfx.gfx_off_req_count > 0)
+ adev->gfx.gfx_off_req_count--;
+
+ if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) {
+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
+ } else if (!enable && adev->gfx.gfx_off_state) {
+ if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false))
+ adev->gfx.gfx_off_state = false;
+ }
+
+ mutex_unlock(&adev->gfx.gfx_off_mutex);
+}