From: Dmytro Laktyushkin <dmytro.laktyush...@amd.com>

Current optc odm interface only accepts 2 opps, we need to
expand this to allow 4 to 1 odm combine.

Signed-off-by: Dmytro Laktyushkin <dmytro.laktyush...@amd.com>
Reviewed-by: Charlene Liu <charlene....@amd.com>
Acked-by: Leo Li <sunpeng...@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.c |  3 +--
 .../gpu/drm/amd/display/dc/dcn10/dcn10_optc.h |  2 +-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    | 22 +++++++++++--------
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.c | 20 +++++++++--------
 .../gpu/drm/amd/display/dc/dcn20/dcn20_optc.h |  4 ++--
 .../amd/display/dc/inc/hw/timing_generator.h  |  6 ++---
 6 files changed, 31 insertions(+), 26 deletions(-)

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 a546c2bc9129..b631786a4a34 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c
@@ -287,7 +287,7 @@ void optc1_program_timing(
 
        h_div_2 = optc1_is_two_pixels_per_containter(&patched_crtc_timing);
        REG_UPDATE(OTG_H_TIMING_CNTL,
-                       OTG_H_TIMING_DIV_BY2, h_div_2 || optc1->comb_opp_id != 
0xf);
+                       OTG_H_TIMING_DIV_BY2, h_div_2 || optc1->opp_count == 2);
 
 }
 
@@ -1513,7 +1513,6 @@ void dcn10_timing_generator_init(struct optc *optc1)
        optc1->min_v_blank_interlace = 5;
        optc1->min_h_sync_width = 8;
        optc1->min_v_sync_width = 1;
-       optc1->comb_opp_id = 0xf;
 }
 
 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
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 66c08d05da0e..82d91ab54ba5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.h
@@ -494,7 +494,7 @@ struct optc {
        const struct dcn_optc_shift *tg_shift;
        const struct dcn_optc_mask *tg_mask;
 
-       int comb_opp_id;
+       int opp_count;
 
        uint32_t max_h_total;
        uint32_t max_v_total;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index c3635f5cd990..5904d4d329df 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -545,12 +545,14 @@ enum dc_status dcn20_enable_stream_timing(
 
        /* TODO check if timing_changed, disable stream if timing changed */
 
-       if (odm_pipe)
+       if (odm_pipe) {
+               int opp_inst[2] = { pipe_ctx->stream_res.opp->inst, 
odm_pipe->stream_res.opp->inst };
+
                pipe_ctx->stream_res.tg->funcs->set_odm_combine(
                                pipe_ctx->stream_res.tg,
-                               odm_pipe->stream_res.opp->inst,
-                               pipe_ctx->stream->timing.h_addressable/2,
-                               pipe_ctx->stream->timing.pixel_encoding);
+                               opp_inst, 2,
+                               &pipe_ctx->stream->timing);
+       }
        /* HW program guide assume display already disable
         * by unplug sequence. OTG assume stop.
         */
@@ -822,13 +824,15 @@ static void dcn20_update_odm(struct dc *dc, struct 
dc_state *context, struct pip
 {
        struct pipe_ctx *combine_pipe = dc_res_get_odm_bottom_pipe(pipe_ctx);
 
-       if (combine_pipe)
+       if (combine_pipe) {
+               int opp_inst[2] = { pipe_ctx->stream_res.opp->inst,
+                               combine_pipe->stream_res.opp->inst };
+
                pipe_ctx->stream_res.tg->funcs->set_odm_combine(
                                pipe_ctx->stream_res.tg,
-                               combine_pipe->stream_res.opp->inst,
-                               pipe_ctx->plane_res.scl_data.h_active,
-                               pipe_ctx->stream->timing.pixel_encoding);
-       else
+                               opp_inst, 2,
+                               &pipe_ctx->stream->timing);
+       } else
                pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
                                pipe_ctx->stream_res.tg, 
&pipe_ctx->stream->timing);
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
index 6dede495d0fd..aedf9de1c947 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
@@ -224,7 +224,6 @@ void optc2_set_odm_bypass(struct timing_generator *optc,
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
        uint32_t h_div_2 = 0;
 
-       optc1->comb_opp_id = 0xf;
        REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0,
                        OPTC_NUM_OF_INPUT_SEGMENT, 0,
                        OPTC_SEG0_SRC_SEL, optc->inst,
@@ -236,13 +235,16 @@ void optc2_set_odm_bypass(struct timing_generator *optc,
                        OTG_H_TIMING_DIV_BY2, h_div_2);
        REG_SET(OPTC_MEMORY_CONFIG, 0,
                        OPTC_MEM_SEL, 0);
+       optc1->opp_count = 1;
 }
 
-void optc2_set_odm_combine(struct timing_generator *optc, int combine_opp_id,
-               int mpcc_hactive, enum dc_pixel_encoding pixel_encoding)
+void optc2_set_odm_combine(struct timing_generator *optc, int *opp_id, int 
opp_cnt,
+               struct dc_crtc_timing *timing)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
        /* 2 pieces of memory required for up to 5120 displays, 4 for up to 
8192 */
+       int mpcc_hactive = (timing->h_addressable + timing->h_border_left + 
timing->h_border_right)
+                       / opp_cnt;
        int memory_mask = mpcc_hactive <= 2560 ? 0x3 : 0xf;
        uint32_t data_fmt = 0;
 
@@ -257,23 +259,24 @@ void optc2_set_odm_combine(struct timing_generator *optc, 
int combine_opp_id,
                REG_SET(OPTC_MEMORY_CONFIG, 0,
                        OPTC_MEM_SEL, memory_mask << (optc->inst * 4));
 
-       if (pixel_encoding == PIXEL_ENCODING_YCBCR422)
+       if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
                data_fmt = 1;
-       else if (pixel_encoding == PIXEL_ENCODING_YCBCR420)
+       else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
                data_fmt = 2;
 
        REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt);
 
+       ASSERT(opp_cnt == 2);
        REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0,
                        OPTC_NUM_OF_INPUT_SEGMENT, 1,
-                       OPTC_SEG0_SRC_SEL, optc->inst,
-                       OPTC_SEG1_SRC_SEL, combine_opp_id);
+                       OPTC_SEG0_SRC_SEL, opp_id[0],
+                       OPTC_SEG1_SRC_SEL, opp_id[1]);
 
        REG_UPDATE(OPTC_WIDTH_CONTROL,
                        OPTC_SEGMENT_WIDTH, mpcc_hactive);
 
        REG_SET(OTG_H_TIMING_CNTL, 0, OTG_H_TIMING_DIV_BY2, 1);
