summary refs log tree commit diff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorCristian Ciocaltea <cristian.ciocaltea@collabora.com>2023-09-15 19:15:46 +0300
committerCristian Ciocaltea <cristian.ciocaltea@collabora.com>2023-09-15 19:15:46 +0300
commite959e54e8bd0b64d8e646c0f55c31d0fbf84f330 (patch)
treebeaccd9d7d62494486e9f99144745bf7ef299000 /drivers/gpu
parentf79b43986c74aeebe7e10f715fd6c7f7bd0083fe (diff)
parentd6b36fa14b05526d537ed5ec237ecc077d4e2e27 (diff)
downloadlinux-e959e54e8bd0b64d8e646c0f55c31d0fbf84f330.tar.gz
Merge additional upstream patches
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c24
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c12
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c104
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c17
-rw-r--r--drivers/gpu/drm/amd/display/modules/color/color_gamma.c115
7 files changed, 171 insertions, 109 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 27edf4fa2aab..8fb33fe87866 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8093,10 +8093,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 		 * fast updates.
 		 */
 		if (crtc->state->async_flip &&
-		    acrtc_state->update_type != UPDATE_TYPE_FAST)
+		    (acrtc_state->update_type != UPDATE_TYPE_FAST ||
+		     get_mem_type(old_plane_state->fb) != get_mem_type(fb)))
 			drm_warn_once(state->dev,
 				      "[PLANE:%d:%s] async flip with non-fast update\n",
 				      plane->base.id, plane->name);
+
 		bundle->flip_addrs[planes_count].flip_immediate =
 			crtc->state->async_flip &&
 			acrtc_state->update_type == UPDATE_TYPE_FAST &&
@@ -10054,6 +10056,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 
 	/* Remove exiting planes if they are modified */
 	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
+		if (old_plane_state->fb && new_plane_state->fb &&
+		    get_mem_type(old_plane_state->fb) !=
+		    get_mem_type(new_plane_state->fb))
+			lock_and_validation_needed = true;
+
 		ret = dm_update_plane_state(dc, state, plane,
 					    old_plane_state,
 					    new_plane_state,
@@ -10301,9 +10308,20 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		struct dm_crtc_state *dm_new_crtc_state =
 			to_dm_crtc_state(new_crtc_state);
 
+		/*
+		 * Only allow async flips for fast updates that don't change
+		 * the FB pitch, the DCC state, rotation, etc.
+		 */
+		if (new_crtc_state->async_flip && lock_and_validation_needed) {
+			drm_dbg_atomic(crtc->dev,
+				       "[CRTC:%d:%s] async flips are only supported for fast updates\n",
+				       crtc->base.id, crtc->name);
+			ret = -EINVAL;
+			goto fail;
+		}
+
 		dm_new_crtc_state->update_type = lock_and_validation_needed ?
-							 UPDATE_TYPE_FULL :
-							 UPDATE_TYPE_FAST;
+			UPDATE_TYPE_FULL : UPDATE_TYPE_FAST;
 	}
 
 	/* Must be success */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 30d4c6fd95f5..440fc0869a34 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -398,18 +398,6 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
-	/*
-	 * Only allow async flips for fast updates that don't change the FB
-	 * pitch, the DCC state, rotation, etc.
-	 */
-	if (crtc_state->async_flip &&
-	    dm_crtc_state->update_type != UPDATE_TYPE_FAST) {
-		drm_dbg_atomic(crtc->dev,
-			       "[CRTC:%d:%s] async flips are only supported for fast updates\n",
-			       crtc->base.id, crtc->name);
-		return -EINVAL;
-	}
-
 	/* In some use cases, like reset, no stream is attached */
 	if (!dm_crtc_state->stream)
 		return 0;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 322668973747..6c84ca2ae373 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1260,6 +1260,13 @@ void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
 	attributes.rotation_angle    = 0;
 	attributes.attribute_flags.value = 0;
 
