drm/amd/display: dc_link_set_psr_allow_active refactoring
[Why] To expose new power optimization flags to PSR interface. It allows the PSR related power features can be enabled separately base on different use scenarios. Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> Acked-by: Agustin Gutierrez <agustin.gutierrez@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Robin Chen <po-tchen@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
33df94e181
commit
e5dfcd2727
@ -107,6 +107,8 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
|||||||
*/
|
*/
|
||||||
// Init fail safe of 2 frames static
|
// Init fail safe of 2 frames static
|
||||||
unsigned int num_frames_static = 2;
|
unsigned int num_frames_static = 2;
|
||||||
|
unsigned int power_opt = 0;
|
||||||
|
bool psr_enable = true;
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("Enabling psr...\n");
|
DRM_DEBUG_DRIVER("Enabling psr...\n");
|
||||||
|
|
||||||
@ -133,7 +135,9 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
|||||||
&stream, 1,
|
&stream, 1,
|
||||||
¶ms);
|
¶ms);
|
||||||
|
|
||||||
return dc_link_set_psr_allow_active(link, true, false, false);
|
power_opt |= psr_power_opt_z10_static_screen;
|
||||||
|
|
||||||
|
return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -144,10 +148,12 @@ bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
|
|||||||
*/
|
*/
|
||||||
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
|
bool amdgpu_dm_psr_disable(struct dc_stream_state *stream)
|
||||||
{
|
{
|
||||||
|
unsigned int power_opt = 0;
|
||||||
|
bool psr_enable = false;
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
DRM_DEBUG_DRIVER("Disabling psr...\n");
|
||||||
|
|
||||||
return dc_link_set_psr_allow_active(stream->link, false, true, false);
|
return dc_link_set_psr_allow_active(stream->link, &psr_enable, true, false, &power_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -100,11 +100,13 @@ void clk_mgr_exit_optimized_pwr_state(const struct dc *dc, struct clk_mgr *clk_m
|
|||||||
|
|
||||||
if (edp_num) {
|
if (edp_num) {
|
||||||
for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
|
for (panel_inst = 0; panel_inst < edp_num; panel_inst++) {
|
||||||
|
bool allow_active = false;
|
||||||
|
|
||||||
edp_link = edp_links[panel_inst];
|
edp_link = edp_links[panel_inst];
|
||||||
if (!edp_link->psr_settings.psr_feature_enabled)
|
if (!edp_link->psr_settings.psr_feature_enabled)
|
||||||
continue;
|
continue;
|
||||||
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
|
clk_mgr->psr_allow_active_cache = edp_link->psr_settings.psr_allow_active;
|
||||||
dc_link_set_psr_allow_active(edp_link, false, false, false);
|
dc_link_set_psr_allow_active(edp_link, &allow_active, false, false, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,7 @@ void clk_mgr_optimize_pwr_state(const struct dc *dc, struct clk_mgr *clk_mgr)
|
|||||||
if (!edp_link->psr_settings.psr_feature_enabled)
|
if (!edp_link->psr_settings.psr_feature_enabled)
|
||||||
continue;
|
continue;
|
||||||
dc_link_set_psr_allow_active(edp_link,
|
dc_link_set_psr_allow_active(edp_link,
|
||||||
clk_mgr->psr_allow_active_cache, false, false);
|
&clk_mgr->psr_allow_active_cache, false, false, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3493,6 +3493,7 @@ void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_
|
|||||||
bool dc_set_psr_allow_active(struct dc *dc, bool enable)
|
bool dc_set_psr_allow_active(struct dc *dc, bool enable)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
bool allow_active;
|
||||||
|
|
||||||
for (i = 0; i < dc->current_state->stream_count ; i++) {
|
for (i = 0; i < dc->current_state->stream_count ; i++) {
|
||||||
struct dc_link *link;
|
struct dc_link *link;
|
||||||
@ -3504,10 +3505,12 @@ bool dc_set_psr_allow_active(struct dc *dc, bool enable)
|
|||||||
|
|
||||||
if (link->psr_settings.psr_feature_enabled) {
|
if (link->psr_settings.psr_feature_enabled) {
|
||||||
if (enable && !link->psr_settings.psr_allow_active) {
|
if (enable && !link->psr_settings.psr_allow_active) {
|
||||||
if (!dc_link_set_psr_allow_active(link, true, false, false))
|
allow_active = true;
|
||||||
|
if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL))
|
||||||
return false;
|
return false;
|
||||||
} else if (!enable && link->psr_settings.psr_allow_active) {
|
} else if (!enable && link->psr_settings.psr_allow_active) {
|
||||||
if (!dc_link_set_psr_allow_active(link, false, true, false))
|
allow_active = false;
|
||||||
|
if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2916,8 +2916,8 @@ bool dc_link_set_backlight_level(const struct dc_link *link,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
|
bool dc_link_set_psr_allow_active(struct dc_link *link, const bool *allow_active,
|
||||||
bool wait, bool force_static)
|
bool wait, bool force_static, const unsigned int *power_opts)
|
||||||
{
|
{
|
||||||
struct dc *dc = link->ctx->dc;
|
struct dc *dc = link->ctx->dc;
|
||||||
struct dmcu *dmcu = dc->res_pool->dmcu;
|
struct dmcu *dmcu = dc->res_pool->dmcu;
|
||||||
@ -2930,20 +2930,33 @@ bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active,
|
|||||||
if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
|
if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
link->psr_settings.psr_allow_active = allow_active;
|
/* Set power optimization flag */
|
||||||
|
if (power_opts && link->psr_settings.psr_power_opt != *power_opts) {
|
||||||
|
link->psr_settings.psr_power_opt = *power_opts;
|
||||||
|
|
||||||
|
if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt)
|
||||||
|
psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable or Disable PSR */
|
||||||
|
if (allow_active && link->psr_settings.psr_allow_active != *allow_active) {
|
||||||
|
link->psr_settings.psr_allow_active = *allow_active;
|
||||||
|
|
||||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||||
if (!allow_active)
|
if (!link->psr_settings.psr_allow_active)
|
||||||
dc_z10_restore(dc);
|
dc_z10_restore(dc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (psr != NULL && link->psr_settings.psr_feature_enabled) {
|
if (psr != NULL && link->psr_settings.psr_feature_enabled) {
|
||||||
if (force_static && psr->funcs->psr_force_static)
|
if (force_static && psr->funcs->psr_force_static)
|
||||||
psr->funcs->psr_force_static(psr, panel_inst);
|
psr->funcs->psr_force_static(psr, panel_inst);
|
||||||
psr->funcs->psr_enable(psr, allow_active, wait, panel_inst);
|
psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst);
|
||||||
} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && link->psr_settings.psr_feature_enabled)
|
} else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) &&
|
||||||
dmcu->funcs->set_psr_enable(dmcu, allow_active, wait);
|
link->psr_settings.psr_feature_enabled)
|
||||||
else
|
dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait);
|
||||||
return false;
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3523,6 +3523,8 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
|
|||||||
if (psr_error_status.bits.LINK_CRC_ERROR ||
|
if (psr_error_status.bits.LINK_CRC_ERROR ||
|
||||||
psr_error_status.bits.RFB_STORAGE_ERROR ||
|
psr_error_status.bits.RFB_STORAGE_ERROR ||
|
||||||
psr_error_status.bits.VSC_SDP_ERROR) {
|
psr_error_status.bits.VSC_SDP_ERROR) {
|
||||||
|
bool allow_active;
|
||||||
|
|
||||||
/* Acknowledge and clear error bits */
|
/* Acknowledge and clear error bits */
|
||||||
dm_helpers_dp_write_dpcd(
|
dm_helpers_dp_write_dpcd(
|
||||||
link->ctx,
|
link->ctx,
|
||||||
@ -3532,8 +3534,10 @@ static bool handle_hpd_irq_psr_sink(struct dc_link *link)
|
|||||||
sizeof(psr_error_status.raw));
|
sizeof(psr_error_status.raw));
|
||||||
|
|
||||||
/* PSR error, disable and re-enable PSR */
|
/* PSR error, disable and re-enable PSR */
|
||||||
dc_link_set_psr_allow_active(link, false, true, false);
|
allow_active = false;
|
||||||
dc_link_set_psr_allow_active(link, true, true, false);
|
dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
|
||||||
|
allow_active = true;
|
||||||
|
dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
|
} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
|
||||||
|
@ -342,6 +342,12 @@ enum visual_confirm {
|
|||||||
VISUAL_CONFIRM_SWIZZLE = 9,
|
VISUAL_CONFIRM_SWIZZLE = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum dc_psr_power_opts {
|
||||||
|
psr_power_opt_invalid = 0x0,
|
||||||
|
psr_power_opt_smu_opt_static_screen = 0x1,
|
||||||
|
psr_power_opt_z10_static_screen = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
enum dcc_option {
|
enum dcc_option {
|
||||||
DCC_ENABLE = 0,
|
DCC_ENABLE = 0,
|
||||||
DCC_DISABLE = 1,
|
DCC_DISABLE = 1,
|
||||||
|
@ -85,6 +85,7 @@ struct psr_settings {
|
|||||||
*/
|
*/
|
||||||
bool psr_frame_capture_indication_req;
|
bool psr_frame_capture_indication_req;
|
||||||
unsigned int psr_sdp_transmit_line_num_deadline;
|
unsigned int psr_sdp_transmit_line_num_deadline;
|
||||||
|
unsigned int psr_power_opt;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -267,8 +268,8 @@ int dc_link_get_backlight_level(const struct dc_link *dc_link);
|
|||||||
|
|
||||||
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
int dc_link_get_target_backlight_pwm(const struct dc_link *link);
|
||||||
|
|
||||||
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, bool enable,
|
bool dc_link_set_psr_allow_active(struct dc_link *dc_link, const bool *enable,
|
||||||
bool wait, bool force_static);
|
bool wait, bool force_static, const unsigned int *power_opts);
|
||||||
|
|
||||||
bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
|
bool dc_link_get_psr_state(const struct dc_link *dc_link, enum dc_psr_state *state);
|
||||||
|
|
||||||
|
@ -227,6 +227,25 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_
|
|||||||
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set PSR power optimization flags.
|
||||||
|
*/
|
||||||
|
static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt)
|
||||||
|
{
|
||||||
|
union dmub_rb_cmd cmd;
|
||||||
|
struct dc_context *dc = dmub->ctx;
|
||||||
|
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR;
|
||||||
|
cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT;
|
||||||
|
cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data);
|
||||||
|
cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt;
|
||||||
|
|
||||||
|
dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd);
|
||||||
|
dc_dmub_srv_cmd_execute(dc->dmub_srv);
|
||||||
|
dc_dmub_srv_wait_idle(dc->dmub_srv);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup PSR by programming phy registers and sending psr hw context values to firmware.
|
* Setup PSR by programming phy registers and sending psr hw context values to firmware.
|
||||||
*/
|
*/
|
||||||
@ -358,6 +377,7 @@ static const struct dmub_psr_funcs psr_funcs = {
|
|||||||
.psr_set_level = dmub_psr_set_level,
|
.psr_set_level = dmub_psr_set_level,
|
||||||
.psr_force_static = dmub_psr_force_static,
|
.psr_force_static = dmub_psr_force_static,
|
||||||
.psr_get_residency = dmub_psr_get_residency,
|
.psr_get_residency = dmub_psr_get_residency,
|
||||||
|
.psr_set_power_opt = dmub_psr_set_power_opt,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,6 +46,7 @@ struct dmub_psr_funcs {
|
|||||||
void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst);
|
void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst);
|
||||||
void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency,
|
void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency,
|
||||||
uint8_t panel_inst);
|
uint8_t panel_inst);
|
||||||
|
void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
|
struct dmub_psr *dmub_psr_create(struct dc_context *ctx);
|
||||||
|
@ -1378,6 +1378,10 @@ enum dmub_cmd_psr_type {
|
|||||||
* Forces PSR enabled until an explicit PSR disable call.
|
* Forces PSR enabled until an explicit PSR disable call.
|
||||||
*/
|
*/
|
||||||
DMUB_CMD__PSR_FORCE_STATIC = 5,
|
DMUB_CMD__PSR_FORCE_STATIC = 5,
|
||||||
|
/**
|
||||||
|
* Set PSR power option
|
||||||
|
*/
|
||||||
|
DMUB_CMD__SET_PSR_POWER_OPT = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1675,6 +1679,44 @@ struct dmub_rb_cmd_psr_force_static {
|
|||||||
struct dmub_cmd_psr_force_static_data psr_force_static_data;
|
struct dmub_cmd_psr_force_static_data psr_force_static_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data passed from driver to FW in a DMUB_CMD__SET_PSR_POWER_OPT command.
|
||||||
|
*/
|
||||||
|
struct dmub_cmd_psr_set_power_opt_data {
|
||||||
|
/**
|
||||||
|
* PSR control version.
|
||||||
|
*/
|
||||||
|
uint8_t cmd_version;
|
||||||
|
/**
|
||||||
|
* Panel Instance.
|
||||||
|
* Panel isntance to identify which psr_state to use
|
||||||
|
* Currently the support is only for 0 or 1
|
||||||
|
*/
|
||||||
|
uint8_t panel_inst;
|
||||||
|
/**
|
||||||
|
* Explicit padding to 4 byte boundary.
|
||||||
|
*/
|
||||||
|
uint8_t pad[2];
|
||||||
|
/**
|
||||||
|
* PSR power option
|
||||||
|
*/
|
||||||
|
uint32_t power_opt;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
|
||||||
|
*/
|
||||||
|
struct dmub_rb_cmd_psr_set_power_opt {
|
||||||
|
/**
|
||||||
|
* Command header.
|
||||||
|
*/
|
||||||
|
struct dmub_cmd_header header;
|
||||||
|
/**
|
||||||
|
* Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
|
||||||
|
*/
|
||||||
|
struct dmub_cmd_psr_set_power_opt_data psr_set_power_opt_data;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of HW components that can be locked.
|
* Set of HW components that can be locked.
|
||||||
*
|
*
|
||||||
@ -2458,6 +2500,10 @@ union dmub_rb_cmd {
|
|||||||
* Definition of a DMUB_CMD__PSR_FORCE_STATIC command.
|
* Definition of a DMUB_CMD__PSR_FORCE_STATIC command.
|
||||||
*/
|
*/
|
||||||
struct dmub_rb_cmd_psr_force_static psr_force_static;
|
struct dmub_rb_cmd_psr_force_static psr_force_static;
|
||||||
|
/**
|
||||||
|
* Definition of a DMUB_CMD__SET_PSR_POWER_OPT command.
|
||||||
|
*/
|
||||||
|
struct dmub_rb_cmd_psr_set_power_opt psr_set_power_opt;
|
||||||
/**
|
/**
|
||||||
* Definition of a DMUB_CMD__PLAT_54186_WA command.
|
* Definition of a DMUB_CMD__PLAT_54186_WA command.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user