From: Wei-Guang Li <[email protected]> [Why&How] Add driver-side support for querying boot-time cumulative PHY-off residency via the REPLAY_SNAPSHOT_CUMULATIVE_RESIDENCY GPINT command implemented in DMUB FW.
Reviewed-by: Jack Chang <[email protected]> Signed-off-by: Wei-Guang Li <[email protected]> Signed-off-by: Jack Chang <[email protected]> Signed-off-by: Chenyu Chen <[email protected]> --- .../gpu/drm/amd/display/dc/dce/dmub_replay.c | 25 +++++++++++++++++++ .../gpu/drm/amd/display/dc/dce/dmub_replay.h | 2 ++ .../gpu/drm/amd/display/dc/inc/link_service.h | 2 ++ .../drm/amd/display/dc/link/link_factory.c | 1 + .../link/protocols/link_edp_panel_control.c | 22 ++++++++++++++++ .../link/protocols/link_edp_panel_control.h | 2 ++ .../drm/amd/display/modules/inc/mod_power.h | 3 +++ .../amd/display/modules/power/power_replay.c | 13 ++++++++++ 8 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c index eda3a2f1402c..0785a30eb643 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c @@ -415,6 +415,30 @@ static void dmub_replay_send_cmd(struct dmub_replay *dmub, dc_wake_and_execute_dmub_cmd(ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); } +static bool dmub_replay_get_cumulative_residency(struct dmub_replay *dmub, + uint8_t panel_inst, uint32_t *residency_milli_pct) +{ + uint32_t milli_pct = 0; + uint16_t param = (uint16_t)panel_inst; + + if (!residency_milli_pct) + return false; + + /* Zero on failure so the caller never reads a stale value, and report + * false so a failed query is still distinguishable from a genuine 0%. + */ + *residency_milli_pct = 0; + + if (!dc_wake_and_execute_gpint(dmub->ctx, + DMUB_GPINT__REPLAY_SNAPSHOT_CUMULATIVE_RESIDENCY, + param, &milli_pct, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)) + return false; + + *residency_milli_pct = milli_pct; + + return true; +} + static const struct dmub_replay_funcs replay_funcs = { .replay_copy_settings = dmub_replay_copy_settings, .replay_enable = dmub_replay_enable, @@ -424,6 +448,7 @@ static const struct dmub_replay_funcs replay_funcs = { .replay_residency = dmub_replay_residency, .replay_set_power_opt_and_coasting_vtotal = dmub_replay_set_power_opt_and_coasting_vtotal, .replay_send_cmd = dmub_replay_send_cmd, + .replay_get_cumulative_residency = dmub_replay_get_cumulative_residency, }; /* diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h index 07c79739a980..271a42a226e9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.h @@ -33,6 +33,8 @@ struct dmub_replay_funcs { void (*replay_set_power_opt_and_coasting_vtotal)(struct dmub_replay *dmub, unsigned int power_opt, uint8_t panel_inst, uint32_t coasting_vtotal, uint16_t frame_skip_number); + bool (*replay_get_cumulative_residency)(struct dmub_replay *dmub, + uint8_t panel_inst, uint32_t *residency_milli_pct); }; struct dmub_replay *dmub_replay_create(struct dc_context *ctx); diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_service.h b/drivers/gpu/drm/amd/display/dc/inc/link_service.h index eaf20ca14bcc..b2f86c51d470 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_service.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_service.h @@ -297,6 +297,8 @@ struct link_service { bool (*edp_replay_residency)(const struct dc_link *link, unsigned int *residency, const bool is_start, const enum pr_residency_mode mode); + bool (*edp_replay_get_cumulative_residency)(const struct dc_link *link, + uint32_t *residency_milli_pct); bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link *link, const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number); diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index fa281de1d566..3b192c539f8b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -223,6 +223,7 @@ static void construct_link_service_edp_panel_control(struct link_service *link_s link_srv->edp_send_replay_cmd = edp_send_replay_cmd; link_srv->edp_set_coasting_vtotal = edp_set_coasting_vtotal; link_srv->edp_replay_residency = edp_replay_residency; + link_srv->edp_replay_get_cumulative_residency = edp_replay_get_cumulative_residency; link_srv->edp_set_replay_power_opt_and_coasting_vtotal = edp_set_replay_power_opt_and_coasting_vtotal; link_srv->edp_wait_for_t12 = edp_wait_for_t12; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 9883216dcc9d..e904c7dd320e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -1154,6 +1154,28 @@ bool edp_replay_residency(const struct dc_link *link, return true; } +bool edp_replay_get_cumulative_residency(const struct dc_link *link, + uint32_t *residency_milli_pct) +{ + struct dc *dc = link->ctx->dc; + struct dmub_replay *replay = dc->res_pool->replay; + unsigned int panel_inst; + + if (!dp_pr_get_pr_panel_inst(dc, link, &panel_inst)) + return false; + + if (replay && link->replay_settings.replay_feature_enabled && + replay->funcs->replay_get_cumulative_residency) + return replay->funcs->replay_get_cumulative_residency(replay, + (uint8_t)panel_inst, residency_milli_pct); + + if (residency_milli_pct) + *residency_milli_pct = 0; + + return true; +} + + bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link, const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h index 51de13e2387e..0082f5e91878 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h @@ -60,6 +60,8 @@ bool edp_send_replay_cmd(struct dc_link *link, bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal, uint16_t frame_skip_number); bool edp_replay_residency(const struct dc_link *link, unsigned int *residency, const bool is_start, const enum pr_residency_mode mode); +bool edp_replay_get_cumulative_residency(const struct dc_link *link, + uint32_t *residency_milli_pct); bool edp_get_replay_state(const struct dc_link *link, uint64_t *state); bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link, const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number); diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h index 5d1275b7cd46..25a0c96ac754 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h @@ -375,6 +375,9 @@ bool mod_power_replay_set_coasting_vtotal(struct mod_power *mod_power, void mod_power_replay_residency(const struct dc_stream_state *stream, unsigned int *residency, const bool is_start, const bool is_alpm); +bool mod_power_replay_get_cumulative_residency(const struct dc_stream_state *stream, + uint32_t *residency_milli_pct); + bool mod_power_replay_set_power_opt_and_coasting_vtotal(struct mod_power *mod_power, const struct dc_stream_state *stream, unsigned int active_replay_events, uint32_t coasting_vtotal, bool is_ultra_sleep_mode, uint16_t frame_skip_number); diff --git a/drivers/gpu/drm/amd/display/modules/power/power_replay.c b/drivers/gpu/drm/amd/display/modules/power/power_replay.c index 31d9cb3a12ba..7861e46c612d 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_replay.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_replay.c @@ -761,6 +761,19 @@ void mod_power_replay_residency(const struct dc_stream_state *stream, link->dc->link_srv->edp_replay_residency(link, residency, is_start, mode); } +bool mod_power_replay_get_cumulative_residency(const struct dc_stream_state *stream, + uint32_t *residency_milli_pct) +{ + const struct dc_link *link = dc_stream_get_link(stream); + + if (!link || !link->dc || !link->dc->link_srv) + return false; + + return link->dc->link_srv->edp_replay_get_cumulative_residency( + link, residency_milli_pct); +} + + bool mod_power_replay_set_power_opt_and_coasting_vtotal(struct mod_power *mod_power, const struct dc_stream_state *stream, unsigned int active_replay_events, uint32_t coasting_vtotal, bool is_ultra_sleep_mode, uint16_t frame_skip_number) -- 2.43.0
