[PATCH 06/14] drm/amd/display: Implement gamma correction using input LUT
Harry Wentland
harry.wentland at amd.com
Fri Dec 23 15:57:58 UTC 2016
From: Aric Cyr <aric.cyr at amd.com>
The dc_gamma in dc_surface will be programmed to the input
LUT if provided. If dc_gamma is not provided in dc_surface
regamma may be used to emulate gamma.
Some refactor and cleanup included as well.
Change-Id: I6bd82a4528befd009a136775cb9953ee67488c3f
Signed-off-by: Aric Cyr <aric.cyr at amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
---
.../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c | 25 +-
drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c | 29 +-
drivers/gpu/drm/amd/display/dc/core/dc_surface.c | 6 +-
drivers/gpu/drm/amd/display/dc/dc.h | 40 +--
drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 10 +
drivers/gpu/drm/amd/display/dc/dce/dce_opp.c | 2 -
drivers/gpu/drm/amd/display/dc/dce/dce_opp.h | 4 -
.../amd/display/dc/dce110/dce110_hw_sequencer.c | 17 +-
drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.c | 1 +
drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.h | 11 +-
.../drm/amd/display/dc/dce110/dce110_ipp_gamma.c | 304 ++++++---------------
.../amd/display/dc/dce110/dce110_opp_regamma_v.c | 1 -
.../gpu/drm/amd/display/dc/dce110/dce110_opp_v.c | 2 -
.../gpu/drm/amd/display/dc/dce110/dce110_opp_v.h | 4 -
drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.c | 1 +
drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.h | 2 -
.../gpu/drm/amd/display/dc/dce80/dce80_ipp_gamma.c | 5 -
drivers/gpu/drm/amd/display/dc/inc/gamma_types.h | 38 ---
drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h | 4 +
drivers/gpu/drm/amd/display/dc/inc/hw/opp.h | 1 -
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h | 2 -
drivers/gpu/drm/amd/display/modules/color/color.c | 6 +-
22 files changed, 144 insertions(+), 371 deletions(-)
delete mode 100644 drivers/gpu/drm/amd/display/dc/inc/gamma_types.h
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
index 9d7d44274e99..6a2548e8082b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c
@@ -515,32 +515,25 @@ static void fill_gamma_from_crtc(
uint16_t *red, *green, *blue;
int end = (crtc->gamma_size > NUM_OF_RAW_GAMMA_RAMP_RGB_256) ?
NUM_OF_RAW_GAMMA_RAMP_RGB_256 : crtc->gamma_size;
- struct amdgpu_device *adev = crtc->dev->dev_private;
red = crtc->gamma_store;
green = red + crtc->gamma_size;
blue = green + crtc->gamma_size;
- gamma = dc_create_gamma(adev->dm.dc);
+ gamma = dc_create_gamma();
if (gamma == NULL)
return;
for (i = 0; i < end; i++) {
- gamma->gamma_ramp_rgb256x3x16.red[i] =
- (unsigned short) red[i];
- gamma->gamma_ramp_rgb256x3x16.green[i] =
- (unsigned short) green[i];
- gamma->gamma_ramp_rgb256x3x16.blue[i] =
- (unsigned short) blue[i];
+ gamma->red[i] = (unsigned short) red[i];
+ gamma->green[i] = (unsigned short) green[i];
+ gamma->blue[i] = (unsigned short) blue[i];
}
- gamma->type = GAMMA_RAMP_RBG256X3X16;
- gamma->size = sizeof(gamma->gamma_ramp_rgb256x3x16);
-
dc_surface->gamma_correction = gamma;
- input_tf = dc_create_transfer_func(adev->dm.dc);
+ input_tf = dc_create_transfer_func();
if (input_tf == NULL)
return;
@@ -838,6 +831,12 @@ static void fill_stream_properties_from_drm_display_mode(
stream->output_color_space = get_output_color_space(timing_out);
+ {
+ struct dc_transfer_func *tf = dc_create_transfer_func();
+ tf->type = TF_TYPE_PREDEFINED;
+ tf->tf = TRANSFER_FUNCTION_SRGB;
+ stream->out_transfer_func = tf;
+ }
}
static void fill_audio_info(
@@ -3211,7 +3210,7 @@ static bool is_dp_capable_without_timing_msa(
dc_read_dpcd(dc, amdgpu_connector->dc_link->link_index,
DP_DOWN_STREAM_PORT_COUNT,
&dpcd_data, sizeof(dpcd_data)) )
- capable = dpcd_data & DP_MSA_TIMING_PAR_IGNORED? true:false;
+ capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false;
return capable;
}
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
index f33135b53a80..ca2234e4b7d2 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
+++ b/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
@@ -573,7 +573,7 @@ static bool find_software_points(
uint32_t *index_right,
enum hw_point_position *pos)
{
- const uint32_t max_number = RGB_256X3X16 + 3;
+ const uint32_t max_number = INPUT_LUT_ENTRIES + 3;
struct fixed31_32 left, right;
@@ -686,12 +686,12 @@ static bool build_custom_gamma_mapping_coefficients_worker(
return false;
}
- if (index_left >= RGB_256X3X16 + 3) {
+ if (index_left >= INPUT_LUT_ENTRIES + 3) {
BREAK_TO_DEBUGGER();
return false;
}
- if (index_right >= RGB_256X3X16 + 3) {
+ if (index_right >= INPUT_LUT_ENTRIES + 3) {
BREAK_TO_DEBUGGER();
return false;
}
@@ -958,20 +958,13 @@ static bool scale_gamma(struct pwl_float_data *pwl_rgb,
const struct core_gamma *ramp,
struct dividers dividers)
{
- const struct dc_gamma_ramp_rgb256x3x16 *gamma;
+ const struct dc_gamma *gamma = &ramp->public;
const uint16_t max_driver = 0xFFFF;
const uint16_t max_os = 0xFF00;
uint16_t scaler = max_os;
- uint32_t i;
+ uint32_t i = 0;
struct pwl_float_data *rgb = pwl_rgb;
- struct pwl_float_data *rgb_last = rgb + RGB_256X3X16 - 1;
-
- if (ramp->public.type == GAMMA_RAMP_RBG256X3X16)
- gamma = &ramp->public.gamma_ramp_rgb256x3x16;
- else
- return false; /* invalid option */
-
- i = 0;
+ struct pwl_float_data *rgb_last = rgb + INPUT_LUT_ENTRIES - 1;
do {
if ((gamma->red[i] > max_os) ||
@@ -981,7 +974,7 @@ static bool scale_gamma(struct pwl_float_data *pwl_rgb,
break;
}
++i;
- } while (i != RGB_256X3X16);
+ } while (i != INPUT_LUT_ENTRIES);
i = 0;
@@ -995,7 +988,7 @@ static bool scale_gamma(struct pwl_float_data *pwl_rgb,
++rgb;
++i;
- } while (i != RGB_256X3X16);
+ } while (i != INPUT_LUT_ENTRIES);
rgb->r = dal_fixed31_32_mul(rgb_last->r,
dividers.divider1);
@@ -1110,7 +1103,7 @@ static bool calculate_interpolated_hardware_curve(
return false;
coeff = coeff128;
- max_entries += RGB_256X3X16;
+ max_entries += INPUT_LUT_ENTRIES;
/* TODO: float point case */
@@ -1440,13 +1433,13 @@ bool calculate_regamma_params(struct pwl_params *params,
coordinates_x = dm_alloc(sizeof(*coordinates_x)*(256 + 3));
if (!coordinates_x)
goto coordinates_x_alloc_fail;
- rgb_user = dm_alloc(sizeof(*rgb_user) * (FLOAT_GAMMA_RAMP_MAX + 3));
+ rgb_user = dm_alloc(sizeof(*rgb_user) * (TRANSFER_FUNC_POINTS + 3));
if (!rgb_user)
goto rgb_user_alloc_fail;
rgb_regamma = dm_alloc(sizeof(*rgb_regamma) * (256 + 3));
if (!rgb_regamma)
goto rgb_regamma_alloc_fail;
- rgb_oem = dm_alloc(sizeof(*rgb_oem) * (FLOAT_GAMMA_RAMP_MAX + 3));
+ rgb_oem = dm_alloc(sizeof(*rgb_oem) * (TRANSFER_FUNC_POINTS + 3));
if (!rgb_oem)
goto rgb_oem_alloc_fail;
axix_x_256 = dm_alloc(sizeof(*axix_x_256) * (256 + 3));
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 1ca40a212008..3ec1f363e43e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -189,9 +189,8 @@ void dc_gamma_release(const struct dc_gamma *dc_gamma)
dm_free(gamma);
}
-struct dc_gamma *dc_create_gamma(const struct dc *dc)
+struct dc_gamma *dc_create_gamma()
{
- struct core_dc *core_dc = DC_TO_CORE(dc);
struct gamma *gamma = dm_alloc(sizeof(*gamma));
if (gamma == NULL)
@@ -221,9 +220,8 @@ void dc_transfer_func_release(const struct dc_transfer_func *dc_tf)
dm_free(tf);
}
-struct dc_transfer_func *dc_create_transfer_func(const struct dc *dc)
+struct dc_transfer_func *dc_create_transfer_func()
{
- struct core_dc *core_dc = DC_TO_CORE(dc);
struct transfer_func *tf = dm_alloc(sizeof(*tf));
if (tf == NULL)
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index 05fcb0663ff0..0ee6f41b6047 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -183,43 +183,9 @@ void dc_destroy(struct dc **dc);
******************************************************************************/
enum {
- RGB_256X3X16 = 256,
- FLOAT_GAMMA_RAMP_MAX = 1025,
TRANSFER_FUNC_POINTS = 1025
};
-enum dc_gamma_ramp_type {
- GAMMA_RAMP_RBG256X3X16,
- GAMMA_RAMP_FLOAT,
-};
-
-struct float_rgb {
- struct fixed32_32 red;
- struct fixed32_32 green;
- struct fixed32_32 blue;
-};
-
-struct dc_gamma_ramp_float {
- struct float_rgb scale;
- struct float_rgb offset;
- struct float_rgb gamma_curve[FLOAT_GAMMA_RAMP_MAX];
-};
-
-struct dc_gamma_ramp_rgb256x3x16 {
- uint16_t red[RGB_256X3X16];
- uint16_t green[RGB_256X3X16];
- uint16_t blue[RGB_256X3X16];
-};
-
-struct dc_gamma {
- enum dc_gamma_ramp_type type;
- union {
- struct dc_gamma_ramp_rgb256x3x16 gamma_ramp_rgb256x3x16;
- struct dc_gamma_ramp_float gamma_ramp_float;
- };
- uint32_t size;
-};
-
enum dc_transfer_func_type {
TF_TYPE_PREDEFINED,
TF_TYPE_DISTRIBUTED_POINTS,
@@ -266,9 +232,7 @@ struct dc_surface {
bool horizontal_mirror;
enum plane_stereo_format stereo_format;
- /* TO BE REMOVED AFTER BELOW TRANSFER FUNCTIONS IMPLEMENTED */
const struct dc_gamma *gamma_correction;
-
const struct dc_transfer_func *in_transfer_func;
};
@@ -332,11 +296,11 @@ void dc_surface_release(const struct dc_surface *dc_surface);
void dc_gamma_retain(const struct dc_gamma *dc_gamma);
void dc_gamma_release(const struct dc_gamma *dc_gamma);
-struct dc_gamma *dc_create_gamma(const struct dc *dc);
+struct dc_gamma *dc_create_gamma(void);
void dc_transfer_func_retain(const struct dc_transfer_func *dc_tf);
void dc_transfer_func_release(const struct dc_transfer_func *dc_tf);
-struct dc_transfer_func *dc_create_transfer_func(const struct dc *dc);
+struct dc_transfer_func *dc_create_transfer_func(void);
/*
* This structure holds a surface address. There could be multiple addresses
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
index 499f6b2a31f8..00958bdbb417 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hw_types.h
@@ -370,6 +370,16 @@ struct dc_cursor_mi_param {
/* IPP related types */
+enum {
+ INPUT_LUT_ENTRIES = 256
+};
+
+struct dc_gamma {
+ uint16_t red[INPUT_LUT_ENTRIES];
+ uint16_t green[INPUT_LUT_ENTRIES];
+ uint16_t blue[INPUT_LUT_ENTRIES];
+};
+
/* Used by both ipp amd opp functions*/
/* TODO: to be consolidated with enum color_space */
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
index 653f93dd281f..46b128708c7e 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
@@ -28,8 +28,6 @@
#include "dce_opp.h"
-#include "gamma_types.h"
-
#include "reg_helper.h"
#define REG(reg)\
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h
index 1c01a83ecc50..f2828f044b96 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_opp.h
@@ -29,10 +29,6 @@
#include "opp.h"
#include "core_types.h"
-#include "gamma_types.h" /* decprecated */
-
-struct gamma_parameters;
-
#define FROM_DCE11_OPP(opp)\
container_of(opp, struct dce110_opp, base)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 2f790753b559..e4cef9da5de1 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -228,10 +228,11 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params,
break;
default:
ASSERT(false);
+ break;
}
}
-static bool dce110_set_degamma(
+static bool dce110_set_input_transfer_func(
struct pipe_ctx *pipe_ctx,
const struct core_surface *surface)
{
@@ -249,6 +250,9 @@ static bool dce110_set_degamma(
build_prescale_params(&prescale_params, surface);
ipp->funcs->ipp_program_prescale(ipp, &prescale_params);
+ if (surface->public.gamma_correction)
+ ipp->funcs->ipp_program_input_lut(ipp, surface->public.gamma_correction);
+
if (tf == NULL) {
/* Default case if no input transfer function specified */
ipp->funcs->ipp_set_degamma(ipp,
@@ -272,6 +276,7 @@ static bool dce110_set_degamma(
break;
default:
result = false;
+ break;
}
} else {
/*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/
@@ -303,8 +308,11 @@ static bool dce110_set_output_transfer_func(
opp->funcs->opp_power_on_regamma_lut(opp, true);
- if (ramp && calculate_regamma_params(
- regamma_params, ramp, surface, stream)) {
+ if (stream->public.out_transfer_func &&
+ stream->public.out_transfer_func->type == TF_TYPE_PREDEFINED &&
+ stream->public.out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
+ opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB);
+ } else if (ramp && calculate_regamma_params(regamma_params, ramp, surface, stream)) {
opp->funcs->opp_program_regamma_pwl(opp, regamma_params);
opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
} else {
@@ -1318,7 +1326,6 @@ enum dc_status dce110_apply_ctx_to_hw(
* instead of per pipe.
*/
struct audio_output audio_output;
- struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
build_audio_output(pipe_ctx, &audio_output);
@@ -1945,7 +1952,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
.set_plane_config = set_plane_config,
.update_plane_addr = update_plane_addr,
.update_pending_status = dce110_update_pending_status,
- .set_input_transfer_func = dce110_set_degamma,
+ .set_input_transfer_func = dce110_set_input_transfer_func,
.set_output_transfer_func = dce110_set_output_transfer_func,
.power_down = dce110_power_down,
.enable_accelerated_mode = dce110_enable_accelerated_mode,
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.c
index dd69f6060bb9..86fa7657a756 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.c
@@ -35,6 +35,7 @@ static const struct ipp_funcs funcs = {
.ipp_cursor_set_attributes = dce110_ipp_cursor_set_attributes,
.ipp_cursor_set_position = dce110_ipp_cursor_set_position,
.ipp_program_prescale = dce110_ipp_program_prescale,
+ .ipp_program_input_lut = dce110_ipp_program_input_lut,
.ipp_set_degamma = dce110_ipp_set_degamma,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.h
index 56fe3274407c..a374ef2c9d0b 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp.h
@@ -28,9 +28,6 @@
#include "ipp.h"
-struct gamma_parameters;
-struct dev_c_lut;
-
#define TO_DCE110_IPP(input_pixel_processor)\
container_of(input_pixel_processor, struct dce110_ipp, base)
@@ -69,9 +66,9 @@ bool dce110_ipp_set_degamma(
void dce110_ipp_program_prescale(
struct input_pixel_processor *ipp,
struct ipp_prescale_params *params);
-/*
- * Helper functions to be resused in other ASICs
- */
-void dce110_helper_select_lut(struct dce110_ipp *ipp110);
+
+void dce110_ipp_program_input_lut(
+ struct input_pixel_processor *ipp,
+ const struct dc_gamma *gamma);
#endif /*__DC_IPP_DCE110_H__*/
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
index 79a6a6dd72fc..c68914bf7af0 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_ipp_gamma.c
@@ -32,21 +32,39 @@
#include "dce/dce_11_0_sh_mask.h"
#include "dce110_ipp.h"
-#include "gamma_types.h"
#define DCP_REG(reg)\
- (reg + ipp110->offsets.dcp_offset)
+ (mm##reg + ipp110->offsets.dcp_offset)
+
+#define DCP_REG_SET_N(reg_name, n, ...) \
+ generic_reg_update_ex(ipp110->base.ctx, \
+ DCP_REG(reg_name), \
+ 0, n, __VA_ARGS__)
+
+#define DCP_REG_SET(reg, field1, val1) \
+ DCP_REG_SET_N(reg, 1, FD(reg##__##field1), val1)
+
+#define DCP_REG_SET_2(reg, field1, val1, field2, val2) \
+ DCP_REG_SET_N(reg, 2, \
+ FD(reg##__##field1), val1, \
+ FD(reg##__##field2), val2)
+
+#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3) \
+ DCP_REG_SET_N(reg, 3, \
+ FD(reg##__##field1), val1, \
+ FD(reg##__##field2), val2, \
+ FD(reg##__##field3), val3)
+
+#define DCP_REG_UPDATE_N(reg_name, n, ...) \
+ generic_reg_update_ex(ipp110->base.ctx, \
+ DCP_REG(reg_name), \
+ dm_read_reg(ipp110->base.ctx, DCP_REG(reg_name)), \
+ n, __VA_ARGS__)
+
+#define DCP_REG_UPDATE(reg, field, val) \
+ DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)
-enum {
- MAX_INPUT_LUT_ENTRY = 256
-};
-/*PROTOTYPE DECLARATIONS*/
-static void set_lut_inc(
- struct dce110_ipp *ipp110,
- uint8_t inc,
- bool is_float,
- bool is_signed);
bool dce110_ipp_set_degamma(
struct input_pixel_processor *ipp,
@@ -61,25 +79,11 @@ bool dce110_ipp_set_degamma(
ASSERT(mode == IPP_DEGAMMA_MODE_BYPASS ||
mode == IPP_DEGAMMA_MODE_HW_sRGB);
- set_reg_field_value(
- value,
- degamma_type,
- DEGAMMA_CONTROL,
- GRPH_DEGAMMA_MODE);
-
- set_reg_field_value(
- value,
- degamma_type,
- DEGAMMA_CONTROL,
- CURSOR_DEGAMMA_MODE);
-
- set_reg_field_value(
- value,
- degamma_type,
+ DCP_REG_SET_3(
DEGAMMA_CONTROL,
- CURSOR2_DEGAMMA_MODE);
-
- dm_write_reg(ipp110->base.ctx, DCP_REG(mmDEGAMMA_CONTROL), value);
+ GRPH_DEGAMMA_MODE, degamma_type,
+ CURSOR_DEGAMMA_MODE, degamma_type,
+ CURSOR2_DEGAMMA_MODE, degamma_type);
return true;
}
@@ -90,214 +94,70 @@ void dce110_ipp_program_prescale(
{
struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
- uint32_t prescale_control = 0;
- uint32_t prescale_value = 0;
- uint32_t legacy_lut_control = 0;
+ /* set to bypass mode first before change */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL,
+ GRPH_PRESCALE_BYPASS, 1);
- prescale_control = dm_read_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_GRPH_CONTROL));
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_R,
+ GRPH_PRESCALE_SCALE_R, params->scale,
+ GRPH_PRESCALE_BIAS_R, params->bias);
- if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_G,
+ GRPH_PRESCALE_SCALE_G, params->scale,
+ GRPH_PRESCALE_BIAS_G, params->bias);
- set_reg_field_value(
- prescale_control,
- 0,
- PRESCALE_GRPH_CONTROL,
- GRPH_PRESCALE_BYPASS);
-
- /*
- * If prescale is in use, then legacy lut should
- * be bypassed
- */
- legacy_lut_control = dm_read_reg(ipp110->base.ctx,
- DCP_REG(mmINPUT_GAMMA_CONTROL));
-
- set_reg_field_value(
- legacy_lut_control,
- 1,
- INPUT_GAMMA_CONTROL,
- GRPH_INPUT_GAMMA_MODE);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmINPUT_GAMMA_CONTROL),
- legacy_lut_control);
- } else {
- set_reg_field_value(
- prescale_control,
- 1,
- PRESCALE_GRPH_CONTROL,
- GRPH_PRESCALE_BYPASS);
- }
+ DCP_REG_SET_2(PRESCALE_VALUES_GRPH_B,
+ GRPH_PRESCALE_SCALE_B, params->scale,
+ GRPH_PRESCALE_BIAS_B, params->bias);
- set_reg_field_value(
- prescale_value,
- params->scale,
- PRESCALE_VALUES_GRPH_R,
- GRPH_PRESCALE_SCALE_R);
-
- set_reg_field_value(
- prescale_value,
- params->bias,
- PRESCALE_VALUES_GRPH_R,
- GRPH_PRESCALE_BIAS_R);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_GRPH_CONTROL),
- prescale_control);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_R),
- prescale_value);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_G),
- prescale_value);
-
- dm_write_reg(ipp110->base.ctx,
- DCP_REG(mmPRESCALE_VALUES_GRPH_B),
- prescale_value);
-}
-
-static void set_lut_inc(
- struct dce110_ipp *ipp110,
- uint8_t inc,
- bool is_float,
- bool is_signed)
-{
- const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
-
- uint32_t value = dm_read_reg(ipp110->base.ctx, addr);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_R);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_G);
-
- set_reg_field_value(
- value,
- inc,
- DC_LUT_CONTROL,
- DC_LUT_INC_B);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_float,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_FLOAT_POINT_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_SIGNED_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_SIGNED_EN);
-
- set_reg_field_value(
- value,
- is_signed,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_SIGNED_EN);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
+ if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
+ /* If prescale is in use, then legacy lut should be bypassed */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 0);
+ DCP_REG_UPDATE(INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 1);
+ }
}
-void dce110_helper_select_lut(struct dce110_ipp *ipp110)
+static void dce110_helper_select_lut(struct dce110_ipp *ipp110)
{
- uint32_t value = 0;
-
- set_lut_inc(ipp110, 0, false, false);
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_WRITE_EN_MASK);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
-
- /* enable all */
- set_reg_field_value(
- value,
- 0x7,
- DC_LUT_WRITE_EN_MASK,
- DC_LUT_WRITE_EN_MASK);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_RW_MODE);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* enable all */
+ DCP_REG_SET(DC_LUT_WRITE_EN_MASK, DC_LUT_WRITE_EN_MASK, 0x7);
- set_reg_field_value(
- value,
- 0,
- DC_LUT_RW_MODE,
- DC_LUT_RW_MODE);
+ /* 256 entry mode */
+ DCP_REG_UPDATE(DC_LUT_RW_MODE, DC_LUT_RW_MODE, 0);
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
-
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
+ /* LUT-256, unsigned, integer, new u0.12 format */
+ DCP_REG_SET_3(DC_LUT_CONTROL,
+ DC_LUT_DATA_R_FORMAT, 3,
+ DC_LUT_DATA_G_FORMAT, 3,
+ DC_LUT_DATA_B_FORMAT, 3);
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* start from index 0 */
+ DCP_REG_SET(DC_LUT_RW_INDEX, DC_LUT_RW_INDEX, 0);
+}
- /* 00 - new u0.12 */
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_R_FORMAT);
+void dce110_ipp_program_input_lut(
+ struct input_pixel_processor *ipp,
+ const struct dc_gamma *gamma)
+{
+ int i;
+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_G_FORMAT);
+ dce110_helper_select_lut(ipp110);
- set_reg_field_value(
- value,
- 3,
- DC_LUT_CONTROL,
- DC_LUT_DATA_B_FORMAT);
+ /* power on LUT memory and give it time to settle */
+ DCP_REG_SET(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 1);
+ udelay(10);
- dm_write_reg(ipp110->base.ctx, addr, value);
+ for (i = 0; i < INPUT_LUT_ENTRIES; i++) {
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->red[i]);
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->green[i]);
+ DCP_REG_SET(DC_LUT_SEQ_COLOR, DC_LUT_SEQ_COLOR, gamma->blue[i]);
}
- {
- const uint32_t addr = DCP_REG(mmDC_LUT_RW_INDEX);
-
- value = dm_read_reg(ipp110->base.ctx, addr);
+ /* power off LUT memory */
+ DCP_REG_SET(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 0);
- set_reg_field_value(
- value,
- 0,
- DC_LUT_RW_INDEX,
- DC_LUT_RW_INDEX);
-
- dm_write_reg(ipp110->base.ctx, addr, value);
- }
+ /* bypass prescale, enable legacy LUT */
+ DCP_REG_UPDATE(PRESCALE_GRPH_CONTROL, GRPH_PRESCALE_BYPASS, 1);
+ DCP_REG_UPDATE(INPUT_GAMMA_CONTROL, GRPH_INPUT_GAMMA_MODE, 0);
}
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c
index 81fcbc52e4ab..8164aa6bcb00 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_regamma_v.c
@@ -30,7 +30,6 @@
#include "dce/dce_11_0_sh_mask.h"
#include "dce/dce_opp.h"
-#include "gamma_types.h"
static void power_on_lut(struct output_pixel_processor *opp,
bool power_on, bool inputgamma, bool regamma)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.c
index dfd63a71d214..0a9b384303d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.c
@@ -32,8 +32,6 @@
#include "dce/dce_opp.h"
#include "dce110_opp_v.h"
-#include "gamma_types.h"
-
/*****************************************/
/* Constructor, Destructor */
/*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.h
index dcdbf86fccc1..ac5937786ce3 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.h
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_opp_v.h
@@ -29,10 +29,6 @@
#include "opp.h"
#include "core_types.h"
-#include "gamma_types.h" /* decprecated */
-
-struct gamma_parameters;
-
bool dce110_opp_v_construct(struct dce110_opp *opp110,
struct dc_context *ctx);
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.c
index 86826c229d39..c195acb6e1a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.c
@@ -37,6 +37,7 @@ static const struct ipp_funcs funcs = {
.ipp_cursor_set_attributes = dce110_ipp_cursor_set_attributes,
.ipp_cursor_set_position = dce110_ipp_cursor_set_position,
.ipp_program_prescale = dce110_ipp_program_prescale,
+ .ipp_program_input_lut = dce110_ipp_program_input_lut,
.ipp_set_degamma = dce110_ipp_set_degamma,
};
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.h b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.h
index d350138e5feb..06e8598d395f 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp.h
@@ -33,8 +33,6 @@
struct dce110_ipp;
struct dce110_ipp_reg_offsets;
-struct gamma_parameters;
-struct dev_c_lut;
bool dce80_ipp_construct(
struct dce110_ipp *ipp,
diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp_gamma.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp_gamma.c
index eacb14e40d52..760168df5290 100644
--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp_gamma.c
+++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_ipp_gamma.c
@@ -34,15 +34,10 @@
#include "dce80_ipp.h"
#include "dce110/dce110_ipp.h"
-#include "gamma_types.h"
#define DCP_REG(reg)\
(reg + ipp80->offsets.dcp_offset)
-enum {
- MAX_INPUT_LUT_ENTRY = 256
-};
-
/*PROTOTYPE DECLARATIONS*/
static void set_legacy_input_gamma_mode(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/gamma_types.h b/drivers/gpu/drm/amd/display/dc/inc/gamma_types.h
deleted file mode 100644
index 7948d2cc0715..000000000000
--- a/drivers/gpu/drm/amd/display/dc/inc/gamma_types.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2012-15 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-#ifndef GAMMA_TYPES_H_
-
-#define GAMMA_TYPES_H_
-
-#include "dc_types.h"
-
-/* TODO: Used in IPP and OPP */
-
-struct dev_c_lut16 {
- uint16_t red;
- uint16_t green;
- uint16_t blue;
-};
-#endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
index e9ed167c9e41..0457bc7a44d4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/ipp.h
@@ -110,6 +110,10 @@ struct ipp_funcs {
struct input_pixel_processor *ipp,
struct ipp_prescale_params *params);
+ void (*ipp_program_input_lut)(
+ struct input_pixel_processor *ipp,
+ const struct dc_gamma *gamma);
+
/*** DEGAMMA RELATED ***/
bool (*ipp_set_degamma)(
struct input_pixel_processor *ipp,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
index e615997be20e..a1f31a4410a3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
@@ -30,7 +30,6 @@
#include "transform.h"
struct fixed31_32;
-struct gamma_parameters;
/* TODO: Need cleanup */
enum clamping_range {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
index 0e803ca83bb9..895c446cebf9 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
@@ -28,8 +28,6 @@
#include "core_types.h"
#include "timing_generator.h"
-struct gamma_parameters;
-
enum pipe_gating_control {
PIPE_GATING_CONTROL_DISABLE = 0,
PIPE_GATING_CONTROL_ENABLE,
diff --git a/drivers/gpu/drm/amd/display/modules/color/color.c b/drivers/gpu/drm/amd/display/modules/color/color.c
index 6d1b20f6bf98..5c578aecf21c 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color.c
@@ -2433,7 +2433,7 @@ bool mod_color_set_input_gamma_correction(struct mod_color *mod_color,
if (surface != NULL) {
struct dc_transfer_func *input_tf =
- dc_create_transfer_func(core_color->dc);
+ dc_create_transfer_func();
struct dc_surface_update updates = {0};
if (input_tf != NULL) {
@@ -2724,7 +2724,7 @@ bool mod_color_update_gamut_info(struct mod_color *mod_color,
/* 3. ---- SET DEGAMMA ---- */
struct dc_transfer_func *input_tf = NULL;
- input_tf = dc_create_transfer_func(core_color->dc);
+ input_tf = dc_create_transfer_func();
if (input_tf != NULL) {
input_tf->type = TF_TYPE_PREDEFINED;
@@ -2747,7 +2747,7 @@ bool mod_color_update_gamut_info(struct mod_color *mod_color,
/* 4. ---- SET REGAMMA ---- */
struct dc_transfer_func *output_tf = NULL;
- output_tf = dc_create_transfer_func(core_color->dc);
+ output_tf = dc_create_transfer_func();
if (output_tf != NULL) {
output_tf->type = TF_TYPE_PREDEFINED;
--
2.9.3
More information about the amd-gfx
mailing list