drm/amd/display: program DPG_OFFSET_SEGMENT for odm_pipe
authorWenjing Liu <Wenjing.Liu@amd.com>
Tue, 11 Feb 2020 15:27:21 +0000 (10:27 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 5 Mar 2020 05:29:47 +0000 (00:29 -0500)
[why]
When test pattern is enabled with ODM combine, test pattern is generated
by piecing multiple DPGs image together.  The current code will program
all DPGs with horizontal offset of 0. This will cause all DPGs to output
the beginning of the pattern. Instead each DPG should program a
horizontal offset of its x position to form a continous pattern when
pieced together.

Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.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 c81f55b28497229a988af917b700796627a282ef..bf5406eaf7b71e4086abed9dd468d68aa9775403 100644 (file)
@@ -3720,6 +3720,8 @@ static void set_crtc_test_pattern(struct dc_link *link,
                        struct pipe_ctx *odm_pipe;
                        enum controller_dp_color_space controller_color_space;
                        int opp_cnt = 1;
+                       int offset = 0;
+                       int dpg_width = width;
 
                        switch (test_pattern_color_space) {
                        case DP_TEST_PATTERN_COLOR_SPACE_RGB:
@@ -3741,28 +3743,31 @@ static void set_crtc_test_pattern(struct dc_link *link,
 
                        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;
 
-                       width /= opp_cnt;
+                       opp->funcs->opp_set_disp_pattern_generator(opp,
+                               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_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
                                odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
                                        controller_test_pattern,
                                        controller_color_space,
                                        color_depth,
                                        NULL,
-                                       width,
-                                       height);
+                                       dpg_width,
+                                       height,
+                                       offset);
+                               offset += offset;
                        }
-                       opp->funcs->opp_set_disp_pattern_generator(opp,
-                               controller_test_pattern,
-                               controller_color_space,
-                               color_depth,
-                               NULL,
-                               width,
-                               height);
                }
        }
        break;
@@ -3779,11 +3784,12 @@ static void set_crtc_test_pattern(struct dc_link *link,
                else if (opp->funcs->opp_set_disp_pattern_generator) {
                        struct pipe_ctx *odm_pipe;
                        int opp_cnt = 1;
+                       int dpg_width = width;
 
                        for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
                                opp_cnt++;
 
-                       width /= 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;
 
@@ -3793,16 +3799,18 @@ static void set_crtc_test_pattern(struct dc_link *link,
                                        CONTROLLER_DP_COLOR_SPACE_UDEFINED,
                                        color_depth,
                                        NULL,
-                                       width,
-                                       height);
+                                       dpg_width,
+                                       height,
+                                       0);
                        }
                        opp->funcs->opp_set_disp_pattern_generator(opp,
                                CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
                                CONTROLLER_DP_COLOR_SPACE_UDEFINED,
                                color_depth,
                                NULL,
-                               width,
-                               height);
+                               dpg_width,
+                               height,
+                               0);
                }
        }
        break;
index 97c0c8ced8e593b40984639a742cfa08ba1d8c2b..49f5af9e30165ab4271a801211e843a37636d05b 100644 (file)
@@ -307,7 +307,8 @@ void dcn20_init_blank(
                        COLOR_DEPTH_UNDEFINED,
                        &black_color,
                        otg_active_width,
-                       otg_active_height);
+                       otg_active_height,
+                       0);
 
        if (num_opps == 2) {
                bottom_opp->funcs->opp_set_disp_pattern_generator(
@@ -317,7 +318,8 @@ void dcn20_init_blank(
                                COLOR_DEPTH_UNDEFINED,
                                &black_color,
                                otg_active_width,
-                               otg_active_height);
+                               otg_active_height,
+                               0);
        }
 
        hws->funcs.wait_for_blank_complete(opp);
