From: Wenjing Liu <[email protected]>

[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 <[email protected]>
Acked-by: Alex Hung <[email protected]>
Signed-off-by: Wenjing Liu <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/dc_hw_types.h  | 24 +++++++++++++
 .../gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c  | 36 ++++++++++++++++++-
 .../gpu/drm/amd/display/dc/dsc/dscc_types.h   |  5 ++-
 .../gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c  | 10 +++---
 4 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 848db8676adf..cc3d6fb39364 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -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 */
 };
 
 /**
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
index c08c01e05dcf..42344aec60d6 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c
@@ -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;
        }
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h 
b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h
index ad80bde9bc0f..31574940ccc7 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h
@@ -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
 
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c 
b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
index f0aea988fef0..36d6c1646a51 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
@@ -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;
 
-- 
2.39.1

Reply via email to