diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0093-drm-amd-display-Implement-gamma-correction-using-inp.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/0093-drm-amd-display-Implement-gamma-correction-using-inp.patch | 1006 |
1 files changed, 1006 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0093-drm-amd-display-Implement-gamma-correction-using-inp.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0093-drm-amd-display-Implement-gamma-correction-using-inp.patch new file mode 100644 index 00000000..bb10fe46 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0093-drm-amd-display-Implement-gamma-correction-using-inp.patch @@ -0,0 +1,1006 @@ +From 734ab62e914908b443ba53c107d9cc5cc18e78f0 Mon Sep 17 00:00:00 2001 +From: Aric Cyr <aric.cyr@amd.com> +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 <aric.cyr@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@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 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 + |