drm/amd/display: Add P-State Keepout to dcn401 Global Sync
authorDillon Varone <dillon.varone@amd.com>
Wed, 3 Jul 2024 16:55:26 +0000 (12:55 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 23 Jul 2024 21:07:12 +0000 (17:07 -0400)
[WHY&HOW]
OTG has new functionality to allow P-State relative to VStartup. Keepout region
for this should be configured based on DML outputs same as other global sync
params.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Jerry Zuo <jerry.zuo@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
20 files changed:
drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c
drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c
drivers/gpu/drm/amd/display/dc/dce60/dce60_timing_generator.c
drivers/gpu/drm/amd/display/dc/dce80/dce80_timing_generator.c
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h
drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/optc.h
drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.c
drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h

index 49bcfe6ec999a5f5da8e05429c267a6ae886ca0e..fa422a8cbced5a26997dda2cd4a66c78dc4865cb 100644 (file)
@@ -1955,6 +1955,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
index 28c58f1dff2d5ac1d7b023b1d835f0fc94fea2a9..ee4de740aceb3c97dc398800caccfb408824b743 100644 (file)
@@ -261,6 +261,7 @@ void dce110_tg_program_timing(struct timing_generator *tg,
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios);
 
index bf35dc65ca29ffdf38b8ae1b16b509bdeef1f788..9837dec837ff27a9fcce74206edaa01233a6ab72 100644 (file)
@@ -438,6 +438,7 @@ static void dce110_timing_generator_v_program_timing(struct timing_generator *tg
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
index eb3557965781eb3930b89d1b2a1e16292bb0f46f..fcf59348eb6249fc8abb488bdd57701c5dd5885d 100644 (file)
@@ -697,6 +697,7 @@ static void dce120_tg_program_timing(struct timing_generator *tg,
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
index c1a85ee374d9dab850a9f102217f2b3cb2cad4a5..e5fb0e8333e43f35d74905319efdf51a30df2ff6 100644 (file)
@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
        if (!use_vbios)
                program_pix_dur(tg, timing->pix_clk_100hz);
 
-       dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios);
+       dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
 }
 
 static void dce60_timing_generator_enable_advanced_request(
index 2df4654858bed2e057aa7f4ddcca5b4a0cefbc8e..003a9330c286916b17324d5702acc3c6928ca251 100644 (file)
@@ -111,13 +111,14 @@ static void program_timing(struct timing_generator *tg,
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
        if (!use_vbios)
                program_pix_dur(tg, timing->pix_clk_100hz);
 
-       dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, use_vbios);
+       dce110_tg_program_timing(tg, timing, 0, 0, 0, 0, 0, 0, use_vbios);
 }
 
 static void dce80_timing_generator_enable_advanced_request(
index 410e4b671228105396c3e57794106c4d5a5453a1..641a8cd019cd52fe1e0cd2a4e9e3564989301822 100644 (file)
@@ -523,6 +523,7 @@ struct _vcs_dpi_display_pipe_dest_params_st {
        unsigned int vupdate_offset;
        unsigned int vupdate_width;
        unsigned int vready_offset;
+       unsigned int pstate_keepout;
        unsigned char interlaced;
        double pixel_rate_mhz;
        unsigned char synchronized_vblank_all_planes;
index e9647f068ee407fff6dad64949be14026aa5dbfa..1fce61323201fa2779b2544cc3b31ffe619f769a 100644 (file)
@@ -1129,6 +1129,7 @@ void dml21_populate_pipe_ctx_dlg_params(struct dml2_context *dml_ctx, struct dc_
        pipe_ctx->pipe_dlg_param.vupdate_offset = global_sync->dcn4.vupdate_offset_pixels;
        pipe_ctx->pipe_dlg_param.vupdate_width = global_sync->dcn4.vupdate_vupdate_width_pixels;
        pipe_ctx->pipe_dlg_param.vready_offset = global_sync->dcn4.vready_offset_pixels;
+       pipe_ctx->pipe_dlg_param.pstate_keepout = global_sync->dcn4.pstate_keepout_start_lines;
 
        pipe_ctx->pipe_dlg_param.otg_inst = pipe_ctx->stream_res.tg->inst;
 
index 982b2d5bfb5fb20a13987d9a041e318c1e60786b..849b41f886d33c050a8375722cc12da357d18909 100644 (file)
@@ -1549,6 +1549,7 @@ static enum dc_status dce110_enable_stream_timing(
                                0,
                                0,
                                0,
+                               0,
                                pipe_ctx->stream->signal,
                                true);
        }
index e06fc370267beaef2cabfa6972c12677be00617f..4846601c612ddaa990ff52227fe4fa4ec9cf7fd5 100644 (file)
@@ -1005,6 +1005,7 @@ enum dc_status dcn10_enable_stream_timing(
                        pipe_ctx->pipe_dlg_param.vstartup_start,
                        pipe_ctx->pipe_dlg_param.vupdate_offset,
                        pipe_ctx->pipe_dlg_param.vupdate_width,
+                       pipe_ctx->pipe_dlg_param.pstate_keepout,
                        pipe_ctx->stream->signal,
                        true);
 
@@ -2995,7 +2996,8 @@ void dcn10_program_pipe(
                                calculate_vready_offset_for_group(pipe_ctx),
                                pipe_ctx->pipe_dlg_param.vstartup_start,
                                pipe_ctx->pipe_dlg_param.vupdate_offset,
-                               pipe_ctx->pipe_dlg_param.vupdate_width);
+                               pipe_ctx->pipe_dlg_param.vupdate_width,
+                               pipe_ctx->pipe_dlg_param.pstate_keepout);
 
                pipe_ctx->stream_res.tg->funcs->set_vtg_params(
                                pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, true);
index 9a00479f04178eb54c4454f24494b873354d3e0f..dd652436a5392022767e8989f7c697807fd32f51 100644 (file)
@@ -909,6 +909,7 @@ enum dc_status dcn20_enable_stream_timing(
                        pipe_ctx->pipe_dlg_param.vstartup_start,
                        pipe_ctx->pipe_dlg_param.vupdate_offset,
                        pipe_ctx->pipe_dlg_param.vupdate_width,
+                       pipe_ctx->pipe_dlg_param.pstate_keepout,
                        pipe_ctx->stream->signal,
                        true);
 
@@ -1885,7 +1886,8 @@ static void dcn20_program_pipe(
                                calculate_vready_offset_for_group(pipe_ctx),
                                pipe_ctx->pipe_dlg_param.vstartup_start,
                                pipe_ctx->pipe_dlg_param.vupdate_offset,
-                               pipe_ctx->pipe_dlg_param.vupdate_width);
+                               pipe_ctx->pipe_dlg_param.vupdate_width,
+                               pipe_ctx->pipe_dlg_param.pstate_keepout);
 
                if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM)
                        pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
