diff options
author | Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> | 2024-02-15 19:10:18 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2024-03-20 20:37:37 +0300 |
commit | 460ea5b3b61604171e6668ce1db2d640c4c8ae7f (patch) | |
tree | 326448905dcd251567cbf7d9449b5f5aaff432e1 /drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | |
parent | 2f72e02f2f54a3ccee7808db80ff8ae474a5fcba (diff) | |
download | linux-460ea5b3b61604171e6668ce1db2d640c4c8ae7f.tar.xz |
drm/amd/display: Add debug prints for IPS testing
[WHY]
To log commit states and when we transition in/out of allow and idle
states and the caller.
[HOW]
Add a new logging helper and wrap idle optimization calls to receive
the caller.
Reviewed-by: Duncan Ma <duncan.ma@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index 6083b1dcf050..b168dfc79381 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -910,6 +910,8 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv) return; } + DC_LOG_ERROR("%s: DMCUB error - collecting diagnostic data\n", __func__); + if (!dc_dmub_srv_get_diagnostic_data(dc_dmub_srv, &diag_data)) { DC_LOG_ERROR("%s: dc_dmub_srv_get_diagnostic_data failed.", __func__); return; @@ -1201,6 +1203,7 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait) static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) { + volatile const struct dmub_shared_state_ips_fw *ips_fw; struct dc_dmub_srv *dc_dmub_srv; union dmub_rb_cmd cmd = {0}; @@ -1211,6 +1214,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) return; dc_dmub_srv = dc->ctx->dmub_srv; + ips_fw = &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_FW].data.ips_fw; memset(&cmd, 0, sizeof(cmd)); cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT; @@ -1226,6 +1230,12 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER].data.ips_driver; union dmub_shared_state_ips_driver_signals new_signals; + DC_LOG_IPS( + "%s wait idle (ips1_commit=%d ips2_commit=%d)", + __func__, + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); memset(&new_signals, 0, sizeof(new_signals)); @@ -1250,6 +1260,13 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) ips_driver->signals = new_signals; } + DC_LOG_IPS( + "%s send allow_idle=%d (ips1_commit=%d ips2_commit=%d)", + __func__, + allow_idle, + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + /* NOTE: This does not use the "wake" interface since this is part of the wake path. */ /* We also do not perform a wait since DMCUB could enter idle after the notification. */ dm_execute_dmub_cmd(dc->ctx, &cmd, allow_idle ? DM_DMUB_WAIT_TYPE_NO_WAIT : DM_DMUB_WAIT_TYPE_WAIT); @@ -1276,38 +1293,92 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc) ips_driver->signals.all = 0; + DC_LOG_IPS( + "%s check (allow_ips1=%d allow_ips2=%d) (ips1_commit=%d ips2_commit=%d)", + __func__, + ips_driver->signals.bits.allow_ips1, + ips_driver->signals.bits.allow_ips2, + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + if (prev_driver_signals.bits.allow_ips2) { + DC_LOG_IPS( + "wait IPS2 eval (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + udelay(dc->debug.ips2_eval_delay_us); if (ips_fw->signals.bits.ips2_commit) { + DC_LOG_IPS( + "exit IPS2 #1 (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + // Tell PMFW to exit low power state dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); + DC_LOG_IPS( + "wait IPS2 entry delay (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + // Wait for IPS2 entry upper bound udelay(dc->debug.ips2_entry_delay_us); + DC_LOG_IPS( + "exit IPS2 #2 (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); + DC_LOG_IPS( + "wait IPS2 commit clear (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + while (ips_fw->signals.bits.ips2_commit) udelay(1); + DC_LOG_IPS( + "wait hw_pwr_up (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true)) ASSERT(0); + DC_LOG_IPS( + "resync inbox1 (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + dmub_srv_sync_inbox1(dc->ctx->dmub_srv->dmub); } } dc_dmub_srv_notify_idle(dc, false); if (prev_driver_signals.bits.allow_ips1) { + DC_LOG_IPS( + "wait for IPS1 commit clear (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); + while (ips_fw->signals.bits.ips1_commit) udelay(1); + DC_LOG_IPS( + "wait for IPS1 commit clear done (ips1_commit=%d ips2_commit=%d)", + ips_fw->signals.bits.ips1_commit, + ips_fw->signals.bits.ips2_commit); } } if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true)) ASSERT(0); + + DC_LOG_IPS("%s exited", __func__); } void dc_dmub_srv_set_power_state(struct dc_dmub_srv *dc_dmub_srv, enum dc_acpi_cm_power_state powerState) @@ -1335,6 +1406,8 @@ void dc_dmub_srv_apply_idle_power_optimizations(const struct dc *dc, bool allow_ if (dc_dmub_srv->idle_allowed == allow_idle) return; + DC_LOG_IPS("%s state change: old=%d new=%d", __func__, dc_dmub_srv->idle_allowed, allow_idle); + /* * Entering a low power state requires a driver notification. * Powering up the hardware requires notifying PMFW and DMCUB. |