drm/amd/display: fixed an error related to 4:2:0/4:2:2 DSC

[Why]
OPTC_BYTES_PER_PIXEL calculation for 4:2:2 and 4:2:0 could have error.

[How]
Change to use following formula:
OPTC_DSC_BYTES_PER_PIXEL = ceiling((chunk size * 2^28) / slice width)

v2: squash in 64 bit divide fix (Alex)

Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Bing Guo <Bing.Guo@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Guo, Bing 2021-11-08 17:17:46 -05:00 committed by Alex Deucher
parent 6984fa418b
commit f53e191e2b
5 changed files with 4 additions and 66 deletions

View File

@ -61,16 +61,6 @@ static double dsc_roundf(double num)
return (int)(num);
}
static double dsc_ceil(double num)
{
double retval = (int)num;
if (retval != num && num > 0)
retval = num + 1;
return (int)retval;
}
static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
enum max_min max_min, float bpp)
{
@ -268,24 +258,3 @@ void _do_calc_rc_params(struct rc_params *rc,
rc->rc_buf_thresh[13] = 8064;
}
u32 _do_bytes_per_pixel_calc(int slice_width,
u16 drm_bpp,
bool is_navite_422_or_420)
{
float bpp;
u32 bytes_per_pixel;
double d_bytes_per_pixel;
dc_assert_fp_enabled();
bpp = ((float)drm_bpp / 16.0);
d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
// TODO: Make sure the formula for calculating this is precise (ceiling
// vs. floor, and at what point they should be applied)
if (is_navite_422_or_420)
d_bytes_per_pixel /= 2;
bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000);
return bytes_per_pixel;
}

View File

@ -78,10 +78,6 @@ struct qp_entry {
typedef struct qp_entry qp_table[];
u32 _do_bytes_per_pixel_calc(int slice_width,
u16 drm_bpp,
bool is_navite_422_or_420);
void _do_calc_rc_params(struct rc_params *rc,
enum colour_mode cm,
enum bits_per_comp bpc,

View File

@ -60,31 +60,3 @@ void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps)
pps->dsc_version_minor);
DC_FP_END();
}
/**
* calc_dsc_bytes_per_pixel - calculate bytes per pixel
* @pps: DRM struct with all required DSC values
*
* Based on the information inside drm_dsc_config, this function calculates the
* total of bytes per pixel.
*
* @note This calculation requires float point operation, most of it executes
* under kernel_fpu_{begin,end}.
*
* Return:
* Return the number of bytes per pixel
*/
u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps)
{
u32 ret;
u16 drm_bpp = pps->bits_per_pixel;
int slice_width = pps->slice_width;
bool is_navite_422_or_420 = pps->native_422 || pps->native_420;
DC_FP_START();
ret = _do_bytes_per_pixel_calc(slice_width, drm_bpp,
is_navite_422_or_420);
DC_FP_END();
return ret;
}

View File

@ -30,7 +30,6 @@
#include "dml/dsc/rc_calc_fpu.h"
void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps);
u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
#endif

View File

@ -100,8 +100,7 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par
int ret;
struct rc_params rc;
struct drm_dsc_config dsc_cfg;
dsc_params->bytes_per_pixel = calc_dsc_bytes_per_pixel(pps);
unsigned long long tmp;
calc_rc_params(&rc, pps);
dsc_params->pps = *pps;
@ -113,6 +112,9 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par
dsc_cfg.mux_word_size = dsc_params->pps.bits_per_component <= 10 ? 48 : 64;
ret = drm_dsc_compute_rc_parameters(&dsc_cfg);
tmp = (unsigned long long)dsc_cfg.slice_chunk_size * 0x10000000 + (dsc_cfg.slice_width - 1);
do_div(tmp, (uint32_t)dsc_cfg.slice_width); //ROUND-UP
dsc_params->bytes_per_pixel = (uint32_t)tmp;
copy_pps_fields(&dsc_params->pps, &dsc_cfg);
dsc_params->rc_buffer_model_size = dsc_cfg.rc_bits;