+	/* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM
+	 * legacy gamma setup.
+	 */
+	if (crtc_state->cm_is_degamma_srgb &&
+	    adev->dm.dc->caps.color.dpp.gamma_corr)
+		attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
+
 	attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
 
 	if (crtc_state->stream) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 20f668d28364..51b5d4f9d00e 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1634,6 +1634,7 @@ static void dcn20_update_dchubp_dpp(
 	if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed
 			|| pipe_ctx->update_flags.bits.plane_changed
 			|| pipe_ctx->stream->update_flags.bits.gamut_remap
+			|| plane_state->update_flags.bits.gamut_remap_change
 			|| pipe_ctx->stream->update_flags.bits.out_csc) {
 		/* dpp/cm gamut remap*/
 		dc->hwss.program_gamut_remap(pipe_ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
index e0df9b0065f9..ddb344056d40 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
@@ -114,7 +114,6 @@ bool cm3_helper_translate_curve_to_hw_format(
 	struct pwl_result_data *rgb;
 	struct pwl_result_data *rgb_plus_1;
 	struct pwl_result_data *rgb_minus_1;
-	struct fixed31_32 end_value;
 
 	int32_t region_start, region_end;
 	int32_t i;
@@ -176,7 +175,7 @@ bool cm3_helper_translate_curve_to_hw_format(
 				NUMBER_SW_SEGMENTS;
 		for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
 				i += increment) {
-			if (j == hw_points - 1)
+			if (j == hw_points)
 				break;
 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
@@ -187,13 +186,13 @@ bool cm3_helper_translate_curve_to_hw_format(
 
 	/* last point */
 	start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS;
-	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];
+	rgb_resulted[hw_points].red = output_tf->tf_pts.red[start_index];
+	rgb_resulted[hw_points].green = output_tf->tf_pts.green[start_index];
+	rgb_resulted[hw_points].blue = output_tf->tf_pts.blue[start_index];
 
-	rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
-	rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
-	rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
+	rgb_resulted[hw_points+1].red = rgb_resulted[hw_points].red;
+	rgb_resulted[hw_points+1].green = rgb_resulted[hw_points].green;
+	rgb_resulted[hw_points+1].blue = rgb_resulted[hw_points].blue;
 
 	// All 3 color channels have same x
 	corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
@@ -220,34 +219,16 @@ bool cm3_helper_translate_curve_to_hw_format(
 	/* see comment above, m_arrPoints[1].y should be the Y value for the
 	 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
 	 */
-	corner_points[1].red.y = rgb_resulted[hw_points - 1].red;
-	corner_points[1].green.y = rgb_resulted[hw_points - 1].green;
-	corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue;
+	corner_points[1].red.y = rgb_resulted[hw_points].red;
+	corner_points[1].green.y = rgb_resulted[hw_points].green;
+	corner_points[1].blue.y = rgb_resulted[hw_points].blue;
 	corner_points[1].red.slope = dc_fixpt_zero;
 	corner_points[1].green.slope = dc_fixpt_zero;
 	corner_points[1].blue.slope = dc_fixpt_zero;
 
-	if (output_tf->tf == TRANSFER_FUNCTION_PQ || output_tf->tf == TRANSFER_FUNCTION_HLG) {
-		/* for PQ/HLG, we want to have a straight line from last HW X point,
-		 * and the slope to be such that we hit 1.0 at 10000/1000 nits.
-		 */
-
-		if (output_tf->tf == TRANSFER_FUNCTION_PQ)
-			end_value = dc_fixpt_from_int(125);
-		else
-			end_value = dc_fixpt_from_fraction(125, 10);
-
-		corner_points[1].red.slope = dc_fixpt_div(
-			dc_fixpt_sub(dc_fixpt_one, corner_points[1].red.y),
-			dc_fixpt_sub(end_value, corner_points[1].red.x));
-		corner_points[1].green.slope = dc_fixpt_div(
-			dc_fixpt_sub(dc_fixpt_one, corner_points[1].green.y),
-			dc_fixpt_sub(end_value, corner_points[1].green.x));
-		corner_points[1].blue.slope = dc_fixpt_div(
-			dc_fixpt_sub(dc_fixpt_one, corner_points[1].blue.y),
-			dc_fixpt_sub(end_value, corner_points[1].blue.x));
-	}
-	lut_params->hw_points_num = hw_points;
+	// DCN3+ have 257 pts in lieu of no separate slope registers
+	// Prior HW had 256 base+slope pairs
+	lut_params->hw_points_num = hw_points + 1;
 
 	k = 0;
 	for (i = 1; i < MAX_REGIONS_NUMBER; i++) {
@@ -267,38 +248,37 @@ bool cm3_helper_translate_curve_to_hw_format(
 	rgb_plus_1 = rgb_resulted + 1;
 	rgb_minus_1 = rgb;
 
-	i = 1;
-	while (i != hw_points + 1) {
-		if (i >= hw_points - 1) {
-			if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
-				rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red);
-			if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
-				rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green);
-			if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
-				rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue);
-		}
-
-		rgb->delta_red   = dc_fixpt_sub(rgb_plus_1->red,   rgb->red);
-		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
-		rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  rgb->blue);
+	if (fixpoint == true) {
+		i = 1;
+		while (i != hw_points + 2) {
+			if (i >= hw_points) {
+				if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
+					rgb_plus_1->red = dc_fixpt_add(rgb->red,
+							rgb_minus_1->delta_red);
+				if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
+					rgb_plus_1->green = dc_fixpt_add(rgb->green,
+							rgb_minus_1->delta_green);
+				if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
+					rgb_plus_1->blue = dc_fixpt_add(rgb->blue,
+							rgb_minus_1->delta_blue);
+			}
 
-		if (fixpoint == true) {
 			rgb->delta_red_reg   = dc_fixpt_clamp_u0d10(rgb->delta_red);
 			rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
 			rgb->delta_blue_reg  = dc_fixpt_clamp_u0d10(rgb->delta_blue);
 			rgb->red_reg         = dc_fixpt_clamp_u0d14(rgb->red);
 			rgb->green_reg       = dc_fixpt_clamp_u0d14(rgb->green);
 			rgb->blue_reg        = dc_fixpt_clamp_u0d14(rgb->blue);
-		}
 
-		++rgb_plus_1;
-		rgb_minus_1 = rgb;
-		++rgb;
-		++i;
+			++rgb_plus_1;
+			rgb_minus_1 = rgb;
+			++rgb;
+			++i;
+		}
 	}
 	cm3_helper_convert_to_custom_float(rgb_resulted,
 						lut_params->corner_points,
-						hw_points, fixpoint);
+						hw_points+1, fixpoint);
 
 	return true;
 }
@@ -603,24 +583,6 @@ bool cm3_helper_convert_to_custom_float(
 			return false;
 		}
 
-		if (!convert_to_custom_float_format(rgb->delta_red, &fmt,
-						    &rgb->delta_red_reg)) {
-			BREAK_TO_DEBUGGER();
-			return false;
-		}
-
-		if (!convert_to_custom_float_format(rgb->delta_green, &fmt,
-						    &rgb->delta_green_reg)) {
-			BREAK_TO_DEBUGGER();
-			return false;
-		}
-
-		if (!convert_to_custom_float_format(rgb->delta_blue, &fmt,
-						    &rgb->delta_blue_reg)) {
-			BREAK_TO_DEBUGGER();
-			return false;
-		}
-
 		++rgb;
 		++i;
 	}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
index 6cf40c1332bc..d1500b223858 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
@@ -278,22 +278,10 @@ static void mpc3_program_ogam_pwl(
 {
 	uint32_t i;
 	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
-	uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
-	uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
-	uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
-
-	/*the entries of DCN3AG gamma LUTs take 18bit base values as opposed to
-	 *38 base+delta values per entry in earlier DCN architectures
-	 *last base value for our lut is compute by adding the last base value
-	 *in our data + last delta
-	 */
 
 	if (is_rgb_equal(rgb,  num)) {
 		for (i = 0 ; i < num; i++)
 			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
-
-		REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
-
 	} else {
 
 		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
@@ -302,8 +290,6 @@ static void mpc3_program_ogam_pwl(
 		for (i = 0 ; i < num; i++)
 			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
 
-		REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
-
 		REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 
 		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
@@ -312,8 +298,6 @@ static void mpc3_program_ogam_pwl(
 		for (i = 0 ; i < num; i++)
 			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg);
 
-		REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_green);
-
 		REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 
 		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
@@ -322,7 +306,6 @@ static void mpc3_program_ogam_pwl(
 		for (i = 0 ; i < num; i++)
 			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg);
 
-		REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_blue);
 	}
 
 }
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index 67a062af3ab0..cb536be92a40 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -37,6 +37,104 @@
 
 static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
 
+// Hardcoded table that depends on setup_x_points_distribution and sdr_level=80
+// If x points are changed, then PQ Y points will be misaligned and a new
+// table would need to be generated. Or use old method that calls compute_pq.
+// The last point is above PQ formula range (0-125 in normalized FP16)
+// The value for the last point (128) is such that interpolation from
+// 120 to 128 will give 1.0 for X = 125.0
+// first couple points are 0 - HW LUT is mirrored around zero, so making first
+// segment 0 to 0 will effectively clip it, and these are very low PQ codes
+// min nonzero value below (216825) is a little under 12-bit PQ code 1.
+static const unsigned long long pq_divider = 1000000000;
+static const unsigned long long pq_numerator[MAX_HW_POINTS + 1] = {
+		0, 0, 0, 0, 216825, 222815,
+		228691, 234460, 240128, 245702, 251187, 256587,
+		261908, 267152, 272324, 277427, 282465, 292353,
+		302011, 311456, 320704, 329768, 338661, 347394,
+		355975, 364415, 372721, 380900, 388959, 396903,
+		404739, 412471, 420104, 435089, 449727, 464042,
+		478060, 491800, 505281, 518520, 531529, 544324,
+		556916, 569316, 581533, 593576, 605454, 617175,
+		628745, 651459, 673643, 695337, 716578, 737395,
+		757817, 777869, 797572, 816947, 836012, 854782,
+		873274, 891500, 909474, 927207, 944709, 979061,
+		1012601, 1045391, 1077485, 1108931, 1139770, 1170042,
+		1199778, 1229011, 1257767, 1286071, 1313948, 1341416,
+		1368497, 1395207, 1421563, 1473272, 1523733, 1573041,
+		1621279, 1668520, 1714828, 1760262, 1804874, 1848710,
+		1891814, 1934223, 1975973, 2017096, 2057622, 2097578,
+		2136989, 2214269, 2289629, 2363216, 2435157, 2505564,
+		2574539, 2642169, 2708536, 2773711, 2837760, 2900742,
+		2962712, 3023719, 3083810, 3143025, 3201405, 3315797,
+		3427246, 3535974, 3642181, 3746038, 3847700, 3947305,
+		4044975, 4140823, 4234949, 4327445, 4418394, 4507872,
+		4595951, 4682694, 4768161, 4935487, 5098326, 5257022,
+		5411878, 5563161, 5711107, 5855928, 5997812, 6136929,
+		6273436, 6407471, 6539163, 6668629, 6795976, 6921304,
+		7044703, 7286050, 7520623, 7748950, 7971492, 8188655,
+		8400800, 8608247, 8811286, 9010175, 9205149, 9396421,
+		9584186, 9768620, 9949889, 10128140, 10303513, 10646126,
+		10978648, 11301874, 11616501, 11923142, 12222340, 12514578,
+		12800290, 13079866, 13353659, 13621988, 13885144, 14143394,
+		14396982, 14646132, 14891052, 15368951, 15832050, 16281537,
+		16718448, 17143696, 17558086, 17962337, 18357092, 18742927,
+		19120364, 19489877, 19851894, 20206810, 20554983, 20896745,
+		21232399, 21886492, 22519276, 23132491, 23727656, 24306104,
+		24869013, 25417430, 25952292, 26474438, 26984626, 27483542,
+		27971811, 28450000, 28918632, 29378184, 29829095, 30706591,
+		31554022, 32373894, 33168387, 33939412, 34688657, 35417620,
+		36127636, 36819903, 37495502, 38155408, 38800507, 39431607,
+		40049446, 40654702, 41247996, 42400951, 43512407, 44585892,
+		45624474, 46630834, 47607339, 48556082, 49478931, 50377558,
+		51253467, 52108015, 52942436, 53757848, 54555277, 55335659,
+		56099856, 57582802, 59009766, 60385607, 61714540, 63000246,
+		64245964, 65454559, 66628579, 67770304, 68881781, 69964856,
+		71021203, 72052340, 73059655, 74044414, 75007782, 76874537,
+		78667536, 80393312, 82057522, 83665098, 85220372, 86727167,
+		88188883, 89608552, 90988895, 92332363, 93641173, 94917336,
+		96162685, 97378894, 98567496, 100867409, 103072439, 105191162,
+		107230989, 109198368, 111098951, 112937723, 114719105, 116447036,
+		118125045, 119756307, 121343688, 122889787, 124396968, 125867388,
+		127303021, 130077030, 132731849, 135278464, 137726346, 140083726,
+		142357803, 144554913, 146680670, 148740067, 150737572, 152677197,
+		154562560, 156396938, 158183306, 159924378, 161622632, 164899602,
+		168030318, 171028513, 173906008, 176673051, 179338593, 181910502,
+		184395731, 186800463, 189130216, 191389941, 193584098, 195716719,
+		197791463, 199811660, 201780351, 205574133, 209192504, 212652233,
+		215967720, 219151432, 222214238, 225165676, 228014163, 230767172,
+		233431363, 236012706, 238516569, 240947800, 243310793, 245609544,
+		247847696, 252155270, 256257056, 260173059, 263920427, 267513978,
+		270966613, 274289634, 277493001, 280585542, 283575118, 286468763,
+		289272796, 291992916, 294634284, 297201585, 299699091, 304500003,
+		309064541, 313416043, 317574484, 321557096, 325378855, 329052864,
+		332590655, 336002433, 339297275, 342483294, 345567766, 348557252,
+		351457680, 354274432, 357012407, 362269536, 367260561, 372012143,
+		376547060, 380884936, 385042798, 389035522, 392876185, 396576344,
+		400146265, 403595112, 406931099, 410161619, 413293351, 416332348,
+		419284117, 424945627, 430313203, 435416697, 440281572, 444929733,
+		449380160, 453649415, 457752035, 461700854, 465507260, 469181407,
+		472732388, 476168376, 479496748, 482724188, 485856764, 491858986,
+		497542280, 502939446, 508078420, 512983199, 517674549, 522170569,
+		526487126, 530638214, 534636233, 538492233, 542216094, 545816693,
+		549302035, 552679362, 555955249, 562226134, 568156709, 573782374,
+		579133244, 584235153, 589110430, 593778512, 598256421, 602559154,
+		606699989, 610690741, 614541971, 618263157, 621862836, 625348729,
+		628727839, 635190643, 641295921, 647081261, 652578597, 657815287,
+		662814957, 667598146, 672182825, 676584810, 680818092, 684895111,
+		688826974, 692623643, 696294085, 699846401, 703287935, 709864782,
+		716071394, 721947076, 727525176, 732834238, 737898880, 742740485,
+		747377745, 751827095, 756103063, 760218552, 764185078, 768012958,
+		771711474, 775289005, 778753144, 785368225, 791604988, 797503949,
+		803099452, 808420859, 813493471, 818339244, 822977353, 827424644,
+		831695997, 835804619, 839762285, 843579541, 847265867, 850829815,
+		854279128, 860861356, 867061719, 872921445, 878475444, 883753534,
+		888781386, 893581259, 898172578, 902572393, 906795754, 910856010,
+		914765057, 918533538, 922171018, 925686119, 929086644, 935571664,
+		941675560, 947439782, 952899395, 958084324, 963020312, 967729662,
+		972231821, 976543852, 980680801, 984656009, 988481353, 992167459,
+		995723865, 999159168, 1002565681};
+
 // these are helpers for calculations to reduce stack usage
 // do not depend on these being preserved across calls
 
@@ -239,14 +337,19 @@ static void compute_hlg_oetf(struct fixed31_32 in_x, struct fixed31_32 *out_y,
 void precompute_pq(void)
 {
 	int i;
+	struct fixed31_32 *pq_table = mod_color_get_table(type_pq_table);
+
+	for (i = 0; i <= MAX_HW_POINTS; i++)
+		pq_table[i] = dc_fixpt_from_fraction(pq_numerator[i], pq_divider);
+
+	/* below is old method that uses run-time calculation in fixed pt space */
+	/* pow function has problems with arguments too small */
+	/*
 	struct fixed31_32 x;
 	const struct hw_x_point *coord_x = coordinates_x + 32;
 	struct fixed31_32 scaling_factor =
 			dc_fixpt_from_fraction(80, 10000);
 
-	struct fixed31_32 *pq_table = mod_color_get_table(type_pq_table);
-
-	/* pow function has problems with arguments too small */
 	for (i = 0; i < 32; i++)
 		pq_table[i] = dc_fixpt_zero;
 
@@ -255,6 +358,7 @@ void precompute_pq(void)
 		compute_pq(x, &pq_table[i]);
 		++coord_x;
 	}
+	*/
 }
 
 /* one-time pre-compute dePQ values - only for max pixel value 125 FP16 */
@@ -779,8 +883,6 @@ static void build_pq(struct pwl_float_data_ex *rgb_regamma,
 		/* should really not happen? */
 		if (dc_fixpt_lt(output, dc_fixpt_zero))
 			output = dc_fixpt_zero;
-		else if (dc_fixpt_lt(dc_fixpt_one, output))
-			output = dc_fixpt_one;
 
 		rgb->r = output;
 		rgb->g = output;
@@ -2193,7 +2295,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
 			cal_buffer);
 
 	if (ret) {
-		do_clamping = !(output_tf->tf == TRANSFER_FUNCTION_GAMMA22 &&
+		do_clamping = !(output_tf->tf == TRANSFER_FUNCTION_PQ) &&
+				!(output_tf->tf == TRANSFER_FUNCTION_GAMMA22 &&
 				fs_params != NULL && fs_params->skip_tm == 0);
 
 		map_regamma_hw_to_x_user(ramp, coeff, rgb_user,