Commit 534db198 authored by Amy Zhang's avatar Amy Zhang Committed by Alex Deucher
Browse files

drm/amd/display: HDR Enablement For Applications



- Made sure dest color space is updated in stream and info frame
- Optimized segment distribution algorithm for regamma mapping

Signed-off-by: default avatarAmy Zhang <Amy.Zhang@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 306dadf0
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1310,6 +1310,20 @@ static void set_avi_info_frame(
		info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
				COLORIMETRY_NO_DATA;

	if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE ||
		color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE ||
		color_space == COLOR_SPACE_2020_YCBCR) {
		info_frame.avi_info_packet.info_packet_hdmi.bits.EC0_EC2 =
				COLORIMETRYEX_BT2020RGBYCBCR;
		info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
				COLORIMETRY_EXTENDED;
	} else if (color_space == COLOR_SPACE_ADOBERGB) {
		info_frame.avi_info_packet.info_packet_hdmi.bits.EC0_EC2 =
				COLORIMETRYEX_ADOBERGB;
		info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
				COLORIMETRY_EXTENDED;
	}

	/* TODO: un-hardcode aspect ratio */
	aspect = stream->public.timing.aspect_ratio;

+5 −1
Original line number Diff line number Diff line
@@ -444,7 +444,11 @@ enum dc_color_space {
	COLOR_SPACE_YCBCR601,
	COLOR_SPACE_YCBCR709,
	COLOR_SPACE_YCBCR601_LIMITED,
	COLOR_SPACE_YCBCR709_LIMITED
	COLOR_SPACE_YCBCR709_LIMITED,
	COLOR_SPACE_2020_RGB_FULLRANGE,
	COLOR_SPACE_2020_RGB_LIMITEDRANGE,
	COLOR_SPACE_2020_YCBCR,
	COLOR_SPACE_ADOBERGB,
};

enum dc_quantization_range {
+77 −17
Original line number Diff line number Diff line
@@ -594,38 +594,87 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func
	struct fixed31_32 y3_max;

	int32_t segment_start, segment_end;
	uint32_t hw_points, start_index;
	uint32_t i, j;
	uint32_t i, j, k, seg_distr[16], increment, start_index;
	uint32_t hw_points = 0;

	memset(regamma_params, 0, sizeof(struct pwl_params));

	if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
		/* 16 segments x 16 points
		/* 16 segments
		 * segments are from 2^-11 to 2^5
		 */
		segment_start = -11;
		segment_end = 5;

		seg_distr[0] = 2;
		seg_distr[1] = 2;
		seg_distr[2] = 2;
		seg_distr[3] = 2;
		seg_distr[4] = 2;
		seg_distr[5] = 2;
		seg_distr[6] = 3;
		seg_distr[7] = 4;
		seg_distr[8] = 4;
		seg_distr[9] = 4;
		seg_distr[10] = 4;
		seg_distr[11] = 5;
		seg_distr[12] = 5;
		seg_distr[13] = 5;
		seg_distr[14] = 5;
		seg_distr[15] = 5;

	} else {
		/* 10 segments x 16 points
		/* 10 segments
		 * segment is from 2^-10 to 2^0
		 */
		segment_start = -10;
		segment_end = 0;

		seg_distr[0] = 3;
		seg_distr[1] = 4;
		seg_distr[2] = 4;
		seg_distr[3] = 4;
		seg_distr[4] = 4;
		seg_distr[5] = 4;
		seg_distr[6] = 4;
		seg_distr[7] = 4;
		seg_distr[8] = 5;
		seg_distr[9] = 5;
		seg_distr[10] = -1;
		seg_distr[11] = -1;
		seg_distr[12] = -1;
		seg_distr[13] = -1;
		seg_distr[14] = -1;
		seg_distr[15] = -1;
	}

	for (k = 0; k < 16; k++) {
		if (seg_distr[k] != -1)
			hw_points += (1 << seg_distr[k]);
	}

	hw_points = (segment_end - segment_start) * 16;
	j = 0;
	/* (segment + 25) * 32, every 2nd point */
	start_index = (segment_start + 25) * 32;
	for (i = start_index; i <= 1025; i += 2) {
		if (j > hw_points)
	for (k = 0; k < (segment_end - segment_start); k++) {
		increment = 32 / (1 << seg_distr[k]);
		start_index = (segment_start + k + 25) * 32;
		for (i = start_index; i < start_index + 32; i += increment) {
			if (j == hw_points - 1)
				break;
			rgb_resulted[j].red = output_tf->tf_pts.red[i];
			rgb_resulted[j].green = output_tf->tf_pts.green[i];
			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
			j++;
		}
	}

	/* last point */
	start_index = (segment_end + 25) * 32;
	rgb_resulted[hw_points - 1].red =
			output_tf->tf_pts.red[start_index];
	rgb_resulted[hw_points - 1].green =
			output_tf->tf_pts.green[start_index];
	rgb_resulted[hw_points - 1].blue =
			output_tf->tf_pts.blue[start_index];

	arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
			dal_fixed31_32_from_int(segment_start));
@@ -677,11 +726,22 @@ static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func

	regamma_params->hw_points_num = hw_points;

	for (i = 0; i < segment_end - segment_start; i++) {
		regamma_params->arr_curve_points[i].offset = i * 16;
		regamma_params->arr_curve_points[i].segments_num = 4;
	i = 1;
	for (k = 0; k < 16 && i < 16; k++) {
		if (seg_distr[k] != -1) {
			regamma_params->arr_curve_points[k].segments_num =
					seg_distr[k];
			regamma_params->arr_curve_points[i].offset =
					regamma_params->arr_curve_points[k].
					offset + (1 << seg_distr[k]);
		}
		i++;
	}

	if (seg_distr[k] != -1)
		regamma_params->arr_curve_points[k].segments_num =
				seg_distr[k];

	struct pwl_result_data *rgb = rgb_resulted;
	struct pwl_result_data *rgb_plus_1 = rgb_resulted + 1;

+11 −0
Original line number Diff line number Diff line
@@ -47,6 +47,17 @@ enum colorimetry {
	COLORIMETRY_EXTENDED = 3
};

enum colorimetry_ext {
	COLORIMETRYEX_XVYCC601 = 0,
	COLORIMETRYEX_XVYCC709 = 1,
	COLORIMETRYEX_SYCC601 = 2,
	COLORIMETRYEX_ADOBEYCC601 = 3,
	COLORIMETRYEX_ADOBERGB = 4,
	COLORIMETRYEX_BT2020YCC = 5,
	COLORIMETRYEX_BT2020RGBYCBCR = 6,
	COLORIMETRYEX_RESERVED = 7
};

enum active_format_info {
	ACTIVE_FORMAT_NO_DATA = 0,
	ACTIVE_FORMAT_VALID = 1