1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * 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 OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 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 FN 35 #define FN(reg_name, field_name) \ 36 oppn20->opp_shift->field_name, oppn20->opp_mask->field_name 37 38 #define CTX \ 39 oppn20->base.ctx 40 41 42 void 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 bits 168 */ 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 gradation 216 * 1 gradation for 6-bit color is 2^10 217 * gradations in 16-bit color 218 */ 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 294 void 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 305 void 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 324 bool 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 341 bool 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 354 void 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 to 364 * the 422 horizontal chroma sub-sample filter. 365 */ 366 REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count); 367 } 368 369 uint32_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 else 377 return 0; 378 } 379 380 /*****************************************/ 381 /* Constructor, Destructor */ 382 /*****************************************/ 383 384 static 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 400 void 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