drm/amd/display: Raise DPG height during timing synchronization
authorTaimur Hassan <syed.hassan@amd.com>
Sun, 4 Oct 2020 19:20:45 +0000 (15:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 26 Oct 2020 17:29:21 +0000 (13:29 -0400)
[Why]
Underflow counter increases in AGM when performing some mode switches due
to timing sync, which is a known hardware issue.

[How]
Temporarily raise DPG height during timing sync so that underflow is not
reported.

Signed-off-by: Taimur Hassan <syed.hassan@amd.com>
Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h
drivers/gpu/drm/amd/display/dc/inc/hw/opp.h

index 9528e3a..6b141c9 100644 (file)
@@ -1847,10 +1847,20 @@ void dcn10_enable_timing_synchronization(
        struct pipe_ctx *grouped_pipes[])
 {
        struct dc_context *dc_ctx = dc->ctx;
-       int i;
+       struct output_pixel_processor *opp;
+       struct timing_generator *tg;
+       int i, width, height;
 
        DC_SYNC_INFO("Setting up OTG reset trigger\n");
 
+       for (i = 1; i < group_size; i++) {
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, 2*(height) + 1);
+       }
+
        for (i = 1; i < group_size; i++)
                grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger(
                                grouped_pipes[i]->stream_res.tg,
@@ -1867,6 +1877,14 @@ void dcn10_enable_timing_synchronization(
                grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger(
                                grouped_pipes[i]->stream_res.tg);
 
+       for (i = 1; i < group_size; i++) {
+               opp = grouped_pipes[i]->stream_res.opp;
+               tg = grouped_pipes[i]->stream_res.tg;
+               tg->funcs->get_otg_active_size(tg, &width, &height);
+               if (opp->funcs->opp_program_dpg_dimensions)
+                       opp->funcs->opp_program_dpg_dimensions(opp, width, height);
+       }
+
        DC_SYNC_INFO("Sync complete\n");
 }
 
index d79718f..d54d731 100644 (file)
@@ -403,6 +403,7 @@ static const struct opp_funcs dcn10_opp_funcs = {
                .opp_program_stereo = opp1_program_stereo,
                .opp_pipe_clock_control = opp1_pipe_clock_control,
                .opp_set_disp_pattern_generator = NULL,
+               .opp_program_dpg_dimensions = NULL,
                .dpg_is_blanked = NULL,
                .opp_destroy = opp1_destroy
 };
index 138321e..0784d01 100644 (file)
@@ -290,6 +290,17 @@ void opp2_set_disp_pattern_generator(
        }
 }
 
+void opp2_program_dpg_dimensions(
+               struct output_pixel_processor *opp,
+               int width, int height)
+{
+       struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
+
+       REG_SET_2(DPG_DIMENSIONS, 0,
+               DPG_ACTIVE_WIDTH, width,
+               DPG_ACTIVE_HEIGHT, height);
+}
+
 void opp2_dpg_set_blank_color(
                struct output_pixel_processor *opp,
                const struct tg_color *color)
@@ -350,6 +361,7 @@ static struct opp_funcs dcn20_opp_funcs = {
                .opp_program_stereo = opp1_program_stereo,
                .opp_pipe_clock_control = opp1_pipe_clock_control,
                .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
+               .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
                .dpg_is_blanked = opp2_dpg_is_blanked,
                .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
                .opp_destroy = opp1_destroy,
index 64c5b42..3ab221b 100644 (file)
@@ -153,6 +153,10 @@ void opp2_set_disp_pattern_generator(
        int height,
        int offset);
 
+void opp2_program_dpg_dimensions(
+               struct output_pixel_processor *opp,
+               int width, int height);
+
 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp);
 
 void opp2_dpg_set_blank_color(
index 2717352..7617fab 100644 (file)
@@ -313,6 +313,11 @@ struct opp_funcs {
                        int height,
                        int offset);
 
+       void (*opp_program_dpg_dimensions)(
+                               struct output_pixel_processor *opp,
+                               int width,
+                               int height);
+
        bool (*dpg_is_blanked)(
                        struct output_pixel_processor *opp);