diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 71993d5983bf..ebc96b720083 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -28,6 +28,8 @@ #include "timing_generator.h" #include "hw_sequencer.h" +#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) + /* used as index in array of black_color_format */ enum black_color_format { BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0, @@ -38,6 +40,15 @@ enum black_color_format { BLACK_COLOR_FORMAT_DEBUG, }; +enum dc_color_space_type { + COLOR_SPACE_RGB_TYPE, + COLOR_SPACE_RGB_LIMITED_TYPE, + COLOR_SPACE_YCBCR601_TYPE, + COLOR_SPACE_YCBCR709_TYPE, + COLOR_SPACE_YCBCR601_LIMITED_TYPE, + COLOR_SPACE_YCBCR709_LIMITED_TYPE +}; + static const struct tg_color black_color_format[] = { /* BlackColorFormat_RGB_FullRange */ {0, 0, 0}, @@ -53,6 +64,140 @@ static const struct tg_color black_color_format[] = { {0xff, 0xff, 0}, }; +struct out_csc_color_matrix_type { + enum dc_color_space_type color_space_type; + uint16_t regval[12]; +}; + +static const struct out_csc_color_matrix_type output_csc_matrix[] = { + { COLOR_SPACE_RGB_TYPE, + { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, + { COLOR_SPACE_RGB_LIMITED_TYPE, + { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} }, + { COLOR_SPACE_YCBCR601_TYPE, + { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45, + 0xF6B7, 0xE04, 0x1004} }, + { COLOR_SPACE_YCBCR709_TYPE, + { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA, + 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} }, + + /* TODO: correct values below */ + { COLOR_SPACE_YCBCR601_LIMITED_TYPE, + { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991, + 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} }, + { COLOR_SPACE_YCBCR709_LIMITED_TYPE, + { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, + 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, +}; + +static bool is_rgb_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_SRGB || + color_space == COLOR_SPACE_XR_RGB || + color_space == COLOR_SPACE_MSREF_SCRGB || + color_space == COLOR_SPACE_2020_RGB_FULLRANGE || + color_space == COLOR_SPACE_ADOBERGB || + color_space == COLOR_SPACE_DCIP3 || + color_space == COLOR_SPACE_DOLBYVISION) + ret = true; + return ret; +} + +static bool is_rgb_limited_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_SRGB_LIMITED || + color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) + ret = true; + return ret; +} + +static bool is_ycbcr601_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_YCBCR601 || + color_space == COLOR_SPACE_XV_YCC_601) + ret = true; + return ret; +} + +static bool is_ycbcr601_limited_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_YCBCR601_LIMITED) + ret = true; + return ret; +} + +static bool is_ycbcr709_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_YCBCR709 || + color_space == COLOR_SPACE_XV_YCC_709) + ret = true; + return ret; +} + +static bool is_ycbcr709_limited_type( + enum dc_color_space color_space) +{ + bool ret = false; + + if (color_space == COLOR_SPACE_YCBCR709_LIMITED) + ret = true; + return ret; +} +enum dc_color_space_type get_color_space_type(enum dc_color_space color_space) +{ + enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE; + + if (is_rgb_type(color_space)) + type = COLOR_SPACE_RGB_TYPE; + else if (is_rgb_limited_type(color_space)) + type = COLOR_SPACE_RGB_LIMITED_TYPE; + else if (is_ycbcr601_type(color_space)) + type = COLOR_SPACE_YCBCR601_TYPE; + else if (is_ycbcr709_type(color_space)) + type = COLOR_SPACE_YCBCR709_TYPE; + else if (is_ycbcr601_limited_type(color_space)) + type = COLOR_SPACE_YCBCR601_LIMITED_TYPE; + else if (is_ycbcr709_limited_type(color_space)) + type = COLOR_SPACE_YCBCR709_LIMITED_TYPE; + + return type; +} + +const uint16_t *find_color_matrix(enum dc_color_space color_space, + uint32_t *array_size) +{ + int i; + enum dc_color_space_type type; + const uint16_t *val = NULL; + int arr_size = NUM_ELEMENTS(output_csc_matrix); + + type = get_color_space_type(color_space); + for (i = 0; i < arr_size; i++) + if (output_csc_matrix[i].color_space_type == type) { + val = output_csc_matrix[i].regval; + *array_size = 12; + break; + } + + return val; +} + + void color_space_to_black_color( const struct dc *dc, enum dc_color_space colorspace, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h index a093ae5fc2de..640edfa05c94 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h @@ -1370,7 +1370,7 @@ void dpp1_cm_program_regamma_lutb_settings( const struct pwl_params *params); void dpp1_cm_set_output_csc_adjustment( struct dpp *dpp_base, - const struct out_csc_color_matrix *tbl_entry); + const uint16_t *regval); void dpp1_cm_set_output_csc_default( struct dpp *dpp_base, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c index 4f5125398bbc..a5b099023652 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c @@ -225,18 +225,18 @@ void dpp1_cm_set_gamut_remap( static void dpp1_cm_program_color_matrix( struct dcn10_dpp *dpp, - const struct out_csc_color_matrix *tbl_entry) + const uint16_t *regval) { uint32_t mode; struct color_matrices_reg gam_regs; REG_GET(CM_OCSC_CONTROL, CM_OCSC_MODE, &mode); - if (tbl_entry == NULL) { + if (regval == NULL) { BREAK_TO_DEBUGGER(); return; } - + mode = 4; gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11; gam_regs.masks.csc_c11 = dpp->tf_mask->CM_OCSC_C11; gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12; @@ -249,7 +249,7 @@ static void dpp1_cm_program_color_matrix( cm_helper_program_color_matrices( dpp->base.ctx, - tbl_entry->regval, + regval, &gam_regs); } else { @@ -259,7 +259,7 @@ static void dpp1_cm_program_color_matrix( cm_helper_program_color_matrices( dpp->base.ctx, - tbl_entry->regval, + regval, &gam_regs); } } @@ -268,24 +268,18 @@ void dpp1_cm_set_output_csc_default( struct dpp *dpp_base, enum dc_color_space colorspace) { - struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - struct out_csc_color_matrix tbl_entry; - int i, j; - int arr_size = NUM_ELEMENTS(output_csc_matrix); + const uint16_t *regval = NULL; + int arr_size; uint32_t ocsc_mode = 4; - tbl_entry.color_space = colorspace; - - for (i = 0; i < arr_size; i++) - if (output_csc_matrix[i].color_space == colorspace) { - for (j = 0; j < 12; j++) - tbl_entry.regval[j] = output_csc_matrix[i].regval[j]; - break; - } - + regval = find_color_matrix(colorspace, &arr_size); + if (regval == NULL) { + BREAK_TO_DEBUGGER(); + return; + } + dpp1_cm_program_color_matrix(dpp, regval); REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); - dpp1_cm_program_color_matrix(dpp, &tbl_entry); } static void dpp1_cm_get_reg_field( @@ -317,41 +311,12 @@ static void dpp1_cm_get_reg_field( void dpp1_cm_set_output_csc_adjustment( struct dpp *dpp_base, - const struct out_csc_color_matrix *tbl_entry) + const uint16_t *regval) { struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); - //enum csc_color_mode config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC; uint32_t ocsc_mode = 4; - - /** - *if (tbl_entry != NULL) { - * switch (tbl_entry->color_space) { - * case COLOR_SPACE_SRGB: - * case COLOR_SPACE_2020_RGB_FULLRANGE: - * ocsc_mode = 0; - * break; - * case COLOR_SPACE_SRGB_LIMITED: - * case COLOR_SPACE_2020_RGB_LIMITEDRANGE: - * ocsc_mode = 1; - * break; - * case COLOR_SPACE_YCBCR601: - * case COLOR_SPACE_YCBCR601_LIMITED: - * ocsc_mode = 2; - * break; - * case COLOR_SPACE_YCBCR709: - * case COLOR_SPACE_YCBCR709_LIMITED: - * case COLOR_SPACE_2020_YCBCR: - * ocsc_mode = 3; - * break; - * case COLOR_SPACE_UNKNOWN: - * default: - * break; - * } - *} - */ - + dpp1_cm_program_color_matrix(dpp, regval); REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); - dpp1_cm_program_color_matrix(dpp, tbl_entry); } void dpp1_cm_power_on_regamma_lut(struct dpp *dpp_base, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 31fd6ae8f61f..ee057de68ed2 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1429,22 +1429,9 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, enum dc_color_space colorspace, uint16_t *matrix) { - int i; - struct out_csc_color_matrix tbl_entry; - if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { - enum dc_color_space color_space = - pipe_ctx->stream->output_color_space; - - //uint16_t matrix[12]; - for (i = 0; i < 12; i++) - tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; - - tbl_entry.color_space = color_space; - //tbl_entry.regval = matrix; - if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) - pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry); + pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, matrix); } else { if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default != NULL) pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h index 6ccc90ffb0f2..25edbde6163e 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h @@ -68,7 +68,7 @@ struct dpp_funcs { void (*dpp_set_csc_adjustment)( struct dpp *dpp, - const struct out_csc_color_matrix *tbl_entry); + const uint16_t *regval); void (*dpp_power_on_regamma_lut)( struct dpp *dpp, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h index 0f70f36a3ebe..e3f0b4056318 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h @@ -126,31 +126,12 @@ struct default_adjustment { bool force_hw_default; }; + struct out_csc_color_matrix { enum dc_color_space color_space; uint16_t regval[12]; }; -static const struct out_csc_color_matrix output_csc_matrix[] = { - { COLOR_SPACE_SRGB, - { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, - { COLOR_SPACE_SRGB_LIMITED, - { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} }, - { COLOR_SPACE_YCBCR601, - { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45, - 0xF6B7, 0xE04, 0x1004} }, - { COLOR_SPACE_YCBCR709, - { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA, - 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} }, - - /* TODO: correct values below */ - { COLOR_SPACE_YCBCR601_LIMITED, - { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991, - 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} }, - { COLOR_SPACE_YCBCR709_LIMITED, - { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, - 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, -}; enum opp_regamma { OPP_REGAMMA_BYPASS = 0, 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 5d2b05b93e76..a32c745b7d88 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -207,4 +207,8 @@ void color_space_to_black_color( bool hwss_wait_for_blank_complete( struct timing_generator *tg); +const uint16_t *find_color_matrix( + enum dc_color_space color_space, + uint32_t *array_size); + #endif /* __DC_HW_SEQUENCER_H__ */