@@ -974,7 +976,8 @@ void dcn20_blank_pixel_data(
                        stream->timing.display_color_depth,
                        &black_color,
                        width,
-                       height);
+                       height,
+                       0);
 
        for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
                odm_pipe->stream_res.opp->funcs->opp_set_disp_pattern_generator(
@@ -985,7 +988,8 @@ void dcn20_blank_pixel_data(
                                stream->timing.display_color_depth,
                                &black_color,
                                width,
-                               height);
+                               height,
+                               0);
        }
 
        if (!blank)
index 023cc71fad0f55f02232b88a5cd0c3875993c398..138321e151eb11f6fe93bc6e6c4c42b4f30bdcb8 100644 (file)
@@ -45,7 +45,8 @@ void opp2_set_disp_pattern_generator(
                enum dc_color_depth color_depth,
                const struct tg_color *solid_color,
                int width,
-               int height)
+               int height,
+               int offset)
 {
        struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
        enum test_pattern_color_format bit_depth;
@@ -92,6 +93,11 @@ void opp2_set_disp_pattern_generator(
                DPG_ACTIVE_WIDTH, width,
                DPG_ACTIVE_HEIGHT, height);
 
+       /* set DPG offset */
+       REG_SET_2(DPG_OFFSET_SEGMENT, 0,
+               DPG_X_OFFSET, offset,
+               DPG_SEGMENT_WIDTH, 0);
+
        switch (test_pattern) {
        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
        case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
index 4093bec172c181479a31aaf276349ae2975f3bf0..64c5b429c79a168eecdf52b319bbd755eb9deec1 100644 (file)
@@ -36,6 +36,7 @@
 #define OPP_DPG_REG_LIST(id) \
        SRI(DPG_CONTROL, DPG, id), \
        SRI(DPG_DIMENSIONS, DPG, id), \
+       SRI(DPG_OFFSET_SEGMENT, DPG, id), \
        SRI(DPG_COLOUR_B_CB, DPG, id), \
        SRI(DPG_COLOUR_G_Y, DPG, id), \
        SRI(DPG_COLOUR_R_CR, DPG, id), \
@@ -53,6 +54,7 @@
        uint32_t FMT_422_CONTROL; \
        uint32_t DPG_CONTROL; \
        uint32_t DPG_DIMENSIONS; \
+       uint32_t DPG_OFFSET_SEGMENT; \
        uint32_t DPG_COLOUR_B_CB; \
        uint32_t DPG_COLOUR_G_Y; \
        uint32_t DPG_COLOUR_R_CR; \
@@ -68,6 +70,8 @@
        OPP_SF(DPG0_DPG_CONTROL, DPG_HRES, mask_sh), \
        OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_WIDTH, mask_sh), \
        OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_HEIGHT, mask_sh), \
+       OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_X_OFFSET, mask_sh), \
+       OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_SEGMENT_WIDTH, mask_sh), \
        OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR0_R_CR, mask_sh), \
        OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR1_R_CR, mask_sh), \
        OPP_SF(DPG0_DPG_COLOUR_B_CB, DPG_COLOUR0_B_CB, mask_sh), \
        type DPG_HRES; \
        type DPG_ACTIVE_WIDTH; \
        type DPG_ACTIVE_HEIGHT; \
+       type DPG_X_OFFSET; \
+       type DPG_SEGMENT_WIDTH; \
        type DPG_COLOUR0_R_CR; \
        type DPG_COLOUR1_R_CR; \
        type DPG_COLOUR0_B_CB; \
@@ -144,7 +150,8 @@ void opp2_set_disp_pattern_generator(
        enum dc_color_depth color_depth,
        const struct tg_color *solid_color,
        int width,
-       int height);
+       int height,
+       int offset);
 
 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp);
 
index 7575564b2265af7f50ab1c473e361a2eaff9cb55..2717352eb697169a362df164bc91e1c2ea676886 100644 (file)
@@ -310,7 +310,8 @@ struct opp_funcs {
                        enum dc_color_depth color_depth,
                        const struct tg_color *solid_color,
                        int width,
-                       int height);
+                       int height,
+                       int offset);
 
        bool (*dpg_is_blanked)(
                        struct output_pixel_processor *opp);