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