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"
28 #include "dce80_opp.h"
29 #include "basics/conversion.h"
31 /* include DCE8 register header files */
32 #include "dce/dce_8_0_d.h"
33 #include "dce/dce_8_0_sh_mask.h"
36 (reg + opp80->offsets.dcp_offset)
39 OUTPUT_CSC_MATRIX_SIZE
= 12
42 static const struct out_csc_color_matrix global_color_matrix
[] = {
44 { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
45 { COLOR_SPACE_SRGB_LIMITED
,
46 { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
47 { COLOR_SPACE_YCBCR601
,
48 { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
49 0xF6B9, 0xE00, 0x1000} },
50 { COLOR_SPACE_YCBCR709
, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
51 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
52 /* TODO: correct values below */
53 { COLOR_SPACE_YCBCR601_LIMITED
, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
54 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
55 { COLOR_SPACE_YCBCR709_LIMITED
, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
56 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
60 /* 00 - BITS2:0 Bypass */
61 CSC_COLOR_MODE_GRAPHICS_BYPASS
,
62 /* 01 - hard coded coefficient TV RGB */
63 CSC_COLOR_MODE_GRAPHICS_PREDEFINED
,
64 /* 04 - programmable OUTPUT CSC coefficient */
65 CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC
,
68 static void program_color_matrix(
69 struct dce80_opp
*opp80
,
70 const struct out_csc_color_matrix
*tbl_entry
,
71 enum grph_color_adjust_option options
)
73 struct dc_context
*ctx
= opp80
->base
.ctx
;
76 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C11_C12
);
77 /* fixed S2.13 format */
90 dm_write_reg(ctx
, addr
, value
);
94 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C13_C14
);
95 /* fixed S2.13 format */
101 /* fixed S0.13 format */
104 tbl_entry
->regval
[3],
108 dm_write_reg(ctx
, addr
, value
);
112 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C21_C22
);
113 /* fixed S2.13 format */
116 tbl_entry
->regval
[4],
119 /* fixed S2.13 format */
122 tbl_entry
->regval
[5],
126 dm_write_reg(ctx
, addr
, value
);
130 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C23_C24
);
131 /* fixed S2.13 format */
134 tbl_entry
->regval
[6],
137 /* fixed S0.13 format */
140 tbl_entry
->regval
[7],
144 dm_write_reg(ctx
, addr
, value
);
148 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C31_C32
);
149 /* fixed S2.13 format */
152 tbl_entry
->regval
[8],
155 /* fixed S0.13 format */
158 tbl_entry
->regval
[9],
162 dm_write_reg(ctx
, addr
, value
);
166 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_C33_C34
);
167 /* fixed S2.13 format */
170 tbl_entry
->regval
[10],
173 /* fixed S0.13 format */
176 tbl_entry
->regval
[11],
180 dm_write_reg(ctx
, addr
, value
);
184 static bool configure_graphics_mode(
185 struct dce80_opp
*opp80
,
186 enum csc_color_mode config
,
187 enum graphics_csc_adjust_type csc_adjust_type
,
188 enum dc_color_space color_space
)
190 struct dc_context
*ctx
= opp80
->base
.ctx
;
191 uint32_t addr
= DCP_REG(mmOUTPUT_CSC_CONTROL
);
192 uint32_t value
= dm_read_reg(ctx
, addr
);
198 OUTPUT_CSC_GRPH_MODE
);
200 if (csc_adjust_type
== GRAPHICS_CSC_ADJUST_TYPE_SW
) {
201 if (config
== CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC
) {
206 OUTPUT_CSC_GRPH_MODE
);
209 switch (color_space
) {
210 case COLOR_SPACE_SRGB
:
216 OUTPUT_CSC_GRPH_MODE
);
218 case COLOR_SPACE_SRGB_LIMITED
:
224 OUTPUT_CSC_GRPH_MODE
);
226 case COLOR_SPACE_YCBCR601
:
227 case COLOR_SPACE_YPBPR601
:
228 case COLOR_SPACE_YCBCR601_LIMITED
:
234 OUTPUT_CSC_GRPH_MODE
);
236 case COLOR_SPACE_YCBCR709
:
237 case COLOR_SPACE_YPBPR709
:
238 case COLOR_SPACE_YCBCR709_LIMITED
:
244 OUTPUT_CSC_GRPH_MODE
);
250 } else if (csc_adjust_type
== GRAPHICS_CSC_ADJUST_TYPE_HW
) {
251 switch (color_space
) {
252 case COLOR_SPACE_SRGB
:
258 OUTPUT_CSC_GRPH_MODE
);
260 case COLOR_SPACE_SRGB_LIMITED
:
266 OUTPUT_CSC_GRPH_MODE
);
268 case COLOR_SPACE_YCBCR601
:
269 case COLOR_SPACE_YPBPR601
:
270 case COLOR_SPACE_YCBCR601_LIMITED
:
276 OUTPUT_CSC_GRPH_MODE
);
278 case COLOR_SPACE_YCBCR709
:
279 case COLOR_SPACE_YPBPR709
:
280 case COLOR_SPACE_YCBCR709_LIMITED
:
286 OUTPUT_CSC_GRPH_MODE
);
298 OUTPUT_CSC_GRPH_MODE
);
300 addr
= DCP_REG(mmOUTPUT_CSC_CONTROL
);
301 dm_write_reg(ctx
, addr
, value
);
306 void dce80_opp_set_csc_adjustment(
307 struct output_pixel_processor
*opp
,
308 const struct out_csc_color_matrix
*tbl_entry
)
310 struct dce80_opp
*opp80
= TO_DCE80_OPP(opp
);
311 enum csc_color_mode config
=
312 CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC
;
314 program_color_matrix(opp80
, tbl_entry
, GRAPHICS_CSC_ADJUST_TYPE_SW
);
316 /* We did everything ,now program DxOUTPUT_CSC_CONTROL */
317 configure_graphics_mode(opp80
, config
, GRAPHICS_CSC_ADJUST_TYPE_SW
,
318 tbl_entry
->color_space
);
321 void dce80_opp_set_csc_default(
322 struct output_pixel_processor
*opp
,
323 const struct default_adjustment
*default_adjust
)
325 struct dce80_opp
*opp80
= TO_DCE80_OPP(opp
);
326 enum csc_color_mode config
=
327 CSC_COLOR_MODE_GRAPHICS_PREDEFINED
;
329 if (default_adjust
->force_hw_default
== false) {
330 const struct out_csc_color_matrix
*elm
;
331 /* currently parameter not in use */
332 enum grph_color_adjust_option option
=
333 GRPH_COLOR_MATRIX_HW_DEFAULT
;
336 * HW default false we program locally defined matrix
337 * HW default true we use predefined hw matrix and we
338 * do not need to program matrix
339 * OEM wants the HW default via runtime parameter.
341 option
= GRPH_COLOR_MATRIX_SW
;
343 for (i
= 0; i
< ARRAY_SIZE(global_color_matrix
); ++i
) {
344 elm
= &global_color_matrix
[i
];
345 if (elm
->color_space
!= default_adjust
->out_color_space
)
347 /* program the matrix with default values from this
349 program_color_matrix(opp80
, elm
, option
);
350 config
= CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC
;
355 /* configure the what we programmed :
356 * 1. Default values from this file
357 * 2. Use hardware default from ROM_A and we do not need to program
360 configure_graphics_mode(opp80
, config
,
361 default_adjust
->csc_adjust_type
,
362 default_adjust
->out_color_space
);