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
,
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
;
55 /* color ramp generator mixes 16-bits color */
56 uint32_t src_bpc
= 16;
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)
65 uint16_t src_color
[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
67 /* dest color (converted to the specified color format) */
68 uint16_t dst_color
[6];
71 /* translate to bit depth */
72 switch (color_depth
) {
74 bit_depth
= TEST_PATTERN_COLOR_FORMAT_BPC_6
;
77 bit_depth
= TEST_PATTERN_COLOR_FORMAT_BPC_8
;
79 case COLOR_DEPTH_101010
:
80 bit_depth
= TEST_PATTERN_COLOR_FORMAT_BPC_10
;
82 case COLOR_DEPTH_121212
:
83 bit_depth
= TEST_PATTERN_COLOR_FORMAT_BPC_12
;
86 bit_depth
= TEST_PATTERN_COLOR_FORMAT_BPC_8
;
90 /* set DPG dimentions */
91 REG_SET_2(DPG_DIMENSIONS
, 0,
92 DPG_ACTIVE_WIDTH
, width
,
93 DPG_ACTIVE_HEIGHT
, height
);
95 switch (test_pattern
) {
96 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES
:
97 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
:
99 dyn_range
= (test_pattern
==
100 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
?
101 TEST_PATTERN_DYN_RANGE_CEA
:
102 TEST_PATTERN_DYN_RANGE_VESA
);
104 switch (color_space
) {
105 case CONTROLLER_DP_COLOR_SPACE_YCBCR601
:
106 mode
= TEST_PATTERN_MODE_COLORSQUARES_YCBCR601
;
108 case CONTROLLER_DP_COLOR_SPACE_YCBCR709
:
109 mode
= TEST_PATTERN_MODE_COLORSQUARES_YCBCR709
;
111 case CONTROLLER_DP_COLOR_SPACE_RGB
:
113 mode
= TEST_PATTERN_MODE_COLORSQUARES_RGB
;
117 REG_UPDATE_6(DPG_CONTROL
,
120 DPG_DYNAMIC_RANGE
, dyn_range
,
121 DPG_BIT_DEPTH
, bit_depth
,
127 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS
:
128 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS
:
130 mode
= (test_pattern
==
131 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS
?
132 TEST_PATTERN_MODE_VERTICALBARS
:
133 TEST_PATTERN_MODE_HORIZONTALBARS
);
136 case TEST_PATTERN_COLOR_FORMAT_BPC_6
:
139 case TEST_PATTERN_COLOR_FORMAT_BPC_8
:
142 case TEST_PATTERN_COLOR_FORMAT_BPC_10
:
150 /* adjust color to the required colorFormat */
151 for (index
= 0; index
< 6; index
++) {
152 /* dst = 2^dstBpc * src / 2^srcBpc = src >>
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
162 dst_color
[index
] <<= (16 - dst_bpc
);
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]);
175 /* enable test pattern */
176 REG_UPDATE_6(DPG_CONTROL
,
179 DPG_DYNAMIC_RANGE
, 0,
180 DPG_BIT_DEPTH
, bit_depth
,
186 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP
:
189 TEST_PATTERN_COLOR_FORMAT_BPC_10
?
190 TEST_PATTERN_MODE_DUALRAMP_RGB
:
191 TEST_PATTERN_MODE_SINGLERAMP_RGB
);
194 case TEST_PATTERN_COLOR_FORMAT_BPC_6
:
197 case TEST_PATTERN_COLOR_FORMAT_BPC_8
:
200 case TEST_PATTERN_COLOR_FORMAT_BPC_10
:
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
212 inc_base
= (src_bpc
- dst_bpc
);
215 case TEST_PATTERN_COLOR_FORMAT_BPC_6
:
217 REG_SET_3(DPG_RAMP_CONTROL
, 0,
221 REG_UPDATE_2(DPG_CONTROL
,
226 case TEST_PATTERN_COLOR_FORMAT_BPC_8
:
228 REG_SET_3(DPG_RAMP_CONTROL
, 0,
232 REG_UPDATE_2(DPG_CONTROL
,
237 case TEST_PATTERN_COLOR_FORMAT_BPC_10
:
239 REG_SET_3(DPG_RAMP_CONTROL
, 0,
240 DPG_RAMP0_OFFSET
, 384 << 6,
242 DPG_INC1
, inc_base
+ 2);
243 REG_UPDATE_2(DPG_CONTROL
,
252 /* enable test pattern */
253 REG_UPDATE_4(DPG_CONTROL
,
256 DPG_DYNAMIC_RANGE
, 0,
257 DPG_BIT_DEPTH
, bit_depth
);
260 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE
:
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);
269 case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR
:
271 opp2_dpg_set_blank_color(opp
, solid_color
);
272 REG_UPDATE_2(DPG_CONTROL
,
274 DPG_MODE
, TEST_PATTERN_MODE_HORIZONTALBARS
);
276 REG_SET_2(DPG_DIMENSIONS
, 0,
277 DPG_ACTIVE_WIDTH
, width
,
278 DPG_ACTIVE_HEIGHT
, height
);
287 void opp2_dpg_set_blank_color(
288 struct output_pixel_processor
*opp
,
289 const struct tg_color
*color
)
291 struct dcn20_opp
*oppn20
= TO_DCN20_OPP(opp
);
293 /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
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);
306 bool opp2_dpg_is_blanked(struct output_pixel_processor
*opp
)
308 struct dcn20_opp
*oppn20
= TO_DCN20_OPP(opp
);
309 uint32_t dpg_en
, dpg_mode
;
310 uint32_t double_buffer_pending
;
312 REG_GET_2(DPG_CONTROL
,
314 DPG_MODE
, &dpg_mode
);
317 DPG_DOUBLE_BUFFER_PENDING
, &double_buffer_pending
);
319 return (dpg_en
== 1) &&
320 (double_buffer_pending
== 0);
323 void opp2_program_left_edge_extra_pixel (
324 struct output_pixel_processor
*opp
,
327 struct dcn20_opp
*oppn20
= TO_DCN20_OPP(opp
);
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
333 REG_UPDATE(FMT_422_CONTROL
, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT
, count
);
336 /*****************************************/
337 /* Constructor, Destructor */
338 /*****************************************/
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
,
353 void dcn20_opp_construct(struct dcn20_opp
*oppn20
,
354 struct dc_context
*ctx
,
356 const struct dcn20_opp_registers
*regs
,
357 const struct dcn20_opp_shift
*opp_shift
,
358 const struct dcn20_opp_mask
*opp_mask
)
360 oppn20
->base
.ctx
= ctx
;
361 oppn20
->base
.inst
= inst
;
362 oppn20
->base
.funcs
= &dcn20_opp_funcs
;
365 oppn20
->opp_shift
= opp_shift
;
366 oppn20
->opp_mask
= opp_mask
;