drm/amd/display: add rc_params_override option in dc_dsc_config

[why]
Current RC params are based on VESA recommended configurations.
Some DSC sink may prefer non standard rc params values due to
hardware limitations. To support those DSC sink we will allow DM to
optionally pass rc_params_ovrd in dc_dsc_config so DC will override
the default VESA recommended configurations.

Reviewed-by: Martin Leung <Martin.Leung@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Wenjing Liu 2023-01-13 16:07:10 -05:00 committed by Alex Deucher
parent 5b49da02dd
commit 0a31efb4d6
4 changed files with 68 additions and 7 deletions

View file

@ -797,6 +797,29 @@ enum dc_timing_3d_format {
TIMING_3D_FORMAT_MAX,
};
#define DC_DSC_QP_SET_SIZE 15
#define DC_DSC_RC_BUF_THRESH_SIZE 14
struct dc_dsc_rc_params_override {
int32_t rc_model_size;
int32_t rc_buf_thresh[DC_DSC_RC_BUF_THRESH_SIZE];
int32_t rc_minqp[DC_DSC_QP_SET_SIZE];
int32_t rc_maxqp[DC_DSC_QP_SET_SIZE];
int32_t rc_offset[DC_DSC_QP_SET_SIZE];
int32_t rc_tgt_offset_hi;
int32_t rc_tgt_offset_lo;
int32_t rc_edge_factor;
int32_t rc_quant_incr_limit0;
int32_t rc_quant_incr_limit1;
int32_t initial_fullness_offset;
int32_t initial_delay;
int32_t flatness_min_qp;
int32_t flatness_max_qp;
int32_t flatness_det_thresh;
};
struct dc_dsc_config {
uint32_t num_slices_h; /* Number of DSC slices - horizontal */
uint32_t num_slices_v; /* Number of DSC slices - vertical */
@ -811,6 +834,7 @@ struct dc_dsc_config {
#endif
bool is_dp; /* indicate if DSC is applied based on DP's capability */
uint32_t mst_pbn; /* pbn of display on dsc mst hub */
const struct dc_dsc_rc_params_override *rc_params_ovrd; /* DM owned memory. If not NULL, apply custom dsc rc params */
};
/**

View file

@ -28,6 +28,7 @@
#include "reg_helper.h"
#include "dcn20_dsc.h"
#include "dsc/dscc_types.h"
#include "dsc/rc_calc.h"
static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_config *pps);
static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals,
@ -344,10 +345,38 @@ static void dsc_log_pps(struct display_stream_compressor *dsc, struct drm_dsc_co
}
}
static void dsc_override_rc_params(struct rc_params *rc, const struct dc_dsc_rc_params_override *override)
{
uint8_t i;
rc->rc_model_size = override->rc_model_size;
for (i = 0; i < DC_DSC_RC_BUF_THRESH_SIZE; i++)
rc->rc_buf_thresh[i] = override->rc_buf_thresh[i];
for (i = 0; i < DC_DSC_QP_SET_SIZE; i++) {
rc->qp_min[i] = override->rc_minqp[i];
rc->qp_max[i] = override->rc_maxqp[i];
rc->ofs[i] = override->rc_offset[i];
}
rc->rc_tgt_offset_hi = override->rc_tgt_offset_hi;
rc->rc_tgt_offset_lo = override->rc_tgt_offset_lo;
rc->rc_edge_factor = override->rc_edge_factor;
rc->rc_quant_incr_limit0 = override->rc_quant_incr_limit0;
rc->rc_quant_incr_limit1 = override->rc_quant_incr_limit1;
rc->initial_fullness_offset = override->initial_fullness_offset;
rc->initial_xmit_delay = override->initial_delay;
rc->flatness_min_qp = override->flatness_min_qp;
rc->flatness_max_qp = override->flatness_max_qp;
rc->flatness_det_thresh = override->flatness_det_thresh;
}
static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values *dsc_reg_vals,
struct dsc_optc_config *dsc_optc_cfg)
{
struct dsc_parameters dsc_params;
struct rc_params rc;
/* Validate input parameters */
ASSERT(dsc_cfg->dc_dsc_cfg.num_slices_h);
@ -412,7 +441,12 @@ static bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_
dsc_reg_vals->pps.native_420 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_NATIVE_YCBCR420);
dsc_reg_vals->pps.simple_422 = (dsc_reg_vals->pixel_format == DSC_PIXFMT_SIMPLE_YCBCR422);
if (dscc_compute_dsc_parameters(&dsc_reg_vals->pps, &dsc_params)) {
calc_rc_params(&rc, &dsc_reg_vals->pps);
if (dsc_cfg->dc_dsc_cfg.rc_params_ovrd)
dsc_override_rc_params(&rc, dsc_cfg->dc_dsc_cfg.rc_params_ovrd);
if (dscc_compute_dsc_parameters(&dsc_reg_vals->pps, &rc, &dsc_params)) {
dm_output_to_console("%s: DSC config failed\n", __func__);
return false;
}

View file

@ -46,7 +46,10 @@ struct dsc_parameters {
uint32_t rc_buffer_model_size;
};
int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params);
struct rc_params;
int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps,
const struct rc_params *rc,
struct dsc_parameters *dsc_params);
#endif

View file

@ -95,19 +95,19 @@ static void copy_rc_to_cfg(struct drm_dsc_config *dsc_cfg, const struct rc_param
dsc_cfg->rc_buf_thresh[i] = rc->rc_buf_thresh[i];
}
int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params)
int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps,
const struct rc_params *rc,
struct dsc_parameters *dsc_params)
{
int ret;
struct rc_params rc;
struct drm_dsc_config dsc_cfg;
unsigned long long tmp;
calc_rc_params(&rc, pps);
dsc_params->pps = *pps;
dsc_params->pps.initial_scale_value = 8 * rc.rc_model_size / (rc.rc_model_size - rc.initial_fullness_offset);
dsc_params->pps.initial_scale_value = 8 * rc->rc_model_size / (rc->rc_model_size - rc->initial_fullness_offset);
copy_pps_fields(&dsc_cfg, &dsc_params->pps);
copy_rc_to_cfg(&dsc_cfg, &rc);
copy_rc_to_cfg(&dsc_cfg, rc);
dsc_cfg.mux_word_size = dsc_params->pps.bits_per_component <= 10 ? 48 : 64;