Merge tag 'ntb-5.11' of git://github.com/jonmason/ntb
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn20 / dcn20_opp.c
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_program_dpg_dimensions(
294                 struct output_pixel_processor *opp,
295                 int width, int height)
296 {
297         struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
298
299         REG_SET_2(DPG_DIMENSIONS, 0,
300                 DPG_ACTIVE_WIDTH, width,
301                 DPG_ACTIVE_HEIGHT, height);
302 }
303
304 void opp2_dpg_set_blank_color(
305                 struct output_pixel_processor *opp,
306                 const struct tg_color *color)
307 {
308         struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
309
310         /* 16-bit MSB aligned value. Bits 3:0 of this field are hardwired to ZERO */
311         ASSERT(color);
312         REG_SET_2(DPG_COLOUR_B_CB, 0,
313                         DPG_COLOUR1_B_CB, color->color_b_cb << 6,
314                         DPG_COLOUR0_B_CB, color->color_b_cb << 6);
315         REG_SET_2(DPG_COLOUR_G_Y, 0,
316                         DPG_COLOUR1_G_Y, color->color_g_y << 6,
317                         DPG_COLOUR0_G_Y, color->color_g_y << 6);
318         REG_SET_2(DPG_COLOUR_R_CR, 0,
319                         DPG_COLOUR1_R_CR, color->color_r_cr << 6,
320                         DPG_COLOUR0_R_CR, color->color_r_cr << 6);
321 }
322
323 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
324 {
325         struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
326         uint32_t dpg_en, dpg_mode;
327         uint32_t double_buffer_pending;
328
329         REG_GET_2(DPG_CONTROL,
330                         DPG_EN, &dpg_en,
331                         DPG_MODE, &dpg_mode);
332
333         REG_GET(DPG_STATUS,
334                         DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
335
336         return (dpg_en == 1) &&
337                 (double_buffer_pending == 0);
338 }
339
340 void opp2_program_left_edge_extra_pixel (
341                 struct output_pixel_processor *opp,
342                 bool count)
343 {
344         struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
345
346         /* Specifies the number of extra left edge pixels that are supplied to
347          * the 422 horizontal chroma sub-sample filter.
348          * Note that when left edge pixel is not "0", fmt pixel encoding can be in either 420 or 422 mode
349          * */
350         REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
351 }
352
353 /*****************************************/
354 /* Constructor, Destructor               */
355 /*****************************************/
356
357 static struct opp_funcs dcn20_opp_funcs = {
358                 .opp_set_dyn_expansion = opp1_set_dyn_expansion,
359                 .opp_program_fmt = opp1_program_fmt,
360                 .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
361                 .opp_program_stereo = opp1_program_stereo,
362                 .opp_pipe_clock_control = opp1_pipe_clock_control,
363                 .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
364                 .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
365                 .dpg_is_blanked = opp2_dpg_is_blanked,
366                 .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
367                 .opp_destroy = opp1_destroy,
368                 .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
369 };
370
371 void dcn20_opp_construct(struct dcn20_opp *oppn20,
372         struct dc_context *ctx,
373         uint32_t inst,
374         const struct dcn20_opp_registers *regs,
375         const struct dcn20_opp_shift *opp_shift,
376         const struct dcn20_opp_mask *opp_mask)
377 {
378         oppn20->base.ctx = ctx;
379         oppn20->base.inst = inst;
380         oppn20->base.funcs = &dcn20_opp_funcs;
381
382         oppn20->regs = regs;
383         oppn20->opp_shift = opp_shift;
384         oppn20->opp_mask = opp_mask;
385 }
386