-       optc1->comb_opp_id = combine_opp_id;
+       optc1->opp_count = opp_cnt;
 }
 
 void optc2_get_optc_source(struct timing_generator *optc,
@@ -538,6 +541,5 @@ void dcn20_timing_generator_init(struct optc *optc1)
        optc1->min_v_blank_interlace = 5;
        optc1->min_h_sync_width = 4;//  Minimum HSYNC = 8 pixels asked By HW in 
the first place for no actual reason. Oculus Rift S will not light up with 8 as 
it's hsyncWidth is 6. Changing it to 4 to fix that issue.
        optc1->min_v_sync_width = 1;
-       optc1->comb_opp_id = 0xf;
 }
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
index ebf07c582da2..47cb4de1564c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.h
@@ -96,8 +96,8 @@ void optc2_set_dsc_config(struct timing_generator *optc,
 void optc2_set_odm_bypass(struct timing_generator *optc,
                const struct dc_crtc_timing *dc_crtc_timing);
 
-void optc2_set_odm_combine(struct timing_generator *optc, int combine_opp_id,
-               int mpcc_hactive, enum dc_pixel_encoding pixel_encoding);
+void optc2_set_odm_combine(struct timing_generator *optc, int *opp_id, int 
opp_cnt,
+               struct dc_crtc_timing *timing);
 
 void optc2_get_optc_source(struct timing_generator *optc,
                uint32_t *num_of_src_opp,
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 5e93bc0e8ff9..1f83cb7c7dd4 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
@@ -267,9 +267,9 @@ struct timing_generator_funcs {
                               uint32_t dsc_bytes_per_pixel,
                               uint32_t dsc_slice_width);
 #endif
-       void (*set_odm_bypass)(struct timing_generator *tg, const struct 
dc_crtc_timing *dc_crtc_timing);
-       void (*set_odm_combine)(struct timing_generator *tg, int combine_opp_id,
-               int mpcc_hactive, enum dc_pixel_encoding pixel_encoding);
+       void (*set_odm_bypass)(struct timing_generator *optc, const struct 
dc_crtc_timing *dc_crtc_timing);
+       void (*set_odm_combine)(struct timing_generator *optc, int *opp_id, int 
opp_cnt,
+                       struct dc_crtc_timing *timing);
        void (*set_gsl)(struct timing_generator *optc, const struct gsl_params 
*params);
        void (*set_gsl_source_select)(struct timing_generator *optc,
                        int group_idx,
-- 
2.22.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to