diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3946-drm-amd-display-Add-vline-IRQ-programming-for-DCN.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3946-drm-amd-display-Add-vline-IRQ-programming-for-DCN.patch | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3946-drm-amd-display-Add-vline-IRQ-programming-for-DCN.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3946-drm-amd-display-Add-vline-IRQ-programming-for-DCN.patch new file mode 100644 index 00000000..29cde47b --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3946-drm-amd-display-Add-vline-IRQ-programming-for-DCN.patch @@ -0,0 +1,238 @@ +From 871cd91f15ce62e16082eb0249f2e74b74f03886 Mon Sep 17 00:00:00 2001 +From: SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com> +Date: Wed, 14 Mar 2018 09:15:24 -0400 +Subject: [PATCH 3946/4131] drm/amd/display: Add vline IRQ programming for DCN + +Signed-off-by: SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com> +Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++ + drivers/gpu/drm/amd/display/dc/dc_stream.h | 4 ++ + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 76 ++++++++++++++++++++++ + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h | 14 ++++ + .../drm/amd/display/dc/inc/hw/timing_generator.h | 3 + + drivers/gpu/drm/amd/display/dc/irq_types.h | 7 ++ + 6 files changed, 110 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 5978e0f..735745e 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1375,6 +1375,12 @@ static void commit_planes_for_stream(struct dc *dc, + pipe_ctx->stream_res.abm->funcs->set_abm_level( + pipe_ctx->stream_res.abm, stream->abm_level); + } ++ ++ if (stream_update && stream_update->periodic_fn_vsync_delta && ++ pipe_ctx->stream_res.tg->funcs->program_vline_interrupt) ++ pipe_ctx->stream_res.tg->funcs->program_vline_interrupt( ++ pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, ++ pipe_ctx->stream->periodic_fn_vsync_delta); + } + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h +index 3a7093e..8d51610 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h +@@ -70,6 +70,9 @@ struct dc_stream_state { + enum color_transfer_func output_tf; + + bool ignore_msa_timing_param; ++ ++ unsigned long long periodic_fn_vsync_delta; ++ + /* TODO: custom INFO packets */ + /* TODO: ABM info (DMCU) */ + /* PSR info */ +@@ -113,6 +116,7 @@ struct dc_stream_update { + struct dc_hdr_static_metadata *hdr_static_metadata; + enum color_transfer_func color_output_tf; + unsigned int *abm_level; ++ unsigned long long *periodic_fn_vsync_delta; + }; + + bool dc_is_stream_unchanged( +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +index 4bf64d1..f56eac0 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +@@ -93,6 +93,81 @@ static void optc1_disable_stereo(struct timing_generator *optc) + OTG_3D_STRUCTURE_STEREO_SEL_OVR, 0); + } + ++static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_crtc_timing *dc_crtc_timing) ++{ ++ struct dc_crtc_timing patched_crtc_timing; ++ uint32_t vesa_sync_start; ++ uint32_t asic_blank_end; ++ uint32_t interlace_factor; ++ uint32_t vertical_line_start; ++ ++ patched_crtc_timing = *dc_crtc_timing; ++ optc1_apply_front_porch_workaround(optc, &patched_crtc_timing); ++ ++ vesa_sync_start = patched_crtc_timing.h_addressable + ++ patched_crtc_timing.h_border_right + ++ patched_crtc_timing.h_front_porch; ++ ++ asic_blank_end = patched_crtc_timing.h_total - ++ vesa_sync_start - ++ patched_crtc_timing.h_border_left; ++ ++ interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1; ++ ++ vesa_sync_start = patched_crtc_timing.v_addressable + ++ patched_crtc_timing.v_border_bottom + ++ patched_crtc_timing.v_front_porch; ++ ++ asic_blank_end = (patched_crtc_timing.v_total - ++ vesa_sync_start - ++ patched_crtc_timing.v_border_top) ++ * interlace_factor; ++ ++ vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; ++ if (vertical_line_start < 0) { ++ ASSERT(0); ++ vertical_line_start = 0; ++ } ++ ++ return vertical_line_start; ++} ++ ++void optc1_program_vline_interrupt( ++ struct timing_generator *optc, ++ const struct dc_crtc_timing *dc_crtc_timing, ++ unsigned long long vsync_delta) ++{ ++ ++ struct optc *optc1 = DCN10TG_FROM_TG(optc); ++ ++ unsigned long long req_delta_tens_of_usec = div64_u64((vsync_delta + 9999), 10000); ++ unsigned long long pix_clk_hundreds_khz = div64_u64((dc_crtc_timing->pix_clk_khz + 99), 100); ++ uint32_t req_delta_lines = (uint32_t) div64_u64( ++ (req_delta_tens_of_usec * pix_clk_hundreds_khz + dc_crtc_timing->h_total - 1), ++ dc_crtc_timing->h_total); ++ ++ uint32_t vsync_line = get_start_vline(optc, dc_crtc_timing); ++ uint32_t start_line = 0; ++ uint32_t endLine = 0; ++ ++ if (req_delta_lines != 0) ++ req_delta_lines--; ++ ++ if (req_delta_lines > vsync_line) ++ start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) - 1; ++ else ++ start_line = vsync_line - req_delta_lines; ++ ++ endLine = start_line + 2; ++ ++ if (endLine >= dc_crtc_timing->v_total) ++ endLine = 2; ++ ++ REG_SET_2(OTG_VERTICAL_INTERRUPT0_POSITION, 0, ++ OTG_VERTICAL_INTERRUPT0_LINE_START, start_line, ++ OTG_VERTICAL_INTERRUPT0_LINE_END, endLine); ++} ++ + /** + * program_timing_generator used by mode timing set + * Program CRTC Timing Registers - OTG_H_*, OTG_V_*, Pixel repetition. +@@ -1215,6 +1290,7 @@ static bool optc1_is_optc_underflow_occurred(struct timing_generator *optc) + static const struct timing_generator_funcs dcn10_tg_funcs = { + .validate_timing = optc1_validate_timing, + .program_timing = optc1_program_timing, ++ .program_vline_interrupt = optc1_program_vline_interrupt, + .program_global_sync = optc1_program_global_sync, + .enable_crtc = optc1_enable_crtc, + .disable_crtc = optc1_disable_crtc, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +index d25e7bf..5a9a73d 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h +@@ -65,6 +65,8 @@ + SRI(OTG_NOM_VERT_POSITION, OTG, inst),\ + SRI(OTG_BLACK_COLOR, OTG, inst),\ + SRI(OTG_CLOCK_CONTROL, OTG, inst),\ ++ SRI(OTG_VERTICAL_INTERRUPT0_CONTROL, OTG, inst),\ ++ SRI(OTG_VERTICAL_INTERRUPT0_POSITION, OTG, inst),\ + SRI(OTG_VERTICAL_INTERRUPT2_CONTROL, OTG, inst),\ + SRI(OTG_VERTICAL_INTERRUPT2_POSITION, OTG, inst),\ + SRI(OPTC_INPUT_CLOCK_CONTROL, ODM, inst),\ +@@ -124,6 +126,8 @@ struct dcn_optc_registers { + uint32_t OTG_TEST_PATTERN_CONTROL; + uint32_t OTG_TEST_PATTERN_COLOR; + uint32_t OTG_CLOCK_CONTROL; ++ uint32_t OTG_VERTICAL_INTERRUPT0_CONTROL; ++ uint32_t OTG_VERTICAL_INTERRUPT0_POSITION; + uint32_t OTG_VERTICAL_INTERRUPT2_CONTROL; + uint32_t OTG_VERTICAL_INTERRUPT2_POSITION; + uint32_t OPTC_INPUT_CLOCK_CONTROL; +@@ -206,6 +210,9 @@ struct dcn_optc_registers { + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_EN, mask_sh),\ + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_ON, mask_sh),\ + SF(OTG0_OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, mask_sh),\ ++ SF(OTG0_OTG_VERTICAL_INTERRUPT0_CONTROL, OTG_VERTICAL_INTERRUPT0_INT_ENABLE, mask_sh),\ ++ SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_START, mask_sh),\ ++ SF(OTG0_OTG_VERTICAL_INTERRUPT0_POSITION, OTG_VERTICAL_INTERRUPT0_LINE_END, mask_sh),\ + SF(OTG0_OTG_VERTICAL_INTERRUPT2_CONTROL, OTG_VERTICAL_INTERRUPT2_INT_ENABLE, mask_sh),\ + SF(OTG0_OTG_VERTICAL_INTERRUPT2_POSITION, OTG_VERTICAL_INTERRUPT2_LINE_START, mask_sh),\ + SF(ODM0_OPTC_INPUT_CLOCK_CONTROL, OPTC_INPUT_CLK_EN, mask_sh),\ +@@ -323,6 +330,9 @@ struct dcn_optc_registers { + type OTG_CLOCK_EN;\ + type OTG_CLOCK_ON;\ + type OTG_CLOCK_GATE_DIS;\ ++ type OTG_VERTICAL_INTERRUPT0_INT_ENABLE;\ ++ type OTG_VERTICAL_INTERRUPT0_LINE_START;\ ++ type OTG_VERTICAL_INTERRUPT0_LINE_END;\ + type OTG_VERTICAL_INTERRUPT2_INT_ENABLE;\ + type OTG_VERTICAL_INTERRUPT2_LINE_START;\ + type OPTC_INPUT_CLK_EN;\ +@@ -420,6 +430,10 @@ void optc1_program_timing( + const struct dc_crtc_timing *dc_crtc_timing, + bool use_vbios); + ++void optc1_program_vline_interrupt(struct timing_generator *optc, ++ const struct dc_crtc_timing *dc_crtc_timing, ++ unsigned long long vsync_delta); ++ + void optc1_program_global_sync( + struct timing_generator *optc); + +diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +index 3217b5b..69cb0a1 100644 +--- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h ++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +@@ -140,6 +140,9 @@ struct timing_generator_funcs { + void (*program_timing)(struct timing_generator *tg, + const struct dc_crtc_timing *timing, + bool use_vbios); ++ void (*program_vline_interrupt)(struct timing_generator *optc, ++ const struct dc_crtc_timing *dc_crtc_timing, ++ unsigned long long vsync_delta); + bool (*enable_crtc)(struct timing_generator *tg); + bool (*disable_crtc)(struct timing_generator *tg); + bool (*is_counter_moving)(struct timing_generator *tg); +diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h +index a506c2e..cc3b1bc 100644 +--- a/drivers/gpu/drm/amd/display/dc/irq_types.h ++++ b/drivers/gpu/drm/amd/display/dc/irq_types.h +@@ -135,6 +135,13 @@ enum dc_irq_source { + DC_IRQ_SOURCE_VBLANK5, + DC_IRQ_SOURCE_VBLANK6, + ++ DC_IRQ_SOURCE_DC1_VLINE0, ++ DC_IRQ_SOURCE_DC2_VLINE0, ++ DC_IRQ_SOURCE_DC3_VLINE0, ++ DC_IRQ_SOURCE_DC4_VLINE0, ++ DC_IRQ_SOURCE_DC5_VLINE0, ++ DC_IRQ_SOURCE_DC6_VLINE0, ++ + DAL_IRQ_SOURCES_NUMBER + }; + +-- +2.7.4 + |