1 /* $NetBSD: amdgpu_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $ */
2
3 /*
4 * Copyright 2012-16 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: AMD
25 *
26 */
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dce110_mem_input_v.c,v 1.4 2021/12/19 10:59:37 riastradh Exp $");
29
30 #include "dm_services.h"
31
32 #include "dce/dce_11_0_d.h"
33 #include "dce/dce_11_0_sh_mask.h"
34 /* TODO: this needs to be looked at, used by Stella's workaround*/
35 #include "gmc/gmc_8_2_d.h"
36 #include "gmc/gmc_8_2_sh_mask.h"
37
38 #include "include/logger_interface.h"
39 #include "inc/dce_calcs.h"
40
41 #include "dce/dce_mem_input.h"
42 #include "dce110/dce110_mem_input_v.h"
43
set_flip_control(struct dce_mem_input * mem_input110,bool immediate)44 static void set_flip_control(
45 struct dce_mem_input *mem_input110,
46 bool immediate)
47 {
48 uint32_t value = 0;
49
50 value = dm_read_reg(
51 mem_input110->base.ctx,
52 mmUNP_FLIP_CONTROL);
53
54 set_reg_field_value(value, 1,
55 UNP_FLIP_CONTROL,
56 GRPH_SURFACE_UPDATE_PENDING_MODE);
57
58 dm_write_reg(
59 mem_input110->base.ctx,
60 mmUNP_FLIP_CONTROL,
61 value);
62 }
63
64 /* chroma part */
program_pri_addr_c(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)65 static void program_pri_addr_c(
66 struct dce_mem_input *mem_input110,
67 PHYSICAL_ADDRESS_LOC address)
68 {
69 uint32_t value = 0;
70 uint32_t temp = 0;
71 /*high register MUST be programmed first*/
72 temp = address.high_part &
73 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C_MASK;
74
75 set_reg_field_value(value, temp,
76 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
77 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C);
78
79 dm_write_reg(
80 mem_input110->base.ctx,
81 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C,
82 value);
83
84 temp = 0;
85 value = 0;
86 temp = address.low_part >>
87 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT;
88
89 set_reg_field_value(value, temp,
90 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
91 GRPH_PRIMARY_SURFACE_ADDRESS_C);
92
93 dm_write_reg(
94 mem_input110->base.ctx,
95 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C,
96 value);
97 }
98
99 /* luma part */
program_pri_addr_l(struct dce_mem_input * mem_input110,PHYSICAL_ADDRESS_LOC address)100 static void program_pri_addr_l(
101 struct dce_mem_input *mem_input110,
102 PHYSICAL_ADDRESS_LOC address)
103 {
104 uint32_t value = 0;
105 uint32_t temp = 0;
106
107 /*high register MUST be programmed first*/
108 temp = address.high_part &
109 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L_MASK;
110
111 set_reg_field_value(value, temp,
112 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
113 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L);
114
115 dm_write_reg(
116 mem_input110->base.ctx,
117 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L,
118 value);
119
120 temp = 0;
121 value = 0;
122 temp = address.low_part >>
123 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT;
124
125 set_reg_field_value(value, temp,
126 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
127 GRPH_PRIMARY_SURFACE_ADDRESS_L);
128
129 dm_write_reg(
130 mem_input110->base.ctx,
131 mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L,
132 value);
133 }
134
program_addr(struct dce_mem_input * mem_input110,const struct dc_plane_address * addr)135 static void program_addr(
136 struct dce_mem_input *mem_input110,
137 const struct dc_plane_address *addr)
138 {
139 switch (addr->type) {
140 case PLN_ADDR_TYPE_GRAPHICS:
141 program_pri_addr_l(
142 mem_input110,
143 addr->grph.addr);
144 break;
145 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
146 program_pri_addr_c(
147 mem_input110,
148 addr->video_progressive.chroma_addr);
149 program_pri_addr_l(
150 mem_input110,
151 addr->video_progressive.luma_addr);
152 break;
153 default:
154 /* not supported */
155 BREAK_TO_DEBUGGER();
156 }
157 }
158
enable(struct dce_mem_input * mem_input110)159 static void enable(struct dce_mem_input *mem_input110)
160 {
161 uint32_t value = 0;
162
163 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_ENABLE);
164 set_reg_field_value(value, 1, UNP_GRPH_ENABLE, GRPH_ENABLE);
165 dm_write_reg(mem_input110->base.ctx,
166 mmUNP_GRPH_ENABLE,
167 value);
168 }
169
program_tiling(struct dce_mem_input * mem_input110,const union dc_tiling_info * info,const enum surface_pixel_format pixel_format)170 static void program_tiling(
171 struct dce_mem_input *mem_input110,
172 const union dc_tiling_info *info,
173 const enum surface_pixel_format pixel_format)
174 {
175 uint32_t value = 0;
176
177 set_reg_field_value(value, info->gfx8.num_banks,
178 UNP_GRPH_CONTROL, GRPH_NUM_BANKS);
179
180 set_reg_field_value(value, info->gfx8.bank_width,
181 UNP_GRPH_CONTROL, GRPH_BANK_WIDTH_L);
182
183 set_reg_field_value(value, info->gfx8.bank_height,
184 UNP_GRPH_CONTROL, GRPH_BANK_HEIGHT_L);
185
186 set_reg_field_value(value, info->gfx8.tile_aspect,
187 UNP_GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT_L);
188
189 set_reg_field_value(value, info->gfx8.tile_split,
190 UNP_GRPH_CONTROL, GRPH_TILE_SPLIT_L);
191
192 set_reg_field_value(value, info->gfx8.tile_mode,
193 UNP_GRPH_CONTROL, GRPH_MICRO_TILE_MODE_L);
194
195 set_reg_field_value(value, info->gfx8.pipe_config,
196 UNP_GRPH_CONTROL, GRPH_PIPE_CONFIG);
197
198 set_reg_field_value(value, info->gfx8.array_mode,
199 UNP_GRPH_CONTROL, GRPH_ARRAY_MODE);
200
201 set_reg_field_value(value, 1,
202 UNP_GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
203
204 set_reg_field_value(value, 0,
205 UNP_GRPH_CONTROL, GRPH_Z);
206
207 dm_write_reg(
208 mem_input110->base.ctx,
209 mmUNP_GRPH_CONTROL,
210 value);
211
212 value = 0;
213
214 set_reg_field_value(value, info->gfx8.bank_width_c,
215 UNP_GRPH_CONTROL_C, GRPH_BANK_WIDTH_C);
216
217 set_reg_field_value(value, info->gfx8.bank_height_c,
218 UNP_GRPH_CONTROL_C, GRPH_BANK_HEIGHT_C);
219
220 set_reg_field_value(value, info->gfx8.tile_aspect_c,
221 UNP_GRPH_CONTROL_C, GRPH_MACRO_TILE_ASPECT_C);
222
223 set_reg_field_value(value, info->gfx8.tile_split_c,
224 UNP_GRPH_CONTROL_C, GRPH_TILE_SPLIT_C);
225
226 set_reg_field_value(value, info->gfx8.tile_mode_c,
227 UNP_GRPH_CONTROL_C, GRPH_MICRO_TILE_MODE_C);
228
229 dm_write_reg(
230 mem_input110->base.ctx,
231 mmUNP_GRPH_CONTROL_C,
232 value);
233 }
234
program_size_and_rotation(struct dce_mem_input * mem_input110,enum dc_rotation_angle rotation,const struct plane_size * plane_size)235 static void program_size_and_rotation(
236 struct dce_mem_input *mem_input110,
237 enum dc_rotation_angle rotation,
238 const struct plane_size *plane_size)
239 {
240 uint32_t value = 0;
241 struct plane_size local_size = *plane_size;
242
243 if (rotation == ROTATION_ANGLE_90 ||
244 rotation == ROTATION_ANGLE_270) {
245
246 swap(local_size.surface_size.x,
247 local_size.surface_size.y);
248 swap(local_size.surface_size.width,
249 local_size.surface_size.height);
250 swap(local_size.chroma_size.x,
251 local_size.chroma_size.y);
252 swap(local_size.chroma_size.width,
253 local_size.chroma_size.height);
254 }
255
256 value = 0;
257 set_reg_field_value(value, local_size.surface_pitch,
258 UNP_GRPH_PITCH_L, GRPH_PITCH_L);
259
260 dm_write_reg(
261 mem_input110->base.ctx,
262 mmUNP_GRPH_PITCH_L,
263 value);
264
265 value = 0;
266 set_reg_field_value(value, local_size.chroma_pitch,
267 UNP_GRPH_PITCH_C, GRPH_PITCH_C);
268 dm_write_reg(
269 mem_input110->base.ctx,
270 mmUNP_GRPH_PITCH_C,
271 value);
272
273 value = 0;
274 set_reg_field_value(value, 0,
275 UNP_GRPH_X_START_L, GRPH_X_START_L);
276 dm_write_reg(
277 mem_input110->base.ctx,
278 mmUNP_GRPH_X_START_L,
279 value);
280
281 value = 0;
282 set_reg_field_value(value, 0,
283 UNP_GRPH_X_START_C, GRPH_X_START_C);
284 dm_write_reg(
285 mem_input110->base.ctx,
286 mmUNP_GRPH_X_START_C,
287 value);
288
289 value = 0;
290 set_reg_field_value(value, 0,
291 UNP_GRPH_Y_START_L, GRPH_Y_START_L);
292 dm_write_reg(
293 mem_input110->base.ctx,
294 mmUNP_GRPH_Y_START_L,
295 value);
296
297 value = 0;
298 set_reg_field_value(value, 0,
299 UNP_GRPH_Y_START_C, GRPH_Y_START_C);
300 dm_write_reg(
301 mem_input110->base.ctx,
302 mmUNP_GRPH_Y_START_C,
303 value);
304
305 value = 0;
306 set_reg_field_value(value, local_size.surface_size.x +
307 local_size.surface_size.width,
308 UNP_GRPH_X_END_L, GRPH_X_END_L);
309 dm_write_reg(
310 mem_input110->base.ctx,
311 mmUNP_GRPH_X_END_L,
312 value);
313
314 value = 0;
315 set_reg_field_value(value, local_size.chroma_size.x +
316 local_size.chroma_size.width,
317 UNP_GRPH_X_END_C, GRPH_X_END_C);
318 dm_write_reg(
319 mem_input110->base.ctx,
320 mmUNP_GRPH_X_END_C,
321 value);
322
323 value = 0;
324 set_reg_field_value(value, local_size.surface_size.y +
325 local_size.surface_size.height,
326 UNP_GRPH_Y_END_L, GRPH_Y_END_L);
327 dm_write_reg(
328 mem_input110->base.ctx,
329 mmUNP_GRPH_Y_END_L,
330 value);
331
332 value = 0;
333 set_reg_field_value(value, local_size.chroma_size.y +
334 local_size.chroma_size.height,
335 UNP_GRPH_Y_END_C, GRPH_Y_END_C);
336 dm_write_reg(
337 mem_input110->base.ctx,
338 mmUNP_GRPH_Y_END_C,
339 value);
340
341 value = 0;
342 switch (rotation) {
343 case ROTATION_ANGLE_90:
344 set_reg_field_value(value, 3,
345 UNP_HW_ROTATION, ROTATION_ANGLE);
346 break;
347 case ROTATION_ANGLE_180:
348 set_reg_field_value(value, 2,
349 UNP_HW_ROTATION, ROTATION_ANGLE);
350 break;
351 case ROTATION_ANGLE_270:
352 set_reg_field_value(value, 1,
353 UNP_HW_ROTATION, ROTATION_ANGLE);
354 break;
355 default:
356 set_reg_field_value(value, 0,
357 UNP_HW_ROTATION, ROTATION_ANGLE);
358 break;
359 }
360
361 dm_write_reg(
362 mem_input110->base.ctx,
363 mmUNP_HW_ROTATION,
364 value);
365 }
366
program_pixel_format(struct dce_mem_input * mem_input110,enum surface_pixel_format format)367 static void program_pixel_format(
368 struct dce_mem_input *mem_input110,
369 enum surface_pixel_format format)
370 {
371 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
372 uint32_t value;
373 uint8_t grph_depth;
374 uint8_t grph_format;
375
376 value = dm_read_reg(
377 mem_input110->base.ctx,
378 mmUNP_GRPH_CONTROL);
379
380 switch (format) {
381 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
382 grph_depth = 0;
383 grph_format = 0;
384 break;
385 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
386 grph_depth = 1;
387 grph_format = 1;
388 break;
389 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
390 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
391 grph_depth = 2;
392 grph_format = 0;
393 break;
394 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
395 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
396 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
397 grph_depth = 2;
398 grph_format = 1;
399 break;
400 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
401 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
402 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
403 grph_depth = 3;
404 grph_format = 0;
405 break;
406 default:
407 grph_depth = 2;
408 grph_format = 0;
409 break;
410 }
411
412 set_reg_field_value(
413 value,
414 grph_depth,
415 UNP_GRPH_CONTROL,
416 GRPH_DEPTH);
417 set_reg_field_value(
418 value,
419 grph_format,
420 UNP_GRPH_CONTROL,
421 GRPH_FORMAT);
422
423 dm_write_reg(
424 mem_input110->base.ctx,
425 mmUNP_GRPH_CONTROL,
426 value);
427
428 value = dm_read_reg(
429 mem_input110->base.ctx,
430 mmUNP_GRPH_CONTROL_EXP);
431
432 /* VIDEO FORMAT 0 */
433 set_reg_field_value(
434 value,
435 0,
436 UNP_GRPH_CONTROL_EXP,
437 VIDEO_FORMAT);
438 dm_write_reg(
439 mem_input110->base.ctx,
440 mmUNP_GRPH_CONTROL_EXP,
441 value);
442
443 } else {
444 /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
445 uint32_t value;
446 uint8_t video_format;
447
448 value = dm_read_reg(
449 mem_input110->base.ctx,
450 mmUNP_GRPH_CONTROL_EXP);
451
452 switch (format) {
453 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
454 video_format = 2;
455 break;
456 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
457 video_format = 3;
458 break;
459 default:
460 video_format = 0;
461 break;
462 }
463
464 set_reg_field_value(
465 value,
466 video_format,
467 UNP_GRPH_CONTROL_EXP,
468 VIDEO_FORMAT);
469
470 dm_write_reg(
471 mem_input110->base.ctx,
472 mmUNP_GRPH_CONTROL_EXP,
473 value);
474 }
475 }
476
dce_mem_input_v_is_surface_pending(struct mem_input * mem_input)477 bool dce_mem_input_v_is_surface_pending(struct mem_input *mem_input)
478 {
479 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
480 uint32_t value;
481
482 value = dm_read_reg(mem_input110->base.ctx, mmUNP_GRPH_UPDATE);
483
484 if (get_reg_field_value(value, UNP_GRPH_UPDATE,
485 GRPH_SURFACE_UPDATE_PENDING))
486 return true;
487
488 mem_input->current_address = mem_input->request_address;
489 return false;
490 }
491
dce_mem_input_v_program_surface_flip_and_addr(struct mem_input * mem_input,const struct dc_plane_address * address,bool flip_immediate)492 bool dce_mem_input_v_program_surface_flip_and_addr(
493 struct mem_input *mem_input,
494 const struct dc_plane_address *address,
495 bool flip_immediate)
496 {
497 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
498
499 set_flip_control(mem_input110, flip_immediate);
500 program_addr(mem_input110,
501 address);
502
503 mem_input->request_address = *address;
504
505 return true;
506 }
507
508 /* Scatter Gather param tables */
509 static const unsigned int dvmm_Hw_Setting_2DTiling[4][9] = {
510 { 8, 64, 64, 8, 8, 1, 4, 0, 0},
511 { 16, 64, 32, 8, 16, 1, 8, 0, 0},
512 { 32, 32, 32, 16, 16, 1, 8, 0, 0},
513 { 64, 8, 32, 16, 16, 1, 8, 0, 0}, /* fake */
514 };
515
516 static const unsigned int dvmm_Hw_Setting_1DTiling[4][9] = {
517 { 8, 512, 8, 1, 0, 1, 0, 0, 0}, /* 0 for invalid */
518 { 16, 256, 8, 2, 0, 1, 0, 0, 0},
519 { 32, 128, 8, 4, 0, 1, 0, 0, 0},
520 { 64, 64, 8, 4, 0, 1, 0, 0, 0}, /* fake */
521 };
522
523 static const unsigned int dvmm_Hw_Setting_Linear[4][9] = {
524 { 8, 4096, 1, 8, 0, 1, 0, 0, 0},
525 { 16, 2048, 1, 8, 0, 1, 0, 0, 0},
526 { 32, 1024, 1, 8, 0, 1, 0, 0, 0},
527 { 64, 512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */
528 };
529
530 /* 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)531 static const unsigned int *get_dvmm_hw_setting(
532 union dc_tiling_info *tiling_info,
533 enum surface_pixel_format format,
534 bool chroma)
535 {
536 enum bits_per_pixel {
537 bpp_8 = 0,
538 bpp_16,
539 bpp_32,
540 bpp_64
541 } bpp;
542
543 if (format >= SURFACE_PIXEL_FORMAT_INVALID)
544 bpp = bpp_32;
545 else if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
546 bpp = chroma ? bpp_16 : bpp_8;
547 else
548 bpp = bpp_8;
549
550 switch (tiling_info->gfx8.array_mode) {
551 case DC_ARRAY_1D_TILED_THIN1:
552 case DC_ARRAY_1D_TILED_THICK:
553 case DC_ARRAY_PRT_TILED_THIN1:
554 return dvmm_Hw_Setting_1DTiling[bpp];
555 case DC_ARRAY_2D_TILED_THIN1:
556 case DC_ARRAY_2D_TILED_THICK:
557 case DC_ARRAY_2D_TILED_X_THICK:
558 case DC_ARRAY_PRT_2D_TILED_THIN1:
559 case DC_ARRAY_PRT_2D_TILED_THICK:
560 return dvmm_Hw_Setting_2DTiling[bpp];
561 case DC_ARRAY_LINEAR_GENERAL:
562 case DC_ARRAY_LINEAR_ALLIGNED:
563 return dvmm_Hw_Setting_Linear[bpp];
564 default:
565 return dvmm_Hw_Setting_2DTiling[bpp];
566 }
567 }
568
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)569 void dce_mem_input_v_program_pte_vm(
570 struct mem_input *mem_input,
571 enum surface_pixel_format format,
572 union dc_tiling_info *tiling_info,
573 enum dc_rotation_angle rotation)
574 {
575 struct dce_mem_input *mem_input110 = TO_DCE_MEM_INPUT(mem_input);
576 const unsigned int *pte = get_dvmm_hw_setting(tiling_info, format, false);
577 const unsigned int *pte_chroma = get_dvmm_hw_setting(tiling_info, format, true);
578
579 unsigned int page_width = 0;
580 unsigned int page_height = 0;
581 unsigned int page_width_chroma = 0;
582 unsigned int page_height_chroma = 0;
583 unsigned int temp_page_width = pte[1];
584 unsigned int temp_page_height = pte[2];
585 unsigned int min_pte_before_flip = 0;
586 unsigned int min_pte_before_flip_chroma = 0;
587 uint32_t value = 0;
588
589 while ((temp_page_width >>= 1) != 0)
590 page_width++;
591 while ((temp_page_height >>= 1) != 0)
592 page_height++;
593
594 temp_page_width = pte_chroma[1];
595 temp_page_height = pte_chroma[2];
596 while ((temp_page_width >>= 1) != 0)
597 page_width_chroma++;
598 while ((temp_page_height >>= 1) != 0)
599 page_height_chroma++;
600
601 switch (rotation) {
602 case ROTATION_ANGLE_90:
603 case ROTATION_ANGLE_270:
604 min_pte_before_flip = pte[4];
605 min_pte_before_flip_chroma = pte_chroma[4];
606 break;
607 default:
608 min_pte_before_flip = pte[3];
609 min_pte_before_flip_chroma = pte_chroma[3];
610 break;
611 }
612
613 value = dm_read_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT);
614 /* TODO: un-hardcode requestlimit */
615 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_L);
616 set_reg_field_value(value, 0xff, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT, UNP_PIPE_OUTSTANDING_REQUEST_LIMIT_C);
617 dm_write_reg(mem_input110->base.ctx, mmUNP_PIPE_OUTSTANDING_REQUEST_LIMIT, value);
618
619 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL);
620 set_reg_field_value(value, page_width, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_WIDTH);
621 set_reg_field_value(value, page_height, UNP_DVMM_PTE_CONTROL, DVMM_PAGE_HEIGHT);
622 set_reg_field_value(value, min_pte_before_flip, UNP_DVMM_PTE_CONTROL, DVMM_MIN_PTE_BEFORE_FLIP);
623 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL, value);
624
625 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL);
626 set_reg_field_value(value, pte[5], UNP_DVMM_PTE_ARB_CONTROL, DVMM_PTE_REQ_PER_CHUNK);
627 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL, DVMM_MAX_PTE_REQ_OUTSTANDING);
628 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL, value);
629
630 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C);
631 set_reg_field_value(value, page_width_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_WIDTH_C);
632 set_reg_field_value(value, page_height_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_PAGE_HEIGHT_C);
633 set_reg_field_value(value, min_pte_before_flip_chroma, UNP_DVMM_PTE_CONTROL_C, DVMM_MIN_PTE_BEFORE_FLIP_C);
634 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_CONTROL_C, value);
635
636 value = dm_read_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C);
637 set_reg_field_value(value, pte_chroma[5], UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_PTE_REQ_PER_CHUNK_C);
638 set_reg_field_value(value, 0xff, UNP_DVMM_PTE_ARB_CONTROL_C, DVMM_MAX_PTE_REQ_OUTSTANDING_C);
639 dm_write_reg(mem_input110->base.ctx, mmUNP_DVMM_PTE_ARB_CONTROL_C, value);
640 }
641
dce_mem_input_v_program_surface_config(struct mem_input * mem_input,enum surface_pixel_format format,union dc_tiling_info * tiling_info,struct 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 struct 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
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)928 void dce_mem_input_v_program_display_marks(
929 struct mem_input *mem_input,
930 struct dce_watermarks nbp,
931 struct dce_watermarks stutter,
932 struct dce_watermarks stutter_enter,
933 struct dce_watermarks urgent,
934 uint32_t total_dest_line_time_ns)
935 {
936 program_urgency_watermark_l(
937 mem_input->ctx,
938 urgent,
939 total_dest_line_time_ns);
940
941 program_nbp_watermark_l(
942 mem_input->ctx,
943 nbp);
944
945 program_stutter_watermark_l(
946 mem_input->ctx,
947 stutter);
948
949 }
950
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)951 void dce_mem_input_program_chroma_display_marks(
952 struct mem_input *mem_input,
953 struct dce_watermarks nbp,
954 struct dce_watermarks stutter,
955 struct dce_watermarks urgent,
956 uint32_t total_dest_line_time_ns)
957 {
958 program_urgency_watermark_c(
959 mem_input->ctx,
960 urgent,
961 total_dest_line_time_ns);
962
963 program_nbp_watermark_c(
964 mem_input->ctx,
965 nbp);
966
967 program_stutter_watermark_c(
968 mem_input->ctx,
969 stutter);
970 }
971
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)972 void dce110_allocate_mem_input_v(
973 struct mem_input *mi,
974 uint32_t h_total,/* for current stream */
975 uint32_t v_total,/* for current stream */
976 uint32_t pix_clk_khz,/* for current stream */
977 uint32_t total_stream_num)
978 {
979 uint32_t addr;
980 uint32_t value;
981 uint32_t pix_dur;
982 if (pix_clk_khz != 0) {
983 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL1;
984 value = dm_read_reg(mi->ctx, addr);
985 pix_dur = 1000000000ULL / pix_clk_khz;
986 set_reg_field_value(
987 value,
988 pix_dur,
989 DPGV0_PIPE_ARBITRATION_CONTROL1,
990 PIXEL_DURATION);
991 dm_write_reg(mi->ctx, addr, value);
992
993 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL1;
994 value = dm_read_reg(mi->ctx, addr);
995 pix_dur = 1000000000ULL / pix_clk_khz;
996 set_reg_field_value(
997 value,
998 pix_dur,
999 DPGV1_PIPE_ARBITRATION_CONTROL1,
1000 PIXEL_DURATION);
1001 dm_write_reg(mi->ctx, addr, value);
1002
1003 addr = mmDPGV0_PIPE_ARBITRATION_CONTROL2;
1004 value = 0x4000800;
1005 dm_write_reg(mi->ctx, addr, value);
1006
1007 addr = mmDPGV1_PIPE_ARBITRATION_CONTROL2;
1008 value = 0x4000800;
1009 dm_write_reg(mi->ctx, addr, value);
1010 }
1011
1012 }
1013
dce110_free_mem_input_v(struct mem_input * mi,uint32_t total_stream_num)1014 void dce110_free_mem_input_v(
1015 struct mem_input *mi,
1016 uint32_t total_stream_num)
1017 {
1018 }
1019
1020 static const struct mem_input_funcs dce110_mem_input_v_funcs = {
1021 .mem_input_program_display_marks =
1022 dce_mem_input_v_program_display_marks,
1023 .mem_input_program_chroma_display_marks =
1024 dce_mem_input_program_chroma_display_marks,
1025 .allocate_mem_input = dce110_allocate_mem_input_v,
1026 .free_mem_input = dce110_free_mem_input_v,
1027 .mem_input_program_surface_flip_and_addr =
1028 dce_mem_input_v_program_surface_flip_and_addr,
1029 .mem_input_program_pte_vm =
1030 dce_mem_input_v_program_pte_vm,
1031 .mem_input_program_surface_config =
1032 dce_mem_input_v_program_surface_config,
1033 .mem_input_is_flip_pending =
1034 dce_mem_input_v_is_surface_pending
1035 };
1036 /*****************************************/
1037 /* Constructor, Destructor */
1038 /*****************************************/
1039
dce110_mem_input_v_construct(struct dce_mem_input * dce_mi,struct dc_context * ctx)1040 void dce110_mem_input_v_construct(
1041 struct dce_mem_input *dce_mi,
1042 struct dc_context *ctx)
1043 {
1044 dce_mi->base.funcs = &dce110_mem_input_v_funcs;
1045 dce_mi->base.ctx = ctx;
1046 }
1047
1048