Commit f53e191e authored by Guo, Bing's avatar Guo, Bing Committed by Alex Deucher
Browse files

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: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarBing Guo <Bing.Guo@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6984fa41
Loading
Loading
Loading
Loading
+0 −31
Original line number Diff line number Diff line
@@ -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;
}
+0 −4
Original line number Diff line number Diff line
@@ -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,
+0 −28
Original line number Diff line number Diff line
@@ -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;
}
+0 −1
Original line number Diff line number Diff line
@@ -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
+4 −2
Original line number Diff line number Diff line
@@ -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;