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 c81f55b..bf5406e 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 97c0c8c..49f5af9 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 023cc71..138321e 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 4093bec..64c5b42 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 7575564..2717352 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);