GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / gpu / drm / amd / display / dc / dce110 / dce110_mem_input_v.c
1 /*
2  * Copyright 2012-16 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 #include "dm_services.h"
26
27 #include "dce/dce_11_0_d.h"
28 #include "dce/dce_11_0_sh_mask.h"
29 /* TODO: this needs to be looked at, used by Stella's workaround*/
30 #include "gmc/gmc_8_2_d.h"
31 #include "gmc/gmc_8_2_sh_mask.h"
32
33 #include "include/logger_interface.h"
34 #include "inc/dce_calcs.h"
35
36 #include "dce/dce_mem_input.h"
37
38 static void set_flip_control(
39         struct dce_mem_input *mem_input110,
40         bool immediate)
41 {
42         uint32_t value = 0;
43
44         value = dm_read_reg(
45                         mem_input110->base.ctx,
46                         mmUNP_FLIP_CONTROL);
47
48         set_reg_field_value(value, 1,
49                         UNP_FLIP_CONTROL,
50                         GRPH_SURFACE_UPDATE_PENDING_MODE);
51
52         dm_write_reg(
53                         mem_input110->base.ctx,
54                         mmUNP_FLIP_CONTROL,
55                         value);
56 }
57
58 /* chroma part */
59 static void program_pri_addr_c(
60         struct dce_mem_input *mem_input110,
61         PHYSICAL_ADDRESS_LOC address)
62 {
63         uint32_t value = 0;
64         uint32_t temp = 0;
65         /*high register MUST be programmed first*/
66         temp = address.high_part &
67 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
68
69         set_reg_field_value(value, temp,
70                 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
71                 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
72
73         dm_write_reg(
74                 mem_input110->base.ctx,
75                 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
76                 value);
77
78         temp = 0;
79         value = 0;
80         temp = address.low_part >>
81         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
82
83         set_reg_field_value(value, temp,
84                 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
85                 GRPH_PRIMARY_SURFACE_ADDRESS_C);
86
87         dm_write_reg(
88                 mem_input110->base.ctx,
89                 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
90                 value);
91 }
92
93 /* luma part */
94 static void program_pri_addr_l(
95         struct dce_mem_input *mem_input110,
96         PHYSICAL_ADDRESS_LOC address)
97 {
98         uint32_t value = 0;
99         uint32_t temp = 0;
100
101         /*high register MUST be programmed first*/
102         temp = address.high_part &
103 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
104
105         set_reg_field_value(value, temp,
106                 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
107                 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
108
109         dm_write_reg(
110                 mem_input110->base.ctx,
111                 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
112                 value);
113
114         temp = 0;
115         value = 0;
116         temp = address.low_part >>
117         UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
118
119         set_reg_field_value(value, temp,
120                 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
121                 GRPH_PRIMARY_SURFACE_ADDRESS_L);
122
123         dm_write_reg(
124                 mem_input110->base.ctx,
125                 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
126                 value);
127 }
128
129 static void program_addr(
130         struct dce_mem_input *mem_input110,
131         const struct dc_plane_address *addr)
132 {
133         switch (addr->type) {
134         case PLN_ADDR_TYPE_GRAPHICS:
135                 program_pri_addr_l(
136                         mem_input110,
137                         addr->grph.addr);
138                 break;
139         case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
140                 program_pri_addr_c(
141                         mem_input110,
142                         addr->video_progressive.chroma_addr);
143                 program_pri_addr_l(
144                         mem_input110,
145                         addr->video_progressive.luma_addr);
146                 break;
147         default:
148                 /* not supported */
149                 BREAK_TO_DEBUGGER();
150         }
151 }
152
153 static void enable(struct dce_mem_input *mem_input110)
154 {
155         uint32_t value = 0;
156
157         value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
158         set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
159         dm_write_reg(mem_input110->base.ctx,
160                 mmUNP_GRPH_ENABLE,
161                 value);
162 }
163
164 static void program_tiling(
165         struct dce_mem_input *mem_input110,
166         const union dc_tiling_info *info,
167         const enum surface_pixel_format pixel_format)
168 {
169         uint32_t value = 0;
170
171         set_reg_field_value(value, info->gfx8.num_banks,
172                 UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
173
174         set_reg_field_value(value, info->gfx8.bank_width,
175                 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
176
177         set_reg_field_value(value, info->gfx8.bank_height,
178                 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
179
180         set_reg_field_value(value, info->gfx8.tile_aspect,
181                 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
182
183         set_reg_field_value(value, info->gfx8.tile_split,
184                 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
185
186         set_reg_field_value(value, info->gfx8.tile_mode,
187                 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
188
189         set_reg_field_value(value, info->gfx8.pipe_config,
190                 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
191
192         set_reg_field_value(value, info->gfx8.array_mode,
193                 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
194
195         set_reg_field_value(value, 1,
196                 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
197
198         set_reg_field_value(value, 0,
199                 UNP_GRPH_CONTROL, GRPH_Z);
200
201         dm_write_reg(
202                 mem_input110->base.ctx,
203                 mmUNP_GRPH_CONTROL,
204                 value);
205
206         value = 0;
207
208         set_reg_field_value(value, info->gfx8.bank_width_c,
209                 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
210
211         set_reg_field_value(value, info->gfx8.bank_height_c,
212                 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
213
214         set_reg_field_value(value, info->gfx8.tile_aspect_c,
215                 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
216
217         set_reg_field_value(value, info->gfx8.tile_split_c,
218                 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
219
220         set_reg_field_value(value, info->gfx8.tile_mode_c,
221                 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
222
223         dm_write_reg(
224                 mem_input110->base.ctx,
225                 mmUNP_GRPH_CONTROL_C,
226                 value);
227 }
228
229 static void program_size_and_rotation(
230         struct dce_mem_input *mem_input110,
231         enum dc_rotation_angle rotation,
232         const union plane_size *plane_size)
233 {
234         uint32_t value = 0;
235         union plane_size local_size = *plane_size;
236
237         if (rotation == ROTATION_ANGLE_90 ||
238                 rotation == ROTATION_ANGLE_270) {
239
240                 swap(local_size.video.luma_size.x,
241                      local_size.video.luma_size.y);
242                 swap(local_size.video.luma_size.width,
243                      local_size.video.luma_size.height);
244                 swap(local_size.video.chroma_size.x,
245                      local_size.video.chroma_size.y);
246                 swap(local_size.video.chroma_size.width,
247                      local_size.video.chroma_size.height);
248         }
249
250         value = 0;
251         set_reg_field_value(value, local_size.video.luma_pitch,
252                         UNP_GRPH_PITCH_L, GRPH_PITCH_L);
253
254         dm_write_reg(
255                 mem_input110->base.ctx,
256                 mmUNP_GRPH_PITCH_L,
257                 value);
258
259         value = 0;
260         set_reg_field_value(value, local_size.video.chroma_pitch,
261                         UNP_GRPH_PITCH_C, GRPH_PITCH_C);
262         dm_write_reg(
263                 mem_input110->base.ctx,
264                 mmUNP_GRPH_PITCH_C,
265                 value);
266
267         value = 0;
268         set_reg_field_value(value, 0,
269                         UNP_GRPH_X_START_L, GRPH_X_START_L);
270         dm_write_reg(
271                 mem_input110->base.ctx,
272                 mmUNP_GRPH_X_START_L,
273                 value);
274
275         value = 0;
276         set_reg_field_value(value, 0,
277                         UNP_GRPH_X_START_C, GRPH_X_START_C);
278         dm_write_reg(
279                 mem_input110->base.ctx,
280                 mmUNP_GRPH_X_START_C,
281                 value);
282
283         value = 0;
284         set_reg_field_value(value, 0,
285                         UNP_GRPH_Y_START_L, GRPH_Y_START_L);
286         dm_write_reg(
287                 mem_input110->base.ctx,
288                 mmUNP_GRPH_Y_START_L,
289                 value);
290
291         value = 0;
292         set_reg_field_value(value, 0,
293                         UNP_GRPH_Y_START_C, GRPH_Y_START_C);
294         dm_write_reg(
295                 mem_input110->base.ctx,
296                 mmUNP_GRPH_Y_START_C,
297                 value);
298
299         value = 0;
300         set_reg_field_value(value, local_size.video.luma_size.x +
301                         local_size.video.luma_size.width,
302                         UNP_GRPH_X_END_L, GRPH_X_END_L);
303         dm_write_reg(
304                 mem_input110->base.ctx,
305                 mmUNP_GRPH_X_END_L,
306                 value);
307
308         value = 0;
309         set_reg_field_value(value, local_size.video.chroma_size.x +
310                         local_size.video.chroma_size.width,
311                         UNP_GRPH_X_END_C, GRPH_X_END_C);
312         dm_write_reg(
313                 mem_input110->base.ctx,
314                 mmUNP_GRPH_X_END_C,
315                 value);
316
317         value = 0;
318         set_reg_field_value(value, local_size.video.luma_size.y +
319                         local_size.video.luma_size.height,
320                         UNP_GRPH_Y_END_L, GRPH_Y_END_L);
321         dm_write_reg(
322                 mem_input110->base.ctx,
323                 mmUNP_GRPH_Y_END_L,
324                 value);
325
326         value = 0;
327         set_reg_field_value(value, local_size.video.chroma_size.y +
328                         local_size.video.chroma_size.height,
329                         UNP_GRPH_Y_END_C, GRPH_Y_END_C);
330         dm_write_reg(
331                 mem_input110->base.ctx,
332                 mmUNP_GRPH_Y_END_C,
333                 value);
334
335         value = 0;
336         switch (rotation) {
337         case ROTATION_ANGLE_90:
338                 set_reg_field_value(value, 3,
339                         UNP_HW_ROTATION, ROTATION_ANGLE);
340                 break;
341         case ROTATION_ANGLE_180:
342                 set_reg_field_value(value, 2,
343                         UNP_HW_ROTATION, ROTATION_ANGLE);
344                 break;
345         case ROTATION_ANGLE_270:
346                 set_reg_field_value(value, 1,
347                         UNP_HW_ROTATION, ROTATION_ANGLE);
348                 break;
349         default:
350                 set_reg_field_value(value, 0,
351                         UNP_HW_ROTATION, ROTATION_ANGLE);
352                 break;
353         }
354
355         dm_write_reg(
356                 mem_input110->base.ctx,
357                 mmUNP_HW_ROTATION,
358                 value);
359 }
360
361 static void program_pixel_format(
362         struct dce_mem_input *mem_input110,
363         enum surface_pixel_format format)
364 {
365         if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
366                 uint32_t value;
367                 uint8_t grph_depth;
368                 uint8_t grph_format;
369
370                 value = dm_read_reg(
371                                 mem_input110->base.ctx,
372                                 mmUNP_GRPH_CONTROL);
373
374                 switch (format) {
375                 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
376                         grph_depth = 0;
377                         grph_format = 0;
378                         break;
379                 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
380                         grph_depth = 1;
381                         grph_format = 1;
382                         break;
383                 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
384                 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
385                         grph_depth = 2;
386                         grph_format = 0;
387                         break;
388                 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
389                 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
390                 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
391                         grph_depth = 2;
392                         grph_format = 1;
393                         break;
394                 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
395                 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
396                 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
397                         grph_depth = 3;
398                         grph_format = 0;
399                         break;
400                 default:
401                         grph_depth = 2;
402                         grph_format = 0;
403                         break;
404                 }
405
406                 set_reg_field_value(
407                                 value,
408                                 grph_depth,
409                                 UNP_GRPH_CONTROL,
410                                 GRPH_DEPTH);
411                 set_reg_field_value(
412                                 value,
413                                 grph_format,
414                                 UNP_GRPH_CONTROL,
415                                 GRPH_FORMAT);
416
417                 dm_write_reg(
418                                 mem_input110->base.ctx,
419                                 mmUNP_GRPH_CONTROL,
420                                 value);
421
422                 value = dm_read_reg(
423                                 mem_input110->base.ctx,
424                                 mmUNP_GRPH_CONTROL_EXP);
425
426                 /* VIDEO FORMAT 0 */
427                 set_reg_field_value(
428                                 value,
429                                 0,
430                                 UNP_GRPH_CONTROL_EXP,
431                                 VIDEO_FORMAT);
432                 dm_write_reg(
433                                 mem_input110->base.ctx,
434                                 mmUNP_GRPH_CONTROL_EXP,
435                                 value);
436
437         } else {
438                 /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
439                 uint32_t value;
440                 uint8_t video_format;
441
442                 value = dm_read_reg(
443                                 mem_input110->base.ctx,
444                                 mmUNP_GRPH_CONTROL_EXP);
445
446                 switch (format) {
447                 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
448                         video_format = 2;
449                         break;
450                 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
451                         video_format = 3;
452                         break;
453                 default:
454                         video_format = 0;
455                         break;
456                 }
457
458                 set_reg_field_value(
459                         value,
460                         video_format,
461                         UNP_GRPH_CONTROL_EXP,
462                         VIDEO_FORMAT);
463
464                 dm_write_reg(
465                         mem_input110->base.ctx,
466                         mmUNP_GRPH_CONTROL_EXP,
467                         value);
468         }
469 }
470
471 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
472 {
473         struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
474         uint32_t value;
475
476         value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
477
478         if (get_reg_field_value(value, UNP_GRPH_UPDATE,
479                         GRPH_SURFACE_UPDATE_PENDING))
480                 return true;
481
482         mem_input->current_address = mem_input->request_address;
483         return false;
484 }
485
486 bool dce_mem_input_v_program_surface_flip_and_addr(
487         struct mem_input *mem_input,
488         const struct dc_plane_address *address,
489         bool flip_immediate)
490 {
491         struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
492
493         set_flip_control(mem_input110, flip_immediate);
494         program_addr(mem_input110,
495                 address);
496
497         mem_input->request_address = *address;
498
499         return true;
500 }
501
502 /* Scatter Gather param tables */
503 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
504                 {  8, 64, 64,  8,  8, 1, 4, 0, 0},
505                 { 16, 64, 32,  8, 16, 1, 8, 0, 0},
506                 { 32, 32, 32, 16, 16, 1, 8, 0, 0},
507                 { 64,  8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
508 };
509
510 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
511                 {  8, 512, 8, 1, 0, 1, 0, 0, 0},  /* 0 for invalid */
512                 { 16, 256, 8, 2, 0, 1, 0, 0, 0},
513                 { 32, 128, 8, 4, 0, 1, 0, 0, 0},
514                 { 64,  64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
515 };
516
517 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
518                 {  8, 4096, 1, 8, 0, 1, 0, 0, 0},
519                 { 16, 2048, 1, 8, 0, 1, 0, 0, 0},
520                 { 32, 1024, 1, 8, 0, 1, 0, 0, 0},
521                 { 64,  512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
522 };
523
524 /* Helper to get table entry from surface info */
525 static const unsigned int *get_dvmm_hw_setting(
526                 union dc_tiling_info *tiling_info,
527                 enum surface_pixel_format format,
528                 bool chroma)
529 {
530         enum bits_per_pixel {
531                 bpp_8 = 0,
532                 bpp_16,
533                 bpp_32,
534                 bpp_64
535         } bpp;
536
537         if (format >= SURFACE_PIXEL_FORMAT_INVALID)
538                 bpp = bpp_32;
539         else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
540                 bpp = chroma ? bpp_16 : bpp_8;
541         else
542                 bpp = bpp_8;
543
544         switch (tiling_info->gfx8.array_mode) {
545         case DC_ARRAY_1D_TILED_THIN1:
546         case DC_ARRAY_1D_TILED_THICK:
547         case DC_ARRAY_PRT_TILED_THIN1:
548                 return dvmm_Hw_Setting_1DTiling[bpp];
549         case DC_ARRAY_2D_TILED_THIN1:
550         case DC_ARRAY_2D_TILED_THICK:
551         case DC_ARRAY_2D_TILED_X_THICK:
552         case DC_ARRAY_PRT_2D_TILED_THIN1:
553         case DC_ARRAY_PRT_2D_TILED_THICK:
554                 return dvmm_Hw_Setting_2DTiling[bpp];
555         case DC_ARRAY_LINEAR_GENERAL:
556         case DC_ARRAY_LINEAR_ALLIGNED:
557                 return dvmm_Hw_Setting_Linear[bpp];
558         default:
559                 return dvmm_Hw_Setting_2DTiling[bpp];
560         }
561 }
562
563 void dce_mem_input_v_program_pte_vm(
564                 struct mem_input *mem_input,
565                 enum surface_pixel_format format,
566                 union dc_tiling_info *tiling_info,
567                 enum dc_rotation_angle rotation)
568 {
569         struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
570         const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
571         const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
572
573         unsigned int page_width = 0;
574         unsigned int page_height = 0;
575         unsigned int page_width_chroma = 0;
576         unsigned int page_height_chroma = 0;
577         unsigned int temp_page_width = pte[1];
578         unsigned int temp_page_height = pte[2];
579         unsigned int min_pte_before_flip = 0;
580         unsigned int min_pte_before_flip_chroma = 0;
581         uint32_t value = 0;
582
583         while ((temp_page_width >>= 1) != 0)
584                 page_width++;
585         while ((temp_page_height >>= 1) != 0)
586                 page_height++;
587
588         temp_page_width = pte_chroma[1];
589         temp_page_height = pte_chroma[2];
590         while ((temp_page_width >>= 1) != 0)
591                 page_width_chroma++;
592         while ((temp_page_height >>= 1) != 0)
593                 page_height_chroma++;
594
595         switch (rotation) {
596         case ROTATION_ANGLE_90:
597         case ROTATION_ANGLE_270:
598                 min_pte_before_flip = pte[4];
599                 min_pte_before_flip_chroma = pte_chroma[4];
600                 break;
601         default:
602                 min_pte_before_flip = pte[3];
603                 min_pte_before_flip_chroma = pte_chroma[3];
604                 break;
605         }
606
607         value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
608         /* TODO: un-hardcode requestlimit */
609         set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
610         set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
611         dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
612
613         value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
614         set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
615         set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
616         set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
617         dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
618
619         value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
620         set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
621         set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
622         dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
623
624         value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
625         set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
626         set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
627         set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
628         dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
629
630         value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
631         set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
632         set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
633         dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
634 }
635
636 void dce_mem_input_v_program_surface_config(
637         struct mem_input *mem_input,
638         enum surface_pixel_format format,
639         union dc_tiling_info *tiling_info,
640         union plane_size *plane_size,
641         enum dc_rotation_angle rotation,
642         struct dc_plane_dcc_param *dcc,
643         bool horizotal_mirror)
644 {
645         struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
646
647         enable(mem_input110);
648         program_tiling(mem_input110, tiling_info, format);
649         program_size_and_rotation(mem_input110, rotation, plane_size);
650         program_pixel_format(mem_input110, format);
651 }
652
653 static void program_urgency_watermark(
654         const struct dc_context *ctx,
655         const uint32_t urgency_addr,
656         const uint32_t wm_addr,
657         struct dce_watermarks marks_low,
658         uint32_t total_dest_line_time_ns)
659 {
660         /* register value */
661         uint32_t urgency_cntl = 0;
662         uint32_t wm_mask_cntl = 0;
663
664         /*Write mask to enable reading/writing of watermark set A*/
665         wm_mask_cntl = dm_read_reg(ctx, wm_addr);
666         set_reg_field_value(wm_mask_cntl,
667                         1,
668                         DPGV0_WATERMARK_MASK_CONTROL,
669                         URGENCY_WATERMARK_MASK);
670         dm_write_reg(ctx, wm_addr, wm_mask_cntl);
671
672         urgency_cntl = dm_read_reg(ctx, urgency_addr);
673
674         set_reg_field_value(
675                 urgency_cntl,
676                 marks_low.a_mark,
677                 DPGV0_PIPE_URGENCY_CONTROL,
678                 URGENCY_LOW_WATERMARK);
679
680         set_reg_field_value(
681                 urgency_cntl,
682                 total_dest_line_time_ns,
683                 DPGV0_PIPE_URGENCY_CONTROL,
684                 URGENCY_HIGH_WATERMARK);
685         dm_write_reg(ctx, urgency_addr, urgency_cntl);
686
687         /*Write mask to enable reading/writing of watermark set B*/
688         wm_mask_cntl = dm_read_reg(ctx, wm_addr);
689         set_reg_field_value(wm_mask_cntl,
690                         2,
691                         DPGV0_WATERMARK_MASK_CONTROL,
692                         URGENCY_WATERMARK_MASK);
693         dm_write_reg(ctx, wm_addr, wm_mask_cntl);
694
695         urgency_cntl = dm_read_reg(ctx, urgency_addr);
696
697         set_reg_field_value(urgency_cntl,
698                 marks_low.b_mark,
699                 DPGV0_PIPE_URGENCY_CONTROL,
700                 URGENCY_LOW_WATERMARK);
701
702         set_reg_field_value(urgency_cntl,
703                 total_dest_line_time_ns,
704                 DPGV0_PIPE_URGENCY_CONTROL,
705                 URGENCY_HIGH_WATERMARK);
706
707         dm_write_reg(ctx, urgency_addr, urgency_cntl);
708 }
709
710 static void program_urgency_watermark_l(
711         const struct dc_context *ctx,
712         struct dce_watermarks marks_low,
713         uint32_t total_dest_line_time_ns)
714 {
715         program_urgency_watermark(
716                 ctx,
717                 mmDPGV0_PIPE_URGENCY_CONTROL,
718                 mmDPGV0_WATERMARK_MASK_CONTROL,
719                 marks_low,
720                 total_dest_line_time_ns);
721 }
722
723 static void program_urgency_watermark_c(
724         const struct dc_context *ctx,
725         struct dce_watermarks marks_low,
726         uint32_t total_dest_line_time_ns)
727 {
728         program_urgency_watermark(
729                 ctx,
730                 mmDPGV1_PIPE_URGENCY_CONTROL,
731                 mmDPGV1_WATERMARK_MASK_CONTROL,
732                 marks_low,
733                 total_dest_line_time_ns);
734 }
735
736 static void program_stutter_watermark(
737         const struct dc_context *ctx,
738         const uint32_t stutter_addr,
739         const uint32_t wm_addr,
740         struct dce_watermarks marks)
741 {
742         /* register value */
743         uint32_t stutter_cntl = 0;
744         uint32_t wm_mask_cntl = 0;
745
746         /*Write mask to enable reading/writing of watermark set A*/
747
748         wm_mask_cntl = dm_read_reg(ctx, wm_addr);
749         set_reg_field_value(wm_mask_cntl,
750                 1,
751                 DPGV0_WATERMARK_MASK_CONTROL,
752                 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
753         dm_write_reg(ctx, wm_addr, wm_mask_cntl);
754
755         stutter_cntl = dm_read_reg(ctx, stutter_addr);
756
757         if (ctx->dc->debug.disable_stutter) {
758                 set_reg_field_value(stutter_cntl,
759                         0,
760                         DPGV0_PIPE_STUTTER_CONTROL,
761                         STUTTER_ENABLE);
762         } else {
763                 set_reg_field_value(stutter_cntl,
764                         1,
765                         DPGV0_PIPE_STUTTER_CONTROL,
766                         STUTTER_ENABLE);
767         }
768
769         set_reg_field_value(stutter_cntl,
770                 1,
771                 DPGV0_PIPE_STUTTER_CONTROL,
772                 STUTTER_IGNORE_FBC);
773
774         /*Write watermark set A*/
775         set_reg_field_value(stutter_cntl,
776                 marks.a_mark,
777                 DPGV0_PIPE_STUTTER_CONTROL,
778                 STUTTER_EXIT_SELF_REFRESH_WATERMARK);
779         dm_write_reg(ctx, stutter_addr, stutter_cntl);
780
781         /*Write mask to enable reading/writing of watermark set B*/
782         wm_mask_cntl = dm_read_reg(ctx, wm_addr);
783         set_reg_field_value(wm_mask_cntl,
784                 2,
785                 DPGV0_WATERMARK_MASK_CONTROL,
786                 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
787         dm_write_reg(ctx, wm_addr, wm_mask_cntl);
788
789         stutter_cntl = dm_read_reg(ctx, stutter_addr);
790         /*Write watermark set B*/
791         set_reg_field_value(stutter_cntl,
792                 marks.b_mark,
793                 DPGV0_PIPE_STUTTER_CONTROL,
794                 STUTTER_EXIT_SELF_REFRESH_WATERMARK);
795         dm_write_reg(ctx, stutter_addr, stutter_cntl);
796 }
797
798 static void program_stutter_watermark_l(
799         const struct dc_context *ctx,
800         struct dce_watermarks marks)
801 {
802         program_stutter_watermark(ctx,
803                         mmDPGV0_PIPE_STUTTER_CONTROL,
804                         mmDPGV0_WATERMARK_MASK_CONTROL,
805                         marks);
806 }
807
808 static void program_stutter_watermark_c(
809         const struct dc_context *ctx,
810         struct dce_watermarks marks)
811 {
812         program_stutter_watermark(ctx,
813                         mmDPGV1_PIPE_STUTTER_CONTROL,
814                         mmDPGV1_WATERMARK_MASK_CONTROL,
815                         marks);
816 }
817
818 static void program_nbp_watermark(
819         const struct dc_context *ctx,
820         const uint32_t wm_mask_ctrl_addr,
821         const uint32_t nbp_pstate_ctrl_addr,
822         struct dce_watermarks marks)
823 {
824         uint32_t value;
825
826         /* Write mask to enable reading/writing of watermark set A */
827
828         value = dm_read_reg(ctx, wm_mask_ctrl_addr);
829
830         set_reg_field_value(
831                 value,
832                 1,
833                 DPGV0_WATERMARK_MASK_CONTROL,
834                 NB_PSTATE_CHANGE_WATERMARK_MASK);
835         dm_write_reg(ctx, wm_mask_ctrl_addr, value);
836
837         value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
838
839         set_reg_field_value(
840                 value,
841                 1,
842                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
843                 NB_PSTATE_CHANGE_ENABLE);
844         set_reg_field_value(
845                 value,
846                 1,
847                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
848                 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
849         set_reg_field_value(
850                 value,
851                 1,
852                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
853                 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
854         dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
855
856         /* Write watermark set A */
857         value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
858         set_reg_field_value(
859                 value,
860                 marks.a_mark,
861                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
862                 NB_PSTATE_CHANGE_WATERMARK);
863         dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
864
865         /* Write mask to enable reading/writing of watermark set B */
866         value = dm_read_reg(ctx, wm_mask_ctrl_addr);
867         set_reg_field_value(
868                 value,
869                 2,
870                 DPGV0_WATERMARK_MASK_CONTROL,
871                 NB_PSTATE_CHANGE_WATERMARK_MASK);
872         dm_write_reg(ctx, wm_mask_ctrl_addr, value);
873
874         value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
875         set_reg_field_value(
876                 value,
877                 1,
878                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
879                 NB_PSTATE_CHANGE_ENABLE);
880         set_reg_field_value(
881                 value,
882                 1,
883                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
884                 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
885         set_reg_field_value(
886                 value,
887                 1,
888                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
889                 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
890         dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
891
892         /* Write watermark set B */
893         value = dm_read_reg(ctx, nbp_pstate_ctrl_addr);
894         set_reg_field_value(
895                 value,
896                 marks.b_mark,
897                 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
898                 NB_PSTATE_CHANGE_WATERMARK);
899         dm_write_reg(ctx, nbp_pstate_ctrl_addr, value);
900 }
901
902 static void program_nbp_watermark_l(
903         const struct dc_context *ctx,
904         struct dce_watermarks marks)
905 {
906         program_nbp_watermark(ctx,
907                         mmDPGV0_WATERMARK_MASK_CONTROL,
908                         mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL,
909                         marks);
910 }
911
912 static void program_nbp_watermark_c(
913         const struct dc_context *ctx,
914         struct dce_watermarks marks)
915 {
916         program_nbp_watermark(ctx,
917                         mmDPGV1_WATERMARK_MASK_CONTROL,
918                         mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL,
919                         marks);
920 }
921
922 void dce_mem_input_v_program_display_marks(
923         struct mem_input *mem_input,
924         struct dce_watermarks nbp,
925         struct dce_watermarks stutter,
926         struct dce_watermarks stutter_enter,
927         struct dce_watermarks urgent,
928         uint32_t total_dest_line_time_ns)
929 {
930         program_urgency_watermark_l(
931                 mem_input->ctx,
932                 urgent,
933                 total_dest_line_time_ns);
934
935         program_nbp_watermark_l(
936                 mem_input->ctx,
937                 nbp);
938
939         program_stutter_watermark_l(
940                 mem_input->ctx,
941                 stutter);
942
943 }
944
945 void dce_mem_input_program_chroma_display_marks(
946         struct mem_input *mem_input,
947         struct dce_watermarks nbp,
948         struct dce_watermarks stutter,
949         struct dce_watermarks urgent,
950         uint32_t total_dest_line_time_ns)
951 {
952         program_urgency_watermark_c(
953                 mem_input->ctx,
954                 urgent,
955                 total_dest_line_time_ns);
956
957         program_nbp_watermark_c(
958                 mem_input->ctx,
959                 nbp);
960
961         program_stutter_watermark_c(
962                 mem_input->ctx,
963                 stutter);
964 }
965
966 void dce110_allocate_mem_input_v(
967         struct mem_input *mi,
968         uint32_t h_total,/* for current stream */
969         uint32_t v_total,/* for current stream */
970         uint32_t pix_clk_khz,/* for current stream */
971         uint32_t total_stream_num)
972 {
973         uint32_t addr;
974         uint32_t value;
975         uint32_t pix_dur;
976         if (pix_clk_khz != 0) {
977                 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
978                 value = dm_read_reg(mi->ctx, addr);
979                 pix_dur = 1000000000ULL / pix_clk_khz;
980                 set_reg_field_value(
981                         value,
982                         pix_dur,
983                         DPGV0_PIPE_ARBITRATION_CONTROL1,
984                         PIXEL_DURATION);
985                 dm_write_reg(mi->ctx, addr, value);
986
987                 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
988                 value = dm_read_reg(mi->ctx, addr);
989                 pix_dur = 1000000000ULL / pix_clk_khz;
990                 set_reg_field_value(
991                         value,
992                         pix_dur,
993                         DPGV1_PIPE_ARBITRATION_CONTROL1,
994                         PIXEL_DURATION);
995                 dm_write_reg(mi->ctx, addr, value);
996
997                 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
998                 value = 0x4000800;
999                 dm_write_reg(mi->ctx, addr, value);
1000
1001                 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1002                 value = 0x4000800;
1003                 dm_write_reg(mi->ctx, addr, value);
1004         }
1005
1006 }
1007
1008 void dce110_free_mem_input_v(
1009         struct mem_input *mi,
1010         uint32_t total_stream_num)
1011 {
1012 }
1013
1014 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1015         .mem_input_program_display_marks =
1016                         dce_mem_input_v_program_display_marks,
1017         .mem_input_program_chroma_display_marks =
1018                         dce_mem_input_program_chroma_display_marks,
1019         .allocate_mem_input = dce110_allocate_mem_input_v,
1020         .free_mem_input = dce110_free_mem_input_v,
1021         .mem_input_program_surface_flip_and_addr =
1022                         dce_mem_input_v_program_surface_flip_and_addr,
1023         .mem_input_program_pte_vm =
1024                         dce_mem_input_v_program_pte_vm,
1025         .mem_input_program_surface_config =
1026                         dce_mem_input_v_program_surface_config,
1027         .mem_input_is_flip_pending =
1028                         dce_mem_input_v_is_surface_pending
1029 };
1030 /*****************************************/
1031 /* Constructor, Destructor               */
1032 /*****************************************/
1033
1034 void dce110_mem_input_v_construct(
1035         struct dce_mem_input *dce_mi,
1036         struct dc_context *ctx)
1037 {
1038         dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1039         dce_mi->base.ctx = ctx;
1040 }
1041