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