diff options
author | Alex Hung <alex.hung@amd.com> | 2023-06-23 09:40:39 -0600 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2023-10-03 15:42:56 -0400 |
commit | 77a66faaccc0455fe30e326e9a997aec8d0abed4 (patch) | |
tree | 9db4e7d8807b329c489287214232b3d9dfd946a8 | |
parent | b79a00a4d4f8fc827ca0fc19e259913a81252f6b (diff) | |
download | linux-77a66faaccc0455fe30e326e9a997aec8d0abed4.tar.gz linux-77a66faaccc0455fe30e326e9a997aec8d0abed4.tar.bz2 linux-77a66faaccc0455fe30e326e9a997aec8d0abed4.zip |
drm/amd/display: Disable DWB frame capture to emulate oneshot
[WHY]
drm_writeback requires to capture exact one frame in each writeback
call.
[HOW]
frame_capture is disabled after each writeback is completed.
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc_stream.h | 4 |
3 files changed, 44 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 932d56ae0af2..ed4f3bb50357 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -593,8 +593,20 @@ static void dm_crtc_high_irq(void *interrupt_params) list_entry); spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags); - if (job) + if (job) { + unsigned int v_total, refresh_hz; + struct dc_stream_state *stream = acrtc->dm_irq_params.stream; + + v_total = stream->adjust.v_total_max ? + stream->adjust.v_total_max : stream->timing.v_total; + refresh_hz = div_u64((uint64_t) stream->timing.pix_clk_100hz * + 100LL, (v_total * stream->timing.h_total)); + mdelay(1000 / refresh_hz); + drm_writeback_signal_completion(acrtc->wb_conn, 0); + dc_stream_fc_disable_writeback(adev->dm.dc, + acrtc->dm_irq_params.stream, 0); + } } else DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__); acrtc->wb_pending = false; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 2bfe8d98507e..2e49b0ab91d7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -538,6 +538,33 @@ bool dc_stream_add_writeback(struct dc *dc, return true; } +bool dc_stream_fc_disable_writeback(struct dc *dc, + struct dc_stream_state *stream, + uint32_t dwb_pipe_inst) +{ + struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst]; + + if (stream == NULL) { + dm_error("DC: dc_stream is NULL!\n"); + return false; + } + + if (dwb_pipe_inst >= MAX_DWB_PIPES) { + dm_error("DC: writeback pipe is invalid!\n"); + return false; + } + + if (stream->num_wb_info > MAX_DWB_PIPES) { + dm_error("DC: num_wb_info is invalid!\n"); + return false; + } + + if (dwb->funcs->set_fc_enable) + dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE); + + return true; +} + bool dc_stream_remove_writeback(struct dc *dc, struct dc_stream_state *stream, uint32_t dwb_pipe_inst) diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index e03bb0e32e1d..889610a8b26b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -454,6 +454,10 @@ bool dc_stream_add_writeback(struct dc *dc, struct dc_stream_state *stream, struct dc_writeback_info *wb_info); +bool dc_stream_fc_disable_writeback(struct dc *dc, + struct dc_stream_state *stream, + uint32_t dwb_pipe_inst); + bool dc_stream_remove_writeback(struct dc *dc, struct dc_stream_state *stream, uint32_t dwb_pipe_inst); |