OSDN Git Service

drm/amd/display: Reduce CPU busy-waiting for long delays
authorAric Cyr <aric.cyr@amd.com>
Fri, 3 Feb 2023 22:46:05 +0000 (17:46 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 28 Feb 2023 19:29:35 +0000 (14:29 -0500)
[WHY]
udelay should not be used for long waits since it keeps CPU active,
wasting power.

[HOW]
Use fsleep where acceptable to allow CPU cores to be parked by the scheduler.

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Aric Cyr <aric.cyr@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/dce/dce_aux.c
drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
drivers/gpu/drm/amd/display/dc/link/link_dpms.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c

index 140297c..739298d 100644 (file)
@@ -832,13 +832,8 @@ bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
                                                                        LOG_FLAG_I2cAux_DceAux,
                                                                        "dce_aux_transfer_with_retries: payload->defer_delay=%u",
                                                                        payload->defer_delay);
-                                               if (payload->defer_delay > 1) {
-                                                       msleep(payload->defer_delay);
-                                                       defer_time_in_ms += payload->defer_delay;
-                                               } else if (payload->defer_delay <= 1) {
-                                                       udelay(payload->defer_delay * 1000);
-                                                       defer_time_in_ms += payload->defer_delay;
-                                               }
+                                               fsleep(payload->defer_delay * 1000);
+                                               defer_time_in_ms += payload->defer_delay;
                                        }
                                }
                                break;
index d3cc5ec..e74266c 100644 (file)
@@ -586,7 +586,7 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, bool enable, bool wait)
                                if (state == PSR_STATE0)
                                        break;
                        }
-                       udelay(500);
+                       fsleep(500);
                }
 
                /* assert if max retry hit */
index 1e2d2cb..19440bd 100644 (file)
@@ -215,7 +215,7 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool enable, bool wait, uint8
                                        break;
                        }
 
-                       udelay(500);
+                       fsleep(500);
                }
 
                /* assert if max retry hit */
index 257e1c3..180c92a 100644 (file)
@@ -1153,7 +1153,7 @@ static bool poll_for_allocation_change_trigger(struct dc_link *link)
                        break;
                }
 
-               msleep(5);
+               fsleep(5000);
        }
 
        if (result == ACT_FAILED) {
@@ -1640,7 +1640,7 @@ static bool write_128b_132b_sst_payload_allocation_table(
                        }
                }
                retries++;
-               msleep(5);
+               fsleep(5000);
        }
 
        if (!result && retries == max_retries) {
index d437085..0f2c598 100644 (file)
@@ -1005,7 +1005,7 @@ static enum dc_status wake_up_aux_channel(struct dc_link *link)
                 * signal and may need up to 1 ms before being able to reply.
                 */
                if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3) {
-                       udelay(1000);
+                       fsleep(1000);
                        aux_channel_retry_cnt++;
                }
        }
@@ -2121,7 +2121,7 @@ static bool dp_verify_link_cap(
 
                if (status == LINK_TRAINING_SUCCESS) {
                        success = true;
-                       udelay(1000);
+                       fsleep(1000);
                        if (dc_link_dp_read_hpd_rx_irq_data(link, &irq_data) == DC_OK &&
                                        dc_link_check_link_loss_status(
                                                        link,
@@ -2171,7 +2171,7 @@ bool dp_verify_link_cap_with_retries(
                        success = true;
                        break;
                }
-               msleep(10);
+               fsleep(10 * 1000);
        }
 
        dp_trace_lt_fail_count_update(link, fail_count, true);
@@ -2231,7 +2231,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link)
                gpio_result = dal_gpio_get_value(ddc->pin_clock, &clock_pin);
                ASSERT(gpio_result == GPIO_RESULT_OK);
                if (clock_pin)
-                       udelay(1000);
+                       fsleep(1000);
                else
                        break;
        } while (retry++ < 3);
index f69e681..fcb82bb 100644 (file)
@@ -424,7 +424,7 @@ int dc_link_dp_dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *li
                                timeout--;
                        else
                                break;
-                       udelay(10 * 1000);
+                       fsleep(10 * 1000);
                } while (!get_cm_response_ready_flag(link));
 
                if (!timeout)
index b48d4d8..5e613ea 100644 (file)
@@ -258,10 +258,7 @@ void dp_wait_for_training_aux_rd_interval(
        struct dc_link *link,
        uint32_t wait_in_micro_secs)
 {
-       if (wait_in_micro_secs > 1000)
-               msleep(wait_in_micro_secs/1000);
-       else
-               udelay(wait_in_micro_secs);
+       fsleep(wait_in_micro_secs);
 
        DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
                __func__,
@@ -970,7 +967,7 @@ static void dpcd_exit_training_mode(struct dc_link *link, enum dp_link_encoding
                        if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) &&
                                        (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0)
                                break;
-                       udelay(1000);
+                       fsleep(1000);
                }
        }
 }
index e60da05..9715fa7 100644 (file)
@@ -1035,7 +1035,7 @@ enum link_training_result dc_link_dpia_perform_link_training(
         * falling back to lower bandwidth settings possible.
         */
        if (result == LINK_TRAINING_SUCCESS) {
-               msleep(5);
+               fsleep(5000);
                if (!link->is_automated)
                        result = dp_check_link_loss_status(link, &lt_settings);
        } else if (result == LINK_TRAINING_ABORT)
index 97e02b5..da7f838 100644 (file)
@@ -325,7 +325,7 @@ bool dc_link_wait_for_t12(struct dc_link *link)
 void link_edp_add_delay_for_T9(struct dc_link *link)
 {
        if (link && link->panel_config.pps.extra_delay_backlight_off > 0)
-               udelay(link->panel_config.pps.extra_delay_backlight_off * 1000);
+               fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000);
 }
 
 bool link_edp_receiver_ready_T9(struct dc_link *link)
@@ -383,7 +383,7 @@ bool link_edp_receiver_ready_T7(struct dc_link *link)
        }
 
        if (link && link->panel_config.pps.extra_t7_ms > 0)
-               udelay(link->panel_config.pps.extra_t7_ms * 1000);
+               fsleep(link->panel_config.pps.extra_t7_ms * 1000);
 
        return result;
 }