From afbeb2638b0a983100a5e6591bd1b76ef45bf20c Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Wed, 1 Nov 2017 16:48:52 -0400 Subject: [PATCH] drm/amd/display: call set_mpc_output_csc from hwsequencer Signed-off-by: Yue Hin Lau Reviewed-by: Eric Bernstein Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_dpp_cm.c | 140 ++++++++++-------- .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 67 ++++++++- drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 16 ++ 3 files changed, 156 insertions(+), 67 deletions(-) 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 b4892f43cd77..b5541985e0d8 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 @@ -117,6 +117,33 @@ static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = { 0x2568, 0x43ee, 0xdbb2} } }; +struct output_csc_matrix { + enum dc_color_space color_space; + uint16_t regval[12]; +}; + +static const struct output_csc_matrix output_csc_matrix[] = { + { COLOR_SPACE_SRGB, + { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, + { COLOR_SPACE_SRGB_LIMITED, + { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} }, + { COLOR_SPACE_YCBCR601, + { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47, + 0xF6B9, 0xE00, 0x1000} }, + { COLOR_SPACE_YCBCR709, + { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA, + 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, + + /* 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} }, + { COLOR_SPACE_UNKNOWN, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } +}; static void program_gamut_remap( @@ -223,68 +250,6 @@ void dpp1_cm_set_gamut_remap( } } -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); - uint32_t ocsc_mode = 0; - - switch (colorspace) { - 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; - } - - REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode); - -} - -static void dpp1_cm_get_reg_field( - struct dcn10_dpp *dpp, - struct xfer_func_reg *reg) -{ - reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; - reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; - reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; - reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; - reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; - reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; - reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; - reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; - - reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B; - reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B; - reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; - reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; - reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; - reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; - reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; - reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; - reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B; - reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B; - reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; - reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; -} - static void dpp1_cm_program_color_matrix( struct dcn10_dpp *dpp, const struct out_csc_color_matrix *tbl_entry) @@ -326,6 +291,57 @@ static void dpp1_cm_program_color_matrix( } } +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 = sizeof(output_csc_matrix) / sizeof(struct output_csc_matrix); + 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; + } + + 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( + struct dcn10_dpp *dpp, + struct xfer_func_reg *reg) +{ + reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; + reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_LUT_OFFSET; + reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; + reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; + reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; + reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_LUT_OFFSET; + reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; + reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_RGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; + + reg->shifts.field_region_end = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_B; + reg->masks.field_region_end = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_B; + reg->shifts.field_region_end_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; + reg->masks.field_region_end_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_SLOPE_B; + reg->shifts.field_region_end_base = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; + reg->masks.field_region_end_base = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_END_BASE_B; + reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; + reg->masks.field_region_linear_slope = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_LINEAR_SLOPE_B; + reg->shifts.exp_region_start = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_B; + reg->masks.exp_region_start = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_B; + reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; + reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_RGAM_RAMB_EXP_REGION_START_SEGMENT_B; +} + void dpp1_cm_set_output_csc_adjustment( struct dpp *dpp_base, const struct out_csc_color_matrix *tbl_entry) 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 b5d048b364a4..e08ad585b7b9 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 @@ -1666,12 +1666,68 @@ static void program_csc_matrix(struct pipe_ctx *pipe_ctx, tbl_entry.color_space = color_space; //tbl_entry.regval = matrix; - pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment(pipe_ctx->plane_res.dpp, &tbl_entry); + 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); } else { - pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_default(pipe_ctx->plane_res.dpp, colorspace); + 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); } } +//program ocsc matrix for dcn 2 +static void set_mpc_output_csc(struct dc *dc, + struct pipe_ctx *pipe_ctx, + enum dc_color_space colorspace, + uint16_t *matrix, + int opp_id) +{ + struct mpc *mpc = dc->res_pool->mpc; + int i; + struct out_csc_color_matrix tbl_entry; + enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A; + + + if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { + //uint16_t matrix[12]; + for (i = 0; i < 12; i++) + tbl_entry.regval[i] = matrix[i]; + tbl_entry.color_space = colorspace; + + if (mpc->funcs->set_output_csc != NULL) + mpc->funcs->set_output_csc(mpc, + opp_id, + &tbl_entry, + ocsc_mode); + } + + else { + if (mpc->funcs->set_ocsc_default != NULL) + mpc->funcs->set_ocsc_default(mpc, + opp_id, + colorspace, + ocsc_mode); + } +} + +static void program_output_csc(struct dc *dc, + struct pipe_ctx *pipe_ctx, + enum dc_color_space colorspace, + uint16_t *matrix, + int opp_id) +{ + if (pipe_ctx->plane_res.dpp->funcs->dpp_set_csc_adjustment != NULL) + program_csc_matrix(pipe_ctx, + colorspace, + matrix); + else + set_mpc_output_csc(dc, + pipe_ctx, + colorspace, + matrix, + opp_id); + +} + static bool is_lower_pipe_tree_visible(struct pipe_ctx *pipe_ctx) { if (pipe_ctx->plane_state->visible) @@ -1909,10 +1965,11 @@ static void update_dchubp_dpp( /*gamut remap*/ program_gamut_remap(pipe_ctx); - program_csc_matrix(pipe_ctx, + program_output_csc(dc, + pipe_ctx, pipe_ctx->stream->output_color_space, - pipe_ctx->stream->csc_color_matrix.matrix); - + pipe_ctx->stream->csc_color_matrix.matrix, + mpcc_cfg.opp_id); hubp->funcs->hubp_program_surface_config( hubp, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h index a786d4c3935c..72ea33526a5c 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h @@ -28,6 +28,12 @@ #include "dc_hw_types.h" #include "opp.h" +enum mpc_output_csc_mode { + MPC_OUTPUT_CSC_DISABLE = 0, + MPC_OUTPUT_CSC_COEF_A, + MPC_OUTPUT_CSC_COEF_B +}; + struct mpcc_cfg { int dpp_id; int opp_id; @@ -58,6 +64,16 @@ struct mpc_funcs { int (*get_opp_id)(struct mpc *mpc, int mpcc_id); + void (*set_output_csc)(struct mpc *mpc, + int opp_id, + const struct out_csc_color_matrix *tbl_entry, + enum mpc_output_csc_mode ocsc_mode); + + void (*set_ocsc_default)(struct mpc *mpc, + int opp_id, + enum dc_color_space color_space, + enum mpc_output_csc_mode ocsc_mode); + }; #endif