416 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "core_types.h"27#include "dm_services.h"28#include "dcn20_opp.h"29#include "reg_helper.h"30 31#define REG(reg) \32 (oppn20->regs->reg)33 34#undef FN35#define FN(reg_name, field_name) \36 oppn20->opp_shift->field_name, oppn20->opp_mask->field_name37 38#define CTX \39 oppn20->base.ctx40 41 42void opp2_set_disp_pattern_generator(43 struct output_pixel_processor *opp,44 enum controller_dp_test_pattern test_pattern,45 enum controller_dp_color_space color_space,46 enum dc_color_depth color_depth,47 const struct tg_color *solid_color,48 int width,49 int height,50 int offset)51{52 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);53 enum test_pattern_color_format bit_depth;54 enum test_pattern_dyn_range dyn_range;55 enum test_pattern_mode mode;56 57 /* color ramp generator mixes 16-bits color */58 uint32_t src_bpc = 16;59 /* requested bpc */60 uint32_t dst_bpc;61 uint32_t index;62 /* RGB values of the color bars.63 * Produce two RGB colors: RGB0 - white (all Fs)64 * and RGB1 - black (all 0s)65 * (three RGB components for two colors)66 */67 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,68 0x0000, 0x0000};69 /* dest color (converted to the specified color format) */70 uint16_t dst_color[6];71 uint32_t inc_base;72 73 /* translate to bit depth */74 switch (color_depth) {75 case COLOR_DEPTH_666:76 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;77 break;78 case COLOR_DEPTH_888:79 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;80 break;81 case COLOR_DEPTH_101010:82 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;83 break;84 case COLOR_DEPTH_121212:85 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;86 break;87 default:88 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;89 break;90 }91 92 /* set DPG dimentions */93 REG_SET_2(DPG_DIMENSIONS, 0,94 DPG_ACTIVE_WIDTH, width,95 DPG_ACTIVE_HEIGHT, height);96 97 /* set DPG offset */98 REG_SET_2(DPG_OFFSET_SEGMENT, 0,99 DPG_X_OFFSET, offset,100 DPG_SEGMENT_WIDTH, 0);101 102 switch (test_pattern) {103 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:104 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:105 {106 dyn_range = (test_pattern ==107 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?108 TEST_PATTERN_DYN_RANGE_CEA :109 TEST_PATTERN_DYN_RANGE_VESA);110 111 switch (color_space) {112 case CONTROLLER_DP_COLOR_SPACE_YCBCR601:113 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;114 break;115 case CONTROLLER_DP_COLOR_SPACE_YCBCR709:116 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;117 break;118 case CONTROLLER_DP_COLOR_SPACE_RGB:119 default:120 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;121 break;122 }123 124 REG_UPDATE_6(DPG_CONTROL,125 DPG_EN, 1,126 DPG_MODE, mode,127 DPG_DYNAMIC_RANGE, dyn_range,128 DPG_BIT_DEPTH, bit_depth,129 DPG_VRES, 6,130 DPG_HRES, 6);131 }132 break;133 134 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:135 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:136 {137 mode = (test_pattern ==138 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?139 TEST_PATTERN_MODE_VERTICALBARS :140 TEST_PATTERN_MODE_HORIZONTALBARS);141 142 switch (bit_depth) {143 case TEST_PATTERN_COLOR_FORMAT_BPC_6:144 dst_bpc = 6;145 break;146 case TEST_PATTERN_COLOR_FORMAT_BPC_8:147 dst_bpc = 8;148 break;149 case TEST_PATTERN_COLOR_FORMAT_BPC_10:150 dst_bpc = 10;151 break;152 default:153 dst_bpc = 8;154 break;155 }156 157 /* adjust color to the required colorFormat */158 for (index = 0; index < 6; index++) {159 /* dst = 2^dstBpc * src / 2^srcBpc = src >>160 * (srcBpc - dstBpc);161 */162 dst_color[index] =163 src_color[index] >> (src_bpc - dst_bpc);164 /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO.165 * XXXXXXXXXX000000 for 10 bit,166 * XXXXXXXX00000000 for 8 bit,167 * XXXXXX0000000000 for 6 bits168 */169 dst_color[index] <<= (16 - dst_bpc);170 }171 172 REG_SET_2(DPG_COLOUR_R_CR, 0,173 DPG_COLOUR1_R_CR, dst_color[0],174 DPG_COLOUR0_R_CR, dst_color[3]);175 REG_SET_2(DPG_COLOUR_G_Y, 0,176 DPG_COLOUR1_G_Y, dst_color[1],177 DPG_COLOUR0_G_Y, dst_color[4]);178 REG_SET_2(DPG_COLOUR_B_CB, 0,179 DPG_COLOUR1_B_CB, dst_color[2],180 DPG_COLOUR0_B_CB, dst_color[5]);181 182 /* enable test pattern */183 REG_UPDATE_6(DPG_CONTROL,184 DPG_EN, 1,185 DPG_MODE, mode,186 DPG_DYNAMIC_RANGE, 0,187 DPG_BIT_DEPTH, bit_depth,188 DPG_VRES, 0,189 DPG_HRES, 0);190 }191 break;192 193 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:194 {195 mode = (bit_depth ==196 TEST_PATTERN_COLOR_FORMAT_BPC_10 ?197 TEST_PATTERN_MODE_DUALRAMP_RGB :198 TEST_PATTERN_MODE_SINGLERAMP_RGB);199 200 switch (bit_depth) {201 case TEST_PATTERN_COLOR_FORMAT_BPC_6:202 dst_bpc = 6;203 break;204 case TEST_PATTERN_COLOR_FORMAT_BPC_8:205 dst_bpc = 8;206 break;207 case TEST_PATTERN_COLOR_FORMAT_BPC_10:208 dst_bpc = 10;209 break;210 default:211 dst_bpc = 8;212 break;213 }214 215 /* increment for the first ramp for one color gradation216 * 1 gradation for 6-bit color is 2^10217 * gradations in 16-bit color218 */219 inc_base = (src_bpc - dst_bpc);220 221 switch (bit_depth) {222 case TEST_PATTERN_COLOR_FORMAT_BPC_6:223 {224 REG_SET_3(DPG_RAMP_CONTROL, 0,225 DPG_RAMP0_OFFSET, 0,226 DPG_INC0, inc_base,227 DPG_INC1, 0);228 REG_UPDATE_2(DPG_CONTROL,229 DPG_VRES, 6,230 DPG_HRES, 6);231 }232 break;233 case TEST_PATTERN_COLOR_FORMAT_BPC_8:234 {235 REG_SET_3(DPG_RAMP_CONTROL, 0,236 DPG_RAMP0_OFFSET, 0,237 DPG_INC0, inc_base,238 DPG_INC1, 0);239 REG_UPDATE_2(DPG_CONTROL,240 DPG_VRES, 6,241 DPG_HRES, 8);242 }243 break;244 case TEST_PATTERN_COLOR_FORMAT_BPC_10:245 {246 REG_SET_3(DPG_RAMP_CONTROL, 0,247 DPG_RAMP0_OFFSET, 384 << 6,248 DPG_INC0, inc_base,249 DPG_INC1, inc_base + 2);250 REG_UPDATE_2(DPG_CONTROL,251 DPG_VRES, 5,252 DPG_HRES, 8);253 }254 break;255 default:256 break;257 }258 259 /* enable test pattern */260 REG_UPDATE_4(DPG_CONTROL,261 DPG_EN, 1,262 DPG_MODE, mode,263 DPG_DYNAMIC_RANGE, 0,264 DPG_BIT_DEPTH, bit_depth);265 }266 break;267 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:268 {269 REG_WRITE(DPG_CONTROL, 0);270 REG_WRITE(DPG_COLOUR_R_CR, 0);271 REG_WRITE(DPG_COLOUR_G_Y, 0);272 REG_WRITE(DPG_COLOUR_B_CB, 0);273 REG_WRITE(DPG_RAMP_CONTROL, 0);274 }275 break;276 case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:277 {278 opp2_dpg_set_blank_color(opp, solid_color);279 REG_UPDATE_2(DPG_CONTROL,280 DPG_EN, 1,281 DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);282 283 REG_SET_2(DPG_DIMENSIONS, 0,284 DPG_ACTIVE_WIDTH, width,285 DPG_ACTIVE_HEIGHT, height);286 }287 break;288 default:289 break;290 291 }292}293 294void opp2_program_dpg_dimensions(295 struct output_pixel_processor *opp,296 int width, int height)297{298 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);299 300 REG_SET_2(DPG_DIMENSIONS, 0,301 DPG_ACTIVE_WIDTH, width,302 DPG_ACTIVE_HEIGHT, height);303}304 305void opp2_dpg_set_blank_color(306 struct output_pixel_processor *opp,307 const struct tg_color *color)308{309 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);310 311 /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */312 ASSERT(color);313 REG_SET_2(DPG_COLOUR_B_CB, 0,314 DPG_COLOUR1_B_CB, color->color_b_cb << 6,315 DPG_COLOUR0_B_CB, color->color_b_cb << 6);316 REG_SET_2(DPG_COLOUR_G_Y, 0,317 DPG_COLOUR1_G_Y, color->color_g_y << 6,318 DPG_COLOUR0_G_Y, color->color_g_y << 6);319 REG_SET_2(DPG_COLOUR_R_CR, 0,320 DPG_COLOUR1_R_CR, color->color_r_cr << 6,321 DPG_COLOUR0_R_CR, color->color_r_cr << 6);322}323 324bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)325{326 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);327 uint32_t dpg_en, dpg_mode;328 uint32_t double_buffer_pending;329 330 REG_GET_2(DPG_CONTROL,331 DPG_EN, &dpg_en,332 DPG_MODE, &dpg_mode);333 334 REG_GET(DPG_STATUS,335 DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);336 337 return (dpg_en == 1) &&338 (double_buffer_pending == 0);339}340 341bool opp2_dpg_is_pending(struct output_pixel_processor *opp)342{343 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);344 uint32_t double_buffer_pending;345 uint32_t dpg_en;346 347 REG_GET(DPG_CONTROL, DPG_EN, &dpg_en);348 349 REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);350 351 return (dpg_en == 1 && double_buffer_pending == 1);352}353 354void opp2_program_left_edge_extra_pixel(355 struct output_pixel_processor *opp,356 enum dc_pixel_encoding pixel_encoding,357 bool is_primary)358{359 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);360 uint32_t count = opp2_get_left_edge_extra_pixel_count(opp, pixel_encoding, is_primary);361 362 /*363 * Specifies the number of extra left edge pixels that are supplied to364 * the 422 horizontal chroma sub-sample filter.365 */366 REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);367}368 369uint32_t opp2_get_left_edge_extra_pixel_count(struct output_pixel_processor *opp,370 enum dc_pixel_encoding pixel_encoding, bool is_primary)371{372 if ((pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420) &&373 !opp->ctx->dc->debug.force_chroma_subsampling_1tap &&374 !is_primary)375 return 1;376 else377 return 0;378}379 380/*****************************************/381/* Constructor, Destructor */382/*****************************************/383 384static struct opp_funcs dcn20_opp_funcs = {385 .opp_set_dyn_expansion = opp1_set_dyn_expansion,386 .opp_program_fmt = opp1_program_fmt,387 .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,388 .opp_program_stereo = opp1_program_stereo,389 .opp_pipe_clock_control = opp1_pipe_clock_control,390 .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,391 .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,392 .dpg_is_blanked = opp2_dpg_is_blanked,393 .dpg_is_pending = opp2_dpg_is_pending,394 .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,395 .opp_destroy = opp1_destroy,396 .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,397 .opp_get_left_edge_extra_pixel_count = opp2_get_left_edge_extra_pixel_count,398};399 400void dcn20_opp_construct(struct dcn20_opp *oppn20,401 struct dc_context *ctx,402 uint32_t inst,403 const struct dcn20_opp_registers *regs,404 const struct dcn20_opp_shift *opp_shift,405 const struct dcn20_opp_mask *opp_mask)406{407 oppn20->base.ctx = ctx;408 oppn20->base.inst = inst;409 oppn20->base.funcs = &dcn20_opp_funcs;410 411 oppn20->regs = regs;412 oppn20->opp_shift = opp_shift;413 oppn20->opp_mask = opp_mask;414}415 416