drm/amd/display: Add P-State Stall Timeout Recovery Support for dcn401
authorDillon Varone <dillon.varone@amd.com>
Fri, 11 Oct 2024 17:51:11 +0000 (13:51 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 28 Oct 2024 20:32:35 +0000 (16:32 -0400)
[WHY&HOW]
Adds support for P-State stall timeout detection in DCHUBBUB.

Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Tom Chung <chiahsuan.chung@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/dml2/dml21/inc/dml_top_dchub_registers.h
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c
drivers/gpu/drm/amd/display/dc/hubbub/dcn10/dcn10_hubbub.h
drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c
drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c
drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h
drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h

index 83fc15b..25b607e 100644 (file)
@@ -88,6 +88,7 @@ struct dml2_display_arb_regs {
        uint32_t sdpif_request_rate_limit;
        uint32_t allow_sdpif_rate_limit_when_cstate_req;
        uint32_t dcfclk_deep_sleep_hysteresis;
+       uint32_t pstate_stall_threshold;
 };
 
 struct dml2_cursor_dlg_regs{
index 3ea54fd..92e43a1 100644 (file)
@@ -12236,6 +12236,8 @@ static void rq_dlg_get_dlg_reg(
 
 static void rq_dlg_get_arb_params(const struct dml2_display_cfg *display_cfg, const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_display_arb_regs *arb_param)
 {
+       double refclk_freq_in_mhz = (display_cfg->overrides.hw.dlg_ref_clk_mhz > 0) ? (double)display_cfg->overrides.hw.dlg_ref_clk_mhz : mode_lib->soc.dchub_refclk_mhz;
+
        arb_param->max_req_outstanding = mode_lib->soc.max_outstanding_reqs;
        arb_param->min_req_outstanding = mode_lib->soc.max_outstanding_reqs; // turn off the sat level feature if this set to max
        arb_param->sdpif_request_rate_limit = (3 * mode_lib->ip.words_per_channel * mode_lib->soc.clk_table.dram_config.channel_count) / 4;
@@ -12247,6 +12249,7 @@ static void rq_dlg_get_arb_params(const struct dml2_display_cfg *display_cfg, co
        arb_param->compbuf_size = mode_lib->mp.CompressedBufferSizeInkByte / mode_lib->ip.compressed_buffer_segment_size_in_kbytes;
        arb_param->allow_sdpif_rate_limit_when_cstate_req = dml_get_hw_debug5(mode_lib);
        arb_param->dcfclk_deep_sleep_hysteresis = dml_get_dcfclk_deep_sleep_hysteresis(mode_lib);
+       arb_param->pstate_stall_threshold = (unsigned int)(mode_lib->ip_caps.fams2.max_allow_delay_us * refclk_freq_in_mhz);
 
 #ifdef __DML_VBA_DEBUG__
        dml2_printf("DML::%s: max_req_outstanding = %d\n", __func__, arb_param->max_req_outstanding);
index a1e2cde..4bd1dda 100644 (file)
@@ -198,6 +198,8 @@ struct dcn_hubbub_registers {
        uint32_t DCHUBBUB_ARB_REFCYC_PER_META_TRIP_B;
        uint32_t DCHUBBUB_ARB_FRAC_URG_BW_MALL_A;
        uint32_t DCHUBBUB_ARB_FRAC_URG_BW_MALL_B;
+       uint32_t DCHUBBUB_TIMEOUT_DETECTION_CTRL1;
+       uint32_t DCHUBBUB_TIMEOUT_DETECTION_CTRL2;
 };
 
 #define HUBBUB_REG_FIELD_LIST_DCN32(type) \
@@ -313,7 +315,12 @@ struct dcn_hubbub_registers {
                type DCN_VM_ERROR_VMID;\
                type DCN_VM_ERROR_TABLE_LEVEL;\
                type DCN_VM_ERROR_PIPE;\
-               type DCN_VM_ERROR_INTERRUPT_STATUS
+               type DCN_VM_ERROR_INTERRUPT_STATUS;\
+               type DCHUBBUB_TIMEOUT_ERROR_STATUS;\
+               type DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD;\
+               type DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD;\
+               type DCHUBBUB_TIMEOUT_DETECTION_EN;\
+               type DCHUBBUB_TIMEOUT_TIMER_RESET
 
 #define HUBBUB_STUTTER_REG_FIELD_LIST(type) \
                type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A;\
index 37d26fa..5d658e9 100644 (file)
@@ -1192,6 +1192,17 @@ static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst)
        }
 }
 
+static void dcn401_program_timeout_thresholds(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs)
+{
+       struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub);
+
+       /* request backpressure and outstanding return threshold (unused)*/
+       //REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, arb_regs->req_stall_threshold);
+
+       /* P-State stall threshold */
+       REG_UPDATE(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, arb_regs->pstate_stall_threshold);
+}
+
 static const struct hubbub_funcs hubbub4_01_funcs = {
        .update_dchub = hubbub2_update_dchub,
        .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx,
@@ -1215,6 +1226,7 @@ static const struct hubbub_funcs hubbub4_01_funcs = {
        .program_det_segments = dcn401_program_det_segments,
        .program_compbuf_segments = dcn401_program_compbuf_segments,
        .wait_for_det_update = dcn401_wait_for_det_update,
+       .program_timeout_thresholds = dcn401_program_timeout_thresholds,
 };
 
 void hubbub401_construct(struct dcn20_hubbub *hubbub2,
index f35f19b..5f19607 100644 (file)
        HUBBUB_SF(DCHUBBUB_CLOCK_CNTL, DCFCLK_R_DCHUBBUB_GATE_DIS, mask_sh),\
        HUBBUB_SF(DCHUBBUB_SDPIF_CFG0, SDPIF_PORT_CONTROL, mask_sh),\
        HUBBUB_SF(DCHUBBUB_SDPIF_CFG1, SDPIF_MAX_NUM_OUTSTANDING, mask_sh),\
-       HUBBUB_SF(DCHUBBUB_MEM_PWR_MODE_CTRL, DET_MEM_PWR_LS_MODE, mask_sh)
-
+       HUBBUB_SF(DCHUBBUB_MEM_PWR_MODE_CTRL, DET_MEM_PWR_LS_MODE, mask_sh),\
+       HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_ERROR_STATUS, mask_sh),\
+       HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL1, DCHUBBUB_TIMEOUT_REQ_STALL_THRESHOLD, mask_sh),\
+       HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_PSTATE_STALL_THRESHOLD, mask_sh),\
+       HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_DETECTION_EN, mask_sh),\
+       HUBBUB_SF(DCHUBBUB_TIMEOUT_DETECTION_CTRL2, DCHUBBUB_TIMEOUT_TIMER_RESET, mask_sh)
 
 bool hubbub401_program_urgent_watermarks(
                struct hubbub *hubbub,
index 3c70f40..e8cc1bf 100644 (file)
@@ -1554,6 +1554,11 @@ void dcn401_optimize_bandwidth(
                                                pipe_ctx->dlg_regs.min_dst_y_next_start);
                }
        }
