2 * Copyright 2012-16 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include "dm_services.h"
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"
33 #include "include/logger_interface.h"
34 #include "inc/bandwidth_calcs.h"
36 #include "dce110_mem_input.h"
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)*/
42 static const struct dce110_mem_input_reg_offsets dce110_mi_v_reg_offsets
[] = {
50 static void set_flip_control(
51 struct dce110_mem_input
*mem_input110
,
57 mem_input110
->base
.ctx
,
58 DCP_REG(mmUNP_FLIP_CONTROL
));
60 set_reg_field_value(value
, 1,
62 GRPH_SURFACE_UPDATE_PENDING_MODE
);
65 mem_input110
->base
.ctx
,
66 DCP_REG(mmUNP_FLIP_CONTROL
),
71 static void program_pri_addr_c(
72 struct dce110_mem_input
*mem_input110
,
73 PHYSICAL_ADDRESS_LOC address
)
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
;
81 set_reg_field_value(value
, temp
,
82 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C
,
83 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C
);
86 mem_input110
->base
.ctx
,
87 DCP_REG(mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_C
),
92 temp
= address
.low_part
>>
93 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C__GRPH_PRIMARY_SURFACE_ADDRESS_C__SHIFT
;
95 set_reg_field_value(value
, temp
,
96 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_C
,
97 GRPH_PRIMARY_SURFACE_ADDRESS_C
);
100 mem_input110
->base
.ctx
,
101 DCP_REG(mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_C
),
106 static void program_pri_addr_l(
107 struct dce110_mem_input
*mem_input110
,
108 PHYSICAL_ADDRESS_LOC address
)
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
;
117 set_reg_field_value(value
, temp
,
118 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L
,
119 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L
);
122 mem_input110
->base
.ctx
,
123 DCP_REG(mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_L
),
128 temp
= address
.low_part
>>
129 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L__GRPH_PRIMARY_SURFACE_ADDRESS_L__SHIFT
;
131 set_reg_field_value(value
, temp
,
132 UNP_GRPH_PRIMARY_SURFACE_ADDRESS_L
,
133 GRPH_PRIMARY_SURFACE_ADDRESS_L
);
136 mem_input110
->base
.ctx
,
137 DCP_REG(mmUNP_GRPH_PRIMARY_SURFACE_ADDRESS_L
),
141 static void program_addr(
142 struct dce110_mem_input
*mem_input110
,
143 const struct dc_plane_address
*addr
)
145 switch (addr
->type
) {
146 case PLN_ADDR_TYPE_GRAPHICS
:
151 case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE
:
154 addr
->video_progressive
.luma_addr
);
157 addr
->video_progressive
.chroma_addr
);
165 static void enable(struct dce110_mem_input
*mem_input110
)
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
),
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
)
183 set_reg_field_value(value
, info
->gfx8
.num_banks
,
184 UNP_GRPH_CONTROL
, GRPH_NUM_BANKS
);
186 set_reg_field_value(value
, info
->gfx8
.bank_width
,
187 UNP_GRPH_CONTROL
, GRPH_BANK_WIDTH_L
);
189 set_reg_field_value(value
, info
->gfx8
.bank_height
,
190 UNP_GRPH_CONTROL
, GRPH_BANK_HEIGHT_L
);
192 set_reg_field_value(value
, info
->gfx8
.tile_aspect
,
193 UNP_GRPH_CONTROL
, GRPH_MACRO_TILE_ASPECT_L
);
195 set_reg_field_value(value
, info
->gfx8
.tile_split
,
196 UNP_GRPH_CONTROL
, GRPH_TILE_SPLIT_L
);
198 set_reg_field_value(value
, info
->gfx8
.tile_mode
,
199 UNP_GRPH_CONTROL
, GRPH_MICRO_TILE_MODE_L
);
201 set_reg_field_value(value
, info
->gfx8
.pipe_config
,
202 UNP_GRPH_CONTROL
, GRPH_PIPE_CONFIG
);
204 set_reg_field_value(value
, info
->gfx8
.array_mode
,
205 UNP_GRPH_CONTROL
, GRPH_ARRAY_MODE
);
207 set_reg_field_value(value
, 1,
208 UNP_GRPH_CONTROL
, GRPH_COLOR_EXPANSION_MODE
);
210 set_reg_field_value(value
, 0,
211 UNP_GRPH_CONTROL
, GRPH_Z
);
214 mem_input110
->base
.ctx
,
220 set_reg_field_value(value
, info
->gfx8
.bank_width_c
,
221 UNP_GRPH_CONTROL_C
, GRPH_BANK_WIDTH_C
);
223 set_reg_field_value(value
, info
->gfx8
.bank_height_c
,
224 UNP_GRPH_CONTROL_C
, GRPH_BANK_HEIGHT_C
);
226 set_reg_field_value(value
, info
->gfx8
.tile_aspect_c
,
227 UNP_GRPH_CONTROL_C
, GRPH_MACRO_TILE_ASPECT_C
);
229 set_reg_field_value(value
, info
->gfx8
.tile_split_c
,
230 UNP_GRPH_CONTROL_C
, GRPH_TILE_SPLIT_C
);
232 set_reg_field_value(value
, info
->gfx8
.tile_mode_c
,
233 UNP_GRPH_CONTROL_C
, GRPH_MICRO_TILE_MODE_C
);
236 mem_input110
->base
.ctx
,
237 mmUNP_GRPH_CONTROL_C
,
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
)
247 union plane_size local_size
= *plane_size
;
249 if (rotation
== ROTATION_ANGLE_90
||
250 rotation
== ROTATION_ANGLE_270
) {
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
;
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
;
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
;
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
;
275 set_reg_field_value(value
, local_size
.video
.luma_pitch
,
276 UNP_GRPH_PITCH_L
, GRPH_PITCH_L
);
279 mem_input110
->base
.ctx
,
280 DCP_REG(mmUNP_GRPH_PITCH_L
),
284 set_reg_field_value(value
, local_size
.video
.chroma_pitch
,
285 UNP_GRPH_PITCH_C
, GRPH_PITCH_C
);
287 mem_input110
->base
.ctx
,
288 DCP_REG(mmUNP_GRPH_PITCH_C
),
292 set_reg_field_value(value
, 0,
293 UNP_GRPH_X_START_L
, GRPH_X_START_L
);
295 mem_input110
->base
.ctx
,
296 DCP_REG(mmUNP_GRPH_X_START_L
),
300 set_reg_field_value(value
, 0,
301 UNP_GRPH_X_START_C
, GRPH_X_START_C
);
303 mem_input110
->base
.ctx
,
304 DCP_REG(mmUNP_GRPH_X_START_C
),
308 set_reg_field_value(value
, 0,
309 UNP_GRPH_Y_START_L
, GRPH_Y_START_L
);
311 mem_input110
->base
.ctx
,
312 DCP_REG(mmUNP_GRPH_Y_START_L
),
316 set_reg_field_value(value
, 0,
317 UNP_GRPH_Y_START_C
, GRPH_Y_START_C
);
319 mem_input110
->base
.ctx
,
320 DCP_REG(mmUNP_GRPH_Y_START_C
),
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
);
328 mem_input110
->base
.ctx
,
329 DCP_REG(mmUNP_GRPH_X_END_L
),
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
);
337 mem_input110
->base
.ctx
,
338 DCP_REG(mmUNP_GRPH_X_END_C
),
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
);
346 mem_input110
->base
.ctx
,
347 DCP_REG(mmUNP_GRPH_Y_END_L
),
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
);
355 mem_input110
->base
.ctx
,
356 DCP_REG(mmUNP_GRPH_Y_END_C
),
361 case ROTATION_ANGLE_90
:
362 set_reg_field_value(value
, 3,
363 UNP_HW_ROTATION
, ROTATION_ANGLE
);
365 case ROTATION_ANGLE_180
:
366 set_reg_field_value(value
, 2,
367 UNP_HW_ROTATION
, ROTATION_ANGLE
);
369 case ROTATION_ANGLE_270
:
370 set_reg_field_value(value
, 1,
371 UNP_HW_ROTATION
, ROTATION_ANGLE
);
374 set_reg_field_value(value
, 0,
375 UNP_HW_ROTATION
, ROTATION_ANGLE
);
380 mem_input110
->base
.ctx
,
381 DCP_REG(mmUNP_HW_ROTATION
),
385 static void program_pixel_format(
386 struct dce110_mem_input
*mem_input110
,
387 enum surface_pixel_format format
)
389 if (format
< SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
) {
395 mem_input110
->base
.ctx
,
396 DCP_REG(mmUNP_GRPH_CONTROL
));
399 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS
:
403 case SURFACE_PIXEL_FORMAT_GRPH_RGB565
:
407 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888
:
408 case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888
:
412 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010
:
413 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010
:
414 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS
:
418 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616
:
419 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F
:
420 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F
:
442 mem_input110
->base
.ctx
,
443 DCP_REG(mmUNP_GRPH_CONTROL
),
447 mem_input110
->base
.ctx
,
448 DCP_REG(mmUNP_GRPH_CONTROL_EXP
));
454 UNP_GRPH_CONTROL_EXP
,
457 mem_input110
->base
.ctx
,
458 DCP_REG(mmUNP_GRPH_CONTROL_EXP
),
462 /* Video 422 and 420 needs UNP_GRPH_CONTROL_EXP programmed */
464 uint8_t video_format
;
467 mem_input110
->base
.ctx
,
468 DCP_REG(mmUNP_GRPH_CONTROL_EXP
));
471 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr
:
474 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb
:
485 UNP_GRPH_CONTROL_EXP
,
489 mem_input110
->base
.ctx
,
490 DCP_REG(mmUNP_GRPH_CONTROL_EXP
),
495 bool dce110_mem_input_v_is_surface_pending(struct mem_input
*mem_input
)
497 struct dce110_mem_input
*mem_input110
= TO_DCE110_MEM_INPUT(mem_input
);
500 value
= dm_read_reg(mem_input110
->base
.ctx
, DCP_REG(mmUNP_GRPH_UPDATE
));
502 if (get_reg_field_value(value
, UNP_GRPH_UPDATE
,
503 GRPH_SURFACE_UPDATE_PENDING
))
506 mem_input
->current_address
= mem_input
->request_address
;
510 bool dce110_mem_input_v_program_surface_flip_and_addr(
511 struct mem_input
*mem_input
,
512 const struct dc_plane_address
*address
,
515 struct dce110_mem_input
*mem_input110
= TO_DCE110_MEM_INPUT(mem_input
);
517 set_flip_control(mem_input110
, flip_immediate
);
518 program_addr(mem_input110
,
521 mem_input
->request_address
= *address
;
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 */
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 */
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 */
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
,
554 enum bits_per_pixel
{
561 if (format
>= SURFACE_PIXEL_FORMAT_INVALID
)
563 else if (format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
)
564 bpp
= chroma
? bpp_16
: bpp_8
;
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
];
583 return dvmm_Hw_Setting_2DTiling
[bpp
];
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
)
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);
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;
607 while ((temp_page_width
>>= 1) != 0)
609 while ((temp_page_height
>>= 1) != 0)
612 temp_page_width
= pte_chroma
[1];
613 temp_page_height
= pte_chroma
[2];
614 while ((temp_page_width
>>= 1) != 0)
616 while ((temp_page_height
>>= 1) != 0)
617 page_height_chroma
++;
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];
626 min_pte_before_flip
= pte
[3];
627 min_pte_before_flip_chroma
= pte_chroma
[3];
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
);
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
);
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
);
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
);
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
);
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
)
671 struct dce110_mem_input
*mem_input110
= TO_DCE110_MEM_INPUT(mem_input
);
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
);
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
)
689 uint32_t urgency_cntl
= 0;
690 uint32_t wm_mask_cntl
= 0;
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
,
696 DPGV0_WATERMARK_MASK_CONTROL
,
697 URGENCY_WATERMARK_MASK
);
698 dm_write_reg(ctx
, wm_addr
, wm_mask_cntl
);
700 urgency_cntl
= dm_read_reg(ctx
, urgency_addr
);
705 DPGV0_PIPE_URGENCY_CONTROL
,
706 URGENCY_LOW_WATERMARK
);
710 total_dest_line_time_ns
,
711 DPGV0_PIPE_URGENCY_CONTROL
,
712 URGENCY_HIGH_WATERMARK
);
713 dm_write_reg(ctx
, urgency_addr
, urgency_cntl
);
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
,
719 DPGV0_WATERMARK_MASK_CONTROL
,
720 URGENCY_WATERMARK_MASK
);
721 dm_write_reg(ctx
, wm_addr
, wm_mask_cntl
);
723 urgency_cntl
= dm_read_reg(ctx
, urgency_addr
);
725 set_reg_field_value(urgency_cntl
,
727 DPGV0_PIPE_URGENCY_CONTROL
,
728 URGENCY_LOW_WATERMARK
);
730 set_reg_field_value(urgency_cntl
,
731 total_dest_line_time_ns
,
732 DPGV0_PIPE_URGENCY_CONTROL
,
733 URGENCY_HIGH_WATERMARK
);
735 dm_write_reg(ctx
, urgency_addr
, urgency_cntl
);
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
)
743 program_urgency_watermark(
745 mmDPGV0_PIPE_URGENCY_CONTROL
,
746 mmDPGV0_WATERMARK_MASK_CONTROL
,
748 total_dest_line_time_ns
);
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
)
756 program_urgency_watermark(
758 mmDPGV1_PIPE_URGENCY_CONTROL
,
759 mmDPGV1_WATERMARK_MASK_CONTROL
,
761 total_dest_line_time_ns
);
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
)
771 uint32_t stutter_cntl
= 0;
772 uint32_t wm_mask_cntl
= 0;
774 /*Write mask to enable reading/writing of watermark set A*/
776 wm_mask_cntl
= dm_read_reg(ctx
, wm_addr
);
777 set_reg_field_value(wm_mask_cntl
,
779 DPGV0_WATERMARK_MASK_CONTROL
,
780 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK
);
781 dm_write_reg(ctx
, wm_addr
, wm_mask_cntl
);
783 stutter_cntl
= dm_read_reg(ctx
, stutter_addr
);
785 if (ctx
->dc
->debug
.disable_stutter
) {
786 set_reg_field_value(stutter_cntl
,
788 DPGV0_PIPE_STUTTER_CONTROL
,
791 set_reg_field_value(stutter_cntl
,
793 DPGV0_PIPE_STUTTER_CONTROL
,
797 set_reg_field_value(stutter_cntl
,
799 DPGV0_PIPE_STUTTER_CONTROL
,
802 /*Write watermark set A*/
803 set_reg_field_value(stutter_cntl
,
805 DPGV0_PIPE_STUTTER_CONTROL
,
806 STUTTER_EXIT_SELF_REFRESH_WATERMARK
);
807 dm_write_reg(ctx
, stutter_addr
, stutter_cntl
);
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
,
813 DPGV0_WATERMARK_MASK_CONTROL
,
814 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK
);
815 dm_write_reg(ctx
, wm_addr
, wm_mask_cntl
);
817 stutter_cntl
= dm_read_reg(ctx
, stutter_addr
);
818 /*Write watermark set B*/
819 set_reg_field_value(stutter_cntl
,
821 DPGV0_PIPE_STUTTER_CONTROL
,
822 STUTTER_EXIT_SELF_REFRESH_WATERMARK
);
823 dm_write_reg(ctx
, stutter_addr
, stutter_cntl
);
826 static void program_stutter_watermark_l(
827 const struct dc_context
*ctx
,
828 struct bw_watermarks marks
)
830 program_stutter_watermark(ctx
,
831 mmDPGV0_PIPE_STUTTER_CONTROL
,
832 mmDPGV0_WATERMARK_MASK_CONTROL
,
836 static void program_stutter_watermark_c(
837 const struct dc_context
*ctx
,
838 struct bw_watermarks marks
)
840 program_stutter_watermark(ctx
,
841 mmDPGV1_PIPE_STUTTER_CONTROL
,
842 mmDPGV1_WATERMARK_MASK_CONTROL
,
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
)
854 /* Write mask to enable reading/writing of watermark set A */
856 value
= dm_read_reg(ctx
, wm_mask_ctrl_addr
);
861 DPGV0_WATERMARK_MASK_CONTROL
,
862 NB_PSTATE_CHANGE_WATERMARK_MASK
);
863 dm_write_reg(ctx
, wm_mask_ctrl_addr
, value
);
865 value
= dm_read_reg(ctx
, nbp_pstate_ctrl_addr
);
870 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
871 NB_PSTATE_CHANGE_ENABLE
);
875 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
876 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST
);
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
);
884 /* Write watermark set A */
885 value
= dm_read_reg(ctx
, nbp_pstate_ctrl_addr
);
889 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
890 NB_PSTATE_CHANGE_WATERMARK
);
891 dm_write_reg(ctx
, nbp_pstate_ctrl_addr
, value
);
893 /* Write mask to enable reading/writing of watermark set B */
894 value
= dm_read_reg(ctx
, wm_mask_ctrl_addr
);
898 DPGV0_WATERMARK_MASK_CONTROL
,
899 NB_PSTATE_CHANGE_WATERMARK_MASK
);
900 dm_write_reg(ctx
, wm_mask_ctrl_addr
, value
);
902 value
= dm_read_reg(ctx
, nbp_pstate_ctrl_addr
);
906 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
907 NB_PSTATE_CHANGE_ENABLE
);
911 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
912 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST
);
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
);
920 /* Write watermark set B */
921 value
= dm_read_reg(ctx
, nbp_pstate_ctrl_addr
);
925 DPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
926 NB_PSTATE_CHANGE_WATERMARK
);
927 dm_write_reg(ctx
, nbp_pstate_ctrl_addr
, value
);
930 static void program_nbp_watermark_l(
931 const struct dc_context
*ctx
,
932 struct bw_watermarks marks
)
934 program_nbp_watermark(ctx
,
935 mmDPGV0_WATERMARK_MASK_CONTROL
,
936 mmDPGV0_PIPE_NB_PSTATE_CHANGE_CONTROL
,
940 static void program_nbp_watermark_c(
941 const struct dc_context
*ctx
,
942 struct bw_watermarks marks
)
944 program_nbp_watermark(ctx
,
945 mmDPGV1_WATERMARK_MASK_CONTROL
,
946 mmDPGV1_PIPE_NB_PSTATE_CHANGE_CONTROL
,
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
)
957 program_urgency_watermark_l(
960 total_dest_line_time_ns
);
962 program_nbp_watermark_l(
966 program_stutter_watermark_l(
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
)
979 program_urgency_watermark_c(
982 total_dest_line_time_ns
);
984 program_nbp_watermark_c(
988 program_stutter_watermark_c(
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
)
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(
1010 DPGV0_PIPE_ARBITRATION_CONTROL1
,
1012 dm_write_reg(mi
->ctx
, addr
, value
);
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(
1020 DPGV1_PIPE_ARBITRATION_CONTROL1
,
1022 dm_write_reg(mi
->ctx
, addr
, value
);
1024 addr
= mmDPGV0_PIPE_ARBITRATION_CONTROL2
;
1026 dm_write_reg(mi
->ctx
, addr
, value
);
1028 addr
= mmDPGV1_PIPE_ARBITRATION_CONTROL2
;
1030 dm_write_reg(mi
->ctx
, addr
, value
);
1035 void dce110_free_mem_input_v(
1036 struct mem_input
*mi
,
1037 uint32_t total_stream_num
)
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
1057 /*****************************************/
1058 /* Constructor, Destructor */
1059 /*****************************************/
1061 bool dce110_mem_input_v_construct(
1062 struct dce110_mem_input
*mem_input110
,
1063 struct dc_context
*ctx
)
1065 mem_input110
->base
.funcs
= &dce110_mem_input_v_funcs
;
1066 mem_input110
->base
.ctx
= ctx
;
1068 mem_input110
->base
.inst
= 0;
1070 mem_input110
->offsets
= dce110_mi_v_reg_offsets
[0];
1076 void dce110_mem_input_v_destroy(struct mem_input
**mem_input
)
1078 dm_free(TO_DCE110_MEM_INPUT(*mem_input
));