OSDN Git Service

drm/amd/display: Update DPG test pattern programming
authorWenjing Liu <wenjing.liu@amd.com>
Thu, 13 Jul 2023 22:40:51 +0000 (18:40 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Jul 2023 17:40:47 +0000 (13:40 -0400)
[Why]
Last ODM slice could be slightly larger than other slice because it can be
including the residual.

[How]
Update DPG pattern programming sequence to use a different width for
last odm slice.

Reviewed-by: Chris Park <chris.park@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c

index 5cfa378..e32d324 100644 (file)
@@ -1054,9 +1054,9 @@ void dcn20_blank_pixel_data(
        enum controller_dp_color_space test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
        struct pipe_ctx *odm_pipe;
        int odm_cnt = 1;
-
-       int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
-       int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
+       int h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
+       int v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
+       int odm_slice_width, last_odm_slice_width, offset = 0;
 
        if (stream->link->test_pattern_enabled)
                return;
@@ -1066,8 +1066,8 @@ void dcn20_blank_pixel_data(
 
        for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
                odm_cnt++;
-
-       width = width / odm_cnt;
+       odm_slice_width = h_active / odm_cnt;
+       last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
 
        if (blank) {
                dc->hwss.set_abm_immediate_disable(pipe_ctx);
@@ -1080,29 +1080,32 @@ void dcn20_blank_pixel_data(
                test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
        }
 
-       dc->hwss.set_disp_pattern_generator(dc,
-                       pipe_ctx,
-                       test_pattern,
-                       test_pattern_color_space,
-                       stream->timing.display_color_depth,
-                       &black_color,
-                       width,
-                       height,
-                       0);
+       odm_pipe = pipe_ctx;
 
-       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
+       while (odm_pipe->next_odm_pipe) {
                dc->hwss.set_disp_pattern_generator(dc,
-                               odm_pipe,
-                               dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ?
-                                               CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern,
+                               pipe_ctx,
+                               test_pattern,
                                test_pattern_color_space,
                                stream->timing.display_color_depth,
                                &black_color,
-                               width,
-                               height,
-                               0);
+                               odm_slice_width,
+                               v_active,
+                               offset);
+               offset += odm_slice_width;
+               odm_pipe = odm_pipe->next_odm_pipe;
        }
 
+       dc->hwss.set_disp_pattern_generator(dc,
+                       odm_pipe,
+                       test_pattern,
+                       test_pattern_color_space,
+                       stream->timing.display_color_depth,
+                       &black_color,
+                       last_odm_slice_width,
+                       v_active,
+                       offset);
+
        if (!blank && dc->debug.enable_single_display_2to1_odm_policy) {
                /* when exiting dynamic ODM need to reinit DPG state for unused pipes */
                struct pipe_ctx *old_odm_pipe = dc->current_state->res_ctx.pipe_ctx[pipe_ctx->pipe_idx].next_odm_pipe;
index db9f1ba..bce0428 100644 (file)
@@ -428,15 +428,24 @@ static void set_crtc_test_pattern(struct dc_link *link,
                stream->timing.display_color_depth;
        struct bit_depth_reduction_params params;
        struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
-       int width = pipe_ctx->stream->timing.h_addressable +
+       struct pipe_ctx *odm_pipe;
+       int odm_cnt = 1;
+       int h_active = pipe_ctx->stream->timing.h_addressable +
                pipe_ctx->stream->timing.h_border_left +
                pipe_ctx->stream->timing.h_border_right;
-       int height = pipe_ctx->stream->timing.v_addressable +
+       int v_active = pipe_ctx->stream->timing.v_addressable +
                pipe_ctx->stream->timing.v_border_bottom +
                pipe_ctx->stream->timing.v_border_top;
+       int odm_slice_width, last_odm_slice_width, offset = 0;
 
        memset(&params, 0, sizeof(params));
 
+       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
+               odm_cnt++;
+
+       odm_slice_width = h_active / odm_cnt;
+       last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);
+
        switch (test_pattern) {
        case DP_TEST_PATTERN_COLOR_SQUARES:
                controller_test_pattern =
@@ -473,16 +482,13 @@ static void set_crtc_test_pattern(struct dc_link *link,
        {
                /* disable bit depth reduction */
                pipe_ctx->stream->bit_depth_params = params;
-               opp->funcs->opp_program_bit_depth_reduction(opp, &params);
-               if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
+               if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
+                       opp->funcs->opp_program_bit_depth_reduction(opp, &params);
                        pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
                                controller_test_pattern, color_depth);
-               else if (link->dc->hwss.set_disp_pattern_generator) {
-                       struct pipe_ctx *odm_pipe;
+               } else if (link->dc->hwss.set_disp_pattern_generator) {
                        enum controller_dp_color_space controller_color_space;
-                       int opp_cnt = 1;
-                       int offset = 0;
-                       int dpg_width = width;
+                       struct output_pixel_processor *odm_opp;
 
                        switch (test_pattern_color_space) {
                        case DP_TEST_PATTERN_COLOR_SPACE_RGB:
@@ -502,36 +508,33 @@ static void set_crtc_test_pattern(struct dc_link *link,
                                break;
                        }
 
-                       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-                               opp_cnt++;
-                       dpg_width = width / opp_cnt;
-                       offset = dpg_width;
-
-                       link->dc->hwss.set_disp_pattern_generator(link->dc,
-                                       pipe_ctx,
-                                       controller_test_pattern,
-                                       controller_color_space,
-                                       color_depth,
-                                       NULL,
-                                       dpg_width,
-                                       height,
-                                       0);
-
-                       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                               struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
-
+                       odm_pipe = pipe_ctx;
+                       while (odm_pipe->next_odm_pipe) {
+                               odm_opp = odm_pipe->stream_res.opp;
                                odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
                                link->dc->hwss.set_disp_pattern_generator(link->dc,
-                                               odm_pipe,
+                                               pipe_ctx,
                                                controller_test_pattern,
                                                controller_color_space,
                                                color_depth,
                                                NULL,
-                                               dpg_width,
-                                               height,
+                                               odm_slice_width,
+                                               v_active,
                                                offset);
-                               offset += offset;
+                               offset += odm_slice_width;
+                               odm_pipe = odm_pipe->next_odm_pipe;
                        }
+                       odm_opp = odm_pipe->stream_res.opp;
+                       odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
+                       link->dc->hwss.set_disp_pattern_generator(link->dc,
+                                       odm_pipe,
+                                       controller_test_pattern,
+                                       controller_color_space,
+                                       color_depth,
+                                       NULL,
+                                       last_odm_slice_width,
+                                       v_active,
+                                       offset);
                }
        }
        break;
@@ -540,23 +543,17 @@ static void set_crtc_test_pattern(struct dc_link *link,
                /* restore bitdepth reduction */
                resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
                pipe_ctx->stream->bit_depth_params = params;
-               opp->funcs->opp_program_bit_depth_reduction(opp, &params);
-               if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
+               if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
+                       opp->funcs->opp_program_bit_depth_reduction(opp, &params);
                        pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
-                               CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
-                               color_depth);
-               else if (link->dc->hwss.set_disp_pattern_generator) {
-                       struct pipe_ctx *odm_pipe;
-                       int opp_cnt = 1;
-                       int dpg_width;
-
-                       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
-                               opp_cnt++;
-
-                       dpg_width = width / opp_cnt;
-                       for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
-                               struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
+                                       CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
+                                       color_depth);
+               } else if (link->dc->hwss.set_disp_pattern_generator) {
+                       struct output_pixel_processor *odm_opp;
 
+                       odm_pipe = pipe_ctx;
+                       while (odm_pipe->next_odm_pipe) {
+                               odm_opp = odm_pipe->stream_res.opp;
                                odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
                                link->dc->hwss.set_disp_pattern_generator(link->dc,
                                                odm_pipe,
@@ -564,19 +561,23 @@ static void set_crtc_test_pattern(struct dc_link *link,
                                                CONTROLLER_DP_COLOR_SPACE_UDEFINED,
                                                color_depth,
                                                NULL,
-                                               dpg_width,
-                                               height,
-                                               0);
+                                               odm_slice_width,
+                                               v_active,
+                                               offset);
+                               offset += odm_slice_width;
+                               odm_pipe = odm_pipe->next_odm_pipe;
                        }
+                       odm_opp = odm_pipe->stream_res.opp;
+                       odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
                        link->dc->hwss.set_disp_pattern_generator(link->dc,
-                                       pipe_ctx,
+                                       odm_pipe,
                                        CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
                                        CONTROLLER_DP_COLOR_SPACE_UDEFINED,
                                        color_depth,
                                        NULL,
-                                       dpg_width,
-                                       height,
-                                       0);
+                                       last_odm_slice_width,
+                                       v_active,
+                                       offset);
                }
        }
        break;