summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
diff options
context:
space:
mode:
authorAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>2017-03-23 15:27:15 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 17:21:04 -0400
commit667e1498a9d0e43849fa84c1c6874184b33aee5f (patch)
tree298606c3350062177be585f64ab1203e4cdbc22a /drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
parent5e141de45218d36a6b98c783834684fd0d617f7a (diff)
drm/amd/display: use CRTC_VERTICAL_INTERRUPT0 as VBLANK trigger.
VBLANK interrupt is driven bu line buffer vcounter which is ahead of CRTC vcounter. Use an interrupt that fires at the actual CRTC vblank start boundry. Signed-off-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Reviewed-by: Andrey Grodzovsky <Andrey.Grodzovsky@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
index f4b8576a0546..006412be7a02 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
@@ -1869,6 +1869,48 @@ void dce110_tg_set_colors(struct timing_generator *tg,
dce110_tg_set_overscan_color(tg, overscan_color);
}
+/* Gets first line of blank region of the display timing for CRTC
+ * and programms is as a trigger to fire vertical interrupt
+ */
+bool dce110_arm_vert_intr(struct timing_generator *tg, uint8_t width)
+{
+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
+ uint32_t vbl = 0;
+ uint32_t val = 0;
+ uint32_t position, vbl_start;
+
+ tg->funcs->get_scanoutpos(
+ tg,
+ &vbl,
+ &position);
+
+ if (vbl == 0)
+ return false;
+
+ vbl_start =
+ get_reg_field_value(
+ vbl,
+ CRTC_V_BLANK_START_END,
+ CRTC_V_BLANK_START);
+
+ set_reg_field_value(
+ val,
+ vbl_start,
+ CRTC_VERTICAL_INTERRUPT0_POSITION,
+ CRTC_VERTICAL_INTERRUPT0_LINE_START);
+
+ /* Set interaval width for interrupt to fire to 1 scanline */
+ set_reg_field_value(
+ val,
+ vbl_start + width,
+ CRTC_VERTICAL_INTERRUPT0_POSITION,
+ CRTC_VERTICAL_INTERRUPT0_LINE_END);
+
+ dm_write_reg(tg->ctx, CRTC_REG(mmCRTC_VERTICAL_INTERRUPT0_POSITION), val);
+
+ return true;
+}
+
static const struct timing_generator_funcs dce110_tg_funcs = {
.validate_timing = dce110_tg_validate_timing,
.program_timing = dce110_tg_program_timing,
@@ -1901,8 +1943,8 @@ static const struct timing_generator_funcs dce110_tg_funcs = {
dce110_timing_generator_set_drr,
.set_static_screen_control =
dce110_timing_generator_set_static_screen_control,
- .set_test_pattern = dce110_timing_generator_set_test_pattern
-
+ .set_test_pattern = dce110_timing_generator_set_test_pattern,
+ .arm_vert_intr = dce110_arm_vert_intr,
};
bool dce110_timing_generator_construct(