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 #include "dce110_mem_input_v.h"
38
set_flip_control(struct dce_mem_input * mem_input110,bool immediate)39 static void set_flip_control(
40 struct dce_mem_input *mem_input110,
41 bool immediate)
42 {
43 uint32_t value = 0;
44
45 value = dm_read_reg(
46 mem_input110->base.ctx,
47 mmUNP_FLIP_CONTROL);
48
49 set_reg_field_value(value, 1,
50 UNP_FLIP_CONTROL,
51 GRPH_SURFACE_UPDATE_PENDING_MODE);
52
53 dm_write_reg(
54 mem_input110->base.ctx,
55 mmUNP_FLIP_CONTROL,
56 value);
57 }
58
59 /* chroma part */
program_pri_addr_c(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)60 static void program_pri_addr_c(
61 struct dce_mem_input *mem_input110,
62 PHYSICAL_ADDRESS_LOC address)
63 {
64 uint32_t value = 0;
65 uint32_t temp = 0;
66 /*high register MUST be programmed first*/
67 temp = address.high_part &
68 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
69
70 set_reg_field_value(value, temp,
71 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
72 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
73
74 dm_write_reg(
75 mem_input110->base.ctx,
76 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
77 value);
78
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 */
program_pri_addr_l(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)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 value = 0;
115 temp = address.low_part >>
116 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
117
118 set_reg_field_value(value, temp,
119 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
120 GRPH_PRIMARY_SURFACE_ADDRESS_L);
121
122 dm_write_reg(
123 mem_input110->base.ctx,
124 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
125 value);
126 }
127
program_addr(struct dce_mem_input * mem_input110,const struct dc_plane_address * addr)128 static void program_addr(
129 struct dce_mem_input *mem_input110,
130 const struct dc_plane_address *addr)
131 {
132 switch (addr->type) {
133 case PLN_ADDR_TYPE_GRAPHICS:
134 program_pri_addr_l(
135 mem_input110,
136 addr->grph.addr);
137 break;
138 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
139 program_pri_addr_c(
140 mem_input110,
141 addr->video_progressive.chroma_addr);
142 program_pri_addr_l(
143 mem_input110,
144 addr->video_progressive.luma_addr);
145 break;
146 default:
147 /* not supported */
148 BREAK_TO_DEBUGGER();
149 }
150 }
151
enable(struct dce_mem_input * mem_input110)152 static void enable(struct dce_mem_input *mem_input110)
153 {
154 uint32_t value = 0;
155
156 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
157 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
158 dm_write_reg(mem_input110->base.ctx,
159 mmUNP_GRPH_ENABLE,
160 value);
161 }
162
program_tiling(struct dce_mem_input * mem_input110,const struct dc_tiling_info * info,const enum surface_pixel_format pixel_format)163 static void program_tiling(
164 struct dce_mem_input *mem_input110,
165 const struct dc_tiling_info *info,
166 const enum surface_pixel_format pixel_format)
167 {
168 uint32_t value = 0;
169
170 set_reg_field_value(value, info->gfx8.num_banks,
171 UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
172
173 set_reg_field_value(value, info->gfx8.bank_width,
174 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
175
176 set_reg_field_value(value, info->gfx8.bank_height,
177 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
178
179 set_reg_field_value(value, info->gfx8.tile_aspect,
180 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
181
182 set_reg_field_value(value, info->gfx8.tile_split,
183 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
184
185 set_reg_field_value(value, info->gfx8.tile_mode,
186 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
187
188 set_reg_field_value(value, info->gfx8.pipe_config,
189 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
190
191 set_reg_field_value(value, info->gfx8.array_mode,
192 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
193
194 set_reg_field_value(value, 1,
195 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
196
197 set_reg_field_value(value, 0,
198 UNP_GRPH_CONTROL, GRPH_Z);
199
200 dm_write_reg(
201 mem_input110->base.ctx,
202 mmUNP_GRPH_CONTROL,
203 value);
204
205 value = 0;
206
207 set_reg_field_value(value, info->gfx8.bank_width_c,
208 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
209
210 set_reg_field_value(value, info->gfx8.bank_height_c,
211 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
212
213 set_reg_field_value(value, info->gfx8.tile_aspect_c,
214 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
215
216 set_reg_field_value(value, info->gfx8.tile_split_c,
217 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
218
219 set_reg_field_value(value, info->gfx8.tile_mode_c,
220 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
221
222 dm_write_reg(
223 mem_input110->base.ctx,
224 mmUNP_GRPH_CONTROL_C,
225 value);
226 }
227
program_size_and_rotation(struct dce_mem_input * mem_input110,enum dc_rotation_angle rotation,const struct plane_size * plane_size)228 static void program_size_and_rotation(
229 struct dce_mem_input *mem_input110,
230 enum dc_rotation_angle rotation,
231 const struct plane_size *plane_size)
232 {
233 uint32_t value = 0;
234 struct plane_size local_size = *plane_size;
235
236 if (rotation == ROTATION_ANGLE_90 ||
237 rotation == ROTATION_ANGLE_270) {
238
239 swap(local_size.surface_size.x,
240 local_size.surface_size.y);
241 swap(local_size.surface_size.width,
242 local_size.surface_size.height);
243 swap(local_size.chroma_size.x,
244 local_size.chroma_size.y);
245 swap(local_size.chroma_size.width,
246 local_size.chroma_size.height);
247 }
248
249 value = 0;
250 set_reg_field_value(value, local_size.surface_pitch,
251 UNP_GRPH_PITCH_L, GRPH_PITCH_L);
252
253 dm_write_reg(
254 mem_input110->base.ctx,
255 mmUNP_GRPH_PITCH_L,
256 value);
257
258 value = 0;
259 set_reg_field_value(value, local_size.chroma_pitch,
260 UNP_GRPH_PITCH_C, GRPH_PITCH_C);
261 dm_write_reg(
262 mem_input110->base.ctx,
263 mmUNP_GRPH_PITCH_C,
264 value);
265
266 value = 0;
267 set_reg_field_value(value, 0,
268 UNP_GRPH_X_START_L, GRPH_X_START_L);
269 dm_write_reg(
270 mem_input110->base.ctx,
271 mmUNP_GRPH_X_START_L,
272 value);
273
274 value = 0;
275 set_reg_field_value(value, 0,
276 UNP_GRPH_X_START_C, GRPH_X_START_C);
277 dm_write_reg(
278 mem_input110->base.ctx,
279 mmUNP_GRPH_X_START_C,
280 value);
281
282 value = 0;
283 set_reg_field_value(value, 0,
284 UNP_GRPH_Y_START_L, GRPH_Y_START_L);
285 dm_write_reg(
286 mem_input110->base.ctx,
287 mmUNP_GRPH_Y_START_L,
288 value);
289
290 value = 0;
291 set_reg_field_value(value, 0,
292 UNP_GRPH_Y_START_C, GRPH_Y_START_C);
293 dm_write_reg(
294 mem_input110->base.ctx,
295 mmUNP_GRPH_Y_START_C,
296 value);
297
298 value = 0;
299 set_reg_field_value(value, local_size.surface_size.x +
300 local_size.surface_size.width,
301 UNP_GRPH_X_END_L, GRPH_X_END_L);
302 dm_write_reg(
303 mem_input110->base.ctx,
304 mmUNP_GRPH_X_END_L,
305 value);
306
307 value = 0;
308 set_reg_field_value(value, local_size.chroma_size.x +
309 local_size.chroma_size.width,
310 UNP_GRPH_X_END_C, GRPH_X_END_C);
311 dm_write_reg(
312 mem_input110->base.ctx,
313 mmUNP_GRPH_X_END_C,
314 value);
315
316 value = 0;
317 set_reg_field_value(value, local_size.surface_size.y +
318 local_size.surface_size.height,
319 UNP_GRPH_Y_END_L, GRPH_Y_END_L);
320 dm_write_reg(
321 mem_input110->base.ctx,
322 mmUNP_GRPH_Y_END_L,
323 value);
324
325 value = 0;
326 set_reg_field_value(value, local_size.chroma_size.y +
327 local_size.chroma_size.height,
328 UNP_GRPH_Y_END_C, GRPH_Y_END_C);
329 dm_write_reg(
330 mem_input110->base.ctx,
331 mmUNP_GRPH_Y_END_C,
332 value);
333
334 value = 0;
335 switch (rotation) {
336 case ROTATION_ANGLE_90:
337 set_reg_field_value(value, 3,
338 UNP_HW_ROTATION, ROTATION_ANGLE);
339 break;
340 case ROTATION_ANGLE_180:
341 set_reg_field_value(value, 2,
342 UNP_HW_ROTATION, ROTATION_ANGLE);
343 break;
344 case ROTATION_ANGLE_270:
345 set_reg_field_value(value, 1,
346 UNP_HW_ROTATION, ROTATION_ANGLE);
347 break;
348 default:
349 set_reg_field_value(value, 0,
350 UNP_HW_ROTATION, ROTATION_ANGLE);
351 break;
352 }
353
354 dm_write_reg(
355 mem_input110->base.ctx,
356 mmUNP_HW_ROTATION,
357 value);
358 }
359
program_pixel_format(struct dce_mem_input * mem_input110,enum surface_pixel_format format)360 static void program_pixel_format(
361 struct dce_mem_input *mem_input110,
362 enum surface_pixel_format format)
363 {
364 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
365 uint32_t value;
366 uint8_t grph_depth;
367 uint8_t grph_format;
368
369 value = dm_read_reg(
370 mem_input110->base.ctx,
371 mmUNP_GRPH_CONTROL);
372
373 switch (format) {
374 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
375 grph_depth = 0;
376 grph_format = 0;
377 break;
378 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
379 grph_depth = 1;
380 grph_format = 1;
381 break;
382 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
383 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
384 grph_depth = 2;
385 grph_format = 0;
386 break;
387 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
388 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
389 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
390 grph_depth = 2;
391 grph_format = 1;
392 break;
393 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
394 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
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
dce_mem_input_v_is_surface_pending(struct mem_input * mem_input)471 static 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
dce_mem_input_v_program_surface_flip_and_addr(struct mem_input * mem_input,const struct dc_plane_address * address,bool flip_immediate)486 static 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 */
get_dvmm_hw_setting(struct dc_tiling_info * tiling_info,enum surface_pixel_format format,bool chroma)525 static const unsigned int *get_dvmm_hw_setting(
526 struct 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
dce_mem_input_v_program_pte_vm(struct mem_input * mem_input,enum surface_pixel_format format,struct dc_tiling_info * tiling_info,enum dc_rotation_angle rotation)563 static void dce_mem_input_v_program_pte_vm(
564 struct mem_input *mem_input,
565 enum surface_pixel_format format,
566 struct 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
dce_mem_input_v_program_surface_config(struct mem_input * mem_input,enum surface_pixel_format format,struct dc_tiling_info * tiling_info,struct plane_size * plane_size,enum dc_rotation_angle rotation,struct dc_plane_dcc_param * dcc,bool horizotal_mirror)636 static void dce_mem_input_v_program_surface_config(
637 struct mem_input *mem_input,
638 enum surface_pixel_format format,
639 struct dc_tiling_info *tiling_info,
640 struct 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
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)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
program_urgency_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks_low,uint32_t total_dest_line_time_ns)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
program_urgency_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks_low,uint32_t total_dest_line_time_ns)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
program_stutter_watermark(const struct dc_context * ctx,const uint32_t stutter_addr,const uint32_t wm_addr,struct dce_watermarks marks)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
program_stutter_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks)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
program_stutter_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks)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
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)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
program_nbp_watermark_l(const struct dc_context * ctx,struct dce_watermarks marks)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
program_nbp_watermark_c(const struct dc_context * ctx,struct dce_watermarks marks)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
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)922 static 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
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)945 static 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
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)966 static 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
dce110_free_mem_input_v(struct mem_input * mi,uint32_t total_stream_num)1008 static 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
dce110_mem_input_v_construct(struct dce_mem_input * dce_mi,struct dc_context * ctx)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
1042