Commit 887ff121 authored by Anthony Koo's avatar Anthony Koo Committed by Alex Deucher

drm/amd/display: Refactor to remove diags specific rgam func

[Why]
It has duplicate code for building regamma curve

[How]
Remove the duplicate code and use the same function for building regamma
Signed-off-by: default avatarAnthony Koo <Anthony.Koo@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Reviewed-by: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 819d4b3f
...@@ -1673,129 +1673,6 @@ static bool map_regamma_hw_to_x_user( ...@@ -1673,129 +1673,6 @@ static bool map_regamma_hw_to_x_user(
#define _EXTRA_POINTS 3 #define _EXTRA_POINTS 3
bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
const struct freesync_hdr_tf_params *fs_params)
{
struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
struct dividers dividers;
struct pwl_float_data *rgb_user = NULL;
struct pwl_float_data_ex *rgb_regamma = NULL;
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
bool ret = false;
if (output_tf->type == TF_TYPE_BYPASS)
return false;
/* we can use hardcoded curve for plain SRGB TF */
if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true &&
output_tf->tf == TRANSFER_FUNCTION_SRGB) {
if (ramp == NULL)
return true;
if ((ramp->is_identity && ramp->type != GAMMA_CS_TFM_1D) ||
(!mapUserRamp && ramp->type == GAMMA_RGB_256))
return true;
}
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
if (ramp && ramp->type != GAMMA_CS_TFM_1D &&
(mapUserRamp || ramp->type != GAMMA_RGB_256)) {
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user),
GFP_KERNEL);
if (!rgb_user)
goto rgb_user_alloc_fail;
axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x),
GFP_KERNEL);
if (!axis_x)
goto axis_x_alloc_fail;
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
dividers.divider2 = dc_fixpt_from_int(2);
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
build_evenly_distributed_points(
axis_x,
ramp->num_entries,
dividers);
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
scale_gamma(rgb_user, ramp, dividers);
else if (ramp->type == GAMMA_RGB_FLOAT_1024)
scale_gamma_dx(rgb_user, ramp, dividers);
}
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
sizeof(*rgb_regamma),
GFP_KERNEL);
if (!rgb_regamma)
goto rgb_regamma_alloc_fail;
coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
GFP_KERNEL);
if (!coeff)
goto coeff_alloc_fail;
tf = output_tf->tf;
if (tf == TRANSFER_FUNCTION_PQ) {
tf_pts->end_exponent = 7;
tf_pts->x_point_at_y1_red = 125;
tf_pts->x_point_at_y1_green = 125;
tf_pts->x_point_at_y1_blue = 125;
build_pq(rgb_regamma,
MAX_HW_POINTS,
coordinates_x,
output_tf->sdr_ref_white_level);
} else if (tf == TRANSFER_FUNCTION_GAMMA22 &&
fs_params != NULL && fs_params->skip_tm == 0) {
build_freesync_hdr(rgb_regamma,
MAX_HW_POINTS,
coordinates_x,
fs_params);
} else if (tf == TRANSFER_FUNCTION_HLG) {
build_freesync_hdr(rgb_regamma,
MAX_HW_POINTS,
coordinates_x,
fs_params);
} else {
tf_pts->end_exponent = 0;
tf_pts->x_point_at_y1_red = 1;
tf_pts->x_point_at_y1_green = 1;
tf_pts->x_point_at_y1_blue = 1;
build_regamma(rgb_regamma,
MAX_HW_POINTS,
coordinates_x, tf);
}
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
coordinates_x, axis_x, rgb_regamma,
MAX_HW_POINTS, tf_pts,
(mapUserRamp || (ramp && ramp->type != GAMMA_RGB_256)) &&
(ramp && ramp->type != GAMMA_CS_TFM_1D));
if (ramp && ramp->type == GAMMA_CS_TFM_1D)
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
ret = true;
kvfree(coeff);
coeff_alloc_fail:
kvfree(rgb_regamma);
rgb_regamma_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(rgb_user);
rgb_user_alloc_fail:
return ret;
}
bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf, bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf,
const struct regamma_lut *regamma) const struct regamma_lut *regamma)
{ {
...@@ -2043,14 +1920,14 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, ...@@ -2043,14 +1920,14 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf,
return ret; return ret;
} }
static bool calculate_curve(enum dc_transfer_func_predefined trans,
bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
struct dc_transfer_func_distributed_points *points, struct dc_transfer_func_distributed_points *points,
struct pwl_float_data_ex *rgb_regamma,
const struct freesync_hdr_tf_params *fs_params,
uint32_t sdr_ref_white_level) uint32_t sdr_ref_white_level)
{ {
uint32_t i; uint32_t i;
bool ret = false; bool ret = false;
struct pwl_float_data_ex *rgb_regamma = NULL;
if (trans == TRANSFER_FUNCTION_UNITY || if (trans == TRANSFER_FUNCTION_UNITY ||
trans == TRANSFER_FUNCTION_LINEAR) { trans == TRANSFER_FUNCTION_LINEAR) {
...@@ -2060,45 +1937,50 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, ...@@ -2060,45 +1937,50 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
points->x_point_at_y1_blue = 1; points->x_point_at_y1_blue = 1;
for (i = 0; i <= MAX_HW_POINTS ; i++) { for (i = 0; i <= MAX_HW_POINTS ; i++) {
points->red[i] = coordinates_x[i].x; rgb_regamma[i].r = coordinates_x[i].x;
points->green[i] = coordinates_x[i].x; rgb_regamma[i].g = coordinates_x[i].x;
points->blue[i] = coordinates_x[i].x; rgb_regamma[i].b = coordinates_x[i].x;
} }
ret = true; ret = true;
} else if (trans == TRANSFER_FUNCTION_PQ) { } else if (trans == TRANSFER_FUNCTION_PQ) {
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
sizeof(*rgb_regamma),
GFP_KERNEL);
if (!rgb_regamma)
goto rgb_regamma_alloc_fail;
points->end_exponent = 7; points->end_exponent = 7;
points->x_point_at_y1_red = 125; points->x_point_at_y1_red = 125;
points->x_point_at_y1_green = 125; points->x_point_at_y1_green = 125;
points->x_point_at_y1_blue = 125; points->x_point_at_y1_blue = 125;
build_pq(rgb_regamma, build_pq(rgb_regamma,
MAX_HW_POINTS, MAX_HW_POINTS,
coordinates_x, coordinates_x,
sdr_ref_white_level); sdr_ref_white_level);
for (i = 0; i <= MAX_HW_POINTS ; i++) {
points->red[i] = rgb_regamma[i].r; ret = true;
points->green[i] = rgb_regamma[i].g; } else if (trans == TRANSFER_FUNCTION_GAMMA22 &&
points->blue[i] = rgb_regamma[i].b; fs_params != NULL && fs_params->skip_tm == 0) {
} build_freesync_hdr(rgb_regamma,
MAX_HW_POINTS,
coordinates_x,
fs_params);
ret = true; ret = true;
} else if (trans == TRANSFER_FUNCTION_HLG) {
points->end_exponent = 4;
points->x_point_at_y1_red = 12;
points->x_point_at_y1_green = 12;
points->x_point_at_y1_blue = 12;
kvfree(rgb_regamma); build_hlg_regamma(rgb_regamma,
} else if (trans == TRANSFER_FUNCTION_SRGB || MAX_HW_POINTS,
trans == TRANSFER_FUNCTION_BT709 || coordinates_x,
trans == TRANSFER_FUNCTION_GAMMA22 || 80, 1000);
trans == TRANSFER_FUNCTION_GAMMA24 ||
trans == TRANSFER_FUNCTION_GAMMA26) { ret = true;
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, } else {
sizeof(*rgb_regamma), // trans == TRANSFER_FUNCTION_SRGB
GFP_KERNEL); // trans == TRANSFER_FUNCTION_BT709
if (!rgb_regamma) // trans == TRANSFER_FUNCTION_GAMMA22
goto rgb_regamma_alloc_fail; // trans == TRANSFER_FUNCTION_GAMMA24
// trans == TRANSFER_FUNCTION_GAMMA26
points->end_exponent = 0; points->end_exponent = 0;
points->x_point_at_y1_red = 1; points->x_point_at_y1_red = 1;
points->x_point_at_y1_green = 1; points->x_point_at_y1_green = 1;
...@@ -2108,42 +1990,111 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans, ...@@ -2108,42 +1990,111 @@ bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
MAX_HW_POINTS, MAX_HW_POINTS,
coordinates_x, coordinates_x,
trans); trans);
for (i = 0; i <= MAX_HW_POINTS ; i++) {
points->red[i] = rgb_regamma[i].r;
points->green[i] = rgb_regamma[i].g;
points->blue[i] = rgb_regamma[i].b;
}
ret = true; ret = true;
}
return ret;
}
bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
const struct freesync_hdr_tf_params *fs_params)
{
struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
struct dividers dividers;
struct pwl_float_data *rgb_user = NULL;
struct pwl_float_data_ex *rgb_regamma = NULL;
struct gamma_pixel *axis_x = NULL;
struct pixel_gamma_point *coeff = NULL;
enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
bool ret = false;
if (output_tf->type == TF_TYPE_BYPASS)
return false;
/* we can use hardcoded curve for plain SRGB TF */
if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true &&
output_tf->tf == TRANSFER_FUNCTION_SRGB) {
if (ramp == NULL)
return true;
if ((ramp->is_identity && ramp->type != GAMMA_CS_TFM_1D) ||
(!mapUserRamp && ramp->type == GAMMA_RGB_256))
return true;
}
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
if (ramp && ramp->type != GAMMA_CS_TFM_1D &&
(mapUserRamp || ramp->type != GAMMA_RGB_256)) {
rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
sizeof(*rgb_user),
GFP_KERNEL);
if (!rgb_user)
goto rgb_user_alloc_fail;
axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x),
GFP_KERNEL);
if (!axis_x)
goto axis_x_alloc_fail;
dividers.divider1 = dc_fixpt_from_fraction(3, 2);
dividers.divider2 = dc_fixpt_from_int(2);
dividers.divider3 = dc_fixpt_from_fraction(5, 2);
build_evenly_distributed_points(
axis_x,
ramp->num_entries,
dividers);
if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
scale_gamma(rgb_user, ramp, dividers);
else if (ramp->type == GAMMA_RGB_FLOAT_1024)
scale_gamma_dx(rgb_user, ramp, dividers);
}
kvfree(rgb_regamma);
} else if (trans == TRANSFER_FUNCTION_HLG) {
rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
sizeof(*rgb_regamma), sizeof(*rgb_regamma),
GFP_KERNEL); GFP_KERNEL);
if (!rgb_regamma) if (!rgb_regamma)
goto rgb_regamma_alloc_fail; goto rgb_regamma_alloc_fail;
points->end_exponent = 4;
points->x_point_at_y1_red = 12;
points->x_point_at_y1_green = 12;
points->x_point_at_y1_blue = 12;
build_hlg_regamma(rgb_regamma, coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
MAX_HW_POINTS, GFP_KERNEL);
coordinates_x, if (!coeff)
80, 1000); goto coeff_alloc_fail;
for (i = 0; i <= MAX_HW_POINTS ; i++) {
points->red[i] = rgb_regamma[i].r; tf = output_tf->tf;
points->green[i] = rgb_regamma[i].g;
points->blue[i] = rgb_regamma[i].b; ret = calculate_curve(tf,
tf_pts,
rgb_regamma,
fs_params,
output_tf->sdr_ref_white_level);
if (ret) {
map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
coordinates_x, axis_x, rgb_regamma,
MAX_HW_POINTS, tf_pts,
(mapUserRamp || (ramp && ramp->type != GAMMA_RGB_256)) &&
(ramp && ramp->type != GAMMA_CS_TFM_1D));
if (ramp && ramp->type == GAMMA_CS_TFM_1D)
apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
} }
ret = true;
kvfree(coeff);
coeff_alloc_fail:
kvfree(rgb_regamma); kvfree(rgb_regamma);
}
rgb_regamma_alloc_fail: rgb_regamma_alloc_fail:
kvfree(axis_x);
axis_x_alloc_fail:
kvfree(rgb_user);
rgb_user_alloc_fail:
return ret; return ret;
} }
bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
struct dc_transfer_func_distributed_points *points) struct dc_transfer_func_distributed_points *points)
{ {
......
...@@ -103,10 +103,6 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, ...@@ -103,10 +103,6 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf, bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf,
const struct dc_gamma *ramp, bool mapUserRamp); const struct dc_gamma *ramp, bool mapUserRamp);
bool mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
struct dc_transfer_func_distributed_points *points,
uint32_t sdr_ref_white_level);
bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans, bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
struct dc_transfer_func_distributed_points *points); struct dc_transfer_func_distributed_points *points);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment