From: Revalla Hari Krishna Date: Wed, 26 Jun 2024 12:33:16 +0000 (+0530) Subject: drm/amd/display: Refactoring OPP X-Git-Tag: v6.12-rc1~15^2~21^2~423 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=f60881ca126cf825b89b4118e93dbd82ea9bcf33;p=linux-block.git drm/amd/display: Refactoring OPP [Why] To refactor OPP files [How] Moved opp related files to specific opp folder and updated Makefiles. Acked-by: Rodrigo Siqueira Signed-off-by: Jerry Zuo Signed-off-by: Revalla Hari Krishna Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile index 9923d0d620d4..75e088b479ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile @@ -24,7 +24,6 @@ DCN10 = dcn10_ipp.o \ dcn10_hw_sequencer_debug.o \ - dcn10_opp.o \ dcn10_mpc.o \ dcn10_cm_common.o \ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c deleted file mode 100644 index 71e9288d60ed..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c +++ /dev/null @@ -1,413 +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 - * - */ - -#include "core_types.h" -#include "dm_services.h" -#include "dcn10_opp.h" -#include "reg_helper.h" - -#define REG(reg) \ - (oppn10->regs->reg) - -#undef FN -#define FN(reg_name, field_name) \ - oppn10->opp_shift->field_name, oppn10->opp_mask->field_name - -#define CTX \ - oppn10->base.ctx - -/** - * opp1_set_truncation(): - * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp - * 2) enable truncation - * 3) HW remove 12bit FMT support for DCE11 power saving reason. - * - * @oppn10: output_pixel_processor struct instance for dcn10. - * @params: pointer to bit_depth_reduction_params. - */ -static void opp1_set_truncation( - struct dcn10_opp *oppn10, - const struct bit_depth_reduction_params *params) -{ - REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, - FMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED, - FMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH, - FMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE); -} - -static void opp1_set_spatial_dither( - struct dcn10_opp *oppn10, - const struct bit_depth_reduction_params *params) -{ - /*Disable spatial (random) dithering*/ - REG_UPDATE_7(FMT_BIT_DEPTH_CONTROL, - FMT_SPATIAL_DITHER_EN, 0, - FMT_SPATIAL_DITHER_MODE, 0, - FMT_SPATIAL_DITHER_DEPTH, 0, - FMT_TEMPORAL_DITHER_EN, 0, - FMT_HIGHPASS_RANDOM_ENABLE, 0, - FMT_FRAME_RANDOM_ENABLE, 0, - FMT_RGB_RANDOM_ENABLE, 0); - - - /* only use FRAME_COUNTER_MAX if frameRandom == 1*/ - if (params->flags.FRAME_RANDOM == 1) { - if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) { - REG_UPDATE_2(FMT_CONTROL, - FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15, - FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2); - } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) { - REG_UPDATE_2(FMT_CONTROL, - FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3, - FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1); - } else { - return; - } - } else { - REG_UPDATE_2(FMT_CONTROL, - FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0, - FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0); - } - - /*Set seed for random values for - * spatial dithering for R,G,B channels*/ - - REG_SET(FMT_DITHER_RAND_R_SEED, 0, - FMT_RAND_R_SEED, params->r_seed_value); - - REG_SET(FMT_DITHER_RAND_G_SEED, 0, - FMT_RAND_G_SEED, params->g_seed_value); - - REG_SET(FMT_DITHER_RAND_B_SEED, 0, - FMT_RAND_B_SEED, params->b_seed_value); - - /* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero - * offset for the R/Cr channel, lower 4LSB - * is forced to zeros. Typically set to 0 - * RGB and 0x80000 YCbCr. - */ - /* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero - * offset for the G/Y channel, lower 4LSB is - * forced to zeros. Typically set to 0 RGB - * and 0x80000 YCbCr. - */ - /* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero - * offset for the B/Cb channel, lower 4LSB is - * forced to zeros. Typically set to 0 RGB and - * 0x80000 YCbCr. - */ - - REG_UPDATE_6(FMT_BIT_DEPTH_CONTROL, - /*Enable spatial dithering*/ - FMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED, - /* Set spatial dithering mode - * (default is Seed patterrn AAAA...) - */ - FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE, - /*Set spatial dithering bit depth*/ - FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH, - /*Disable High pass filter*/ - FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM, - /*Reset only at startup*/ - FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM, - /*Set RGB data dithered with x^28+x^3+1*/ - FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM); -} - -void opp1_program_bit_depth_reduction( - struct output_pixel_processor *opp, - const struct bit_depth_reduction_params *params) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - - opp1_set_truncation(oppn10, params); - opp1_set_spatial_dither(oppn10, params); - /* TODO - * set_temporal_dither(oppn10, params); - */ -} - -/** - * opp1_set_pixel_encoding(): - * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly - * 1: YCbCr 4:2:2 - * - * @oppn10: output_pixel_processor struct instance for dcn10. - * @params: pointer to clamping_and_pixel_encoding_params. - */ -static void opp1_set_pixel_encoding( - struct dcn10_opp *oppn10, - const struct clamping_and_pixel_encoding_params *params) -{ - bool force_chroma_subsampling_1tap = - oppn10->base.ctx->dc->debug.force_chroma_subsampling_1tap; - - switch (params->pixel_encoding) { - - case PIXEL_ENCODING_RGB: - case PIXEL_ENCODING_YCBCR444: - REG_UPDATE_3(FMT_CONTROL, - FMT_PIXEL_ENCODING, 0, - FMT_SUBSAMPLING_MODE, 0, - FMT_CBCR_BIT_REDUCTION_BYPASS, 0); - REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 0); - break; - case PIXEL_ENCODING_YCBCR422: - REG_UPDATE_3(FMT_CONTROL, - FMT_PIXEL_ENCODING, 1, - FMT_SUBSAMPLING_MODE, 2, - FMT_CBCR_BIT_REDUCTION_BYPASS, 0); - break; - case PIXEL_ENCODING_YCBCR420: - REG_UPDATE_3(FMT_CONTROL, - FMT_PIXEL_ENCODING, 2, - FMT_SUBSAMPLING_MODE, 2, - FMT_CBCR_BIT_REDUCTION_BYPASS, 1); - break; - default: - break; - } - - if (force_chroma_subsampling_1tap) - REG_UPDATE(FMT_CONTROL, FMT_SUBSAMPLING_MODE, 0); -} - -/** - * opp1_set_clamping(): - * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) - * 1 for 8 bpc - * 2 for 10 bpc - * 3 for 12 bpc - * 7 for programable - * 2) Enable clamp if Limited range requested - * - * @oppn10: output_pixel_processor struct instance for dcn10. - * @params: pointer to clamping_and_pixel_encoding_params. - */ -static void opp1_set_clamping( - struct dcn10_opp *oppn10, - const struct clamping_and_pixel_encoding_params *params) -{ - REG_UPDATE_2(FMT_CLAMP_CNTL, - FMT_CLAMP_DATA_EN, 0, - FMT_CLAMP_COLOR_FORMAT, 0); - - switch (params->clamping_level) { - case CLAMPING_FULL_RANGE: - REG_UPDATE_2(FMT_CLAMP_CNTL, - FMT_CLAMP_DATA_EN, 1, - FMT_CLAMP_COLOR_FORMAT, 0); - break; - case CLAMPING_LIMITED_RANGE_8BPC: - REG_UPDATE_2(FMT_CLAMP_CNTL, - FMT_CLAMP_DATA_EN, 1, - FMT_CLAMP_COLOR_FORMAT, 1); - break; - case CLAMPING_LIMITED_RANGE_10BPC: - REG_UPDATE_2(FMT_CLAMP_CNTL, - FMT_CLAMP_DATA_EN, 1, - FMT_CLAMP_COLOR_FORMAT, 2); - - break; - case CLAMPING_LIMITED_RANGE_12BPC: - REG_UPDATE_2(FMT_CLAMP_CNTL, - FMT_CLAMP_DATA_EN, 1, - FMT_CLAMP_COLOR_FORMAT, 3); - break; - case CLAMPING_LIMITED_RANGE_PROGRAMMABLE: - /* TODO */ - default: - break; - } - -} - -void opp1_set_dyn_expansion( - struct output_pixel_processor *opp, - enum dc_color_space color_sp, - enum dc_color_depth color_dpth, - enum signal_type signal) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - - REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, - FMT_DYNAMIC_EXP_EN, 0, - FMT_DYNAMIC_EXP_MODE, 0); - - if (opp->dyn_expansion == DYN_EXPANSION_DISABLE) - return; - - /*00 - 10-bit -> 12-bit dynamic expansion*/ - /*01 - 8-bit -> 12-bit dynamic expansion*/ - if (signal == SIGNAL_TYPE_HDMI_TYPE_A || - signal == SIGNAL_TYPE_DISPLAY_PORT || - signal == SIGNAL_TYPE_DISPLAY_PORT_MST || - signal == SIGNAL_TYPE_VIRTUAL) { - switch (color_dpth) { - case COLOR_DEPTH_888: - REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, - FMT_DYNAMIC_EXP_EN, 1, - FMT_DYNAMIC_EXP_MODE, 1); - break; - case COLOR_DEPTH_101010: - REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, - FMT_DYNAMIC_EXP_EN, 1, - FMT_DYNAMIC_EXP_MODE, 0); - break; - case COLOR_DEPTH_121212: - REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, - FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/ - FMT_DYNAMIC_EXP_MODE, 0); - break; - default: - break; - } - } -} - -static void opp1_program_clamping_and_pixel_encoding( - struct output_pixel_processor *opp, - const struct clamping_and_pixel_encoding_params *params) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - - opp1_set_clamping(oppn10, params); - opp1_set_pixel_encoding(oppn10, params); -} - -void opp1_program_fmt( - struct output_pixel_processor *opp, - struct bit_depth_reduction_params *fmt_bit_depth, - struct clamping_and_pixel_encoding_params *clamping) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - - if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420) - REG_UPDATE(FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, 0); - - /* dithering is affected by , hence should be - * programmed afterwards */ - opp1_program_bit_depth_reduction( - opp, - fmt_bit_depth); - - opp1_program_clamping_and_pixel_encoding( - opp, - clamping); - - return; -} - -void opp1_program_stereo( - struct output_pixel_processor *opp, - bool enable, - const struct dc_crtc_timing *timing) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - - uint32_t active_width = timing->h_addressable - timing->h_border_right - timing->h_border_right; - uint32_t space1_size = timing->v_total - timing->v_addressable; - /* TODO: confirm computation of space2_size */ - uint32_t space2_size = timing->v_total - timing->v_addressable; - - if (!enable) { - active_width = 0; - space1_size = 0; - space2_size = 0; - } - - /* TODO: for which cases should FMT_STEREOSYNC_OVERRIDE be set? */ - REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, 0); - - REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, active_width); - - /* Program OPPBUF_3D_VACT_SPACE1_SIZE and OPPBUF_VACT_SPACE2_SIZE registers - * In 3D progressive frames, Vactive space happens only in between the 2 frames, - * so only need to program OPPBUF_3D_VACT_SPACE1_SIZE - * In 3D alternative frames, left and right frames, top and bottom field. - */ - if (timing->timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE) - REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, space2_size); - else - REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, space1_size); - - /* TODO: Is programming of OPPBUF_DUMMY_DATA_R/G/B needed? */ - /* - REG_UPDATE(OPPBUF_3D_PARAMETERS_0, - OPPBUF_DUMMY_DATA_R, data_r); - REG_UPDATE(OPPBUF_3D_PARAMETERS_1, - OPPBUF_DUMMY_DATA_G, data_g); - REG_UPDATE(OPPBUF_3D_PARAMETERS_1, - OPPBUF_DUMMY_DATA_B, _data_b); - */ -} - -void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable) -{ - struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); - uint32_t regval = enable ? 1 : 0; - - REG_UPDATE(OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, regval); -} - -/*****************************************/ -/* Constructor, Destructor */ -/*****************************************/ - -void opp1_destroy(struct output_pixel_processor **opp) -{ - kfree(TO_DCN10_OPP(*opp)); - *opp = NULL; -} - -static const struct opp_funcs dcn10_opp_funcs = { - .opp_set_dyn_expansion = opp1_set_dyn_expansion, - .opp_program_fmt = opp1_program_fmt, - .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, - .opp_program_stereo = opp1_program_stereo, - .opp_pipe_clock_control = opp1_pipe_clock_control, - .opp_set_disp_pattern_generator = NULL, - .opp_program_dpg_dimensions = NULL, - .dpg_is_blanked = NULL, - .dpg_is_pending = NULL, - .opp_destroy = opp1_destroy -}; - -void dcn10_opp_construct(struct dcn10_opp *oppn10, - struct dc_context *ctx, - uint32_t inst, - const struct dcn10_opp_registers *regs, - const struct dcn10_opp_shift *opp_shift, - const struct dcn10_opp_mask *opp_mask) -{ - - oppn10->base.ctx = ctx; - oppn10->base.inst = inst; - oppn10->base.funcs = &dcn10_opp_funcs; - - oppn10->regs = regs; - oppn10->opp_shift = opp_shift; - oppn10->opp_mask = opp_mask; -} diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h deleted file mode 100644 index c87de68a509e..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.h +++ /dev/null @@ -1,191 +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 __DC_OPP_DCN10_H__ -#define __DC_OPP_DCN10_H__ - -#include "opp.h" - -#define TO_DCN10_OPP(opp)\ - container_of(opp, struct dcn10_opp, base) - -#define OPP_SF(reg_name, field_name, post_fix)\ - .field_name = reg_name ## __ ## field_name ## post_fix - -#define OPP_REG_LIST_DCN(id) \ - SRI(FMT_BIT_DEPTH_CONTROL, FMT, id), \ - SRI(FMT_CONTROL, FMT, id), \ - SRI(FMT_DITHER_RAND_R_SEED, FMT, id), \ - SRI(FMT_DITHER_RAND_G_SEED, FMT, id), \ - SRI(FMT_DITHER_RAND_B_SEED, FMT, id), \ - SRI(FMT_CLAMP_CNTL, FMT, id), \ - SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \ - SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \ - SRI(OPPBUF_CONTROL, OPPBUF, id),\ - SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \ - SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id), \ - SRI(OPP_PIPE_CONTROL, OPP_PIPE, id) - -#define OPP_REG_LIST_DCN10(id) \ - OPP_REG_LIST_DCN(id) - -#define OPP_COMMON_REG_VARIABLE_LIST \ - uint32_t FMT_BIT_DEPTH_CONTROL; \ - uint32_t FMT_CONTROL; \ - uint32_t FMT_DITHER_RAND_R_SEED; \ - uint32_t FMT_DITHER_RAND_G_SEED; \ - uint32_t FMT_DITHER_RAND_B_SEED; \ - uint32_t FMT_CLAMP_CNTL; \ - uint32_t FMT_DYNAMIC_EXP_CNTL; \ - uint32_t FMT_MAP420_MEMORY_CONTROL; \ - uint32_t OPPBUF_CONTROL; \ - uint32_t OPPBUF_CONTROL1; \ - uint32_t OPPBUF_3D_PARAMETERS_0; \ - uint32_t OPPBUF_3D_PARAMETERS_1; \ - uint32_t OPP_PIPE_CONTROL - -#define OPP_MASK_SH_LIST_DCN(mask_sh) \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE, mask_sh), \ - OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_PIXEL_ENCODING, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_SUBSAMPLING_MODE, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_CBCR_BIT_REDUCTION_BYPASS, mask_sh), \ - OPP_SF(FMT0_FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh), \ - OPP_SF(FMT0_FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh), \ - OPP_SF(FMT0_FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh), \ - OPP_SF(FMT0_FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh), \ - OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_DATA_EN, mask_sh), \ - OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_COLOR_FORMAT, mask_sh), \ - OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh), \ - OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh), \ - OPP_SF(FMT0_FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, mask_sh), \ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, mask_sh),\ - OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh), \ - OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh), \ - OPP_SF(OPP_PIPE0_OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh) - -#define OPP_MASK_SH_LIST_DCN10(mask_sh) \ - OPP_MASK_SH_LIST_DCN(mask_sh), \ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, mask_sh),\ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, mask_sh) - -#define OPP_DCN10_REG_FIELD_LIST(type) \ - type FMT_TRUNCATE_EN; \ - type FMT_TRUNCATE_DEPTH; \ - type FMT_TRUNCATE_MODE; \ - type FMT_SPATIAL_DITHER_EN; \ - type FMT_SPATIAL_DITHER_MODE; \ - type FMT_SPATIAL_DITHER_DEPTH; \ - type FMT_TEMPORAL_DITHER_EN; \ - type FMT_HIGHPASS_RANDOM_ENABLE; \ - type FMT_FRAME_RANDOM_ENABLE; \ - type FMT_RGB_RANDOM_ENABLE; \ - type FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \ - type FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \ - type FMT_RAND_R_SEED; \ - type FMT_RAND_G_SEED; \ - type FMT_RAND_B_SEED; \ - type FMT_PIXEL_ENCODING; \ - type FMT_SUBSAMPLING_MODE; \ - type FMT_CBCR_BIT_REDUCTION_BYPASS; \ - type FMT_CLAMP_DATA_EN; \ - type FMT_CLAMP_COLOR_FORMAT; \ - type FMT_DYNAMIC_EXP_EN; \ - type FMT_DYNAMIC_EXP_MODE; \ - type FMT_MAP420MEM_PWR_FORCE; \ - type FMT_STEREOSYNC_OVERRIDE; \ - type OPPBUF_ACTIVE_WIDTH;\ - type OPPBUF_PIXEL_REPETITION;\ - type OPPBUF_DISPLAY_SEGMENTATION;\ - type OPPBUF_OVERLAP_PIXEL_NUM;\ - type OPPBUF_NUM_SEGMENT_PADDED_PIXELS; \ - type OPPBUF_3D_VACT_SPACE1_SIZE; \ - type OPPBUF_3D_VACT_SPACE2_SIZE; \ - type OPP_PIPE_CLOCK_EN - -struct dcn10_opp_registers { - OPP_COMMON_REG_VARIABLE_LIST; -}; - -struct dcn10_opp_shift { - OPP_DCN10_REG_FIELD_LIST(uint8_t); -}; - -struct dcn10_opp_mask { - OPP_DCN10_REG_FIELD_LIST(uint32_t); -}; - -struct dcn10_opp { - struct output_pixel_processor base; - - const struct dcn10_opp_registers *regs; - const struct dcn10_opp_shift *opp_shift; - const struct dcn10_opp_mask *opp_mask; - - bool is_write_to_ram_a_safe; -}; - -void dcn10_opp_construct(struct dcn10_opp *oppn10, - struct dc_context *ctx, - uint32_t inst, - const struct dcn10_opp_registers *regs, - const struct dcn10_opp_shift *opp_shift, - const struct dcn10_opp_mask *opp_mask); - -void opp1_set_dyn_expansion( - struct output_pixel_processor *opp, - enum dc_color_space color_sp, - enum dc_color_depth color_dpth, - enum signal_type signal); - -void opp1_program_fmt( - struct output_pixel_processor *opp, - struct bit_depth_reduction_params *fmt_bit_depth, - struct clamping_and_pixel_encoding_params *clamping); - -void opp1_program_bit_depth_reduction( - struct output_pixel_processor *opp, - const struct bit_depth_reduction_params *params); - -void opp1_program_stereo( - struct output_pixel_processor *opp, - bool enable, - const struct dc_crtc_timing *timing); - -void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable); - -void opp1_destroy(struct output_pixel_processor **opp); - -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index b3aeabc4d605..744a6c4ac816 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT # Copyright © 2019-2024 Advanced Micro Devices, Inc. All rights reserved. -DCN20 = dcn20_mpc.o dcn20_opp.o dcn20_mmhubbub.o \ +DCN20 = dcn20_mpc.o dcn20_mmhubbub.o \ dcn20_vmid.o dcn20_dwb.o dcn20_dwb_scl.o AMD_DAL_DCN20 = $(addprefix $(AMDDALPATH)/dc/dcn20/,$(DCN20)) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c deleted file mode 100644 index f5fe0cac7cb0..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c +++ /dev/null @@ -1,415 +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 - * - */ - -#include "core_types.h" -#include "dm_services.h" -#include "dcn20_opp.h" -#include "reg_helper.h" - -#define REG(reg) \ - (oppn20->regs->reg) - -#undef FN -#define FN(reg_name, field_name) \ - oppn20->opp_shift->field_name, oppn20->opp_mask->field_name - -#define CTX \ - oppn20->base.ctx - - -void opp2_set_disp_pattern_generator( - struct output_pixel_processor *opp, - enum controller_dp_test_pattern test_pattern, - enum controller_dp_color_space color_space, - enum dc_color_depth color_depth, - const struct tg_color *solid_color, - int width, - int height, - int offset) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - enum test_pattern_color_format bit_depth; - enum test_pattern_dyn_range dyn_range; - enum test_pattern_mode mode; - - /* color ramp generator mixes 16-bits color */ - uint32_t src_bpc = 16; - /* requested bpc */ - uint32_t dst_bpc; - uint32_t index; - /* RGB values of the color bars. - * Produce two RGB colors: RGB0 - white (all Fs) - * and RGB1 - black (all 0s) - * (three RGB components for two colors) - */ - uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, - 0x0000, 0x0000}; - /* dest color (converted to the specified color format) */ - uint16_t dst_color[6]; - uint32_t inc_base; - - /* translate to bit depth */ - switch (color_depth) { - case COLOR_DEPTH_666: - bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; - break; - case COLOR_DEPTH_888: - bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; - break; - case COLOR_DEPTH_101010: - bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; - break; - case COLOR_DEPTH_121212: - bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; - break; - default: - bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; - break; - } - - /* set DPG dimentions */ - REG_SET_2(DPG_DIMENSIONS, 0, - DPG_ACTIVE_WIDTH, width, - DPG_ACTIVE_HEIGHT, height); - - /* set DPG offset */ - REG_SET_2(DPG_OFFSET_SEGMENT, 0, - DPG_X_OFFSET, offset, - DPG_SEGMENT_WIDTH, 0); - - switch (test_pattern) { - case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: - case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: - { - dyn_range = (test_pattern == - CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? - TEST_PATTERN_DYN_RANGE_CEA : - TEST_PATTERN_DYN_RANGE_VESA); - - switch (color_space) { - case CONTROLLER_DP_COLOR_SPACE_YCBCR601: - mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601; - break; - case CONTROLLER_DP_COLOR_SPACE_YCBCR709: - mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709; - break; - case CONTROLLER_DP_COLOR_SPACE_RGB: - default: - mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; - break; - } - - REG_UPDATE_6(DPG_CONTROL, - DPG_EN, 1, - DPG_MODE, mode, - DPG_DYNAMIC_RANGE, dyn_range, - DPG_BIT_DEPTH, bit_depth, - DPG_VRES, 6, - DPG_HRES, 6); - } - break; - - case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: - case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: - { - mode = (test_pattern == - CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? - TEST_PATTERN_MODE_VERTICALBARS : - TEST_PATTERN_MODE_HORIZONTALBARS); - - switch (bit_depth) { - case TEST_PATTERN_COLOR_FORMAT_BPC_6: - dst_bpc = 6; - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_8: - dst_bpc = 8; - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_10: - dst_bpc = 10; - break; - default: - dst_bpc = 8; - break; - } - - /* adjust color to the required colorFormat */ - for (index = 0; index < 6; index++) { - /* dst = 2^dstBpc * src / 2^srcBpc = src >> - * (srcBpc - dstBpc); - */ - dst_color[index] = - src_color[index] >> (src_bpc - dst_bpc); - /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO. - * XXXXXXXXXX000000 for 10 bit, - * XXXXXXXX00000000 for 8 bit, - * XXXXXX0000000000 for 6 bits - */ - dst_color[index] <<= (16 - dst_bpc); - } - - REG_SET_2(DPG_COLOUR_R_CR, 0, - DPG_COLOUR1_R_CR, dst_color[0], - DPG_COLOUR0_R_CR, dst_color[3]); - REG_SET_2(DPG_COLOUR_G_Y, 0, - DPG_COLOUR1_G_Y, dst_color[1], - DPG_COLOUR0_G_Y, dst_color[4]); - REG_SET_2(DPG_COLOUR_B_CB, 0, - DPG_COLOUR1_B_CB, dst_color[2], - DPG_COLOUR0_B_CB, dst_color[5]); - - /* enable test pattern */ - REG_UPDATE_6(DPG_CONTROL, - DPG_EN, 1, - DPG_MODE, mode, - DPG_DYNAMIC_RANGE, 0, - DPG_BIT_DEPTH, bit_depth, - DPG_VRES, 0, - DPG_HRES, 0); - } - break; - - case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: - { - mode = (bit_depth == - TEST_PATTERN_COLOR_FORMAT_BPC_10 ? - TEST_PATTERN_MODE_DUALRAMP_RGB : - TEST_PATTERN_MODE_SINGLERAMP_RGB); - - switch (bit_depth) { - case TEST_PATTERN_COLOR_FORMAT_BPC_6: - dst_bpc = 6; - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_8: - dst_bpc = 8; - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_10: - dst_bpc = 10; - break; - default: - dst_bpc = 8; - break; - } - - /* increment for the first ramp for one color gradation - * 1 gradation for 6-bit color is 2^10 - * gradations in 16-bit color - */ - inc_base = (src_bpc - dst_bpc); - - switch (bit_depth) { - case TEST_PATTERN_COLOR_FORMAT_BPC_6: - { - REG_SET_3(DPG_RAMP_CONTROL, 0, - DPG_RAMP0_OFFSET, 0, - DPG_INC0, inc_base, - DPG_INC1, 0); - REG_UPDATE_2(DPG_CONTROL, - DPG_VRES, 6, - DPG_HRES, 6); - } - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_8: - { - REG_SET_3(DPG_RAMP_CONTROL, 0, - DPG_RAMP0_OFFSET, 0, - DPG_INC0, inc_base, - DPG_INC1, 0); - REG_UPDATE_2(DPG_CONTROL, - DPG_VRES, 6, - DPG_HRES, 8); - } - break; - case TEST_PATTERN_COLOR_FORMAT_BPC_10: - { - REG_SET_3(DPG_RAMP_CONTROL, 0, - DPG_RAMP0_OFFSET, 384 << 6, - DPG_INC0, inc_base, - DPG_INC1, inc_base + 2); - REG_UPDATE_2(DPG_CONTROL, - DPG_VRES, 5, - DPG_HRES, 8); - } - break; - default: - break; - } - - /* enable test pattern */ - REG_UPDATE_4(DPG_CONTROL, - DPG_EN, 1, - DPG_MODE, mode, - DPG_DYNAMIC_RANGE, 0, - DPG_BIT_DEPTH, bit_depth); - } - break; - case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: - { - REG_WRITE(DPG_CONTROL, 0); - REG_WRITE(DPG_COLOUR_R_CR, 0); - REG_WRITE(DPG_COLOUR_G_Y, 0); - REG_WRITE(DPG_COLOUR_B_CB, 0); - REG_WRITE(DPG_RAMP_CONTROL, 0); - } - break; - case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR: - { - opp2_dpg_set_blank_color(opp, solid_color); - REG_UPDATE_2(DPG_CONTROL, - DPG_EN, 1, - DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS); - - REG_SET_2(DPG_DIMENSIONS, 0, - DPG_ACTIVE_WIDTH, width, - DPG_ACTIVE_HEIGHT, height); - } - break; - default: - break; - - } -} - -void opp2_program_dpg_dimensions( - struct output_pixel_processor *opp, - int width, int height) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - - REG_SET_2(DPG_DIMENSIONS, 0, - DPG_ACTIVE_WIDTH, width, - DPG_ACTIVE_HEIGHT, height); -} - -void opp2_dpg_set_blank_color( - struct output_pixel_processor *opp, - const struct tg_color *color) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - - /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */ - ASSERT(color); - REG_SET_2(DPG_COLOUR_B_CB, 0, - DPG_COLOUR1_B_CB, color->color_b_cb << 6, - DPG_COLOUR0_B_CB, color->color_b_cb << 6); - REG_SET_2(DPG_COLOUR_G_Y, 0, - DPG_COLOUR1_G_Y, color->color_g_y << 6, - DPG_COLOUR0_G_Y, color->color_g_y << 6); - REG_SET_2(DPG_COLOUR_R_CR, 0, - DPG_COLOUR1_R_CR, color->color_r_cr << 6, - DPG_COLOUR0_R_CR, color->color_r_cr << 6); -} - -bool opp2_dpg_is_blanked(struct output_pixel_processor *opp) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - uint32_t dpg_en, dpg_mode; - uint32_t double_buffer_pending; - - REG_GET_2(DPG_CONTROL, - DPG_EN, &dpg_en, - DPG_MODE, &dpg_mode); - - REG_GET(DPG_STATUS, - DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); - - return (dpg_en == 1) && - (double_buffer_pending == 0); -} - -bool opp2_dpg_is_pending(struct output_pixel_processor *opp) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - uint32_t double_buffer_pending; - uint32_t dpg_en; - - REG_GET(DPG_CONTROL, DPG_EN, &dpg_en); - - REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); - - return (dpg_en == 1 && double_buffer_pending == 1); -} - -void opp2_program_left_edge_extra_pixel( - struct output_pixel_processor *opp, - enum dc_pixel_encoding pixel_encoding, - bool is_primary) -{ - struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); - uint32_t count = opp2_get_left_edge_extra_pixel_count(opp, pixel_encoding, is_primary); - - /* - * Specifies the number of extra left edge pixels that are supplied to - * the 422 horizontal chroma sub-sample filter. - */ - REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count); -} - -uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp, - enum dc_pixel_encoding pixel_encoding, bool is_primary) -{ - if ((pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) && - !opp->ctx->dc->debug.force_chroma_subsampling_1tap && - !is_primary) - return 1; - else - return 0; -} - -/*****************************************/ -/* Constructor, Destructor */ -/*****************************************/ - -static struct opp_funcs dcn20_opp_funcs = { - .opp_set_dyn_expansion = opp1_set_dyn_expansion, - .opp_program_fmt = opp1_program_fmt, - .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, - .opp_program_stereo = opp1_program_stereo, - .opp_pipe_clock_control = opp1_pipe_clock_control, - .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, - .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, - .dpg_is_blanked = opp2_dpg_is_blanked, - .dpg_is_pending = opp2_dpg_is_pending, - .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, - .opp_destroy = opp1_destroy, - .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, - .opp_get_left_edge_extra_pixel_count = opp2_get_left_edge_extra_pixel_count, -}; - -void dcn20_opp_construct(struct dcn20_opp *oppn20, - struct dc_context *ctx, - uint32_t inst, - const struct dcn20_opp_registers *regs, - const struct dcn20_opp_shift *opp_shift, - const struct dcn20_opp_mask *opp_mask) -{ - oppn20->base.ctx = ctx; - oppn20->base.inst = inst; - oppn20->base.funcs = &dcn20_opp_funcs; - - oppn20->regs = regs; - oppn20->opp_shift = opp_shift; - oppn20->opp_mask = opp_mask; -} - diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h deleted file mode 100644 index 34936e6c49f3..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h +++ /dev/null @@ -1,174 +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 __DC_OPP_DCN20_H__ -#define __DC_OPP_DCN20_H__ - -#include "dcn10/dcn10_opp.h" - -#define TO_DCN20_OPP(opp)\ - container_of(opp, struct dcn20_opp, base) - -#define OPP_SF(reg_name, field_name, post_fix)\ - .field_name = reg_name ## __ ## field_name ## post_fix - -#define OPP_DPG_REG_LIST(id) \ - SRI(DPG_CONTROL, DPG, id), \ - SRI(DPG_DIMENSIONS, DPG, id), \ - SRI(DPG_OFFSET_SEGMENT, DPG, id), \ - SRI(DPG_COLOUR_B_CB, DPG, id), \ - SRI(DPG_COLOUR_G_Y, DPG, id), \ - SRI(DPG_COLOUR_R_CR, DPG, id), \ - SRI(DPG_RAMP_CONTROL, DPG, id), \ - SRI(DPG_STATUS, DPG, id) - -#define OPP_REG_LIST_DCN20(id) \ - OPP_REG_LIST_DCN10(id), \ - OPP_DPG_REG_LIST(id), \ - SRI(FMT_422_CONTROL, FMT, id), \ - SRI(OPPBUF_CONTROL1, OPPBUF, id) - -#define OPP_REG_VARIABLE_LIST_DCN2_0 \ - OPP_COMMON_REG_VARIABLE_LIST; \ - uint32_t FMT_422_CONTROL; \ - uint32_t DPG_CONTROL; \ - uint32_t DPG_DIMENSIONS; \ - uint32_t DPG_OFFSET_SEGMENT; \ - uint32_t DPG_COLOUR_B_CB; \ - uint32_t DPG_COLOUR_G_Y; \ - uint32_t DPG_COLOUR_R_CR; \ - uint32_t DPG_RAMP_CONTROL; \ - uint32_t DPG_STATUS - -#define OPP_DPG_MASK_SH_LIST(mask_sh) \ - OPP_SF(DPG0_DPG_CONTROL, DPG_EN, mask_sh), \ - OPP_SF(DPG0_DPG_CONTROL, DPG_MODE, mask_sh), \ - OPP_SF(DPG0_DPG_CONTROL, DPG_DYNAMIC_RANGE, mask_sh), \ - OPP_SF(DPG0_DPG_CONTROL, DPG_BIT_DEPTH, mask_sh), \ - OPP_SF(DPG0_DPG_CONTROL, DPG_VRES, mask_sh), \ - OPP_SF(DPG0_DPG_CONTROL, DPG_HRES, mask_sh), \ - OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_WIDTH, mask_sh), \ - OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_HEIGHT, mask_sh), \ - OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_X_OFFSET, mask_sh), \ - OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_SEGMENT_WIDTH, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR0_R_CR, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR1_R_CR, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_B_CB, DPG_COLOUR0_B_CB, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_B_CB, DPG_COLOUR1_B_CB, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_G_Y, DPG_COLOUR0_G_Y, mask_sh), \ - OPP_SF(DPG0_DPG_COLOUR_G_Y, DPG_COLOUR1_G_Y, mask_sh), \ - OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_RAMP0_OFFSET, mask_sh), \ - OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_INC0, mask_sh), \ - OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_INC1, mask_sh), \ - OPP_SF(DPG0_DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, mask_sh) - -#define OPP_MASK_SH_LIST_DCN20(mask_sh) \ - OPP_MASK_SH_LIST_DCN(mask_sh), \ - OPP_DPG_MASK_SH_LIST(mask_sh), \ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, mask_sh),\ - OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, mask_sh), \ - OPP_SF(FMT0_FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, mask_sh) - -#define OPP_DCN20_REG_FIELD_LIST(type) \ - OPP_DCN10_REG_FIELD_LIST(type); \ - type FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT; \ - type DPG_EN; \ - type DPG_MODE; \ - type DPG_DYNAMIC_RANGE; \ - type DPG_BIT_DEPTH; \ - type DPG_VRES; \ - type DPG_HRES; \ - type DPG_ACTIVE_WIDTH; \ - type DPG_ACTIVE_HEIGHT; \ - type DPG_X_OFFSET; \ - type DPG_SEGMENT_WIDTH; \ - type DPG_COLOUR0_R_CR; \ - type DPG_COLOUR1_R_CR; \ - type DPG_COLOUR0_B_CB; \ - type DPG_COLOUR1_B_CB; \ - type DPG_COLOUR0_G_Y; \ - type DPG_COLOUR1_G_Y; \ - type DPG_RAMP0_OFFSET; \ - type DPG_INC0; \ - type DPG_INC1; \ - type DPG_DOUBLE_BUFFER_PENDING - -struct dcn20_opp_registers { - OPP_REG_VARIABLE_LIST_DCN2_0; -}; - -struct dcn20_opp_shift { - OPP_DCN20_REG_FIELD_LIST(uint8_t); -}; - -struct dcn20_opp_mask { - OPP_DCN20_REG_FIELD_LIST(uint32_t); -}; - -struct dcn20_opp { - struct output_pixel_processor base; - - const struct dcn20_opp_registers *regs; - const struct dcn20_opp_shift *opp_shift; - const struct dcn20_opp_mask *opp_mask; - - bool is_write_to_ram_a_safe; -}; - -void dcn20_opp_construct(struct dcn20_opp *oppn20, - struct dc_context *ctx, - uint32_t inst, - const struct dcn20_opp_registers *regs, - const struct dcn20_opp_shift *opp_shift, - const struct dcn20_opp_mask *opp_mask); - -void opp2_set_disp_pattern_generator( - struct output_pixel_processor *opp, - enum controller_dp_test_pattern test_pattern, - enum controller_dp_color_space color_space, - enum dc_color_depth color_depth, - const struct tg_color *solid_color, - int width, - int height, - int offset); - -void opp2_program_dpg_dimensions( - struct output_pixel_processor *opp, - int width, int height); - -bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); - -bool opp2_dpg_is_pending(struct output_pixel_processor *opp); - -void opp2_dpg_set_blank_color( - struct output_pixel_processor *opp, - const struct tg_color *color); - -void opp2_program_left_edge_extra_pixel ( - struct output_pixel_processor *opp, - enum dc_pixel_encoding pixel_encoding, bool is_primary); - -uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp, - enum dc_pixel_encoding pixel_encoding, bool is_primary); -#endif diff --git a/drivers/gpu/drm/amd/display/dc/opp/Makefile b/drivers/gpu/drm/amd/display/dc/opp/Makefile index fbfb3c3ad819..1be76754db30 100644 --- a/drivers/gpu/drm/amd/display/dc/opp/Makefile +++ b/drivers/gpu/drm/amd/display/dc/opp/Makefile @@ -25,6 +25,22 @@ ifdef CONFIG_DRM_AMD_DC_FP ############################################################################### +# DCN10 +############################################################################### +OPP_DCN10 = dcn10_opp.o + +AMD_DAL_OPP_DCN10 = $(addprefix $(AMDDALPATH)/dc/opp/dcn10/,$(OPP_DCN10)) + +AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN10) +############################################################################### +# DCN20 +############################################################################### +OPP_DCN20 = dcn20_opp.o + +AMD_DAL_OPP_DCN20 = $(addprefix $(AMDDALPATH)/dc/opp/dcn20/,$(OPP_DCN20)) + +AMD_DISPLAY_FILES += $(AMD_DAL_OPP_DCN20) +############################################################################### # DCN35 ############################################################################### OPP_DCN35 = dcn35_opp.o diff --git a/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c new file mode 100644 index 000000000000..71e9288d60ed --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.c @@ -0,0 +1,413 @@ +/* + * 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 + * + */ + +#include "core_types.h" +#include "dm_services.h" +#include "dcn10_opp.h" +#include "reg_helper.h" + +#define REG(reg) \ + (oppn10->regs->reg) + +#undef FN +#define FN(reg_name, field_name) \ + oppn10->opp_shift->field_name, oppn10->opp_mask->field_name + +#define CTX \ + oppn10->base.ctx + +/** + * opp1_set_truncation(): + * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp + * 2) enable truncation + * 3) HW remove 12bit FMT support for DCE11 power saving reason. + * + * @oppn10: output_pixel_processor struct instance for dcn10. + * @params: pointer to bit_depth_reduction_params. + */ +static void opp1_set_truncation( + struct dcn10_opp *oppn10, + const struct bit_depth_reduction_params *params) +{ + REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL, + FMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED, + FMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH, + FMT_TRUNCATE_MODE, params->flags.TRUNCATE_MODE); +} + +static void opp1_set_spatial_dither( + struct dcn10_opp *oppn10, + const struct bit_depth_reduction_params *params) +{ + /*Disable spatial (random) dithering*/ + REG_UPDATE_7(FMT_BIT_DEPTH_CONTROL, + FMT_SPATIAL_DITHER_EN, 0, + FMT_SPATIAL_DITHER_MODE, 0, + FMT_SPATIAL_DITHER_DEPTH, 0, + FMT_TEMPORAL_DITHER_EN, 0, + FMT_HIGHPASS_RANDOM_ENABLE, 0, + FMT_FRAME_RANDOM_ENABLE, 0, + FMT_RGB_RANDOM_ENABLE, 0); + + + /* only use FRAME_COUNTER_MAX if frameRandom == 1*/ + if (params->flags.FRAME_RANDOM == 1) { + if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) { + REG_UPDATE_2(FMT_CONTROL, + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15, + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2); + } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) { + REG_UPDATE_2(FMT_CONTROL, + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3, + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1); + } else { + return; + } + } else { + REG_UPDATE_2(FMT_CONTROL, + FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0, + FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0); + } + + /*Set seed for random values for + * spatial dithering for R,G,B channels*/ + + REG_SET(FMT_DITHER_RAND_R_SEED, 0, + FMT_RAND_R_SEED, params->r_seed_value); + + REG_SET(FMT_DITHER_RAND_G_SEED, 0, + FMT_RAND_G_SEED, params->g_seed_value); + + REG_SET(FMT_DITHER_RAND_B_SEED, 0, + FMT_RAND_B_SEED, params->b_seed_value); + + /* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero + * offset for the R/Cr channel, lower 4LSB + * is forced to zeros. Typically set to 0 + * RGB and 0x80000 YCbCr. + */ + /* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero + * offset for the G/Y channel, lower 4LSB is + * forced to zeros. Typically set to 0 RGB + * and 0x80000 YCbCr. + */ + /* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero + * offset for the B/Cb channel, lower 4LSB is + * forced to zeros. Typically set to 0 RGB and + * 0x80000 YCbCr. + */ + + REG_UPDATE_6(FMT_BIT_DEPTH_CONTROL, + /*Enable spatial dithering*/ + FMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED, + /* Set spatial dithering mode + * (default is Seed patterrn AAAA...) + */ + FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE, + /*Set spatial dithering bit depth*/ + FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH, + /*Disable High pass filter*/ + FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM, + /*Reset only at startup*/ + FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM, + /*Set RGB data dithered with x^28+x^3+1*/ + FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM); +} + +void opp1_program_bit_depth_reduction( + struct output_pixel_processor *opp, + const struct bit_depth_reduction_params *params) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + opp1_set_truncation(oppn10, params); + opp1_set_spatial_dither(oppn10, params); + /* TODO + * set_temporal_dither(oppn10, params); + */ +} + +/** + * opp1_set_pixel_encoding(): + * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly + * 1: YCbCr 4:2:2 + * + * @oppn10: output_pixel_processor struct instance for dcn10. + * @params: pointer to clamping_and_pixel_encoding_params. + */ +static void opp1_set_pixel_encoding( + struct dcn10_opp *oppn10, + const struct clamping_and_pixel_encoding_params *params) +{ + bool force_chroma_subsampling_1tap = + oppn10->base.ctx->dc->debug.force_chroma_subsampling_1tap; + + switch (params->pixel_encoding) { + + case PIXEL_ENCODING_RGB: + case PIXEL_ENCODING_YCBCR444: + REG_UPDATE_3(FMT_CONTROL, + FMT_PIXEL_ENCODING, 0, + FMT_SUBSAMPLING_MODE, 0, + FMT_CBCR_BIT_REDUCTION_BYPASS, 0); + REG_UPDATE(FMT_CONTROL, FMT_PIXEL_ENCODING, 0); + break; + case PIXEL_ENCODING_YCBCR422: + REG_UPDATE_3(FMT_CONTROL, + FMT_PIXEL_ENCODING, 1, + FMT_SUBSAMPLING_MODE, 2, + FMT_CBCR_BIT_REDUCTION_BYPASS, 0); + break; + case PIXEL_ENCODING_YCBCR420: + REG_UPDATE_3(FMT_CONTROL, + FMT_PIXEL_ENCODING, 2, + FMT_SUBSAMPLING_MODE, 2, + FMT_CBCR_BIT_REDUCTION_BYPASS, 1); + break; + default: + break; + } + + if (force_chroma_subsampling_1tap) + REG_UPDATE(FMT_CONTROL, FMT_SUBSAMPLING_MODE, 0); +} + +/** + * opp1_set_clamping(): + * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping) + * 1 for 8 bpc + * 2 for 10 bpc + * 3 for 12 bpc + * 7 for programable + * 2) Enable clamp if Limited range requested + * + * @oppn10: output_pixel_processor struct instance for dcn10. + * @params: pointer to clamping_and_pixel_encoding_params. + */ +static void opp1_set_clamping( + struct dcn10_opp *oppn10, + const struct clamping_and_pixel_encoding_params *params) +{ + REG_UPDATE_2(FMT_CLAMP_CNTL, + FMT_CLAMP_DATA_EN, 0, + FMT_CLAMP_COLOR_FORMAT, 0); + + switch (params->clamping_level) { + case CLAMPING_FULL_RANGE: + REG_UPDATE_2(FMT_CLAMP_CNTL, + FMT_CLAMP_DATA_EN, 1, + FMT_CLAMP_COLOR_FORMAT, 0); + break; + case CLAMPING_LIMITED_RANGE_8BPC: + REG_UPDATE_2(FMT_CLAMP_CNTL, + FMT_CLAMP_DATA_EN, 1, + FMT_CLAMP_COLOR_FORMAT, 1); + break; + case CLAMPING_LIMITED_RANGE_10BPC: + REG_UPDATE_2(FMT_CLAMP_CNTL, + FMT_CLAMP_DATA_EN, 1, + FMT_CLAMP_COLOR_FORMAT, 2); + + break; + case CLAMPING_LIMITED_RANGE_12BPC: + REG_UPDATE_2(FMT_CLAMP_CNTL, + FMT_CLAMP_DATA_EN, 1, + FMT_CLAMP_COLOR_FORMAT, 3); + break; + case CLAMPING_LIMITED_RANGE_PROGRAMMABLE: + /* TODO */ + default: + break; + } + +} + +void opp1_set_dyn_expansion( + struct output_pixel_processor *opp, + enum dc_color_space color_sp, + enum dc_color_depth color_dpth, + enum signal_type signal) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, + FMT_DYNAMIC_EXP_EN, 0, + FMT_DYNAMIC_EXP_MODE, 0); + + if (opp->dyn_expansion == DYN_EXPANSION_DISABLE) + return; + + /*00 - 10-bit -> 12-bit dynamic expansion*/ + /*01 - 8-bit -> 12-bit dynamic expansion*/ + if (signal == SIGNAL_TYPE_HDMI_TYPE_A || + signal == SIGNAL_TYPE_DISPLAY_PORT || + signal == SIGNAL_TYPE_DISPLAY_PORT_MST || + signal == SIGNAL_TYPE_VIRTUAL) { + switch (color_dpth) { + case COLOR_DEPTH_888: + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, + FMT_DYNAMIC_EXP_EN, 1, + FMT_DYNAMIC_EXP_MODE, 1); + break; + case COLOR_DEPTH_101010: + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, + FMT_DYNAMIC_EXP_EN, 1, + FMT_DYNAMIC_EXP_MODE, 0); + break; + case COLOR_DEPTH_121212: + REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL, + FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/ + FMT_DYNAMIC_EXP_MODE, 0); + break; + default: + break; + } + } +} + +static void opp1_program_clamping_and_pixel_encoding( + struct output_pixel_processor *opp, + const struct clamping_and_pixel_encoding_params *params) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + opp1_set_clamping(oppn10, params); + opp1_set_pixel_encoding(oppn10, params); +} + +void opp1_program_fmt( + struct output_pixel_processor *opp, + struct bit_depth_reduction_params *fmt_bit_depth, + struct clamping_and_pixel_encoding_params *clamping) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420) + REG_UPDATE(FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, 0); + + /* dithering is affected by , hence should be + * programmed afterwards */ + opp1_program_bit_depth_reduction( + opp, + fmt_bit_depth); + + opp1_program_clamping_and_pixel_encoding( + opp, + clamping); + + return; +} + +void opp1_program_stereo( + struct output_pixel_processor *opp, + bool enable, + const struct dc_crtc_timing *timing) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + + uint32_t active_width = timing->h_addressable - timing->h_border_right - timing->h_border_right; + uint32_t space1_size = timing->v_total - timing->v_addressable; + /* TODO: confirm computation of space2_size */ + uint32_t space2_size = timing->v_total - timing->v_addressable; + + if (!enable) { + active_width = 0; + space1_size = 0; + space2_size = 0; + } + + /* TODO: for which cases should FMT_STEREOSYNC_OVERRIDE be set? */ + REG_UPDATE(FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, 0); + + REG_UPDATE(OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, active_width); + + /* Program OPPBUF_3D_VACT_SPACE1_SIZE and OPPBUF_VACT_SPACE2_SIZE registers + * In 3D progressive frames, Vactive space happens only in between the 2 frames, + * so only need to program OPPBUF_3D_VACT_SPACE1_SIZE + * In 3D alternative frames, left and right frames, top and bottom field. + */ + if (timing->timing_3d_format == TIMING_3D_FORMAT_FRAME_ALTERNATE) + REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, space2_size); + else + REG_UPDATE(OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, space1_size); + + /* TODO: Is programming of OPPBUF_DUMMY_DATA_R/G/B needed? */ + /* + REG_UPDATE(OPPBUF_3D_PARAMETERS_0, + OPPBUF_DUMMY_DATA_R, data_r); + REG_UPDATE(OPPBUF_3D_PARAMETERS_1, + OPPBUF_DUMMY_DATA_G, data_g); + REG_UPDATE(OPPBUF_3D_PARAMETERS_1, + OPPBUF_DUMMY_DATA_B, _data_b); + */ +} + +void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable) +{ + struct dcn10_opp *oppn10 = TO_DCN10_OPP(opp); + uint32_t regval = enable ? 1 : 0; + + REG_UPDATE(OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, regval); +} + +/*****************************************/ +/* Constructor, Destructor */ +/*****************************************/ + +void opp1_destroy(struct output_pixel_processor **opp) +{ + kfree(TO_DCN10_OPP(*opp)); + *opp = NULL; +} + +static const struct opp_funcs dcn10_opp_funcs = { + .opp_set_dyn_expansion = opp1_set_dyn_expansion, + .opp_program_fmt = opp1_program_fmt, + .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, + .opp_program_stereo = opp1_program_stereo, + .opp_pipe_clock_control = opp1_pipe_clock_control, + .opp_set_disp_pattern_generator = NULL, + .opp_program_dpg_dimensions = NULL, + .dpg_is_blanked = NULL, + .dpg_is_pending = NULL, + .opp_destroy = opp1_destroy +}; + +void dcn10_opp_construct(struct dcn10_opp *oppn10, + struct dc_context *ctx, + uint32_t inst, + const struct dcn10_opp_registers *regs, + const struct dcn10_opp_shift *opp_shift, + const struct dcn10_opp_mask *opp_mask) +{ + + oppn10->base.ctx = ctx; + oppn10->base.inst = inst; + oppn10->base.funcs = &dcn10_opp_funcs; + + oppn10->regs = regs; + oppn10->opp_shift = opp_shift; + oppn10->opp_mask = opp_mask; +} diff --git a/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h new file mode 100644 index 000000000000..c87de68a509e --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/opp/dcn10/dcn10_opp.h @@ -0,0 +1,191 @@ +/* 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 __DC_OPP_DCN10_H__ +#define __DC_OPP_DCN10_H__ + +#include "opp.h" + +#define TO_DCN10_OPP(opp)\ + container_of(opp, struct dcn10_opp, base) + +#define OPP_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define OPP_REG_LIST_DCN(id) \ + SRI(FMT_BIT_DEPTH_CONTROL, FMT, id), \ + SRI(FMT_CONTROL, FMT, id), \ + SRI(FMT_DITHER_RAND_R_SEED, FMT, id), \ + SRI(FMT_DITHER_RAND_G_SEED, FMT, id), \ + SRI(FMT_DITHER_RAND_B_SEED, FMT, id), \ + SRI(FMT_CLAMP_CNTL, FMT, id), \ + SRI(FMT_DYNAMIC_EXP_CNTL, FMT, id), \ + SRI(FMT_MAP420_MEMORY_CONTROL, FMT, id), \ + SRI(OPPBUF_CONTROL, OPPBUF, id),\ + SRI(OPPBUF_3D_PARAMETERS_0, OPPBUF, id), \ + SRI(OPPBUF_3D_PARAMETERS_1, OPPBUF, id), \ + SRI(OPP_PIPE_CONTROL, OPP_PIPE, id) + +#define OPP_REG_LIST_DCN10(id) \ + OPP_REG_LIST_DCN(id) + +#define OPP_COMMON_REG_VARIABLE_LIST \ + uint32_t FMT_BIT_DEPTH_CONTROL; \ + uint32_t FMT_CONTROL; \ + uint32_t FMT_DITHER_RAND_R_SEED; \ + uint32_t FMT_DITHER_RAND_G_SEED; \ + uint32_t FMT_DITHER_RAND_B_SEED; \ + uint32_t FMT_CLAMP_CNTL; \ + uint32_t FMT_DYNAMIC_EXP_CNTL; \ + uint32_t FMT_MAP420_MEMORY_CONTROL; \ + uint32_t OPPBUF_CONTROL; \ + uint32_t OPPBUF_CONTROL1; \ + uint32_t OPPBUF_3D_PARAMETERS_0; \ + uint32_t OPPBUF_3D_PARAMETERS_1; \ + uint32_t OPP_PIPE_CONTROL + +#define OPP_MASK_SH_LIST_DCN(mask_sh) \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE, mask_sh), \ + OPP_SF(FMT0_FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_PIXEL_ENCODING, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_SUBSAMPLING_MODE, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_CBCR_BIT_REDUCTION_BYPASS, mask_sh), \ + OPP_SF(FMT0_FMT_CONTROL, FMT_STEREOSYNC_OVERRIDE, mask_sh), \ + OPP_SF(FMT0_FMT_DITHER_RAND_R_SEED, FMT_RAND_R_SEED, mask_sh), \ + OPP_SF(FMT0_FMT_DITHER_RAND_G_SEED, FMT_RAND_G_SEED, mask_sh), \ + OPP_SF(FMT0_FMT_DITHER_RAND_B_SEED, FMT_RAND_B_SEED, mask_sh), \ + OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_DATA_EN, mask_sh), \ + OPP_SF(FMT0_FMT_CLAMP_CNTL, FMT_CLAMP_COLOR_FORMAT, mask_sh), \ + OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN, mask_sh), \ + OPP_SF(FMT0_FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE, mask_sh), \ + OPP_SF(FMT0_FMT_MAP420_MEMORY_CONTROL, FMT_MAP420MEM_PWR_FORCE, mask_sh), \ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_ACTIVE_WIDTH, mask_sh),\ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_PIXEL_REPETITION, mask_sh),\ + OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE1_SIZE, mask_sh), \ + OPP_SF(OPPBUF0_OPPBUF_3D_PARAMETERS_0, OPPBUF_3D_VACT_SPACE2_SIZE, mask_sh), \ + OPP_SF(OPP_PIPE0_OPP_PIPE_CONTROL, OPP_PIPE_CLOCK_EN, mask_sh) + +#define OPP_MASK_SH_LIST_DCN10(mask_sh) \ + OPP_MASK_SH_LIST_DCN(mask_sh), \ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, mask_sh),\ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, mask_sh) + +#define OPP_DCN10_REG_FIELD_LIST(type) \ + type FMT_TRUNCATE_EN; \ + type FMT_TRUNCATE_DEPTH; \ + type FMT_TRUNCATE_MODE; \ + type FMT_SPATIAL_DITHER_EN; \ + type FMT_SPATIAL_DITHER_MODE; \ + type FMT_SPATIAL_DITHER_DEPTH; \ + type FMT_TEMPORAL_DITHER_EN; \ + type FMT_HIGHPASS_RANDOM_ENABLE; \ + type FMT_FRAME_RANDOM_ENABLE; \ + type FMT_RGB_RANDOM_ENABLE; \ + type FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX; \ + type FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP; \ + type FMT_RAND_R_SEED; \ + type FMT_RAND_G_SEED; \ + type FMT_RAND_B_SEED; \ + type FMT_PIXEL_ENCODING; \ + type FMT_SUBSAMPLING_MODE; \ + type FMT_CBCR_BIT_REDUCTION_BYPASS; \ + type FMT_CLAMP_DATA_EN; \ + type FMT_CLAMP_COLOR_FORMAT; \ + type FMT_DYNAMIC_EXP_EN; \ + type FMT_DYNAMIC_EXP_MODE; \ + type FMT_MAP420MEM_PWR_FORCE; \ + type FMT_STEREOSYNC_OVERRIDE; \ + type OPPBUF_ACTIVE_WIDTH;\ + type OPPBUF_PIXEL_REPETITION;\ + type OPPBUF_DISPLAY_SEGMENTATION;\ + type OPPBUF_OVERLAP_PIXEL_NUM;\ + type OPPBUF_NUM_SEGMENT_PADDED_PIXELS; \ + type OPPBUF_3D_VACT_SPACE1_SIZE; \ + type OPPBUF_3D_VACT_SPACE2_SIZE; \ + type OPP_PIPE_CLOCK_EN + +struct dcn10_opp_registers { + OPP_COMMON_REG_VARIABLE_LIST; +}; + +struct dcn10_opp_shift { + OPP_DCN10_REG_FIELD_LIST(uint8_t); +}; + +struct dcn10_opp_mask { + OPP_DCN10_REG_FIELD_LIST(uint32_t); +}; + +struct dcn10_opp { + struct output_pixel_processor base; + + const struct dcn10_opp_registers *regs; + const struct dcn10_opp_shift *opp_shift; + const struct dcn10_opp_mask *opp_mask; + + bool is_write_to_ram_a_safe; +}; + +void dcn10_opp_construct(struct dcn10_opp *oppn10, + struct dc_context *ctx, + uint32_t inst, + const struct dcn10_opp_registers *regs, + const struct dcn10_opp_shift *opp_shift, + const struct dcn10_opp_mask *opp_mask); + +void opp1_set_dyn_expansion( + struct output_pixel_processor *opp, + enum dc_color_space color_sp, + enum dc_color_depth color_dpth, + enum signal_type signal); + +void opp1_program_fmt( + struct output_pixel_processor *opp, + struct bit_depth_reduction_params *fmt_bit_depth, + struct clamping_and_pixel_encoding_params *clamping); + +void opp1_program_bit_depth_reduction( + struct output_pixel_processor *opp, + const struct bit_depth_reduction_params *params); + +void opp1_program_stereo( + struct output_pixel_processor *opp, + bool enable, + const struct dc_crtc_timing *timing); + +void opp1_pipe_clock_control(struct output_pixel_processor *opp, bool enable); + +void opp1_destroy(struct output_pixel_processor **opp); + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c new file mode 100644 index 000000000000..f5fe0cac7cb0 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.c @@ -0,0 +1,415 @@ +/* + * 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 + * + */ + +#include "core_types.h" +#include "dm_services.h" +#include "dcn20_opp.h" +#include "reg_helper.h" + +#define REG(reg) \ + (oppn20->regs->reg) + +#undef FN +#define FN(reg_name, field_name) \ + oppn20->opp_shift->field_name, oppn20->opp_mask->field_name + +#define CTX \ + oppn20->base.ctx + + +void opp2_set_disp_pattern_generator( + struct output_pixel_processor *opp, + enum controller_dp_test_pattern test_pattern, + enum controller_dp_color_space color_space, + enum dc_color_depth color_depth, + const struct tg_color *solid_color, + int width, + int height, + int offset) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + enum test_pattern_color_format bit_depth; + enum test_pattern_dyn_range dyn_range; + enum test_pattern_mode mode; + + /* color ramp generator mixes 16-bits color */ + uint32_t src_bpc = 16; + /* requested bpc */ + uint32_t dst_bpc; + uint32_t index; + /* RGB values of the color bars. + * Produce two RGB colors: RGB0 - white (all Fs) + * and RGB1 - black (all 0s) + * (three RGB components for two colors) + */ + uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, + 0x0000, 0x0000}; + /* dest color (converted to the specified color format) */ + uint16_t dst_color[6]; + uint32_t inc_base; + + /* translate to bit depth */ + switch (color_depth) { + case COLOR_DEPTH_666: + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; + break; + case COLOR_DEPTH_888: + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; + break; + case COLOR_DEPTH_101010: + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; + break; + case COLOR_DEPTH_121212: + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; + break; + default: + bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; + break; + } + + /* set DPG dimentions */ + REG_SET_2(DPG_DIMENSIONS, 0, + DPG_ACTIVE_WIDTH, width, + DPG_ACTIVE_HEIGHT, height); + + /* set DPG offset */ + REG_SET_2(DPG_OFFSET_SEGMENT, 0, + DPG_X_OFFSET, offset, + DPG_SEGMENT_WIDTH, 0); + + switch (test_pattern) { + case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: + case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: + { + dyn_range = (test_pattern == + CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? + TEST_PATTERN_DYN_RANGE_CEA : + TEST_PATTERN_DYN_RANGE_VESA); + + switch (color_space) { + case CONTROLLER_DP_COLOR_SPACE_YCBCR601: + mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601; + break; + case CONTROLLER_DP_COLOR_SPACE_YCBCR709: + mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709; + break; + case CONTROLLER_DP_COLOR_SPACE_RGB: + default: + mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; + break; + } + + REG_UPDATE_6(DPG_CONTROL, + DPG_EN, 1, + DPG_MODE, mode, + DPG_DYNAMIC_RANGE, dyn_range, + DPG_BIT_DEPTH, bit_depth, + DPG_VRES, 6, + DPG_HRES, 6); + } + break; + + case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: + case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: + { + mode = (test_pattern == + CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? + TEST_PATTERN_MODE_VERTICALBARS : + TEST_PATTERN_MODE_HORIZONTALBARS); + + switch (bit_depth) { + case TEST_PATTERN_COLOR_FORMAT_BPC_6: + dst_bpc = 6; + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_8: + dst_bpc = 8; + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_10: + dst_bpc = 10; + break; + default: + dst_bpc = 8; + break; + } + + /* adjust color to the required colorFormat */ + for (index = 0; index < 6; index++) { + /* dst = 2^dstBpc * src / 2^srcBpc = src >> + * (srcBpc - dstBpc); + */ + dst_color[index] = + src_color[index] >> (src_bpc - dst_bpc); + /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO. + * XXXXXXXXXX000000 for 10 bit, + * XXXXXXXX00000000 for 8 bit, + * XXXXXX0000000000 for 6 bits + */ + dst_color[index] <<= (16 - dst_bpc); + } + + REG_SET_2(DPG_COLOUR_R_CR, 0, + DPG_COLOUR1_R_CR, dst_color[0], + DPG_COLOUR0_R_CR, dst_color[3]); + REG_SET_2(DPG_COLOUR_G_Y, 0, + DPG_COLOUR1_G_Y, dst_color[1], + DPG_COLOUR0_G_Y, dst_color[4]); + REG_SET_2(DPG_COLOUR_B_CB, 0, + DPG_COLOUR1_B_CB, dst_color[2], + DPG_COLOUR0_B_CB, dst_color[5]); + + /* enable test pattern */ + REG_UPDATE_6(DPG_CONTROL, + DPG_EN, 1, + DPG_MODE, mode, + DPG_DYNAMIC_RANGE, 0, + DPG_BIT_DEPTH, bit_depth, + DPG_VRES, 0, + DPG_HRES, 0); + } + break; + + case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: + { + mode = (bit_depth == + TEST_PATTERN_COLOR_FORMAT_BPC_10 ? + TEST_PATTERN_MODE_DUALRAMP_RGB : + TEST_PATTERN_MODE_SINGLERAMP_RGB); + + switch (bit_depth) { + case TEST_PATTERN_COLOR_FORMAT_BPC_6: + dst_bpc = 6; + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_8: + dst_bpc = 8; + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_10: + dst_bpc = 10; + break; + default: + dst_bpc = 8; + break; + } + + /* increment for the first ramp for one color gradation + * 1 gradation for 6-bit color is 2^10 + * gradations in 16-bit color + */ + inc_base = (src_bpc - dst_bpc); + + switch (bit_depth) { + case TEST_PATTERN_COLOR_FORMAT_BPC_6: + { + REG_SET_3(DPG_RAMP_CONTROL, 0, + DPG_RAMP0_OFFSET, 0, + DPG_INC0, inc_base, + DPG_INC1, 0); + REG_UPDATE_2(DPG_CONTROL, + DPG_VRES, 6, + DPG_HRES, 6); + } + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_8: + { + REG_SET_3(DPG_RAMP_CONTROL, 0, + DPG_RAMP0_OFFSET, 0, + DPG_INC0, inc_base, + DPG_INC1, 0); + REG_UPDATE_2(DPG_CONTROL, + DPG_VRES, 6, + DPG_HRES, 8); + } + break; + case TEST_PATTERN_COLOR_FORMAT_BPC_10: + { + REG_SET_3(DPG_RAMP_CONTROL, 0, + DPG_RAMP0_OFFSET, 384 << 6, + DPG_INC0, inc_base, + DPG_INC1, inc_base + 2); + REG_UPDATE_2(DPG_CONTROL, + DPG_VRES, 5, + DPG_HRES, 8); + } + break; + default: + break; + } + + /* enable test pattern */ + REG_UPDATE_4(DPG_CONTROL, + DPG_EN, 1, + DPG_MODE, mode, + DPG_DYNAMIC_RANGE, 0, + DPG_BIT_DEPTH, bit_depth); + } + break; + case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: + { + REG_WRITE(DPG_CONTROL, 0); + REG_WRITE(DPG_COLOUR_R_CR, 0); + REG_WRITE(DPG_COLOUR_G_Y, 0); + REG_WRITE(DPG_COLOUR_B_CB, 0); + REG_WRITE(DPG_RAMP_CONTROL, 0); + } + break; + case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR: + { + opp2_dpg_set_blank_color(opp, solid_color); + REG_UPDATE_2(DPG_CONTROL, + DPG_EN, 1, + DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS); + + REG_SET_2(DPG_DIMENSIONS, 0, + DPG_ACTIVE_WIDTH, width, + DPG_ACTIVE_HEIGHT, height); + } + break; + default: + break; + + } +} + +void opp2_program_dpg_dimensions( + struct output_pixel_processor *opp, + int width, int height) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + + REG_SET_2(DPG_DIMENSIONS, 0, + DPG_ACTIVE_WIDTH, width, + DPG_ACTIVE_HEIGHT, height); +} + +void opp2_dpg_set_blank_color( + struct output_pixel_processor *opp, + const struct tg_color *color) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + + /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */ + ASSERT(color); + REG_SET_2(DPG_COLOUR_B_CB, 0, + DPG_COLOUR1_B_CB, color->color_b_cb << 6, + DPG_COLOUR0_B_CB, color->color_b_cb << 6); + REG_SET_2(DPG_COLOUR_G_Y, 0, + DPG_COLOUR1_G_Y, color->color_g_y << 6, + DPG_COLOUR0_G_Y, color->color_g_y << 6); + REG_SET_2(DPG_COLOUR_R_CR, 0, + DPG_COLOUR1_R_CR, color->color_r_cr << 6, + DPG_COLOUR0_R_CR, color->color_r_cr << 6); +} + +bool opp2_dpg_is_blanked(struct output_pixel_processor *opp) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + uint32_t dpg_en, dpg_mode; + uint32_t double_buffer_pending; + + REG_GET_2(DPG_CONTROL, + DPG_EN, &dpg_en, + DPG_MODE, &dpg_mode); + + REG_GET(DPG_STATUS, + DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); + + return (dpg_en == 1) && + (double_buffer_pending == 0); +} + +bool opp2_dpg_is_pending(struct output_pixel_processor *opp) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + uint32_t double_buffer_pending; + uint32_t dpg_en; + + REG_GET(DPG_CONTROL, DPG_EN, &dpg_en); + + REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); + + return (dpg_en == 1 && double_buffer_pending == 1); +} + +void opp2_program_left_edge_extra_pixel( + struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, + bool is_primary) +{ + struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); + uint32_t count = opp2_get_left_edge_extra_pixel_count(opp, pixel_encoding, is_primary); + + /* + * Specifies the number of extra left edge pixels that are supplied to + * the 422 horizontal chroma sub-sample filter. + */ + REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count); +} + +uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, bool is_primary) +{ + if ((pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) && + !opp->ctx->dc->debug.force_chroma_subsampling_1tap && + !is_primary) + return 1; + else + return 0; +} + +/*****************************************/ +/* Constructor, Destructor */ +/*****************************************/ + +static struct opp_funcs dcn20_opp_funcs = { + .opp_set_dyn_expansion = opp1_set_dyn_expansion, + .opp_program_fmt = opp1_program_fmt, + .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, + .opp_program_stereo = opp1_program_stereo, + .opp_pipe_clock_control = opp1_pipe_clock_control, + .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, + .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, + .dpg_is_blanked = opp2_dpg_is_blanked, + .dpg_is_pending = opp2_dpg_is_pending, + .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, + .opp_destroy = opp1_destroy, + .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, + .opp_get_left_edge_extra_pixel_count = opp2_get_left_edge_extra_pixel_count, +}; + +void dcn20_opp_construct(struct dcn20_opp *oppn20, + struct dc_context *ctx, + uint32_t inst, + const struct dcn20_opp_registers *regs, + const struct dcn20_opp_shift *opp_shift, + const struct dcn20_opp_mask *opp_mask) +{ + oppn20->base.ctx = ctx; + oppn20->base.inst = inst; + oppn20->base.funcs = &dcn20_opp_funcs; + + oppn20->regs = regs; + oppn20->opp_shift = opp_shift; + oppn20->opp_mask = opp_mask; +} + diff --git a/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h new file mode 100644 index 000000000000..34936e6c49f3 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/opp/dcn20/dcn20_opp.h @@ -0,0 +1,174 @@ +/* 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 __DC_OPP_DCN20_H__ +#define __DC_OPP_DCN20_H__ + +#include "dcn10/dcn10_opp.h" + +#define TO_DCN20_OPP(opp)\ + container_of(opp, struct dcn20_opp, base) + +#define OPP_SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define OPP_DPG_REG_LIST(id) \ + SRI(DPG_CONTROL, DPG, id), \ + SRI(DPG_DIMENSIONS, DPG, id), \ + SRI(DPG_OFFSET_SEGMENT, DPG, id), \ + SRI(DPG_COLOUR_B_CB, DPG, id), \ + SRI(DPG_COLOUR_G_Y, DPG, id), \ + SRI(DPG_COLOUR_R_CR, DPG, id), \ + SRI(DPG_RAMP_CONTROL, DPG, id), \ + SRI(DPG_STATUS, DPG, id) + +#define OPP_REG_LIST_DCN20(id) \ + OPP_REG_LIST_DCN10(id), \ + OPP_DPG_REG_LIST(id), \ + SRI(FMT_422_CONTROL, FMT, id), \ + SRI(OPPBUF_CONTROL1, OPPBUF, id) + +#define OPP_REG_VARIABLE_LIST_DCN2_0 \ + OPP_COMMON_REG_VARIABLE_LIST; \ + uint32_t FMT_422_CONTROL; \ + uint32_t DPG_CONTROL; \ + uint32_t DPG_DIMENSIONS; \ + uint32_t DPG_OFFSET_SEGMENT; \ + uint32_t DPG_COLOUR_B_CB; \ + uint32_t DPG_COLOUR_G_Y; \ + uint32_t DPG_COLOUR_R_CR; \ + uint32_t DPG_RAMP_CONTROL; \ + uint32_t DPG_STATUS + +#define OPP_DPG_MASK_SH_LIST(mask_sh) \ + OPP_SF(DPG0_DPG_CONTROL, DPG_EN, mask_sh), \ + OPP_SF(DPG0_DPG_CONTROL, DPG_MODE, mask_sh), \ + OPP_SF(DPG0_DPG_CONTROL, DPG_DYNAMIC_RANGE, mask_sh), \ + OPP_SF(DPG0_DPG_CONTROL, DPG_BIT_DEPTH, mask_sh), \ + OPP_SF(DPG0_DPG_CONTROL, DPG_VRES, mask_sh), \ + OPP_SF(DPG0_DPG_CONTROL, DPG_HRES, mask_sh), \ + OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_WIDTH, mask_sh), \ + OPP_SF(DPG0_DPG_DIMENSIONS, DPG_ACTIVE_HEIGHT, mask_sh), \ + OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_X_OFFSET, mask_sh), \ + OPP_SF(DPG0_DPG_OFFSET_SEGMENT, DPG_SEGMENT_WIDTH, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR0_R_CR, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_R_CR, DPG_COLOUR1_R_CR, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_B_CB, DPG_COLOUR0_B_CB, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_B_CB, DPG_COLOUR1_B_CB, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_G_Y, DPG_COLOUR0_G_Y, mask_sh), \ + OPP_SF(DPG0_DPG_COLOUR_G_Y, DPG_COLOUR1_G_Y, mask_sh), \ + OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_RAMP0_OFFSET, mask_sh), \ + OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_INC0, mask_sh), \ + OPP_SF(DPG0_DPG_RAMP_CONTROL, DPG_INC1, mask_sh), \ + OPP_SF(DPG0_DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, mask_sh) + +#define OPP_MASK_SH_LIST_DCN20(mask_sh) \ + OPP_MASK_SH_LIST_DCN(mask_sh), \ + OPP_DPG_MASK_SH_LIST(mask_sh), \ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_DISPLAY_SEGMENTATION, mask_sh),\ + OPP_SF(OPPBUF0_OPPBUF_CONTROL, OPPBUF_OVERLAP_PIXEL_NUM, mask_sh), \ + OPP_SF(FMT0_FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, mask_sh) + +#define OPP_DCN20_REG_FIELD_LIST(type) \ + OPP_DCN10_REG_FIELD_LIST(type); \ + type FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT; \ + type DPG_EN; \ + type DPG_MODE; \ + type DPG_DYNAMIC_RANGE; \ + type DPG_BIT_DEPTH; \ + type DPG_VRES; \ + type DPG_HRES; \ + type DPG_ACTIVE_WIDTH; \ + type DPG_ACTIVE_HEIGHT; \ + type DPG_X_OFFSET; \ + type DPG_SEGMENT_WIDTH; \ + type DPG_COLOUR0_R_CR; \ + type DPG_COLOUR1_R_CR; \ + type DPG_COLOUR0_B_CB; \ + type DPG_COLOUR1_B_CB; \ + type DPG_COLOUR0_G_Y; \ + type DPG_COLOUR1_G_Y; \ + type DPG_RAMP0_OFFSET; \ + type DPG_INC0; \ + type DPG_INC1; \ + type DPG_DOUBLE_BUFFER_PENDING + +struct dcn20_opp_registers { + OPP_REG_VARIABLE_LIST_DCN2_0; +}; + +struct dcn20_opp_shift { + OPP_DCN20_REG_FIELD_LIST(uint8_t); +}; + +struct dcn20_opp_mask { + OPP_DCN20_REG_FIELD_LIST(uint32_t); +}; + +struct dcn20_opp { + struct output_pixel_processor base; + + const struct dcn20_opp_registers *regs; + const struct dcn20_opp_shift *opp_shift; + const struct dcn20_opp_mask *opp_mask; + + bool is_write_to_ram_a_safe; +}; + +void dcn20_opp_construct(struct dcn20_opp *oppn20, + struct dc_context *ctx, + uint32_t inst, + const struct dcn20_opp_registers *regs, + const struct dcn20_opp_shift *opp_shift, + const struct dcn20_opp_mask *opp_mask); + +void opp2_set_disp_pattern_generator( + struct output_pixel_processor *opp, + enum controller_dp_test_pattern test_pattern, + enum controller_dp_color_space color_space, + enum dc_color_depth color_depth, + const struct tg_color *solid_color, + int width, + int height, + int offset); + +void opp2_program_dpg_dimensions( + struct output_pixel_processor *opp, + int width, int height); + +bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); + +bool opp2_dpg_is_pending(struct output_pixel_processor *opp); + +void opp2_dpg_set_blank_color( + struct output_pixel_processor *opp, + const struct tg_color *color); + +void opp2_program_left_edge_extra_pixel ( + struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, bool is_primary); + +uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp, + enum dc_pixel_encoding pixel_encoding, bool is_primary); +#endif