[PATCH v2 19/19] drm/amd/display: PSR-SU rate control support in DC
David Zhang
dingchen.zhang at amd.com
Tue May 10 20:45:08 UTC 2022
[why & how]
We need to add the necessary DC codes to support PSR-SU rate
control (RC).
Signed-off-by: David Zhang <dingchen.zhang at amd.com>
---
drivers/gpu/drm/amd/display/dc/core/dc_link.c | 14 +++++++++++
drivers/gpu/drm/amd/display/dc/dc_link.h | 3 +++
drivers/gpu/drm/amd/display/dc/dc_types.h | 2 ++
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c | 23 +++++++++++++++++++
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h | 2 ++
.../drm/amd/display/dc/inc/hw/link_encoder.h | 8 +++++++
6 files changed, 52 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 259745074ebb..08dedc16a9c5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -1765,6 +1765,7 @@ static bool dc_link_construct_legacy(struct dc_link *link,
*/
program_hpd_filter(link);
+ link->psr_settings.psr_vtotal_control_support = false;
link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
@@ -3377,6 +3378,19 @@ void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency)
*residency = 0;
}
+bool dc_link_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
+{
+ struct dc *dc = link->ctx->dc;
+ struct dmub_psr *psr = dc->res_pool->psr;
+
+ if (psr == NULL || !link->psr_settings.psr_feature_enabled || !link->psr_settings.psr_vtotal_control_support)
+ return false;
+
+ psr->funcs->psr_set_sink_vtotal_in_psr_active(psr, psr_vtotal_idle, psr_vtotal_su);
+
+ return true;
+}
+
const struct dc_link_status *dc_link_get_status(const struct dc_link *link)
{
return &link->link_status;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h
index 5e7f70840e1a..4e15e68375da 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_link.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_link.h
@@ -100,6 +100,7 @@ struct psr_settings {
bool psr_feature_enabled; // PSR is supported by sink
bool psr_allow_active; // PSR is currently active
enum dc_psr_version psr_version; // Internal PSR version, determined based on DPCD
+ bool psr_vtotal_control_support; // Vtotal control is supported by sink
/* These parameters are calculated in Driver,
* based on display timing and Sink capabilities.
@@ -326,6 +327,8 @@ void dc_link_get_psr_residency(const struct dc_link *link, uint32_t *residency);
void dc_link_blank_all_dp_displays(struct dc *dc);
void dc_link_blank_dp_stream(struct dc_link *link, bool hw_init);
+bool dc_link_set_sink_vtotal_in_psr_active(const struct dc_link *link,
+ uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su);
/* Request DC to detect if there is a Panel connected.
* boot - If this call is during initial boot.
diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h
index 26b62f50ac4e..fa735d5f730f 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -684,6 +684,7 @@ struct psr_config {
/* psr2 selective update y granularity capability */
uint8_t su_y_granularity;
unsigned int line_time_in_us;
+ uint8_t rate_control_caps;
};
union dmcu_psr_level {
@@ -794,6 +795,7 @@ struct psr_context {
/* psr2 selective update y granularity capability */
uint8_t su_y_granularity;
unsigned int line_time_in_us;
+ uint8_t rate_control_caps;
};
struct colorspace_transform {
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
index 9ca0cbb0af9b..0df06740ec39 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
@@ -250,6 +250,27 @@ static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_
dc_dmub_srv_wait_idle(dc->dmub_srv);
}
+/**
+ * Set PSR vtotal requirement for FreeSync PSR.
+ */
+static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub,
+ uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
+{
+ union dmub_rb_cmd cmd;
+ struct dc_context *dc = dmub->ctx;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.psr_set_vtotal.header.type = DMUB_CMD__PSR;
+ cmd.psr_set_vtotal.header.sub_type = DMUB_CMD__SET_SINK_VTOTAL_IN_PSR_ACTIVE;
+ cmd.psr_set_vtotal.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_vtotal_data);
+ cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_idle = psr_vtotal_idle;
+ cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_su = psr_vtotal_su;
+
+ 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);
+}
+
/*
* Set PSR power optimization flags.
*/
@@ -358,6 +379,7 @@ static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
copy_settings_data->line_capture_indication = 0;
copy_settings_data->line_time_in_us = psr_context->line_time_in_us;
+ copy_settings_data->rate_control_caps = psr_context->rate_control_caps;
copy_settings_data->fec_enable_status = (link->fec_state == dc_link_fec_enabled);
copy_settings_data->fec_enable_delay_in100us = link->dc->debug.fec_enable_delay_in100us;
copy_settings_data->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
@@ -435,6 +457,7 @@ static const struct dmub_psr_funcs psr_funcs = {
.psr_set_level = dmub_psr_set_level,
.psr_force_static = dmub_psr_force_static,
.psr_get_residency = dmub_psr_get_residency,
+ .psr_set_sink_vtotal_in_psr_active = dmub_psr_set_sink_vtotal_in_psr_active,
.psr_set_power_opt = dmub_psr_set_power_opt,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
index 01acc01cc191..74005b9d352a 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.h
@@ -46,6 +46,8 @@ struct dmub_psr_funcs {
void (*psr_force_static)(struct dmub_psr *dmub, uint8_t panel_inst);
void (*psr_get_residency)(struct dmub_psr *dmub, uint32_t *residency,
uint8_t panel_inst);
+ void (*psr_set_sink_vtotal_in_psr_active)(struct dmub_psr *dmub,
+ uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su);
void (*psr_set_power_opt)(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst);
};
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
index 66132f3cac42..c89643eaa0f4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
@@ -101,6 +101,14 @@ union dpcd_alpm_configuration {
unsigned char raw;
};
+union dpcd_sink_active_vtotal_control_mode {
+ struct {
+ unsigned char ENABLE : 1;
+ unsigned char RESERVED : 7;
+ } bits;
+ unsigned char raw;
+};
+
union psr_error_status {
struct {
unsigned char LINK_CRC_ERROR :1;
--
2.25.1
More information about the amd-gfx
mailing list