diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 74 | 
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); +}  | 
