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 "dm_services.h" 27 #include "dcn20_opp.h" 28 #include "reg_helper.h" 29 30 #define REG(reg) \ 31 (oppn20->regs->reg) 32 33 #undef FN 34 #define FN(reg_name, field_name) \ 35 oppn20->opp_shift->field_name, oppn20->opp_mask->field_name 36 37 #define CTX \ 38 oppn20->base.ctx 39 40 41 void opp2_set_disp_pattern_generator( 42 struct output_pixel_processor *opp, 43 enum controller_dp_test_pattern test_pattern, 44 enum controller_dp_color_space color_space, 45 enum dc_color_depth color_depth, 46 const struct tg_color *solid_color, 47 int width, 48 int height, 49 int offset) 50 { 51 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); 52 enum test_pattern_color_format bit_depth; 53 enum test_pattern_dyn_range dyn_range; 54 enum test_pattern_mode mode; 55 56 /* color ramp generator mixes 16-bits color */ 57 uint32_t src_bpc = 16; 58 /* requested bpc */ 59 uint32_t dst_bpc; 60 uint32_t index; 61 /* RGB values of the color bars. 62 * Produce two RGB colors: RGB0 - white (all Fs) 63 * and RGB1 - black (all 0s) 64 * (three RGB components for two colors) 65 */ 66 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 67 0x0000, 0x0000}; 68 /* dest color (converted to the specified color format) */ 69 uint16_t dst_color[6]; 70 uint32_t inc_base; 71 72 /* translate to bit depth */ 73 switch (color_depth) { 74 case COLOR_DEPTH_666: 75 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6; 76 break; 77 case COLOR_DEPTH_888: 78 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 79 break; 80 case COLOR_DEPTH_101010: 81 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10; 82 break; 83 case COLOR_DEPTH_121212: 84 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12; 85 break; 86 default: 87 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8; 88 break; 89 } 90 91 /* set DPG dimentions */ 92 REG_SET_2(DPG_DIMENSIONS, 0, 93 DPG_ACTIVE_WIDTH, width, 94 DPG_ACTIVE_HEIGHT, height); 95 96 /* set DPG offset */ 97 REG_SET_2(DPG_OFFSET_SEGMENT, 0, 98 DPG_X_OFFSET, offset, 99 DPG_SEGMENT_WIDTH, 0); 100 101 switch (test_pattern) { 102 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES: 103 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA: 104 { 105 dyn_range = (test_pattern == 106 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ? 107 TEST_PATTERN_DYN_RANGE_CEA : 108 TEST_PATTERN_DYN_RANGE_VESA); 109 110 switch (color_space) { 111 case CONTROLLER_DP_COLOR_SPACE_YCBCR601: 112 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601; 113 break; 114 case CONTROLLER_DP_COLOR_SPACE_YCBCR709: 115 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709; 116 break; 117 case CONTROLLER_DP_COLOR_SPACE_RGB: 118 default: 119 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB; 120 break; 121 } 122 123 REG_UPDATE_6(DPG_CONTROL, 124 DPG_EN, 1, 125 DPG_MODE, mode, 126 DPG_DYNAMIC_RANGE, dyn_range, 127 DPG_BIT_DEPTH, bit_depth, 128 DPG_VRES, 6, 129 DPG_HRES, 6); 130 } 131 break; 132 133 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS: 134 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS: 135 { 136 mode = (test_pattern == 137 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ? 138 TEST_PATTERN_MODE_VERTICALBARS : 139 TEST_PATTERN_MODE_HORIZONTALBARS); 140 141 switch (bit_depth) { 142 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 143 dst_bpc = 6; 144 break; 145 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 146 dst_bpc = 8; 147 break; 148 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 149 dst_bpc = 10; 150 break; 151 default: 152 dst_bpc = 8; 153 break; 154 } 155 156 /* adjust color to the required colorFormat */ 157 for (index = 0; index < 6; index++) { 158 /* dst = 2^dstBpc * src / 2^srcBpc = src >> 159 * (srcBpc - dstBpc); 160 */ 161 dst_color[index] = 162 src_color[index] >> (src_bpc - dst_bpc); 163 /* DPG_COLOUR registers are 16-bit MSB aligned value with bits 3:0 hardwired to ZERO. 164 * XXXXXXXXXX000000 for 10 bit, 165 * XXXXXXXX00000000 for 8 bit, 166 * XXXXXX0000000000 for 6 bits 167 */ 168 dst_color[index] <<= (16 - dst_bpc); 169 } 170 171 REG_SET_2(DPG_COLOUR_R_CR, 0, 172 DPG_COLOUR1_R_CR, dst_color[0], 173 DPG_COLOUR0_R_CR, dst_color[3]); 174 REG_SET_2(DPG_COLOUR_G_Y, 0, 175 DPG_COLOUR1_G_Y, dst_color[1], 176 DPG_COLOUR0_G_Y, dst_color[4]); 177 REG_SET_2(DPG_COLOUR_B_CB, 0, 178 DPG_COLOUR1_B_CB, dst_color[2], 179 DPG_COLOUR0_B_CB, dst_color[5]); 180 181 /* enable test pattern */ 182 REG_UPDATE_6(DPG_CONTROL, 183 DPG_EN, 1, 184 DPG_MODE, mode, 185 DPG_DYNAMIC_RANGE, 0, 186 DPG_BIT_DEPTH, bit_depth, 187 DPG_VRES, 0, 188 DPG_HRES, 0); 189 } 190 break; 191 192 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP: 193 { 194 mode = (bit_depth == 195 TEST_PATTERN_COLOR_FORMAT_BPC_10 ? 196 TEST_PATTERN_MODE_DUALRAMP_RGB : 197 TEST_PATTERN_MODE_SINGLERAMP_RGB); 198 199 switch (bit_depth) { 200 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 201 dst_bpc = 6; 202 break; 203 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 204 dst_bpc = 8; 205 break; 206 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 207 dst_bpc = 10; 208 break; 209 default: 210 dst_bpc = 8; 211 break; 212 } 213 214 /* increment for the first ramp for one color gradation 215 * 1 gradation for 6-bit color is 2^10 216 * gradations in 16-bit color 217 */ 218 inc_base = (src_bpc - dst_bpc); 219 220 switch (bit_depth) { 221 case TEST_PATTERN_COLOR_FORMAT_BPC_6: 222 { 223 REG_SET_3(DPG_RAMP_CONTROL, 0, 224 DPG_RAMP0_OFFSET, 0, 225 DPG_INC0, inc_base, 226 DPG_INC1, 0); 227 REG_UPDATE_2(DPG_CONTROL, 228 DPG_VRES, 6, 229 DPG_HRES, 6); 230 } 231 break; 232 case TEST_PATTERN_COLOR_FORMAT_BPC_8: 233 { 234 REG_SET_3(DPG_RAMP_CONTROL, 0, 235 DPG_RAMP0_OFFSET, 0, 236 DPG_INC0, inc_base, 237 DPG_INC1, 0); 238 REG_UPDATE_2(DPG_CONTROL, 239 DPG_VRES, 6, 240 DPG_HRES, 8); 241 } 242 break; 243 case TEST_PATTERN_COLOR_FORMAT_BPC_10: 244 { 245 REG_SET_3(DPG_RAMP_CONTROL, 0, 246 DPG_RAMP0_OFFSET, 384 << 6, 247 DPG_INC0, inc_base, 248 DPG_INC1, inc_base + 2); 249 REG_UPDATE_2(DPG_CONTROL, 250 DPG_VRES, 5, 251 DPG_HRES, 8); 252 } 253 break; 254 default: 255 break; 256 } 257 258 /* enable test pattern */ 259 REG_UPDATE_4(DPG_CONTROL, 260 DPG_EN, 1, 261 DPG_MODE, mode, 262 DPG_DYNAMIC_RANGE, 0, 263 DPG_BIT_DEPTH, bit_depth); 264 } 265 break; 266 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE: 267 { 268 REG_WRITE(DPG_CONTROL, 0); 269 REG_WRITE(DPG_COLOUR_R_CR, 0); 270 REG_WRITE(DPG_COLOUR_G_Y, 0); 271 REG_WRITE(DPG_COLOUR_B_CB, 0); 272 REG_WRITE(DPG_RAMP_CONTROL, 0); 273 } 274 break; 275 case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR: 276 { 277 opp2_dpg_set_blank_color(opp, solid_color); 278 REG_UPDATE_2(DPG_CONTROL, 279 DPG_EN, 1, 280 DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS); 281 282 REG_SET_2(DPG_DIMENSIONS, 0, 283 DPG_ACTIVE_WIDTH, width, 284 DPG_ACTIVE_HEIGHT, height); 285 } 286 break; 287 default: 288 break; 289 290 } 291 } 292 293 void opp2_dpg_set_blank_color( 294 struct output_pixel_processor *opp, 295 const struct tg_color *color) 296 { 297 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); 298 299 /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */ 300 ASSERT(color); 301 REG_SET_2(DPG_COLOUR_B_CB, 0, 302 DPG_COLOUR1_B_CB, color->color_b_cb << 6, 303 DPG_COLOUR0_B_CB, color->color_b_cb << 6); 304 REG_SET_2(DPG_COLOUR_G_Y, 0, 305 DPG_COLOUR1_G_Y, color->color_g_y << 6, 306 DPG_COLOUR0_G_Y, color->color_g_y << 6); 307 REG_SET_2(DPG_COLOUR_R_CR, 0, 308 DPG_COLOUR1_R_CR, color->color_r_cr << 6, 309 DPG_COLOUR0_R_CR, color->color_r_cr << 6); 310 } 311 312 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp) 313 { 314 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); 315 uint32_t dpg_en, dpg_mode; 316 uint32_t double_buffer_pending; 317 318 REG_GET_2(DPG_CONTROL, 319 DPG_EN, &dpg_en, 320 DPG_MODE, &dpg_mode); 321 322 REG_GET(DPG_STATUS, 323 DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending); 324 325 return (dpg_en == 1) && 326 (double_buffer_pending == 0); 327 } 328 329 void opp2_program_left_edge_extra_pixel ( 330 struct output_pixel_processor *opp, 331 bool count) 332 { 333 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp); 334 335 /* Specifies the number of extra left edge pixels that are supplied to 336 * the 422 horizontal chroma sub-sample filter. 337 * Note that when left edge pixel is not "0", fmt pixel encoding can be in either 420 or 422 mode 338 * */ 339 REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count); 340 } 341 342 /*****************************************/ 343 /* Constructor, Destructor */ 344 /*****************************************/ 345 346 static struct opp_funcs dcn20_opp_funcs = { 347 .opp_set_dyn_expansion = opp1_set_dyn_expansion, 348 .opp_program_fmt = opp1_program_fmt, 349 .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction, 350 .opp_program_stereo = opp1_program_stereo, 351 .opp_pipe_clock_control = opp1_pipe_clock_control, 352 .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, 353 .dpg_is_blanked = opp2_dpg_is_blanked, 354 .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, 355 .opp_destroy = opp1_destroy, 356 .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel, 357 }; 358 359 void dcn20_opp_construct(struct dcn20_opp *oppn20, 360 struct dc_context *ctx, 361 uint32_t inst, 362 const struct dcn20_opp_registers *regs, 363 const struct dcn20_opp_shift *opp_shift, 364 const struct dcn20_opp_mask *opp_mask) 365 { 366 oppn20->base.ctx = ctx; 367 oppn20->base.inst = inst; 368 oppn20->base.funcs = &dcn20_opp_funcs; 369 370 oppn20->regs = regs; 371 oppn20->opp_shift = opp_shift; 372 oppn20->opp_mask = opp_mask; 373 } 374 375