+
+       /* update timeout thresholds */
+       if (hubbub->funcs->program_timeout_thresholds) {
+               hubbub->funcs->program_timeout_thresholds(hubbub, &context->bw_ctx.bw.dcn.arb_regs);
+       }
 }
 
 void dcn401_fams2_global_control_lock(struct dc *dc,
index 67c3240..6c1d41c 100644 (file)
@@ -228,6 +228,7 @@ struct hubbub_funcs {
        void (*program_det_segments)(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg);
        void (*program_compbuf_segments)(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase);
        void (*wait_for_det_update)(struct hubbub *hubbub, int hubp_inst);
+       void (*program_timeout_thresholds)(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs);
 };
 
 struct hubbub {
index bdafa74..7c8d61d 100644 (file)
@@ -610,7 +610,9 @@ void dcn401_prepare_mcache_programming(struct dc *dc, struct dc_state *context);
        SR(DCHUBBUB_CLOCK_CNTL),                                                 \
        SR(DCHUBBUB_SDPIF_CFG0),                                                 \
        SR(DCHUBBUB_SDPIF_CFG1),                                                 \
-       SR(DCHUBBUB_MEM_PWR_MODE_CTRL)
+       SR(DCHUBBUB_MEM_PWR_MODE_CTRL),                                          \
+       SR(DCHUBBUB_TIMEOUT_DETECTION_CTRL1),                                    \
+       SR(DCHUBBUB_TIMEOUT_DETECTION_CTRL2)
 
 /* DCCG */