summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
diff options
context:
space:
mode:
authorDavid Francis <David.Francis@amd.com>2019-02-21 15:04:05 -0500
committerAlex Deucher <alexander.deucher@amd.com>2019-03-19 15:36:49 -0500
commitc6ade4ee7375c0bb47ba25be53918eaa842ae263 (patch)
treebf17992af2e8c3fe77a6d2ad1182c20a18fb3636 /drivers/gpu/drm/amd/display/dc/core/dc_stream.c
parent0dcdcc898234f87c996adb5de1496e3ec7da315b (diff)
drm/amd/display: On DCN1, Wait for vupdate on cursor updates
[Why] Cursor updates must acquire the pipe control lock to prevent vupdate from triggering in the middle of cursor programming. On DCN1 the pipe control lock prevents pageflips from occurring. This means that a cursor update right before vupdate can delay a pending pageflip [How] If the time until the next vupdate is less than a conservative estimate of the cursor programming time, wait until the vupdate has passed before locking. Signed-off-by: David Francis <David.Francis@amd.com> Reviewed-by: Harry Wentland <Harry.Wentland@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/core/dc_stream.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_stream.c31
1 files changed, 31 insertions, 0 deletions
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 996298c35f42..59ccab36dab8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -29,6 +29,7 @@
#include "resource.h"
#include "ipp.h"
#include "timing_generator.h"
+#include "dcn10/dcn10_hw_sequencer.h"
#define DC_LOGGER dc->ctx->logger
@@ -196,6 +197,32 @@ struct dc_stream_status *dc_stream_get_status(
return dc_stream_get_status_from_state(dc->current_state, stream);
}
+static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc)
+{
+ unsigned int vupdate_line;
+ unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos;
+ struct dc_stream_state *stream = pipe_ctx->stream;
+ unsigned int us_per_line;
+
+ if (stream->ctx->asic_id.chip_family == FAMILY_RV &&
+ ASIC_REV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) {
+
+ vupdate_line = get_vupdate_offset_from_vsync(pipe_ctx);
+ dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos);
+
+ if (vpos >= vupdate_line)
+ return;
+
+ us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz;
+ lines_to_vupdate = vupdate_line - vpos;
+ us_to_vupdate = lines_to_vupdate * us_per_line;
+
+ /* 70 us is a conservative estimate of cursor update time*/
+ if (us_to_vupdate < 70)
+ udelay(us_to_vupdate);
+ }
+}
+
/**
* dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
*/
@@ -234,6 +261,8 @@ bool dc_stream_set_cursor_attributes(
if (!pipe_to_program) {
pipe_to_program = pipe_ctx;
+
+ delay_cursor_until_vupdate(pipe_ctx, core_dc);
core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, true);
}
@@ -283,6 +312,8 @@ bool dc_stream_set_cursor_position(
if (!pipe_to_program) {
pipe_to_program = pipe_ctx;
+
+ delay_cursor_until_vupdate(pipe_ctx, core_dc);
core_dc->hwss.pipe_control_lock(core_dc, pipe_to_program, true);
}