2 * Copyright 2012-15 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dm_services.h"
27 #include "dcn20_opp.h"
28 #include "reg_helper.h"
34 #define FN(reg_name, field_name) \
35 oppn20->opp_shift->field_name, oppn20->opp_mask->field_name
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,
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;
56 /* color ramp generator mixes 16-bits color */
57 uint32_t src_bpc = 16;
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)
66 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
68 /* dest color (converted to the specified color format) */
69 uint16_t dst_color[6];
72 /* translate to bit depth */
73 switch (color_depth) {
75 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
78 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
80 case COLOR_DEPTH_101010:
81 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
83 case COLOR_DEPTH_121212:
84 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
87 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
91 /* set DPG dimentions */
92 REG_SET_2(DPG_DIMENSIONS, 0,
93 DPG_ACTIVE_WIDTH, width,
94 DPG_ACTIVE_HEIGHT, height);
97 REG_SET_2(DPG_OFFSET_SEGMENT, 0,
99 DPG_SEGMENT_WIDTH, 0);
101 switch (test_pattern) {
102 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
103 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
105 dyn_range = (test_pattern ==
106 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
107 TEST_PATTERN_DYN_RANGE_CEA :
108 TEST_PATTERN_DYN_RANGE_VESA);
110 switch (color_space) {
111 case CONTROLLER_DP_COLOR_SPACE_YCBCR601:
112 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;
114 case CONTROLLER_DP_COLOR_SPACE_YCBCR709:
115 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;
117 case CONTROLLER_DP_COLOR_SPACE_RGB:
119 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
123 REG_UPDATE_6(DPG_CONTROL,
126 DPG_DYNAMIC_RANGE, dyn_range,
127 DPG_BIT_DEPTH, bit_depth,
133 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
134 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
136 mode = (test_pattern ==
137 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
138 TEST_PATTERN_MODE_VERTICALBARS :
139 TEST_PATTERN_MODE_HORIZONTALBARS);
142 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
145 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
148 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
156 /* adjust color to the required colorFormat */
157 for (index = 0; index < 6; index++) {
158 /* dst = 2^dstBpc * src / 2^srcBpc = src >>
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
168 dst_color[index] <<= (16 - dst_bpc);
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]);
181 /* enable test pattern */
182 REG_UPDATE_6(DPG_CONTROL,
185 DPG_DYNAMIC_RANGE, 0,
186 DPG_BIT_DEPTH, bit_depth,
192 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
195 TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
196 TEST_PATTERN_MODE_DUALRAMP_RGB :
197 TEST_PATTERN_MODE_SINGLERAMP_RGB);
200 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
203 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
206 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
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
218 inc_base = (src_bpc - dst_bpc);
221 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
223 REG_SET_3(DPG_RAMP_CONTROL, 0,
227 REG_UPDATE_2(DPG_CONTROL,
232 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
234 REG_SET_3(DPG_RAMP_CONTROL, 0,
238 REG_UPDATE_2(DPG_CONTROL,
243 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
245 REG_SET_3(DPG_RAMP_CONTROL, 0,
246 DPG_RAMP0_OFFSET, 384 << 6,
248 DPG_INC1, inc_base + 2);
249 REG_UPDATE_2(DPG_CONTROL,
258 /* enable test pattern */
259 REG_UPDATE_4(DPG_CONTROL,
262 DPG_DYNAMIC_RANGE, 0,
263 DPG_BIT_DEPTH, bit_depth);
266 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
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);
275 case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
277 opp2_dpg_set_blank_color(opp, solid_color);
278 REG_UPDATE_2(DPG_CONTROL,
280 DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
282 REG_SET_2(DPG_DIMENSIONS, 0,
283 DPG_ACTIVE_WIDTH, width,
284 DPG_ACTIVE_HEIGHT, height);
293 void opp2_dpg_set_blank_color(
294 struct output_pixel_processor *opp,
295 const struct tg_color *color)
297 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
299 /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
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);
312 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
314 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
315 uint32_t dpg_en, dpg_mode;
316 uint32_t double_buffer_pending;
318 REG_GET_2(DPG_CONTROL,
320 DPG_MODE, &dpg_mode);
323 DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
325 return (dpg_en == 1) &&
326 (double_buffer_pending == 0);
329 void opp2_program_left_edge_extra_pixel (
330 struct output_pixel_processor *opp,
333 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
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
339 REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
342 /*****************************************/
343 /* Constructor, Destructor */
344 /*****************************************/
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,
359 void dcn20_opp_construct(struct dcn20_opp *oppn20,
360 struct dc_context *ctx,
362 const struct dcn20_opp_registers *regs,
363 const struct dcn20_opp_shift *opp_shift,
364 const struct dcn20_opp_mask *opp_mask)
366 oppn20->base.ctx = ctx;
367 oppn20->base.inst = inst;
368 oppn20->base.funcs = &dcn20_opp_funcs;
371 oppn20->opp_shift = opp_shift;
372 oppn20->opp_mask = opp_mask;