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