]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dce/dce_opp.c
Merge remote-tracking branch 'spi/for-5.14' into spi-linus
[linux.git] / drivers / gpu / drm / amd / display / dc / dce / dce_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 <linux/slab.h>
27
28 #include "dm_services.h"
29 #include "basics/conversion.h"
30
31 #include "dce_opp.h"
32
33 #include "reg_helper.h"
34
35 #define REG(reg)\
36         (opp110->regs->reg)
37
38 #undef FN
39 #define FN(reg_name, field_name) \
40         opp110->opp_shift->field_name, opp110->opp_mask->field_name
41
42 #define CTX \
43         opp110->base.ctx
44
45 enum {
46         MAX_PWL_ENTRY = 128,
47         MAX_REGIONS_NUMBER = 16
48 };
49
50 enum {
51         MAX_LUT_ENTRY = 256,
52         MAX_NUMBER_OF_ENTRIES = 256
53 };
54
55
56 enum {
57         OUTPUT_CSC_MATRIX_SIZE = 12
58 };
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 /*
82  *****************************************************************************
83  *  Function: regamma_config_regions_and_segments
84  *
85  *     build regamma curve by using predefined hw points
86  *     uses interface parameters ,like EDID coeff.
87  *
88  * @param   : parameters   interface parameters
89  *  @return void
90  *
91  *  @note
92  *
93  *  @see
94  *
95  *****************************************************************************
96  */
97
98
99
100 /*
101  *      set_truncation
102  *      1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
103  *      2) enable truncation
104  *      3) HW remove 12bit FMT support for DCE11 power saving reason.
105  */
106 static void set_truncation(
107                 struct dce110_opp *opp110,
108                 const struct bit_depth_reduction_params *params)
109 {
110         /*Disable truncation*/
111         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
112                         FMT_TRUNCATE_EN, 0,
113                         FMT_TRUNCATE_DEPTH, 0,
114                         FMT_TRUNCATE_MODE, 0);
115
116
117         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
118                 /*  8bpc trunc on YCbCr422*/
119                 if (params->flags.TRUNCATE_DEPTH == 1)
120                         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
121                                         FMT_TRUNCATE_EN, 1,
122                                         FMT_TRUNCATE_DEPTH, 1,
123                                         FMT_TRUNCATE_MODE, 0);
124                 else if (params->flags.TRUNCATE_DEPTH == 2)
125                         /*  10bpc trunc on YCbCr422*/
126                         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
127                                         FMT_TRUNCATE_EN, 1,
128                                         FMT_TRUNCATE_DEPTH, 2,
129                                         FMT_TRUNCATE_MODE, 0);
130                 return;
131         }
132         /* on other format-to do */
133         if (params->flags.TRUNCATE_ENABLED == 0)
134                 return;
135         /*Set truncation depth and Enable truncation*/
136         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
137                                 FMT_TRUNCATE_EN, 1,
138                                 FMT_TRUNCATE_DEPTH,
139                                 params->flags.TRUNCATE_DEPTH,
140                                 FMT_TRUNCATE_MODE,
141                                 params->flags.TRUNCATE_MODE);
142 }
143
144 #if defined(CONFIG_DRM_AMD_DC_SI)
145 /*
146  *      dce60_set_truncation
147  *      1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
148  *      2) enable truncation
149  *      3) HW remove 12bit FMT support for DCE11 power saving reason.
150  */
151 static void dce60_set_truncation(
152                 struct dce110_opp *opp110,
153                 const struct bit_depth_reduction_params *params)
154 {
155         /* DCE6 has no FMT_TRUNCATE_MODE bit in FMT_BIT_DEPTH_CONTROL reg */
156
157         /*Disable truncation*/
158         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
159                         FMT_TRUNCATE_EN, 0,
160                         FMT_TRUNCATE_DEPTH, 0);
161
162         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
163                 /*  8bpc trunc on YCbCr422*/
164                 if (params->flags.TRUNCATE_DEPTH == 1)
165                         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
166                                         FMT_TRUNCATE_EN, 1,
167                                         FMT_TRUNCATE_DEPTH, 1);
168                 else if (params->flags.TRUNCATE_DEPTH == 2)
169                         /*  10bpc trunc on YCbCr422*/
170                         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
171                                         FMT_TRUNCATE_EN, 1,
172                                         FMT_TRUNCATE_DEPTH, 2);
173                 return;
174         }
175         /* on other format-to do */
176         if (params->flags.TRUNCATE_ENABLED == 0)
177                 return;
178         /*Set truncation depth and Enable truncation*/
179         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
180                                 FMT_TRUNCATE_EN, 1,
181                                 FMT_TRUNCATE_DEPTH,
182                                 params->flags.TRUNCATE_DEPTH);
183 }
184 #endif
185
186 /*
187  *      set_spatial_dither
188  *      1) set spatial dithering mode: pattern of seed
189  *      2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp
190  *      3) set random seed
191  *      4) set random mode
192  *              lfsr is reset every frame or not reset
193  *              RGB dithering method
194  *              0: RGB data are all dithered with x^28+x^3+1
195  *              1: R data is dithered with x^28+x^3+1
196  *              G data is dithered with x^28+X^9+1
197  *              B data is dithered with x^28+x^13+1
198  *              enable high pass filter or not
199  *      5) enable spatical dithering
200  */
201 static void set_spatial_dither(
202         struct dce110_opp *opp110,
203         const struct bit_depth_reduction_params *params)
204 {
205         /*Disable spatial (random) dithering*/
206         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
207                 FMT_SPATIAL_DITHER_EN, 0,
208                 FMT_SPATIAL_DITHER_DEPTH, 0,
209                 FMT_SPATIAL_DITHER_MODE, 0);
210
211         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
212                 FMT_HIGHPASS_RANDOM_ENABLE, 0,
213                 FMT_FRAME_RANDOM_ENABLE, 0,
214                 FMT_RGB_RANDOM_ENABLE, 0);
215
216         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
217                 FMT_TEMPORAL_DITHER_EN, 0);
218
219         if (params->flags.SPATIAL_DITHER_ENABLED == 0)
220                 return;
221
222         /* only use FRAME_COUNTER_MAX if frameRandom == 1*/
223
224         if (opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX &&
225                         opp110->opp_mask->FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP) {
226                 if (params->flags.FRAME_RANDOM == 1) {
227                         if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||
228                         params->flags.SPATIAL_DITHER_DEPTH == 1) {
229                                 REG_UPDATE_2(FMT_CONTROL,
230                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
231                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
232                         } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
233                                 REG_UPDATE_2(FMT_CONTROL,
234                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
235                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
236                         } else
237                                 return;
238                 } else {
239                         REG_UPDATE_2(FMT_CONTROL,
240                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
241                                         FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
242                 }
243         }
244         /* Set seed for random values for
245          * spatial dithering for R,G,B channels
246          */
247         REG_UPDATE(FMT_DITHER_RAND_R_SEED,
248                         FMT_RAND_R_SEED, params->r_seed_value);
249
250         REG_UPDATE(FMT_DITHER_RAND_G_SEED,
251                         FMT_RAND_G_SEED, params->g_seed_value);
252
253         REG_UPDATE(FMT_DITHER_RAND_B_SEED,
254                         FMT_RAND_B_SEED, params->b_seed_value);
255
256         /* FMT_OFFSET_R_Cr  31:16 0x0 Setting the zero
257          * offset for the R/Cr channel, lower 4LSB
258          * is forced to zeros. Typically set to 0
259          * RGB and 0x80000 YCbCr.
260          */
261         /* FMT_OFFSET_G_Y   31:16 0x0 Setting the zero
262          * offset for the G/Y  channel, lower 4LSB is
263          * forced to zeros. Typically set to 0 RGB
264          * and 0x80000 YCbCr.
265          */
266         /* FMT_OFFSET_B_Cb  31:16 0x0 Setting the zero
267          * offset for the B/Cb channel, lower 4LSB is
268          * forced to zeros. Typically set to 0 RGB and
269          * 0x80000 YCbCr.
270          */
271
272         /* Disable High pass filter
273          * Reset only at startup
274          * Set RGB data dithered with x^28+x^3+1
275          */
276         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
277                 FMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
278                 FMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
279                 FMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
280
281         /* Set spatial dithering bit depth
282          * Set spatial dithering mode
283          * (default is Seed patterrn AAAA...)
284          * Enable spatial dithering
285          */
286         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
287                 FMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
288                 FMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
289                 FMT_SPATIAL_DITHER_EN, 1);
290 }
291
292 /*
293  *      SetTemporalDither (Frame Modulation)
294  *      1) set temporal dither depth
295  *      2) select pattern: from hard-coded pattern or programmable pattern
296  *      3) select optimized strips for BGR or RGB LCD sub-pixel
297  *      4) set s matrix
298  *      5) set t matrix
299  *      6) set grey level for 0.25, 0.5, 0.75
300  *      7) enable temporal dithering
301  */
302
303 static void set_temporal_dither(
304         struct dce110_opp *opp110,
305         const struct bit_depth_reduction_params *params)
306 {
307         /*Disable temporal (frame modulation) dithering first*/
308         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
309                 FMT_TEMPORAL_DITHER_EN, 0,
310                 FMT_TEMPORAL_DITHER_RESET, 0,
311                 FMT_TEMPORAL_DITHER_OFFSET, 0);
312
313         REG_UPDATE_2(FMT_BIT_DEPTH_CONTROL,
314                 FMT_TEMPORAL_DITHER_DEPTH, 0,
315                 FMT_TEMPORAL_LEVEL, 0);
316
317         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
318                 FMT_25FRC_SEL, 0,
319                 FMT_50FRC_SEL, 0,
320                 FMT_75FRC_SEL, 0);
321
322         /* no 10bpc dither on DCE11*/
323         if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
324                 params->flags.FRAME_MODULATION_DEPTH == 2)
325                 return;
326
327         /* Set temporal dithering depth*/
328         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
329                 FMT_TEMPORAL_DITHER_DEPTH, params->flags.FRAME_MODULATION_DEPTH,
330                 FMT_TEMPORAL_DITHER_RESET, 0,
331                 FMT_TEMPORAL_DITHER_OFFSET, 0);
332
333         /*Select legacy pattern based on FRC and Temporal level*/
334         if (REG(FMT_TEMPORAL_DITHER_PATTERN_CONTROL)) {
335                 REG_WRITE(FMT_TEMPORAL_DITHER_PATTERN_CONTROL, 0);
336                 /*Set s matrix*/
337                 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX, 0);
338                 /*Set t matrix*/
339                 REG_WRITE(FMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX, 0);
340         }
341
342         /*Select patterns for 0.25, 0.5 and 0.75 grey level*/
343         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
344                 FMT_TEMPORAL_LEVEL, params->flags.TEMPORAL_LEVEL);
345
346         REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
347                 FMT_25FRC_SEL, params->flags.FRC25,
348                 FMT_50FRC_SEL, params->flags.FRC50,
349                 FMT_75FRC_SEL, params->flags.FRC75);
350
351         /*Enable bit reduction by temporal (frame modulation) dithering*/
352         REG_UPDATE(FMT_BIT_DEPTH_CONTROL,
353                 FMT_TEMPORAL_DITHER_EN, 1);
354 }
355
356 /*
357  *      Set Clamping
358  *      1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
359  *              1 for 8 bpc
360  *              2 for 10 bpc
361  *              3 for 12 bpc
362  *              7 for programable
363  *      2) Enable clamp if Limited range requested
364  */
365 void dce110_opp_set_clamping(
366         struct dce110_opp *opp110,
367         const struct clamping_and_pixel_encoding_params *params)
368 {
369         REG_SET_2(FMT_CLAMP_CNTL, 0,
370                 FMT_CLAMP_DATA_EN, 0,
371                 FMT_CLAMP_COLOR_FORMAT, 0);
372
373         switch (params->clamping_level) {
374         case CLAMPING_FULL_RANGE:
375                 break;
376         case CLAMPING_LIMITED_RANGE_8BPC:
377                 REG_SET_2(FMT_CLAMP_CNTL, 0,
378                         FMT_CLAMP_DATA_EN, 1,
379                         FMT_CLAMP_COLOR_FORMAT, 1);
380                 break;
381         case CLAMPING_LIMITED_RANGE_10BPC:
382                 REG_SET_2(FMT_CLAMP_CNTL, 0,
383                         FMT_CLAMP_DATA_EN, 1,
384                         FMT_CLAMP_COLOR_FORMAT, 2);
385                 break;
386         case CLAMPING_LIMITED_RANGE_12BPC:
387                 REG_SET_2(FMT_CLAMP_CNTL, 0,
388                         FMT_CLAMP_DATA_EN, 1,
389                         FMT_CLAMP_COLOR_FORMAT, 3);
390                 break;
391         case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
392                 /*Set clamp control*/
393                 REG_SET_2(FMT_CLAMP_CNTL, 0,
394                         FMT_CLAMP_DATA_EN, 1,
395                         FMT_CLAMP_COLOR_FORMAT, 7);
396
397                 /*set the defaults*/
398                 REG_SET_2(FMT_CLAMP_COMPONENT_R, 0,
399                         FMT_CLAMP_LOWER_R, 0x10,
400                         FMT_CLAMP_UPPER_R, 0xFEF);
401
402                 REG_SET_2(FMT_CLAMP_COMPONENT_G, 0,
403                         FMT_CLAMP_LOWER_G, 0x10,
404                         FMT_CLAMP_UPPER_G, 0xFEF);
405
406                 REG_SET_2(FMT_CLAMP_COMPONENT_B, 0,
407                         FMT_CLAMP_LOWER_B, 0x10,
408                         FMT_CLAMP_UPPER_B, 0xFEF);
409                 break;
410         default:
411                 break;
412         }
413 }
414
415 #if defined(CONFIG_DRM_AMD_DC_SI)
416 /*
417  *      Set Clamping for DCE6 parts
418  *      1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
419  *              1 for 8 bpc
420  *              2 for 10 bpc
421  *              3 for 12 bpc
422  *              7 for programable
423  *      2) Enable clamp if Limited range requested
424  */
425 static void dce60_opp_set_clamping(
426         struct dce110_opp *opp110,
427         const struct clamping_and_pixel_encoding_params *params)
428 {
429         REG_SET_2(FMT_CLAMP_CNTL, 0,
430                 FMT_CLAMP_DATA_EN, 0,
431                 FMT_CLAMP_COLOR_FORMAT, 0);
432
433         switch (params->clamping_level) {
434         case CLAMPING_FULL_RANGE:
435                 break;
436         case CLAMPING_LIMITED_RANGE_8BPC:
437                 REG_SET_2(FMT_CLAMP_CNTL, 0,
438                         FMT_CLAMP_DATA_EN, 1,
439                         FMT_CLAMP_COLOR_FORMAT, 1);
440                 break;
441         case CLAMPING_LIMITED_RANGE_10BPC:
442                 REG_SET_2(FMT_CLAMP_CNTL, 0,
443                         FMT_CLAMP_DATA_EN, 1,
444                         FMT_CLAMP_COLOR_FORMAT, 2);
445                 break;
446         case CLAMPING_LIMITED_RANGE_12BPC:
447                 REG_SET_2(FMT_CLAMP_CNTL, 0,
448                         FMT_CLAMP_DATA_EN, 1,
449                         FMT_CLAMP_COLOR_FORMAT, 3);
450                 break;
451         case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
452                 /*Set clamp control*/
453                 REG_SET_2(FMT_CLAMP_CNTL, 0,
454                         FMT_CLAMP_DATA_EN, 1,
455                         FMT_CLAMP_COLOR_FORMAT, 7);
456
457                 /* DCE6 does have FMT_CLAMP_COMPONENT_{R,G,B} registers */
458
459                 break;
460         default:
461                 break;
462         }
463 }
464 #endif
465
466 /*
467  *      set_pixel_encoding
468  *
469  *      Set Pixel Encoding
470  *              0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
471  *              1: YCbCr 4:2:2
472  */
473 static void set_pixel_encoding(
474         struct dce110_opp *opp110,
475         const struct clamping_and_pixel_encoding_params *params)
476 {
477         if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)
478                 REG_UPDATE_3(FMT_CONTROL,
479                                 FMT_PIXEL_ENCODING, 0,
480                                 FMT_SUBSAMPLING_MODE, 0,
481                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);
482         else
483                 REG_UPDATE_2(FMT_CONTROL,
484                                 FMT_PIXEL_ENCODING, 0,
485                                 FMT_SUBSAMPLING_MODE, 0);
486
487         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
488                 REG_UPDATE_2(FMT_CONTROL,
489                                 FMT_PIXEL_ENCODING, 1,
490                                 FMT_SUBSAMPLING_ORDER, 0);
491         }
492         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
493                 REG_UPDATE_3(FMT_CONTROL,
494                                 FMT_PIXEL_ENCODING, 2,
495                                 FMT_SUBSAMPLING_MODE, 2,
496                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);
497         }
498
499 }
500
501 #if defined(CONFIG_DRM_AMD_DC_SI)
502 /*
503  *      dce60_set_pixel_encoding
504  *      DCE6 has no FMT_SUBSAMPLING_{MODE,ORDER} bits in FMT_CONTROL reg
505  *      Set Pixel Encoding
506  *              0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
507  *              1: YCbCr 4:2:2
508  */
509 static void dce60_set_pixel_encoding(
510         struct dce110_opp *opp110,
511         const struct clamping_and_pixel_encoding_params *params)
512 {
513         if (opp110->opp_mask->FMT_CBCR_BIT_REDUCTION_BYPASS)
514                 REG_UPDATE_2(FMT_CONTROL,
515                                 FMT_PIXEL_ENCODING, 0,
516                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 0);
517         else
518                 REG_UPDATE(FMT_CONTROL,
519                                 FMT_PIXEL_ENCODING, 0);
520
521         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
522                 REG_UPDATE(FMT_CONTROL,
523                                 FMT_PIXEL_ENCODING, 1);
524         }
525         if (params->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
526                 REG_UPDATE_2(FMT_CONTROL,
527                                 FMT_PIXEL_ENCODING, 2,
528                                 FMT_CBCR_BIT_REDUCTION_BYPASS, 1);
529         }
530
531 }
532 #endif
533
534 void dce110_opp_program_bit_depth_reduction(
535         struct output_pixel_processor *opp,
536         const struct bit_depth_reduction_params *params)
537 {
538         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
539
540         set_truncation(opp110, params);
541         set_spatial_dither(opp110, params);
542         set_temporal_dither(opp110, params);
543 }
544
545 #if defined(CONFIG_DRM_AMD_DC_SI)
546 static void dce60_opp_program_bit_depth_reduction(
547         struct output_pixel_processor *opp,
548         const struct bit_depth_reduction_params *params)
549 {
550         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
551
552         dce60_set_truncation(opp110, params);
553         set_spatial_dither(opp110, params);
554         set_temporal_dither(opp110, params);
555 }
556 #endif
557
558 void dce110_opp_program_clamping_and_pixel_encoding(
559         struct output_pixel_processor *opp,
560         const struct clamping_and_pixel_encoding_params *params)
561 {
562         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
563
564         dce110_opp_set_clamping(opp110, params);
565         set_pixel_encoding(opp110, params);
566 }
567
568 #if defined(CONFIG_DRM_AMD_DC_SI)
569 static void dce60_opp_program_clamping_and_pixel_encoding(
570         struct output_pixel_processor *opp,
571         const struct clamping_and_pixel_encoding_params *params)
572 {
573         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
574
575         dce60_opp_set_clamping(opp110, params);
576         dce60_set_pixel_encoding(opp110, params);
577 }
578 #endif
579
580
581 static void program_formatter_420_memory(struct output_pixel_processor *opp)
582 {
583         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
584         uint32_t fmt_mem_cntl_value;
585
586         /* Program source select*/
587         /* Use HW default source select for FMT_MEMORYx_CONTROL */
588         /* Use that value for FMT_SRC_SELECT as well*/
589         REG_GET(CONTROL,
590                         FMT420_MEM0_SOURCE_SEL, &fmt_mem_cntl_value);
591
592         REG_UPDATE(FMT_CONTROL,
593                         FMT_SRC_SELECT, fmt_mem_cntl_value);
594
595         /* Turn on the memory */
596         REG_UPDATE(CONTROL,
597                         FMT420_MEM0_PWR_FORCE, 0);
598 }
599
600 void dce110_opp_set_dyn_expansion(
601         struct output_pixel_processor *opp,
602         enum dc_color_space color_sp,
603         enum dc_color_depth color_dpth,
604         enum signal_type signal)
605 {
606         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
607
608         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
609                         FMT_DYNAMIC_EXP_EN, 0,
610                         FMT_DYNAMIC_EXP_MODE, 0);
611
612         /*00 - 10-bit -> 12-bit dynamic expansion*/
613         /*01 - 8-bit  -> 12-bit dynamic expansion*/
614         if (signal == SIGNAL_TYPE_HDMI_TYPE_A ||
615                 signal == SIGNAL_TYPE_DISPLAY_PORT ||
616                 signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
617                 switch (color_dpth) {
618                 case COLOR_DEPTH_888:
619                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
620                                 FMT_DYNAMIC_EXP_EN, 1,
621                                 FMT_DYNAMIC_EXP_MODE, 1);
622                         break;
623                 case COLOR_DEPTH_101010:
624                         REG_UPDATE_2(FMT_DYNAMIC_EXP_CNTL,
625                                 FMT_DYNAMIC_EXP_EN, 1,
626                                 FMT_DYNAMIC_EXP_MODE, 0);
627                         break;
628                 case COLOR_DEPTH_121212:
629                         REG_UPDATE_2(
630                                 FMT_DYNAMIC_EXP_CNTL,
631                                 FMT_DYNAMIC_EXP_EN, 1,/*otherwise last two bits are zero*/
632                                 FMT_DYNAMIC_EXP_MODE, 0);
633                         break;
634                 default:
635                         break;
636                 }
637         }
638 }
639
640 static void program_formatter_reset_dig_resync_fifo(struct output_pixel_processor *opp)
641 {
642         struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
643
644         /* clear previous phase lock status*/
645         REG_UPDATE(FMT_CONTROL,
646                         FMT_420_PIXEL_PHASE_LOCKED_CLEAR, 1);
647
648         /* poll until FMT_420_PIXEL_PHASE_LOCKED become 1*/
649         REG_WAIT(FMT_CONTROL, FMT_420_PIXEL_PHASE_LOCKED, 1, 10, 10);
650
651 }
652
653 void dce110_opp_program_fmt(
654         struct output_pixel_processor *opp,
655         struct bit_depth_reduction_params *fmt_bit_depth,
656         struct clamping_and_pixel_encoding_params *clamping)
657 {
658         /* dithering is affected by <CrtcSourceSelect>, hence should be
659          * programmed afterwards */
660
661         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
662                 program_formatter_420_memory(opp);
663
664         dce110_opp_program_bit_depth_reduction(
665                 opp,
666                 fmt_bit_depth);
667
668         dce110_opp_program_clamping_and_pixel_encoding(
669                 opp,
670                 clamping);
671
672         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
673                 program_formatter_reset_dig_resync_fifo(opp);
674
675         return;
676 }
677
678 #if defined(CONFIG_DRM_AMD_DC_SI)
679 static void dce60_opp_program_fmt(
680         struct output_pixel_processor *opp,
681         struct bit_depth_reduction_params *fmt_bit_depth,
682         struct clamping_and_pixel_encoding_params *clamping)
683 {
684         /* dithering is affected by <CrtcSourceSelect>, hence should be
685          * programmed afterwards */
686
687         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
688                 program_formatter_420_memory(opp);
689
690         dce60_opp_program_bit_depth_reduction(
691                 opp,
692                 fmt_bit_depth);
693
694         dce60_opp_program_clamping_and_pixel_encoding(
695                 opp,
696                 clamping);
697
698         if (clamping->pixel_encoding == PIXEL_ENCODING_YCBCR420)
699                 program_formatter_reset_dig_resync_fifo(opp);
700
701         return;
702 }
703 #endif
704
705
706
707 /*****************************************/
708 /* Constructor, Destructor               */
709 /*****************************************/
710
711 static const struct opp_funcs funcs = {
712         .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
713         .opp_destroy = dce110_opp_destroy,
714         .opp_program_fmt = dce110_opp_program_fmt,
715         .opp_program_bit_depth_reduction = dce110_opp_program_bit_depth_reduction
716 };
717
718 #if defined(CONFIG_DRM_AMD_DC_SI)
719 static const struct opp_funcs dce60_opp_funcs = {
720         .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
721         .opp_destroy = dce110_opp_destroy,
722         .opp_program_fmt = dce60_opp_program_fmt,
723         .opp_program_bit_depth_reduction = dce60_opp_program_bit_depth_reduction
724 };
725 #endif
726
727 void dce110_opp_construct(struct dce110_opp *opp110,
728         struct dc_context *ctx,
729         uint32_t inst,
730         const struct dce_opp_registers *regs,
731         const struct dce_opp_shift *opp_shift,
732         const struct dce_opp_mask *opp_mask)
733 {
734         opp110->base.funcs = &funcs;
735
736         opp110->base.ctx = ctx;
737
738         opp110->base.inst = inst;
739
740         opp110->regs = regs;
741         opp110->opp_shift = opp_shift;
742         opp110->opp_mask = opp_mask;
743 }
744
745 #if defined(CONFIG_DRM_AMD_DC_SI)
746 void dce60_opp_construct(struct dce110_opp *opp110,
747         struct dc_context *ctx,
748         uint32_t inst,
749         const struct dce_opp_registers *regs,
750         const struct dce_opp_shift *opp_shift,
751         const struct dce_opp_mask *opp_mask)
752 {
753         opp110->base.funcs = &dce60_opp_funcs;
754
755         opp110->base.ctx = ctx;
756
757         opp110->base.inst = inst;
758
759         opp110->regs = regs;
760         opp110->opp_shift = opp_shift;
761         opp110->opp_mask = opp_mask;
762 }
763 #endif
764
765 void dce110_opp_destroy(struct output_pixel_processor **opp)
766 {
767         if (*opp)
768                 kfree(FROM_DCE11_OPP(*opp));
769         *opp = NULL;
770 }
771
This page took 0.075319 seconds and 4 git commands to generate.