@@ -2458,7 +2460,8 @@ bool dcn20_update_bandwidth(
                                        calculate_vready_offset_for_group(pipe_ctx),
                                        pipe_ctx->pipe_dlg_param.vstartup_start,
                                        pipe_ctx->pipe_dlg_param.vupdate_offset,
-                                       pipe_ctx->pipe_dlg_param.vupdate_width);
+                                       pipe_ctx->pipe_dlg_param.vupdate_width,
+                                       pipe_ctx->pipe_dlg_param.pstate_keepout);
 
                        pipe_ctx->stream_res.tg->funcs->set_vtg_params(
                                        pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing, false);
index 31e0e9210dd7e769c53de4e987f0660b8acf4547..d0b4308dca96d775697e9c742ce03d15cbf7a110 100644 (file)
@@ -871,6 +871,7 @@ enum dc_status dcn401_enable_stream_timing(
                        pipe_ctx->pipe_dlg_param.vstartup_start,
                        pipe_ctx->pipe_dlg_param.vupdate_offset,
                        pipe_ctx->pipe_dlg_param.vupdate_width,
+                       pipe_ctx->pipe_dlg_param.pstate_keepout,
                        pipe_ctx->stream->signal,
                        true);
 
index 287bf8a90ff66172de27c02178bb543e9a4a6ba9..03cbcbb36f1c1638d3976275421365ee07f9262b 100644 (file)
@@ -65,6 +65,7 @@ struct optc {
        int vupdate_offset;
        int vupdate_width;
        int vready_offset;
+       int pstate_keepout;
        struct dc_crtc_timing orginal_patched_timing;
        enum signal_type signal;
 };
@@ -110,6 +111,7 @@ void optc1_program_timing(struct timing_generator *optc,
                          int vstartup_start,
                          int vupdate_offset,
                          int vupdate_width,
+                         int pstate_keepout,
                          const enum signal_type signal,
                          bool use_vbios);
 
