On 5/10/22 16:45, David Zhang wrote:
> [why & how]
> We need to add the necessary DC codes to support PSR-SU rate
> control (RC).

We'll probably want to expand a bit on what rate control
is and also note that this is just adding core functionality
for RC but not enabling it.

Harry

> 
> Signed-off-by: David Zhang <[email protected]>
> ---
>  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;

Reply via email to