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