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>hifive-unleashed-5.1
parent
3c25e920f0
commit
d7194cf6b8
|
@ -521,14 +521,11 @@ static void fill_gamma_from_crtc(
|
|||
return;
|
||||
|
||||
for (i = 0; i < NUM_OF_RAW_GAMMA_RAMP_RGB_256; i++) {
|
||||
gamma->gamma_ramp_rgb256x3x16.red[i] = lut[i].red;
|
||||
gamma->gamma_ramp_rgb256x3x16.green[i] = lut[i].green;
|
||||
gamma->gamma_ramp_rgb256x3x16.blue[i] = lut[i].blue;
|
||||
gamma->red[i] = lut[i].red;
|
||||
gamma->green[i] = lut[i].green;
|
||||
gamma->blue[i] = lut[i].blue;
|
||||
}
|
||||
|
||||
gamma->type = GAMMA_RAMP_RBG256X3X16;
|
||||
gamma->size = sizeof(gamma->gamma_ramp_rgb256x3x16);
|
||||
|
||||
dc_surface->gamma_correction = gamma;
|
||||
|
||||
input_tf = dc_create_transfer_func();
|
||||
|
@ -822,6 +819,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(
|
||||
|
@ -3066,7 +3069,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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "dce_opp.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
||||
#include "reg_helper.h"
|
||||
|
||||
#define REG(reg)\
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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,
|
||||
DCP_REG_SET_3(
|
||||
DEGAMMA_CONTROL,
|
||||
GRPH_DEGAMMA_MODE);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
degamma_type,
|
||||
DEGAMMA_CONTROL,
|
||||
CURSOR_DEGAMMA_MODE);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
degamma_type,
|
||||
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);
|
||||
|
||||
DCP_REG_SET_2(PRESCALE_VALUES_GRPH_G,
|
||||
GRPH_PRESCALE_SCALE_G, params->scale,
|
||||
GRPH_PRESCALE_BIAS_G, params->bias);
|
||||
|
||||
DCP_REG_SET_2(PRESCALE_VALUES_GRPH_B,
|
||||
GRPH_PRESCALE_SCALE_B, params->scale,
|
||||
GRPH_PRESCALE_BIAS_B, params->bias);
|
||||
|
||||
if (params->mode != IPP_PRESCALE_MODE_BYPASS) {
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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)
|
||||
static void dce110_helper_select_lut(struct dce110_ipp *ipp110)
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
|
||||
/* enable all */
|
||||
DCP_REG_SET(DC_LUT_WRITE_EN_MASK, DC_LUT_WRITE_EN_MASK, 0x7);
|
||||
|
||||
uint32_t value = dm_read_reg(ipp110->base.ctx, addr);
|
||||
/* 256 entry mode */
|
||||
DCP_REG_UPDATE(DC_LUT_RW_MODE, DC_LUT_RW_MODE, 0);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
inc,
|
||||
DC_LUT_CONTROL,
|
||||
DC_LUT_INC_R);
|
||||
/* 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);
|
||||
|
||||
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);
|
||||
/* start from index 0 */
|
||||
DCP_REG_SET(DC_LUT_RW_INDEX, DC_LUT_RW_INDEX, 0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
int i;
|
||||
struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
|
||||
|
||||
set_lut_inc(ipp110, 0, false, false);
|
||||
dce110_helper_select_lut(ipp110);
|
||||
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmDC_LUT_WRITE_EN_MASK);
|
||||
/* 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);
|
||||
|
||||
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);
|
||||
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_MODE);
|
||||
/* power off LUT memory */
|
||||
DCP_REG_SET(DCFE_MEM_PWR_CTRL, DCP_LUT_MEM_PWR_DIS, 0);
|
||||
|
||||
value = dm_read_reg(ipp110->base.ctx, addr);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
0,
|
||||
DC_LUT_RW_MODE,
|
||||
DC_LUT_RW_MODE);
|
||||
|
||||
dm_write_reg(ipp110->base.ctx, addr, value);
|
||||
}
|
||||
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
|
||||
|
||||
value = dm_read_reg(ipp110->base.ctx, addr);
|
||||
|
||||
/* 00 - new u0.12 */
|
||||
set_reg_field_value(
|
||||
value,
|
||||
3,
|
||||
DC_LUT_CONTROL,
|
||||
DC_LUT_DATA_R_FORMAT);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
3,
|
||||
DC_LUT_CONTROL,
|
||||
DC_LUT_DATA_G_FORMAT);
|
||||
|
||||
set_reg_field_value(
|
||||
value,
|
||||
3,
|
||||
DC_LUT_CONTROL,
|
||||
DC_LUT_DATA_B_FORMAT);
|
||||
|
||||
dm_write_reg(ipp110->base.ctx, addr, value);
|
||||
}
|
||||
|
||||
{
|
||||
const uint32_t addr = DCP_REG(mmDC_LUT_RW_INDEX);
|
||||
|
||||
value = dm_read_reg(ipp110->base.ctx, addr);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
#include "dce/dce_opp.h"
|
||||
#include "dce110_opp_v.h"
|
||||
|
||||
#include "gamma_types.h"
|
||||
|
||||
/*****************************************/
|
||||
/* Constructor, Destructor */
|
||||
/*****************************************/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "transform.h"
|
||||
|
||||
struct fixed31_32;
|
||||
struct gamma_parameters;
|
||||
|
||||
/* TODO: Need cleanup */
|
||||
enum clamping_range {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue