drm/amd/display: Add disable timeout option
authorDuncan Ma <duncan.ma@amd.com>
Tue, 31 Oct 2023 20:57:36 +0000 (16:57 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 17 Nov 2023 14:30:50 +0000 (09:30 -0500)
[WHY]
Driver continues running whenever there is
is timeout from smu or dmcub.

It is difficult to track failure state
when dcn, dc or dmcub changes on root failure.

[HOW]
Add disable_timeout option to halt driver
whenever there is a failure in response.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Duncan Ma <duncan.ma@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/clk_mgr/dcn35/dcn35_smu.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c

index b6b8c3ca1572ccf6097cc48539e868b121aae0cd..af0a0f2925950629113a075f9a1ad35079ac4856 100644 (file)
@@ -116,6 +116,9 @@ static uint32_t dcn35_smu_wait_for_response(struct clk_mgr_internal *clk_mgr, un
                        msleep(delay_us/1000);
                else if (delay_us > 0)
                        udelay(delay_us);
+
+               if (clk_mgr->base.ctx->dc->debug.disable_timeout)
+                       max_retries++;
        } while (max_retries--);
 
        return res_val;
index 9316b737a8ba892c6494687bae472e206d01283d..ae54ef6837f98c50fb7e5e991b08a15e981dec8f 100644 (file)
@@ -978,6 +978,7 @@ struct dc_debug_options {
        bool psp_disabled_wa;
        unsigned int ips2_eval_delay_us;
        unsigned int ips2_entry_delay_us;
+       bool disable_timeout;
 };
 
 struct gpu_info_soc_bounding_box_v1_0;
index 0e07699c1e83529acfbf48ba2f36bea06a0cd884..53400cc05b5b6de5e4522376e94fe9b30fe2caff 100644 (file)
@@ -241,7 +241,12 @@ bool dc_dmub_srv_cmd_run_list(struct dc_dmub_srv *dc_dmub_srv, unsigned int coun
 
        // Wait for DMUB to process command
        if (wait_type != DM_DMUB_WAIT_TYPE_NO_WAIT) {
-               status = dmub_srv_wait_for_idle(dmub, 100000);
+               if (dc_dmub_srv->ctx->dc->debug.disable_timeout) {
+                       do {
+                               status = dmub_srv_wait_for_idle(dmub, 100000);
+                       } while (status != DMUB_STATUS_OK);
+               } else
+                       status = dmub_srv_wait_for_idle(dmub, 100000);
 
                if (status != DMUB_STATUS_OK) {
                        DC_LOG_DEBUG("No reply for DMUB command: status=%d\n", status);
@@ -1147,10 +1152,16 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait)
                return true;
 
        if (wait) {
-               status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 500000);
-               if (status != DMUB_STATUS_OK) {
-                       DC_ERROR("Error querying DMUB hw power up status: error=%d\n", status);
-                       return false;
+               if (dc_dmub_srv->ctx->dc->debug.disable_timeout) {
+                       do {
+                               status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 500000);
+                       } while (status != DMUB_STATUS_OK);
+               } else {
+                       status = dmub_srv_wait_for_hw_pwr_up(dc_dmub_srv->dmub, 500000);
+                       if (status != DMUB_STATUS_OK) {
+                               DC_ERROR("Error querying DMUB hw power up status: error=%d\n", status);
+                               return false;
+                       }
                }
        } else
                return dmub_srv_is_hw_pwr_up(dc_dmub_srv->dmub);
@@ -1187,7 +1198,7 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
        const uint32_t max_num_polls = 10000;
        uint32_t allow_state = 0;
        uint32_t commit_state = 0;
-       uint32_t i;
+       int i;
 
        if (dc->debug.dmcub_emulation)
                return;
@@ -1220,6 +1231,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
                                                break;
 
                                        udelay(1);
+
+                                       if (dc->debug.disable_timeout)
+                                               i--;
                                }
                                ASSERT(i < max_num_polls);
 
@@ -1242,6 +1256,9 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
                                        break;
 
                                udelay(1);
+
+                               if (dc->debug.disable_timeout)
+                                       i--;
                        }
                        ASSERT(i < max_num_polls);
                }