From: Alex Hung Date: Fri, 23 Jun 2023 15:40:39 +0000 (-0600) Subject: drm/amd/display: Disable DWB frame capture to emulate oneshot X-Git-Tag: v6.7-rc1~145^2~10^2~174 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77a66faaccc0455fe30e326e9a997aec8d0abed4;p=thirdparty%2Fkernel%2Flinux.git 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 Signed-off-by: Alex Hung Signed-off-by: Alex Deucher --- 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 932d56ae0af2a..ed4f3bb50357d 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 2bfe8d98507e1..2e49b0ab91d72 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 e03bb0e32e1dd..889610a8b26b0 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);