From 734ab62e914908b443ba53c107d9cc5cc18e78f0 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Tue, 20 Dec 2016 20:24:24 -0500 Subject: [PATCH 0093/4131] drm/amd/display: Implement gamma correction using input LUT 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. Signed-off-by: Aric Cyr Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../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 6aede70..e7ada89 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 @@ -516,32 +516,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; @@ -839,6 +832,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( @@ -3212,7 +3211,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 f33135b..ca2234e 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 1ca40a2..3ec1f36 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 05fcb06..0ee6f41 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 499f6b2..00958bd 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 653f93d..46b1287 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 1c01a83e..f2828f0 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 2f79075..e4cef9d 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 dd69f60..86fa765 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 56fe327..a374ef2 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 79a6a6d..c68914b 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 81fcbc5..8164aa6 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 dfd63a7..0a9b384 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 dcdbf86..ac59377 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 86826c2..c195acb 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 d350138..06e8598 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 eacb14e..760168d 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 7948d2c..0000000 --- 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 e9ed167..0457bc7 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 e615997..a1f31a4 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 0e803ca..895c446 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 6d1b20f..5c578aec 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.7.4