2a8007928210c2a4510f0294bc4481cdc26fa9ff
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / core / dc_hw_sequencer.c
1 /*
2  * Copyright 2015 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 "core_types.h"
28 #include "timing_generator.h"
29 #include "hw_sequencer.h"
30
31 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
32
33 /* used as index in array of black_color_format */
34 enum black_color_format {
35         BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0,
36         BLACK_COLOR_FORMAT_RGB_LIMITED,
37         BLACK_COLOR_FORMAT_YUV_TV,
38         BLACK_COLOR_FORMAT_YUV_CV,
39         BLACK_COLOR_FORMAT_YUV_SUPER_AA,
40         BLACK_COLOR_FORMAT_DEBUG,
41 };
42
43 enum dc_color_space_type {
44         COLOR_SPACE_RGB_TYPE,
45         COLOR_SPACE_RGB_LIMITED_TYPE,
46         COLOR_SPACE_YCBCR601_TYPE,
47         COLOR_SPACE_YCBCR709_TYPE,
48         COLOR_SPACE_YCBCR2020_TYPE,
49         COLOR_SPACE_YCBCR601_LIMITED_TYPE,
50         COLOR_SPACE_YCBCR709_LIMITED_TYPE,
51         COLOR_SPACE_YCBCR709_BLACK_TYPE,
52 };
53
54 static const struct tg_color black_color_format[] = {
55         /* BlackColorFormat_RGB_FullRange */
56         {0, 0, 0},
57         /* BlackColorFormat_RGB_Limited */
58         {0x40, 0x40, 0x40},
59         /* BlackColorFormat_YUV_TV */
60         {0x200, 0x40, 0x200},
61         /* BlackColorFormat_YUV_CV */
62         {0x1f4, 0x40, 0x1f4},
63         /* BlackColorFormat_YUV_SuperAA */
64         {0x1a2, 0x20, 0x1a2},
65         /* visual confirm debug */
66         {0xff, 0xff, 0},
67 };
68
69 struct out_csc_color_matrix_type {
70         enum dc_color_space_type color_space_type;
71         uint16_t regval[12];
72 };
73
74 static const struct out_csc_color_matrix_type output_csc_matrix[] = {
75         { COLOR_SPACE_RGB_TYPE,
76                 { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
77         { COLOR_SPACE_RGB_LIMITED_TYPE,
78                 { 0x1B67, 0, 0, 0x201, 0, 0x1B67, 0, 0x201, 0, 0, 0x1B67, 0x201} },
79         { COLOR_SPACE_YCBCR601_TYPE,
80                 { 0xE04, 0xF444, 0xFDB9, 0x1004, 0x831, 0x1016, 0x320, 0x201, 0xFB45,
81                                 0xF6B7, 0xE04, 0x1004} },
82         { COLOR_SPACE_YCBCR709_TYPE,
83                 { 0xE04, 0xF345, 0xFEB7, 0x1004, 0x5D3, 0x1399, 0x1FA,
84                                 0x201, 0xFCCA, 0xF533, 0xE04, 0x1004} },
85         /* TODO: correct values below */
86         { COLOR_SPACE_YCBCR601_LIMITED_TYPE,
87                 { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
88                                 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
89         { COLOR_SPACE_YCBCR709_LIMITED_TYPE,
90                 { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
91                                 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
92         { COLOR_SPACE_YCBCR2020_TYPE,
93                 { 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2,
94                                 0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} },
95         { COLOR_SPACE_YCBCR709_BLACK_TYPE,
96                 { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000,
97                                 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} },
98 };
99
100 static bool is_rgb_type(
101                 enum dc_color_space color_space)
102 {
103         bool ret = false;
104
105         if (color_space == COLOR_SPACE_SRGB                     ||
106                 color_space == COLOR_SPACE_XR_RGB               ||
107                 color_space == COLOR_SPACE_MSREF_SCRGB          ||
108                 color_space == COLOR_SPACE_2020_RGB_FULLRANGE   ||
109                 color_space == COLOR_SPACE_ADOBERGB             ||
110                 color_space == COLOR_SPACE_DCIP3        ||
111                 color_space == COLOR_SPACE_DOLBYVISION)
112                 ret = true;
113         return ret;
114 }
115
116 static bool is_rgb_limited_type(
117                 enum dc_color_space color_space)
118 {
119         bool ret = false;
120
121         if (color_space == COLOR_SPACE_SRGB_LIMITED             ||
122                 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE)
123                 ret = true;
124         return ret;
125 }
126
127 static bool is_ycbcr601_type(
128                 enum dc_color_space color_space)
129 {
130         bool ret = false;
131
132         if (color_space == COLOR_SPACE_YCBCR601 ||
133                 color_space == COLOR_SPACE_XV_YCC_601)
134                 ret = true;
135         return ret;
136 }
137
138 static bool is_ycbcr601_limited_type(
139                 enum dc_color_space color_space)
140 {
141         bool ret = false;
142
143         if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
144                 ret = true;
145         return ret;
146 }
147
148 static bool is_ycbcr709_type(
149                 enum dc_color_space color_space)
150 {
151         bool ret = false;
152
153         if (color_space == COLOR_SPACE_YCBCR709 ||
154                 color_space == COLOR_SPACE_XV_YCC_709)
155                 ret = true;
156         return ret;
157 }
158
159 static bool is_ycbcr2020_type(
160         enum dc_color_space color_space)
161 {
162         bool ret = false;
163
164         if (color_space == COLOR_SPACE_2020_YCBCR)
165                 ret = true;
166         return ret;
167 }
168
169 static bool is_ycbcr709_limited_type(
170                 enum dc_color_space color_space)
171 {
172         bool ret = false;
173
174         if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
175                 ret = true;
176         return ret;
177 }
178 static enum dc_color_space_type get_color_space_type(enum dc_color_space color_space)
179 {
180         enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE;
181
182         if (is_rgb_type(color_space))
183                 type = COLOR_SPACE_RGB_TYPE;
184         else if (is_rgb_limited_type(color_space))
185                 type = COLOR_SPACE_RGB_LIMITED_TYPE;
186         else if (is_ycbcr601_type(color_space))
187                 type = COLOR_SPACE_YCBCR601_TYPE;
188         else if (is_ycbcr709_type(color_space))
189                 type = COLOR_SPACE_YCBCR709_TYPE;
190         else if (is_ycbcr601_limited_type(color_space))
191                 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
192         else if (is_ycbcr709_limited_type(color_space))
193                 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
194         else if (is_ycbcr2020_type(color_space))
195                 type = COLOR_SPACE_YCBCR2020_TYPE;
196         else if (color_space == COLOR_SPACE_YCBCR709)
197                 type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
198         else if (color_space == COLOR_SPACE_YCBCR709_BLACK)
199                 type = COLOR_SPACE_YCBCR709_BLACK_TYPE;
200         return type;
201 }
202
203 const uint16_t *find_color_matrix(enum dc_color_space color_space,
204                                                         uint32_t *array_size)
205 {
206         int i;
207         enum dc_color_space_type type;
208         const uint16_t *val = NULL;
209         int arr_size = NUM_ELEMENTS(output_csc_matrix);
210
211         type = get_color_space_type(color_space);
212         for (i = 0; i < arr_size; i++)
213                 if (output_csc_matrix[i].color_space_type == type) {
214                         val = output_csc_matrix[i].regval;
215                         *array_size = 12;
216                         break;
217                 }
218
219         return val;
220 }
221
222
223 void color_space_to_black_color(
224         const struct dc *dc,
225         enum dc_color_space colorspace,
226         struct tg_color *black_color)
227 {
228         switch (colorspace) {
229         case COLOR_SPACE_YCBCR601:
230         case COLOR_SPACE_YCBCR709:
231         case COLOR_SPACE_YCBCR709_BLACK:
232         case COLOR_SPACE_YCBCR601_LIMITED:
233         case COLOR_SPACE_YCBCR709_LIMITED:
234         case COLOR_SPACE_2020_YCBCR:
235                 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
236                 break;
237
238         case COLOR_SPACE_SRGB_LIMITED:
239                 *black_color =
240                         black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
241                 break;
242
243         /**
244          * Remove default and add case for all color space
245          * so when we forget to add new color space
246          * compiler will give a warning
247          */
248         case COLOR_SPACE_UNKNOWN:
249         case COLOR_SPACE_SRGB:
250         case COLOR_SPACE_XR_RGB:
251         case COLOR_SPACE_MSREF_SCRGB:
252         case COLOR_SPACE_XV_YCC_709:
253         case COLOR_SPACE_XV_YCC_601:
254         case COLOR_SPACE_2020_RGB_FULLRANGE:
255         case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
256         case COLOR_SPACE_ADOBERGB:
257         case COLOR_SPACE_DCIP3:
258         case COLOR_SPACE_DISPLAYNATIVE:
259         case COLOR_SPACE_DOLBYVISION:
260         case COLOR_SPACE_APPCTRL:
261         case COLOR_SPACE_CUSTOMPOINTS:
262                 /* fefault is sRGB black (full range). */
263                 *black_color =
264                         black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
265                 /* default is sRGB black 0. */
266                 break;
267         }
268 }
269
270 bool hwss_wait_for_blank_complete(
271                 struct timing_generator *tg)
272 {
273         int counter;
274
275         /* Not applicable if the pipe is not primary, save 300ms of boot time */
276         if (!tg->funcs->is_blanked)
277                 return true;
278         for (counter = 0; counter < 100; counter++) {
279                 if (tg->funcs->is_blanked(tg))
280                         break;
281
282                 msleep(1);
283         }
284
285         if (counter == 100) {
286                 dm_error("DC: failed to blank crtc!\n");
287                 return false;
288         }
289
290         return true;
291 }
292
293 void get_mpctree_visual_confirm_color(
294                 struct pipe_ctx *pipe_ctx,
295                 struct tg_color *color)
296 {
297         const struct tg_color pipe_colors[6] = {
298                         {MAX_TG_COLOR_VALUE, 0, 0}, /* red */
299                         {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */
300                         {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */
301                         {0, MAX_TG_COLOR_VALUE, 0}, /* green */
302                         {0, 0, MAX_TG_COLOR_VALUE}, /* blue */
303                         {MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */
304         };
305
306         struct pipe_ctx *top_pipe = pipe_ctx;
307
308         while (top_pipe->top_pipe)
309                 top_pipe = top_pipe->top_pipe;
310
311         *color = pipe_colors[top_pipe->pipe_idx];
312 }
313
314 void get_surface_visual_confirm_color(
315                 const struct pipe_ctx *pipe_ctx,
316                 struct tg_color *color)
317 {
318         uint32_t color_value = MAX_TG_COLOR_VALUE;
319
320         switch (pipe_ctx->plane_res.scl_data.format) {
321         case PIXEL_FORMAT_ARGB8888:
322                 /* set border color to red */
323                 color->color_r_cr = color_value;
324                 if (pipe_ctx->plane_state->layer_index > 0) {
325                         /* set border color to pink */
326                         color->color_b_cb = color_value;
327                         color->color_g_y = color_value * 0.5;
328                 }
329                 break;
330
331         case PIXEL_FORMAT_ARGB2101010:
332                 /* set border color to blue */
333                 color->color_b_cb = color_value;
334                 if (pipe_ctx->plane_state->layer_index > 0) {
335                         /* set border color to cyan */
336                         color->color_g_y = color_value;
337                 }
338                 break;
339         case PIXEL_FORMAT_420BPP8:
340                 /* set border color to green */
341                 color->color_g_y = color_value;
342                 break;
343         case PIXEL_FORMAT_420BPP10:
344                 /* set border color to yellow */
345                 color->color_g_y = color_value;
346                 color->color_r_cr = color_value;
347                 break;
348         case PIXEL_FORMAT_FP16:
349                 /* set border color to white */
350                 color->color_r_cr = color_value;
351                 color->color_b_cb = color_value;
352                 color->color_g_y = color_value;
353                 if (pipe_ctx->plane_state->layer_index > 0) {
354                         /* set border color to orange */
355                         color->color_g_y = 0.22 * color_value;
356                         color->color_b_cb = 0;
357                 }
358                 break;
359         default:
360                 break;
361         }
362 }
363
364 void get_hdr_visual_confirm_color(
365                 struct pipe_ctx *pipe_ctx,
366                 struct tg_color *color)
367 {
368         uint32_t color_value = MAX_TG_COLOR_VALUE;
369
370         /* Determine the overscan color based on the top-most (desktop) plane's context */
371         struct pipe_ctx *top_pipe_ctx  = pipe_ctx;
372
373         while (top_pipe_ctx->top_pipe != NULL)
374                 top_pipe_ctx = top_pipe_ctx->top_pipe;
375
376         switch (top_pipe_ctx->plane_res.scl_data.format) {
377         case PIXEL_FORMAT_ARGB2101010:
378                 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
379                         /* HDR10, ARGB2101010 - set border color to red */
380                         color->color_r_cr = color_value;
381                 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
382                         /* FreeSync 2 ARGB2101010 - set border color to pink */
383                         color->color_r_cr = color_value;
384                         color->color_b_cb = color_value;
385                 }
386                 break;
387         case PIXEL_FORMAT_FP16:
388                 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) {
389                         /* HDR10, FP16 - set border color to blue */
390                         color->color_b_cb = color_value;
391                 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) {
392                         /* FreeSync 2 HDR - set border color to green */
393                         color->color_g_y = color_value;
394                 }
395                 break;
396         default:
397                 /* SDR - set border color to Gray */
398                 color->color_r_cr = color_value/2;
399                 color->color_b_cb = color_value/2;
400                 color->color_g_y = color_value/2;
401                 break;
402         }
403 }
404
405 void get_surface_tile_visual_confirm_color(
406                 struct pipe_ctx *pipe_ctx,
407                 struct tg_color *color)
408 {
409         uint32_t color_value = MAX_TG_COLOR_VALUE;
410         /* Determine the overscan color based on the bottom-most plane's context */
411         struct pipe_ctx *bottom_pipe_ctx  = pipe_ctx;
412
413         while (bottom_pipe_ctx->bottom_pipe != NULL)
414                 bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe;
415
416         switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) {
417         case DC_SW_LINEAR:
418                 /* LINEAR Surface - set border color to red */
419                 color->color_r_cr = color_value;
420                 break;
421         default:
422                 break;
423         }
424 }