@@ -127,7 +129,8 @@ void optc1_program_global_sync(struct timing_generator *optc,
                               int vready_offset,
                               int vstartup_start,
                               int vupdate_offset,
-                              int vupdate_width);
+                              int vupdate_width,
+                                  int pstate_keepout);
 
 bool optc1_disable_crtc(struct timing_generator *optc);
 
index 0f453452234cef12e05072839b93f749b24aca61..3d4c8bd42b4920dff974d2b4bf85b319bdbbc03c 100644 (file)
@@ -172,6 +172,7 @@ struct timing_generator_funcs {
                                                        int vstartup_start,
                                                        int vupdate_offset,
                                                        int vupdate_width,
+                                                       int pstate_keepout,
                                                        const enum signal_type signal,
                                                        bool use_vbios
        );
@@ -256,7 +257,8 @@ struct timing_generator_funcs {
                        int vready_offset,
                        int vstartup_start,
                        int vupdate_offset,
-                       int vupdate_width);
+                       int vupdate_width,
+                       int pstate_keepout);
        void (*enable_optc_clock)(struct timing_generator *tg, bool enable);
        void (*program_stereo)(struct timing_generator *tg,
                const struct dc_crtc_timing *timing, struct crtc_stereo_flags *flags);
index 94427875bcdd70bb328f407089f38a6a4d2629a2..f00d27b7c6fe48e18d0058f7fbd6c448972d8b1d 100644 (file)
@@ -65,7 +65,8 @@ void optc1_program_global_sync(
                int vready_offset,
                int vstartup_start,
                int vupdate_offset,
-               int vupdate_width)
+               int vupdate_width,
+               int pstate_keepout)
 {
        struct optc *optc1 = DCN10TG_FROM_TG(optc);
 
@@ -73,6 +74,7 @@ void optc1_program_global_sync(
        optc1->vstartup_start = vstartup_start;
        optc1->vupdate_offset = vupdate_offset;
        optc1->vupdate_width = vupdate_width;
+       optc1->pstate_keepout = pstate_keepout;
 
        if (optc1->vstartup_start == 0) {
                BREAK_TO_DEBUGGER();
@@ -157,6 +159,7 @@ void optc1_program_timing(
        int vstartup_start,
        int vupdate_offset,
        int vupdate_width,
+       int pstate_keepout,
        const enum signal_type signal,
        bool use_vbios)
 {
@@ -177,6 +180,7 @@ void optc1_program_timing(
        optc1->vstartup_start = vstartup_start;
        optc1->vupdate_offset = vupdate_offset;
        optc1->vupdate_width = vupdate_width;
+       optc1->pstate_keepout = pstate_keepout;
        patched_crtc_timing = *dc_crtc_timing;
        apply_front_porch_workaround(&patched_crtc_timing);
        optc1->orginal_patched_timing = patched_crtc_timing;
@@ -282,7 +286,8 @@ void optc1_program_timing(
                        vready_offset,
                        vstartup_start,
                        vupdate_offset,
-                       vupdate_width);
+                       vupdate_width,
+                       pstate_keepout);
 
        optc->funcs->set_vtg_params(optc, dc_crtc_timing, true);
 
index 369a13244e5eccaa43ad52bc9970643b7e813fc9..b7a57f98553d78171113664cb1ad39278014d629 100644 (file)
@@ -201,6 +201,7 @@ struct dcn_optc_registers {
        uint32_t OTG_CRC1_WINDOWB_Y_CONTROL_READBACK;
        uint32_t OPTC_CLOCK_CONTROL;
        uint32_t OPTC_WIDTH_CONTROL2;
+       uint32_t OTG_PSTATE_REGISTER;
 };
 
 #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
@@ -590,7 +591,11 @@ struct dcn_optc_registers {
        type OTG_V_COUNT_STOP_TIMER;
 
 #define TG_REG_FIELD_LIST_DCN401(type) \
-       type OPTC_SEGMENT_WIDTH_LAST;
+       type OPTC_SEGMENT_WIDTH_LAST;\
+       type OTG_PSTATE_KEEPOUT_START;\
+       type OTG_PSTATE_EXTEND;\
+       type OTG_UNBLANK;\
+       type OTG_PSTATE_ALLOW_WIDTH_MIN;
 
 
 struct dcn_optc_shift {
index 9f5c2efa7560b8331bf0e53c5ecdba48229fb08b..a5d6a7dca554c345ae27807208fc0081e6e55d56 100644 (file)
@@ -396,13 +396,47 @@ void optc401_set_vtotal_min_max(struct timing_generator *optc, int vtotal_min, i
        }
 }
 
+static void optc401_program_global_sync(
+               struct timing_generator *optc,
+               int vready_offset,
+               int vstartup_start,
+               int vupdate_offset,
+               int vupdate_width,
+               int pstate_keepout)
+{
+       struct optc *optc1 = DCN10TG_FROM_TG(optc);
+
+       optc1->vready_offset = vready_offset;
+       optc1->vstartup_start = vstartup_start;
+       optc1->vupdate_offset = vupdate_offset;
+       optc1->vupdate_width = vupdate_width;
+       optc1->pstate_keepout = pstate_keepout;
+
+       if (optc1->vstartup_start == 0) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       REG_SET(OTG_VSTARTUP_PARAM, 0,
+               VSTARTUP_START, optc1->vstartup_start);
+
+       REG_SET_2(OTG_VUPDATE_PARAM, 0,
+                       VUPDATE_OFFSET, optc1->vupdate_offset,
+                       VUPDATE_WIDTH, optc1->vupdate_width);
+
+       REG_SET(OTG_VREADY_PARAM, 0,
+                       VREADY_OFFSET, optc1->vready_offset);
+
+       REG_UPDATE(OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, pstate_keepout);
+}
+
 static struct timing_generator_funcs dcn401_tg_funcs = {
                .validate_timing = optc1_validate_timing,
                .program_timing = optc1_program_timing,
                .setup_vertical_interrupt0 = optc1_setup_vertical_interrupt0,
                .setup_vertical_interrupt1 = optc1_setup_vertical_interrupt1,
                .setup_vertical_interrupt2 = optc1_setup_vertical_interrupt2,
-               .program_global_sync = optc1_program_global_sync,
+               .program_global_sync = optc401_program_global_sync,
                .enable_crtc = optc401_enable_crtc,
                .disable_crtc = optc401_disable_crtc,
                .phantom_crtc_post_enable = optc401_phantom_crtc_post_enable,
index 3114ecef332a5c45c59cfa19cb54c21e3dcfd8d5..bb13a645802d0eb6081f57a268426bf13ce8c3d6 100644 (file)
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE, mask_sh),\
        SF(OTG0_OTG_H_TIMING_CNTL, OTG_H_TIMING_DIV_MODE_MANUAL, mask_sh),\
        SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_DRR_TIMING_DBUF_UPDATE_MODE, mask_sh),\
-       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh)
+       SF(OTG0_OTG_DRR_CONTROL, OTG_V_TOTAL_LAST_USED_BY_DRR, mask_sh),\
+       SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_KEEPOUT_START, mask_sh),\
+       SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_EXTEND, mask_sh),\
+       SF(OTG0_OTG_PSTATE_REGISTER, OTG_UNBLANK, mask_sh),\
+       SF(OTG0_OTG_PSTATE_REGISTER, OTG_PSTATE_ALLOW_WIDTH_MIN, mask_sh)
 
 void dcn401_timing_generator_init(struct optc *optc1);
 
index fe518fd27b083dedfeeede55ab8decb92de4256b..91da5cf85b69fa37fbe02c4d71a78cede041617a 100644 (file)
@@ -1163,6 +1163,7 @@ static struct pipe_ctx *dce110_acquire_underlay(
                                0,
                                0,
                                0,
+                               0,
                                pipe_ctx->stream->signal,
                                false);
 
index 26efeada4f41fd7649fa7ad0311ec3ef9c5b6132..106008593464fe36e7534166ef4f4c72c9b42561 100644 (file)
@@ -534,7 +534,8 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context);
        SRI_ARR(OPTC_WIDTH_CONTROL, ODM, inst),                                  \
        SRI_ARR(OPTC_WIDTH_CONTROL2, ODM, inst),                                 \
        SRI_ARR(OPTC_MEMORY_CONFIG, ODM, inst),                                  \
-       SRI_ARR(OTG_DRR_CONTROL, OTG, inst)
+       SRI_ARR(OTG_DRR_CONTROL, OTG, inst),                                                                             \
+       SRI_ARR(OTG_PSTATE_REGISTER, OTG, inst)
 
 /* HUBBUB */
 #define HUBBUB_REG_LIST_DCN4_01_RI(id)                                       \