2 * Copyright 2017 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.
26 #include "dml1_display_rq_dlg_calc.h"
27 #include "display_mode_lib.h"
29 #include "dml_inline_defs.h"
31 static unsigned int get_bytes_per_element(enum source_format_class source_format
, bool is_chroma
)
33 unsigned int ret_val
= 0;
35 if (source_format
== dm_444_16
) {
38 } else if (source_format
== dm_444_32
) {
41 } else if (source_format
== dm_444_64
) {
44 } else if (source_format
== dm_420_8
) {
49 } else if (source_format
== dm_420_10
) {
58 static bool is_dual_plane(enum source_format_class source_format
)
62 if ((source_format
== dm_420_8
) || (source_format
== dm_420_10
))
68 static void get_blk256_size(
69 unsigned int *blk256_width
,
70 unsigned int *blk256_height
,
71 unsigned int bytes_per_element
)
73 if (bytes_per_element
== 1) {
76 } else if (bytes_per_element
== 2) {
79 } else if (bytes_per_element
== 4) {
82 } else if (bytes_per_element
== 8) {
88 static double get_refcyc_per_delivery(
89 struct display_mode_lib
*mode_lib
,
90 double refclk_freq_in_mhz
,
91 double pclk_freq_in_mhz
,
92 unsigned int recout_width
,
94 double hscale_pixel_rate
,
95 unsigned int delivery_width
,
96 unsigned int req_per_swath_ub
)
98 double refcyc_per_delivery
= 0.0;
101 refcyc_per_delivery
= (double) refclk_freq_in_mhz
* (double) recout_width
102 / pclk_freq_in_mhz
/ (double) req_per_swath_ub
;
104 refcyc_per_delivery
= (double) refclk_freq_in_mhz
* (double) delivery_width
105 / (double) hscale_pixel_rate
/ (double) req_per_swath_ub
;
108 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__
, refclk_freq_in_mhz
);
109 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__
, pclk_freq_in_mhz
);
110 DTRACE("DLG: %s: recout_width = %d", __func__
, recout_width
);
111 DTRACE("DLG: %s: vratio = %3.2f", __func__
, vratio
);
112 DTRACE("DLG: %s: req_per_swath_ub = %d", __func__
, req_per_swath_ub
);
113 DTRACE("DLG: %s: refcyc_per_delivery= %3.2f", __func__
, refcyc_per_delivery
);
115 return refcyc_per_delivery
;
119 static double get_vratio_pre(
120 struct display_mode_lib
*mode_lib
,
121 unsigned int max_num_sw
,
122 unsigned int max_partial_sw
,
123 unsigned int swath_height
,
127 double prefill
= dml_floor(vinit
, 1);
128 double vratio_pre
= 1.0;
130 vratio_pre
= (max_num_sw
* swath_height
+ max_partial_sw
) / l_sw
;
132 if (swath_height
> 4) {
133 double tmp0
= (max_num_sw
* swath_height
) / (l_sw
- (prefill
- 3.0) / 2.0);
135 if (tmp0
> vratio_pre
)
139 DTRACE("DLG: %s: max_num_sw = %0d", __func__
, max_num_sw
);
140 DTRACE("DLG: %s: max_partial_sw = %0d", __func__
, max_partial_sw
);
141 DTRACE("DLG: %s: swath_height = %0d", __func__
, swath_height
);
142 DTRACE("DLG: %s: vinit = %3.2f", __func__
, vinit
);
143 DTRACE("DLG: %s: vratio_pre = %3.2f", __func__
, vratio_pre
);
145 if (vratio_pre
< 1.0) {
146 DTRACE("WARNING_DLG: %s: vratio_pre=%3.2f < 1.0, set to 1.0", __func__
, vratio_pre
);
150 if (vratio_pre
> 4.0) {
152 "WARNING_DLG: %s: vratio_pre=%3.2f > 4.0 (max scaling ratio). set to 4.0",
161 static void get_swath_need(
162 struct display_mode_lib
*mode_lib
,
163 unsigned int *max_num_sw
,
164 unsigned int *max_partial_sw
,
165 unsigned int swath_height
,
168 double prefill
= dml_floor(vinit
, 1);
169 unsigned int max_partial_sw_int
;
171 DTRACE("DLG: %s: swath_height = %0d", __func__
, swath_height
);
172 DTRACE("DLG: %s: vinit = %3.2f", __func__
, vinit
);
174 ASSERT(prefill
> 0.0 && prefill
<= 8.0);
176 *max_num_sw
= (unsigned int) (dml_ceil((prefill
- 1.0) / (double) swath_height
, 1) + 1.0); /* prefill has to be >= 1 */
180 ((unsigned int) (prefill
- 2.0) % swath_height
);
181 *max_partial_sw
= (max_partial_sw_int
< 1) ? 1 : max_partial_sw_int
; /* ensure minimum of 1 is used */
183 DTRACE("DLG: %s: max_num_sw = %0d", __func__
, *max_num_sw
);
184 DTRACE("DLG: %s: max_partial_sw = %0d", __func__
, *max_partial_sw
);
187 static unsigned int get_blk_size_bytes(const enum source_macro_tile_size tile_size
)
189 if (tile_size
== dm_256k_tile
)
191 else if (tile_size
== dm_64k_tile
)
197 static void extract_rq_sizing_regs(
198 struct display_mode_lib
*mode_lib
,
199 struct _vcs_dpi_display_data_rq_regs_st
*rq_regs
,
200 const struct _vcs_dpi_display_data_rq_sizing_params_st rq_sizing
)
202 DTRACE("DLG: %s: rq_sizing param", __func__
);
203 print__data_rq_sizing_params_st(mode_lib
, rq_sizing
);
205 rq_regs
->chunk_size
= dml_log2(rq_sizing
.chunk_bytes
) - 10;
207 if (rq_sizing
.min_chunk_bytes
== 0)
208 rq_regs
->min_chunk_size
= 0;
210 rq_regs
->min_chunk_size
= dml_log2(rq_sizing
.min_chunk_bytes
) - 8 + 1;
212 rq_regs
->meta_chunk_size
= dml_log2(rq_sizing
.meta_chunk_bytes
) - 10;
213 if (rq_sizing
.min_meta_chunk_bytes
== 0)
214 rq_regs
->min_meta_chunk_size
= 0;
216 rq_regs
->min_meta_chunk_size
= dml_log2(rq_sizing
.min_meta_chunk_bytes
) - 6 + 1;
218 rq_regs
->dpte_group_size
= dml_log2(rq_sizing
.dpte_group_bytes
) - 6;
219 rq_regs
->mpte_group_size
= dml_log2(rq_sizing
.mpte_group_bytes
) - 6;
222 void dml1_extract_rq_regs(
223 struct display_mode_lib
*mode_lib
,
224 struct _vcs_dpi_display_rq_regs_st
*rq_regs
,
225 const struct _vcs_dpi_display_rq_params_st rq_param
)
227 unsigned int detile_buf_size_in_bytes
= mode_lib
->ip
.det_buffer_size_kbytes
* 1024;
228 unsigned int detile_buf_plane1_addr
= 0;
230 extract_rq_sizing_regs(mode_lib
, &(rq_regs
->rq_regs_l
), rq_param
.sizing
.rq_l
);
232 extract_rq_sizing_regs(mode_lib
, &(rq_regs
->rq_regs_c
), rq_param
.sizing
.rq_c
);
234 rq_regs
->rq_regs_l
.swath_height
= dml_log2(rq_param
.dlg
.rq_l
.swath_height
);
235 rq_regs
->rq_regs_c
.swath_height
= dml_log2(rq_param
.dlg
.rq_c
.swath_height
);
237 /* FIXME: take the max between luma, chroma chunk size?
238 * okay for now, as we are setting chunk_bytes to 8kb anyways
240 if (rq_param
.sizing
.rq_l
.chunk_bytes
>= 32 * 1024) { /*32kb */
241 rq_regs
->drq_expansion_mode
= 0;
243 rq_regs
->drq_expansion_mode
= 2;
245 rq_regs
->prq_expansion_mode
= 1;
246 rq_regs
->mrq_expansion_mode
= 1;
247 rq_regs
->crq_expansion_mode
= 1;
249 if (rq_param
.yuv420
) {
250 if ((double) rq_param
.misc
.rq_l
.stored_swath_bytes
251 / (double) rq_param
.misc
.rq_c
.stored_swath_bytes
<= 1.5) {
252 detile_buf_plane1_addr
= (detile_buf_size_in_bytes
/ 2.0 / 64.0); /* half to chroma */
254 detile_buf_plane1_addr
= dml_round_to_multiple(
255 (unsigned int) ((2.0 * detile_buf_size_in_bytes
) / 3.0),
257 0) / 64.0; /* 2/3 to chroma */
260 rq_regs
->plane1_base_address
= detile_buf_plane1_addr
;
263 static void handle_det_buf_split(
264 struct display_mode_lib
*mode_lib
,
265 struct _vcs_dpi_display_rq_params_st
*rq_param
,
266 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param
)
268 unsigned int total_swath_bytes
= 0;
269 unsigned int swath_bytes_l
= 0;
270 unsigned int swath_bytes_c
= 0;
271 unsigned int full_swath_bytes_packed_l
= 0;
272 unsigned int full_swath_bytes_packed_c
= 0;
275 bool surf_linear
= (pipe_src_param
.sw_mode
== dm_sw_linear
);
276 bool surf_vert
= (pipe_src_param
.source_scan
== dm_vert
);
277 unsigned int log2_swath_height_l
= 0;
278 unsigned int log2_swath_height_c
= 0;
279 unsigned int detile_buf_size_in_bytes
= mode_lib
->ip
.det_buffer_size_kbytes
* 1024;
281 full_swath_bytes_packed_l
= rq_param
->misc
.rq_l
.full_swath_bytes
;
282 full_swath_bytes_packed_c
= rq_param
->misc
.rq_c
.full_swath_bytes
;
284 if (rq_param
->yuv420_10bpc
) {
285 full_swath_bytes_packed_l
= dml_round_to_multiple(
286 rq_param
->misc
.rq_l
.full_swath_bytes
* 2 / 3,
289 full_swath_bytes_packed_c
= dml_round_to_multiple(
290 rq_param
->misc
.rq_c
.full_swath_bytes
* 2 / 3,
295 if (rq_param
->yuv420
) {
296 total_swath_bytes
= 2 * full_swath_bytes_packed_l
+ 2 * full_swath_bytes_packed_c
;
298 if (total_swath_bytes
<= detile_buf_size_in_bytes
) { /*full 256b request */
301 swath_bytes_l
= full_swath_bytes_packed_l
;
302 swath_bytes_c
= full_swath_bytes_packed_c
;
303 } else { /*128b request (for luma only for yuv420 8bpc) */
306 swath_bytes_l
= full_swath_bytes_packed_l
/ 2;
307 swath_bytes_c
= full_swath_bytes_packed_c
;
310 /* Bug workaround, luma and chroma req size needs to be the same. (see: DEGVIDCN10-137)
311 * TODO: Remove after rtl fix
315 DTRACE("DLG: %s: bug workaround DEGVIDCN10-137", __func__
);
318 /* Note: assumption, the config that pass in will fit into
319 * the detiled buffer.
322 total_swath_bytes
= 2 * full_swath_bytes_packed_l
;
324 if (total_swath_bytes
<= detile_buf_size_in_bytes
)
329 swath_bytes_l
= total_swath_bytes
;
332 rq_param
->misc
.rq_l
.stored_swath_bytes
= swath_bytes_l
;
333 rq_param
->misc
.rq_c
.stored_swath_bytes
= swath_bytes_c
;
336 log2_swath_height_l
= 0;
337 log2_swath_height_c
= 0;
338 } else if (!surf_vert
) {
339 log2_swath_height_l
= dml_log2(rq_param
->misc
.rq_l
.blk256_height
) - req128_l
;
340 log2_swath_height_c
= dml_log2(rq_param
->misc
.rq_c
.blk256_height
) - req128_c
;
342 log2_swath_height_l
= dml_log2(rq_param
->misc
.rq_l
.blk256_width
) - req128_l
;
343 log2_swath_height_c
= dml_log2(rq_param
->misc
.rq_c
.blk256_width
) - req128_c
;
345 rq_param
->dlg
.rq_l
.swath_height
= 1 << log2_swath_height_l
;
346 rq_param
->dlg
.rq_c
.swath_height
= 1 << log2_swath_height_c
;
348 DTRACE("DLG: %s: req128_l = %0d", __func__
, req128_l
);
349 DTRACE("DLG: %s: req128_c = %0d", __func__
, req128_c
);
350 DTRACE("DLG: %s: full_swath_bytes_packed_l = %0d", __func__
, full_swath_bytes_packed_l
);
351 DTRACE("DLG: %s: full_swath_bytes_packed_c = %0d", __func__
, full_swath_bytes_packed_c
);
355 static void dml1_rq_dlg_get_row_heights(
356 struct display_mode_lib
*mode_lib
,
357 unsigned int *o_dpte_row_height
,
358 unsigned int *o_meta_row_height
,
359 unsigned int vp_width
,
360 unsigned int data_pitch
,
367 bool surf_linear
= (tiling
== dm_sw_linear
);
368 bool surf_vert
= (source_scan
== dm_vert
);
370 unsigned int bytes_per_element
= get_bytes_per_element(
371 (enum source_format_class
) source_format
,
373 unsigned int log2_bytes_per_element
= dml_log2(bytes_per_element
);
374 unsigned int blk256_width
= 0;
375 unsigned int blk256_height
= 0;
377 unsigned int log2_blk256_height
;
378 unsigned int blk_bytes
;
379 unsigned int log2_blk_bytes
;
380 unsigned int log2_blk_height
;
381 unsigned int log2_blk_width
;
382 unsigned int log2_meta_req_bytes
;
383 unsigned int log2_meta_req_height
;
384 unsigned int log2_meta_req_width
;
385 unsigned int log2_meta_row_height
;
386 unsigned int log2_vmpg_bytes
;
387 unsigned int dpte_buf_in_pte_reqs
;
388 unsigned int log2_vmpg_height
;
389 unsigned int log2_vmpg_width
;
390 unsigned int log2_dpte_req_height_ptes
;
391 unsigned int log2_dpte_req_width_ptes
;
392 unsigned int log2_dpte_req_height
;
393 unsigned int log2_dpte_req_width
;
394 unsigned int log2_dpte_row_height_linear
;
395 unsigned int log2_dpte_row_height
;
396 unsigned int dpte_req_width
;
402 get_blk256_size(&blk256_width
, &blk256_height
, bytes_per_element
);
405 log2_blk256_height
= dml_log2((double) blk256_height
);
406 blk_bytes
= surf_linear
?
407 256 : get_blk_size_bytes((enum source_macro_tile_size
) macro_tile_size
);
408 log2_blk_bytes
= dml_log2((double) blk_bytes
);
413 * "+" in log is multiply
414 * "-" in log is divide
415 * "/2" is like square root
416 * blk is vertical biased
418 if (tiling
!= dm_sw_linear
)
419 log2_blk_height
= log2_blk256_height
420 + dml_ceil((double) (log2_blk_bytes
- 8) / 2.0, 1);
422 log2_blk_height
= 0; /* blk height of 1 */
424 log2_blk_width
= log2_blk_bytes
- log2_bytes_per_element
- log2_blk_height
;
429 log2_meta_req_bytes
= 6; /* meta request is 64b and is 8x8byte meta element */
431 /* each 64b meta request for dcn is 8x8 meta elements and
432 * a meta element covers one 256b block of the the data surface.
434 log2_meta_req_height
= log2_blk256_height
+ 3; /* meta req is 8x8 */
435 log2_meta_req_width
= log2_meta_req_bytes
+ 8 - log2_bytes_per_element
436 - log2_meta_req_height
;
437 log2_meta_row_height
= 0;
439 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
440 * calculate upper bound of the meta_row_width
443 log2_meta_row_height
= log2_meta_req_height
;
445 log2_meta_row_height
= log2_meta_req_width
;
447 *o_meta_row_height
= 1 << log2_meta_row_height
;
452 log2_vmpg_bytes
= dml_log2(mode_lib
->soc
.vmm_page_size_bytes
);
453 dpte_buf_in_pte_reqs
= mode_lib
->ip
.dpte_buffer_size_in_pte_reqs
;
455 log2_vmpg_height
= 0;
457 log2_dpte_req_height_ptes
= 0;
458 log2_dpte_req_width_ptes
= 0;
459 log2_dpte_req_height
= 0;
460 log2_dpte_req_width
= 0;
461 log2_dpte_row_height_linear
= 0;
462 log2_dpte_row_height
= 0;
463 dpte_req_width
= 0; /* 64b dpte req width in data element */
466 log2_vmpg_height
= 0; /* one line high */
468 log2_vmpg_height
= (log2_vmpg_bytes
- 8) / 2 + log2_blk256_height
;
469 log2_vmpg_width
= log2_vmpg_bytes
- log2_bytes_per_element
- log2_vmpg_height
;
471 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
472 if (log2_blk_bytes
<= log2_vmpg_bytes
)
473 log2_dpte_req_height_ptes
= 0;
474 else if (log2_blk_height
- log2_vmpg_height
>= 2)
475 log2_dpte_req_height_ptes
= 2;
477 log2_dpte_req_height_ptes
= log2_blk_height
- log2_vmpg_height
;
478 log2_dpte_req_width_ptes
= 3 - log2_dpte_req_height_ptes
;
480 ASSERT((log2_dpte_req_width_ptes
== 3 && log2_dpte_req_height_ptes
== 0) || /* 8x1 */
481 (log2_dpte_req_width_ptes
== 2 && log2_dpte_req_height_ptes
== 1) || /* 4x2 */
482 (log2_dpte_req_width_ptes
== 1 && log2_dpte_req_height_ptes
== 2)); /* 2x4 */
484 /* the dpte request dimensions in data elements is dpte_req_width x dpte_req_height
485 * log2_wmpg_width is how much 1 pte represent, now trying to calculate how much 64b pte req represent
487 log2_dpte_req_height
= log2_vmpg_height
+ log2_dpte_req_height_ptes
;
488 log2_dpte_req_width
= log2_vmpg_width
+ log2_dpte_req_width_ptes
;
489 dpte_req_width
= 1 << log2_dpte_req_width
;
491 /* calculate pitch dpte row buffer can hold
492 * round the result down to a power of two.
495 log2_dpte_row_height_linear
= dml_floor(
496 dml_log2(dpte_buf_in_pte_reqs
* dpte_req_width
/ data_pitch
),
499 ASSERT(log2_dpte_row_height_linear
>= 3);
501 if (log2_dpte_row_height_linear
> 7)
502 log2_dpte_row_height_linear
= 7;
504 log2_dpte_row_height
= log2_dpte_row_height_linear
;
506 /* the upper bound of the dpte_row_width without dependency on viewport position follows. */
508 log2_dpte_row_height
= log2_dpte_req_height
;
510 log2_dpte_row_height
=
511 (log2_blk_width
< log2_dpte_req_width
) ?
512 log2_blk_width
: log2_dpte_req_width
;
515 /* From programming guide:
516 * There is a special case of saving only half of ptes returned due to buffer space limits.
517 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
518 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
520 if (!surf_vert
&& vp_width
> (2560 + 16) && bytes_per_element
>= 4 && log2_vmpg_bytes
== 12
521 && log2_blk_bytes
>= 16)
522 log2_dpte_row_height
= log2_dpte_row_height
- 1; /*half of the full height */
524 *o_dpte_row_height
= 1 << log2_dpte_row_height
;
527 static void get_surf_rq_param(
528 struct display_mode_lib
*mode_lib
,
529 struct _vcs_dpi_display_data_rq_sizing_params_st
*rq_sizing_param
,
530 struct _vcs_dpi_display_data_rq_dlg_params_st
*rq_dlg_param
,
531 struct _vcs_dpi_display_data_rq_misc_params_st
*rq_misc_param
,
532 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param
,
536 unsigned int vp_width
= 0;
537 unsigned int vp_height
= 0;
538 unsigned int data_pitch
= 0;
539 unsigned int meta_pitch
= 0;
540 unsigned int ppe
= mode_422
? 2 : 1;
543 unsigned int bytes_per_element
;
544 unsigned int log2_bytes_per_element
;
545 unsigned int blk256_width
;
546 unsigned int blk256_height
;
547 unsigned int log2_blk256_width
;
548 unsigned int log2_blk256_height
;
549 unsigned int blk_bytes
;
550 unsigned int log2_blk_bytes
;
551 unsigned int log2_blk_height
;
552 unsigned int log2_blk_width
;
553 unsigned int log2_meta_req_bytes
;
554 unsigned int log2_meta_req_height
;
555 unsigned int log2_meta_req_width
;
556 unsigned int meta_req_width
;
557 unsigned int meta_req_height
;
558 unsigned int log2_meta_row_height
;
559 unsigned int meta_row_width_ub
;
560 unsigned int log2_meta_chunk_bytes
;
561 unsigned int log2_meta_chunk_height
;
562 unsigned int log2_meta_chunk_width
;
563 unsigned int log2_min_meta_chunk_bytes
;
564 unsigned int min_meta_chunk_width
;
565 unsigned int meta_chunk_width
;
566 unsigned int meta_chunk_per_row_int
;
567 unsigned int meta_row_remainder
;
568 unsigned int meta_chunk_threshold
;
569 unsigned int meta_blk_bytes
;
570 unsigned int meta_blk_height
;
571 unsigned int meta_blk_width
;
572 unsigned int meta_surface_bytes
;
573 unsigned int vmpg_bytes
;
574 unsigned int meta_pte_req_per_frame_ub
;
575 unsigned int meta_pte_bytes_per_frame_ub
;
576 unsigned int log2_vmpg_bytes
;
577 unsigned int dpte_buf_in_pte_reqs
;
578 unsigned int log2_vmpg_height
;
579 unsigned int log2_vmpg_width
;
580 unsigned int log2_dpte_req_height_ptes
;
581 unsigned int log2_dpte_req_width_ptes
;
582 unsigned int log2_dpte_req_height
;
583 unsigned int log2_dpte_req_width
;
584 unsigned int log2_dpte_row_height_linear
;
585 unsigned int log2_dpte_row_height
;
586 unsigned int log2_dpte_group_width
;
587 unsigned int dpte_row_width_ub
;
588 unsigned int dpte_row_height
;
589 unsigned int dpte_req_height
;
590 unsigned int dpte_req_width
;
591 unsigned int dpte_group_width
;
592 unsigned int log2_dpte_group_bytes
;
593 unsigned int log2_dpte_group_length
;
594 unsigned int func_meta_row_height
, func_dpte_row_height
;
596 /* FIXME check if ppe apply for both luma and chroma in 422 case */
598 vp_width
= pipe_src_param
.viewport_width_c
/ ppe
;
599 vp_height
= pipe_src_param
.viewport_height_c
;
600 data_pitch
= pipe_src_param
.data_pitch_c
;
601 meta_pitch
= pipe_src_param
.meta_pitch_c
;
603 vp_width
= pipe_src_param
.viewport_width
/ ppe
;
604 vp_height
= pipe_src_param
.viewport_height
;
605 data_pitch
= pipe_src_param
.data_pitch
;
606 meta_pitch
= pipe_src_param
.meta_pitch
;
609 rq_sizing_param
->chunk_bytes
= 8192;
611 if (rq_sizing_param
->chunk_bytes
== 64 * 1024)
612 rq_sizing_param
->min_chunk_bytes
= 0;
614 rq_sizing_param
->min_chunk_bytes
= 1024;
616 rq_sizing_param
->meta_chunk_bytes
= 2048;
617 rq_sizing_param
->min_meta_chunk_bytes
= 256;
619 rq_sizing_param
->mpte_group_bytes
= 2048;
621 surf_linear
= (pipe_src_param
.sw_mode
== dm_sw_linear
);
622 surf_vert
= (pipe_src_param
.source_scan
== dm_vert
);
624 bytes_per_element
= get_bytes_per_element(
625 (enum source_format_class
) pipe_src_param
.source_format
,
627 log2_bytes_per_element
= dml_log2(bytes_per_element
);
632 blk256_width
= 256 / bytes_per_element
;
635 get_blk256_size(&blk256_width
, &blk256_height
, bytes_per_element
);
638 DTRACE("DLG: %s: surf_linear = %d", __func__
, surf_linear
);
639 DTRACE("DLG: %s: surf_vert = %d", __func__
, surf_vert
);
640 DTRACE("DLG: %s: blk256_width = %d", __func__
, blk256_width
);
641 DTRACE("DLG: %s: blk256_height = %d", __func__
, blk256_height
);
643 log2_blk256_width
= dml_log2((double) blk256_width
);
644 log2_blk256_height
= dml_log2((double) blk256_height
);
646 surf_linear
? 256 : get_blk_size_bytes(
647 (enum source_macro_tile_size
) pipe_src_param
.macro_tile_size
);
648 log2_blk_bytes
= dml_log2((double) blk_bytes
);
653 * "+" in log is multiply
654 * "-" in log is divide
655 * "/2" is like square root
656 * blk is vertical biased
658 if (pipe_src_param
.sw_mode
!= dm_sw_linear
)
659 log2_blk_height
= log2_blk256_height
660 + dml_ceil((double) (log2_blk_bytes
- 8) / 2.0, 1);
662 log2_blk_height
= 0; /* blk height of 1 */
664 log2_blk_width
= log2_blk_bytes
- log2_bytes_per_element
- log2_blk_height
;
667 rq_dlg_param
->swath_width_ub
= dml_round_to_multiple(vp_width
- 1, blk256_width
, 1)
669 rq_dlg_param
->req_per_swath_ub
= rq_dlg_param
->swath_width_ub
>> log2_blk256_width
;
671 rq_dlg_param
->swath_width_ub
= dml_round_to_multiple(
675 rq_dlg_param
->req_per_swath_ub
= rq_dlg_param
->swath_width_ub
>> log2_blk256_height
;
679 rq_misc_param
->full_swath_bytes
= rq_dlg_param
->swath_width_ub
* blk256_height
682 rq_misc_param
->full_swath_bytes
= rq_dlg_param
->swath_width_ub
* blk256_width
685 rq_misc_param
->blk256_height
= blk256_height
;
686 rq_misc_param
->blk256_width
= blk256_width
;
691 log2_meta_req_bytes
= 6; /* meta request is 64b and is 8x8byte meta element */
693 /* each 64b meta request for dcn is 8x8 meta elements and
694 * a meta element covers one 256b block of the the data surface.
696 log2_meta_req_height
= log2_blk256_height
+ 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
697 log2_meta_req_width
= log2_meta_req_bytes
+ 8 - log2_bytes_per_element
698 - log2_meta_req_height
;
699 meta_req_width
= 1 << log2_meta_req_width
;
700 meta_req_height
= 1 << log2_meta_req_height
;
701 log2_meta_row_height
= 0;
702 meta_row_width_ub
= 0;
704 /* the dimensions of a meta row are meta_row_width x meta_row_height in elements.
705 * calculate upper bound of the meta_row_width
708 log2_meta_row_height
= log2_meta_req_height
;
709 meta_row_width_ub
= dml_round_to_multiple(vp_width
- 1, meta_req_width
, 1)
711 rq_dlg_param
->meta_req_per_row_ub
= meta_row_width_ub
/ meta_req_width
;
713 log2_meta_row_height
= log2_meta_req_width
;
714 meta_row_width_ub
= dml_round_to_multiple(vp_height
- 1, meta_req_height
, 1)
716 rq_dlg_param
->meta_req_per_row_ub
= meta_row_width_ub
/ meta_req_height
;
718 rq_dlg_param
->meta_bytes_per_row_ub
= rq_dlg_param
->meta_req_per_row_ub
* 64;
720 log2_meta_chunk_bytes
= dml_log2(rq_sizing_param
->meta_chunk_bytes
);
721 log2_meta_chunk_height
= log2_meta_row_height
;
723 /*full sized meta chunk width in unit of data elements */
724 log2_meta_chunk_width
= log2_meta_chunk_bytes
+ 8 - log2_bytes_per_element
725 - log2_meta_chunk_height
;
726 log2_min_meta_chunk_bytes
= dml_log2(rq_sizing_param
->min_meta_chunk_bytes
);
727 min_meta_chunk_width
= 1
728 << (log2_min_meta_chunk_bytes
+ 8 - log2_bytes_per_element
729 - log2_meta_chunk_height
);
730 meta_chunk_width
= 1 << log2_meta_chunk_width
;
731 meta_chunk_per_row_int
= (unsigned int) (meta_row_width_ub
/ meta_chunk_width
);
732 meta_row_remainder
= meta_row_width_ub
% meta_chunk_width
;
733 meta_chunk_threshold
= 0;
734 meta_blk_bytes
= 4096;
735 meta_blk_height
= blk256_height
* 64;
736 meta_blk_width
= meta_blk_bytes
* 256 / bytes_per_element
/ meta_blk_height
;
737 meta_surface_bytes
= meta_pitch
738 * (dml_round_to_multiple(vp_height
- 1, meta_blk_height
, 1)
739 + meta_blk_height
) * bytes_per_element
/ 256;
740 vmpg_bytes
= mode_lib
->soc
.vmm_page_size_bytes
;
741 meta_pte_req_per_frame_ub
= (dml_round_to_multiple(
742 meta_surface_bytes
- vmpg_bytes
,
744 1) + 8 * vmpg_bytes
) / (8 * vmpg_bytes
);
745 meta_pte_bytes_per_frame_ub
= meta_pte_req_per_frame_ub
* 64; /*64B mpte request */
746 rq_dlg_param
->meta_pte_bytes_per_frame_ub
= meta_pte_bytes_per_frame_ub
;
748 DTRACE("DLG: %s: meta_blk_height = %d", __func__
, meta_blk_height
);
749 DTRACE("DLG: %s: meta_blk_width = %d", __func__
, meta_blk_width
);
750 DTRACE("DLG: %s: meta_surface_bytes = %d", __func__
, meta_surface_bytes
);
751 DTRACE("DLG: %s: meta_pte_req_per_frame_ub = %d", __func__
, meta_pte_req_per_frame_ub
);
752 DTRACE("DLG: %s: meta_pte_bytes_per_frame_ub = %d", __func__
, meta_pte_bytes_per_frame_ub
);
755 meta_chunk_threshold
= 2 * min_meta_chunk_width
- meta_req_width
;
757 meta_chunk_threshold
= 2 * min_meta_chunk_width
- meta_req_height
;
759 if (meta_row_remainder
<= meta_chunk_threshold
)
760 rq_dlg_param
->meta_chunks_per_row_ub
= meta_chunk_per_row_int
+ 1;
762 rq_dlg_param
->meta_chunks_per_row_ub
= meta_chunk_per_row_int
+ 2;
764 rq_dlg_param
->meta_row_height
= 1 << log2_meta_row_height
;
769 log2_vmpg_bytes
= dml_log2(mode_lib
->soc
.vmm_page_size_bytes
);
770 dpte_buf_in_pte_reqs
= mode_lib
->ip
.dpte_buffer_size_in_pte_reqs
;
772 log2_vmpg_height
= 0;
774 log2_dpte_req_height_ptes
= 0;
775 log2_dpte_req_width_ptes
= 0;
776 log2_dpte_req_height
= 0;
777 log2_dpte_req_width
= 0;
778 log2_dpte_row_height_linear
= 0;
779 log2_dpte_row_height
= 0;
780 log2_dpte_group_width
= 0;
781 dpte_row_width_ub
= 0;
783 dpte_req_height
= 0; /* 64b dpte req height in data element */
784 dpte_req_width
= 0; /* 64b dpte req width in data element */
785 dpte_group_width
= 0;
786 log2_dpte_group_bytes
= 0;
787 log2_dpte_group_length
= 0;
790 log2_vmpg_height
= 0; /* one line high */
792 log2_vmpg_height
= (log2_vmpg_bytes
- 8) / 2 + log2_blk256_height
;
793 log2_vmpg_width
= log2_vmpg_bytes
- log2_bytes_per_element
- log2_vmpg_height
;
795 /* only 3 possible shapes for dpte request in dimensions of ptes: 8x1, 4x2, 2x4. */
796 if (log2_blk_bytes
<= log2_vmpg_bytes
)
797 log2_dpte_req_height_ptes
= 0;
798 else if (log2_blk_height
- log2_vmpg_height
>= 2)
799 log2_dpte_req_height_ptes
= 2;
801 log2_dpte_req_height_ptes
= log2_blk_height
- log2_vmpg_height
;
802 log2_dpte_req_width_ptes
= 3 - log2_dpte_req_height_ptes
;
804 /* Ensure we only have the 3 shapes */
805 ASSERT((log2_dpte_req_width_ptes
== 3 && log2_dpte_req_height_ptes
== 0) || /* 8x1 */
806 (log2_dpte_req_width_ptes
== 2 && log2_dpte_req_height_ptes
== 1) || /* 4x2 */
807 (log2_dpte_req_width_ptes
== 1 && log2_dpte_req_height_ptes
== 2)); /* 2x4 */
809 /* The dpte request dimensions in data elements is dpte_req_width x dpte_req_height
810 * log2_vmpg_width is how much 1 pte represent, now calculating how much a 64b pte req represent
811 * That depends on the pte shape (i.e. 8x1, 4x2, 2x4)
813 log2_dpte_req_height
= log2_vmpg_height
+ log2_dpte_req_height_ptes
;
814 log2_dpte_req_width
= log2_vmpg_width
+ log2_dpte_req_width_ptes
;
815 dpte_req_height
= 1 << log2_dpte_req_height
;
816 dpte_req_width
= 1 << log2_dpte_req_width
;
818 /* calculate pitch dpte row buffer can hold
819 * round the result down to a power of two.
822 log2_dpte_row_height_linear
= dml_floor(
823 dml_log2(dpte_buf_in_pte_reqs
* dpte_req_width
/ data_pitch
),
826 ASSERT(log2_dpte_row_height_linear
>= 3);
828 if (log2_dpte_row_height_linear
> 7)
829 log2_dpte_row_height_linear
= 7;
831 log2_dpte_row_height
= log2_dpte_row_height_linear
;
832 rq_dlg_param
->dpte_row_height
= 1 << log2_dpte_row_height
;
834 /* For linear, the dpte row is pitch dependent and the pte requests wrap at the pitch boundary.
835 * the dpte_row_width_ub is the upper bound of data_pitch*dpte_row_height in elements with this unique buffering.
837 dpte_row_width_ub
= dml_round_to_multiple(
838 data_pitch
* dpte_row_height
- 1,
841 rq_dlg_param
->dpte_req_per_row_ub
= dpte_row_width_ub
/ dpte_req_width
;
843 /* for tiled mode, row height is the same as req height and row store up to vp size upper bound */
845 log2_dpte_row_height
= log2_dpte_req_height
;
846 dpte_row_width_ub
= dml_round_to_multiple(vp_width
- 1, dpte_req_width
, 1)
848 rq_dlg_param
->dpte_req_per_row_ub
= dpte_row_width_ub
/ dpte_req_width
;
850 log2_dpte_row_height
=
851 (log2_blk_width
< log2_dpte_req_width
) ?
852 log2_blk_width
: log2_dpte_req_width
;
853 dpte_row_width_ub
= dml_round_to_multiple(vp_height
- 1, dpte_req_height
, 1)
855 rq_dlg_param
->dpte_req_per_row_ub
= dpte_row_width_ub
/ dpte_req_height
;
857 rq_dlg_param
->dpte_row_height
= 1 << log2_dpte_row_height
;
859 rq_dlg_param
->dpte_bytes_per_row_ub
= rq_dlg_param
->dpte_req_per_row_ub
* 64;
861 /* From programming guide:
862 * There is a special case of saving only half of ptes returned due to buffer space limits.
863 * this case applies to 4 and 8bpe in horizontal access of a vp_width greater than 2560+16
864 * when the pte request is 2x4 ptes (which happens when vmpg_bytes =4kb and tile blk_bytes >=64kb).
866 if (!surf_vert
&& vp_width
> (2560 + 16) && bytes_per_element
>= 4 && log2_vmpg_bytes
== 12
867 && log2_blk_bytes
>= 16) {
868 log2_dpte_row_height
= log2_dpte_row_height
- 1; /*half of the full height */
869 rq_dlg_param
->dpte_row_height
= 1 << log2_dpte_row_height
;
872 /* the dpte_group_bytes is reduced for the specific case of vertical
873 * access of a tile surface that has dpte request of 8x1 ptes.
875 if (!surf_linear
& (log2_dpte_req_height_ptes
== 0) & surf_vert
) /*reduced, in this case, will have page fault within a group */
876 rq_sizing_param
->dpte_group_bytes
= 512;
879 rq_sizing_param
->dpte_group_bytes
= 2048;
881 /*since pte request size is 64byte, the number of data pte requests per full sized group is as follows. */
882 log2_dpte_group_bytes
= dml_log2(rq_sizing_param
->dpte_group_bytes
);
883 log2_dpte_group_length
= log2_dpte_group_bytes
- 6; /*length in 64b requests */
885 /* full sized data pte group width in elements */
887 log2_dpte_group_width
= log2_dpte_group_length
+ log2_dpte_req_width
;
889 log2_dpte_group_width
= log2_dpte_group_length
+ log2_dpte_req_height
;
891 dpte_group_width
= 1 << log2_dpte_group_width
;
893 /* since dpte groups are only aligned to dpte_req_width and not dpte_group_width,
894 * the upper bound for the dpte groups per row is as follows.
896 rq_dlg_param
->dpte_groups_per_row_ub
= dml_ceil(
897 (double) dpte_row_width_ub
/ dpte_group_width
,
900 dml1_rq_dlg_get_row_heights(
902 &func_dpte_row_height
,
903 &func_meta_row_height
,
906 pipe_src_param
.source_format
,
907 pipe_src_param
.sw_mode
,
908 pipe_src_param
.macro_tile_size
,
909 pipe_src_param
.source_scan
,
912 /* Just a check to make sure this function and the new one give the same
913 * result. The standalone get_row_heights() function is based off of the
914 * code in this function so the same changes need to be made to both.
916 if (rq_dlg_param
->meta_row_height
!= func_meta_row_height
) {
918 "MISMATCH: rq_dlg_param->meta_row_height = %d",
919 rq_dlg_param
->meta_row_height
);
920 DTRACE("MISMATCH: func_meta_row_height = %d", func_meta_row_height
);
924 if (rq_dlg_param
->dpte_row_height
!= func_dpte_row_height
) {
926 "MISMATCH: rq_dlg_param->dpte_row_height = %d",
927 rq_dlg_param
->dpte_row_height
);
928 DTRACE("MISMATCH: func_dpte_row_height = %d", func_dpte_row_height
);
933 void dml1_rq_dlg_get_rq_params(
934 struct display_mode_lib
*mode_lib
,
935 struct _vcs_dpi_display_rq_params_st
*rq_param
,
936 const struct _vcs_dpi_display_pipe_source_params_st pipe_src_param
)
938 /* get param for luma surface */
939 rq_param
->yuv420
= pipe_src_param
.source_format
== dm_420_8
940 || pipe_src_param
.source_format
== dm_420_10
;
941 rq_param
->yuv420_10bpc
= pipe_src_param
.source_format
== dm_420_10
;
945 &(rq_param
->sizing
.rq_l
),
946 &(rq_param
->dlg
.rq_l
),
947 &(rq_param
->misc
.rq_l
),
951 if (is_dual_plane((enum source_format_class
) pipe_src_param
.source_format
)) {
952 /* get param for chroma surface */
955 &(rq_param
->sizing
.rq_c
),
956 &(rq_param
->dlg
.rq_c
),
957 &(rq_param
->misc
.rq_c
),
962 /* calculate how to split the det buffer space between luma and chroma */
963 handle_det_buf_split(mode_lib
, rq_param
, pipe_src_param
);
964 print__rq_params_st(mode_lib
, *rq_param
);
967 /* Note: currently taken in as is.
968 * Nice to decouple code from hw register implement and extract code that are repeated for luma and chroma.
970 void dml1_rq_dlg_get_dlg_params(
971 struct display_mode_lib
*mode_lib
,
972 struct _vcs_dpi_display_dlg_regs_st
*disp_dlg_regs
,
973 struct _vcs_dpi_display_ttu_regs_st
*disp_ttu_regs
,
974 const struct _vcs_dpi_display_rq_dlg_params_st rq_dlg_param
,
975 const struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param
,
976 const struct _vcs_dpi_display_e2e_pipe_params_st e2e_pipe_param
,
977 const bool cstate_en
,
978 const bool pstate_en
,
983 unsigned int htotal
= e2e_pipe_param
.pipe
.dest
.htotal
;
984 unsigned int hblank_end
= e2e_pipe_param
.pipe
.dest
.hblank_end
;
985 unsigned int vblank_start
= e2e_pipe_param
.pipe
.dest
.vblank_start
;
986 unsigned int vblank_end
= e2e_pipe_param
.pipe
.dest
.vblank_end
;
987 bool interlaced
= e2e_pipe_param
.pipe
.dest
.interlaced
;
988 unsigned int min_vblank
= mode_lib
->ip
.min_vblank_lines
;
990 double pclk_freq_in_mhz
= e2e_pipe_param
.pipe
.dest
.pixel_rate_mhz
;
991 double refclk_freq_in_mhz
= e2e_pipe_param
.clks_cfg
.refclk_mhz
;
992 double dppclk_freq_in_mhz
= e2e_pipe_param
.clks_cfg
.dppclk_mhz
;
993 double dispclk_freq_in_mhz
= e2e_pipe_param
.clks_cfg
.dispclk_mhz
;
995 double ref_freq_to_pix_freq
;
996 double prefetch_xy_calc_in_dcfclk
;
997 double min_dcfclk_mhz
;
999 double min_ttu_vblank
;
1000 double min_dst_y_ttu_vblank
;
1001 unsigned int dlg_vblank_start
;
1005 unsigned int access_dir
;
1006 unsigned int bytes_per_element_l
;
1007 unsigned int bytes_per_element_c
;
1008 unsigned int vp_height_l
;
1009 unsigned int vp_width_l
;
1010 unsigned int vp_height_c
;
1011 unsigned int vp_width_c
;
1012 unsigned int htaps_l
;
1013 unsigned int htaps_c
;
1018 double line_time_in_us
;
1023 unsigned int swath_height_l
;
1024 unsigned int swath_width_ub_l
;
1025 unsigned int dpte_bytes_per_row_ub_l
;
1026 unsigned int dpte_groups_per_row_ub_l
;
1027 unsigned int meta_pte_bytes_per_frame_ub_l
;
1028 unsigned int meta_bytes_per_row_ub_l
;
1029 unsigned int swath_height_c
;
1030 unsigned int swath_width_ub_c
;
1031 unsigned int dpte_bytes_per_row_ub_c
;
1032 unsigned int dpte_groups_per_row_ub_c
;
1033 unsigned int meta_chunks_per_row_ub_l
;
1034 unsigned int vupdate_offset
;
1035 unsigned int vupdate_width
;
1036 unsigned int vready_offset
;
1037 unsigned int dppclk_delay_subtotal
;
1038 unsigned int dispclk_delay_subtotal
;
1039 unsigned int pixel_rate_delay_subtotal
;
1040 unsigned int vstartup_start
;
1041 unsigned int dst_x_after_scaler
;
1042 unsigned int dst_y_after_scaler
;
1047 double dst_y_prefetch
;
1049 unsigned int vm_bytes
;
1050 unsigned int meta_row_bytes
;
1051 unsigned int max_num_sw_l
;
1052 unsigned int max_num_sw_c
;
1053 unsigned int max_partial_sw_l
;
1054 unsigned int max_partial_sw_c
;
1059 unsigned int sw_bytes_ub_l
;
1060 unsigned int sw_bytes_ub_c
;
1061 unsigned int sw_bytes
;
1062 unsigned int dpte_row_bytes
;
1067 double dst_y_per_vm_vblank
;
1068 double dst_y_per_row_vblank
;
1069 double min_dst_y_per_vm_vblank
;
1070 double min_dst_y_per_row_vblank
;
1072 double vratio_pre_l
;
1073 double vratio_pre_c
;
1074 unsigned int req_per_swath_ub_l
;
1075 unsigned int req_per_swath_ub_c
;
1076 unsigned int meta_row_height_l
;
1077 unsigned int swath_width_pixels_ub_l
;
1078 unsigned int swath_width_pixels_ub_c
;
1079 unsigned int scaler_rec_in_width_l
;
1080 unsigned int scaler_rec_in_width_c
;
1081 unsigned int dpte_row_height_l
;
1082 unsigned int dpte_row_height_c
;
1083 double hscale_pixel_rate_l
;
1084 double hscale_pixel_rate_c
;
1085 double min_hratio_fact_l
;
1086 double min_hratio_fact_c
;
1087 double refcyc_per_line_delivery_pre_l
;
1088 double refcyc_per_line_delivery_pre_c
;
1089 double refcyc_per_line_delivery_l
;
1090 double refcyc_per_line_delivery_c
;
1091 double refcyc_per_req_delivery_pre_l
;
1092 double refcyc_per_req_delivery_pre_c
;
1093 double refcyc_per_req_delivery_l
;
1094 double refcyc_per_req_delivery_c
;
1095 double refcyc_per_req_delivery_pre_cur0
;
1096 double refcyc_per_req_delivery_cur0
;
1097 unsigned int full_recout_width
;
1098 double hratios_cur0
;
1099 unsigned int cur0_src_width
;
1100 enum cursor_bpp cur0_bpp
;
1101 unsigned int cur0_req_size
;
1102 unsigned int cur0_req_width
;
1103 double cur0_width_ub
;
1104 double cur0_req_per_width
;
1105 double hactive_cur0
;
1107 memset(disp_dlg_regs
, 0, sizeof(*disp_dlg_regs
));
1108 memset(disp_ttu_regs
, 0, sizeof(*disp_ttu_regs
));
1110 DTRACE("DLG: %s: cstate_en = %d", __func__
, cstate_en
);
1111 DTRACE("DLG: %s: pstate_en = %d", __func__
, pstate_en
);
1112 DTRACE("DLG: %s: vm_en = %d", __func__
, vm_en
);
1113 DTRACE("DLG: %s: iflip_en = %d", __func__
, iflip_en
);
1115 /* ------------------------- */
1116 /* Section 1.5.2.1: OTG dependent Params */
1117 /* ------------------------- */
1118 DTRACE("DLG: %s: dppclk_freq_in_mhz = %3.2f", __func__
, dppclk_freq_in_mhz
);
1119 DTRACE("DLG: %s: dispclk_freq_in_mhz = %3.2f", __func__
, dispclk_freq_in_mhz
);
1120 DTRACE("DLG: %s: refclk_freq_in_mhz = %3.2f", __func__
, refclk_freq_in_mhz
);
1121 DTRACE("DLG: %s: pclk_freq_in_mhz = %3.2f", __func__
, pclk_freq_in_mhz
);
1122 DTRACE("DLG: %s: interlaced = %d", __func__
, interlaced
);
1124 ref_freq_to_pix_freq
= refclk_freq_in_mhz
/ pclk_freq_in_mhz
;
1125 ASSERT(ref_freq_to_pix_freq
< 4.0);
1126 disp_dlg_regs
->ref_freq_to_pix_freq
=
1127 (unsigned int) (ref_freq_to_pix_freq
* dml_pow(2, 19));
1128 disp_dlg_regs
->refcyc_per_htotal
= (unsigned int) (ref_freq_to_pix_freq
* (double) htotal
1130 disp_dlg_regs
->refcyc_h_blank_end
= (unsigned int) ((double) hblank_end
1131 * (double) ref_freq_to_pix_freq
);
1132 ASSERT(disp_dlg_regs
->refcyc_h_blank_end
< (unsigned int) dml_pow(2, 13));
1133 disp_dlg_regs
->dlg_vblank_end
= interlaced
? (vblank_end
/ 2) : vblank_end
; /* 15 bits */
1135 prefetch_xy_calc_in_dcfclk
= 24.0; /* FIXME: ip_param */
1136 min_dcfclk_mhz
= dlg_sys_param
.deepsleep_dcfclk_mhz
;
1137 t_calc_us
= prefetch_xy_calc_in_dcfclk
/ min_dcfclk_mhz
;
1138 min_ttu_vblank
= dlg_sys_param
.t_urg_wm_us
;
1140 min_ttu_vblank
= dml_max(dlg_sys_param
.t_sr_wm_us
, min_ttu_vblank
);
1142 min_ttu_vblank
= dml_max(dlg_sys_param
.t_mclk_wm_us
, min_ttu_vblank
);
1143 min_ttu_vblank
= min_ttu_vblank
+ t_calc_us
;
1145 min_dst_y_ttu_vblank
= min_ttu_vblank
* pclk_freq_in_mhz
/ (double) htotal
;
1146 dlg_vblank_start
= interlaced
? (vblank_start
/ 2) : vblank_start
;
1148 disp_dlg_regs
->min_dst_y_next_start
= (unsigned int) (((double) dlg_vblank_start
1149 + min_dst_y_ttu_vblank
) * dml_pow(2, 2));
1150 ASSERT(disp_dlg_regs
->min_dst_y_next_start
< (unsigned int) dml_pow(2, 18));
1152 DTRACE("DLG: %s: min_dcfclk_mhz = %3.2f", __func__
, min_dcfclk_mhz
);
1153 DTRACE("DLG: %s: min_ttu_vblank = %3.2f", __func__
, min_ttu_vblank
);
1155 "DLG: %s: min_dst_y_ttu_vblank = %3.2f",
1157 min_dst_y_ttu_vblank
);
1158 DTRACE("DLG: %s: t_calc_us = %3.2f", __func__
, t_calc_us
);
1160 "DLG: %s: disp_dlg_regs->min_dst_y_next_start = 0x%0x",
1162 disp_dlg_regs
->min_dst_y_next_start
);
1164 "DLG: %s: ref_freq_to_pix_freq = %3.2f",
1166 ref_freq_to_pix_freq
);
1168 /* ------------------------- */
1169 /* Section 1.5.2.2: Prefetch, Active and TTU */
1170 /* ------------------------- */
1173 dcc_en
= e2e_pipe_param
.pipe
.src
.dcc
;
1174 dual_plane
= is_dual_plane(
1175 (enum source_format_class
) e2e_pipe_param
.pipe
.src
.source_format
);
1176 mode_422
= 0; /* FIXME */
1177 access_dir
= (e2e_pipe_param
.pipe
.src
.source_scan
== dm_vert
); /* vp access direction: horizontal or vertical accessed */
1178 bytes_per_element_l
= get_bytes_per_element(
1179 (enum source_format_class
) e2e_pipe_param
.pipe
.src
.source_format
,
1181 bytes_per_element_c
= get_bytes_per_element(
1182 (enum source_format_class
) e2e_pipe_param
.pipe
.src
.source_format
,
1184 vp_height_l
= e2e_pipe_param
.pipe
.src
.viewport_height
;
1185 vp_width_l
= e2e_pipe_param
.pipe
.src
.viewport_width
;
1186 vp_height_c
= e2e_pipe_param
.pipe
.src
.viewport_height_c
;
1187 vp_width_c
= e2e_pipe_param
.pipe
.src
.viewport_width_c
;
1190 htaps_l
= e2e_pipe_param
.pipe
.scale_taps
.htaps
;
1191 htaps_c
= e2e_pipe_param
.pipe
.scale_taps
.htaps_c
;
1192 hratios_l
= e2e_pipe_param
.pipe
.scale_ratio_depth
.hscl_ratio
;
1193 hratios_c
= e2e_pipe_param
.pipe
.scale_ratio_depth
.hscl_ratio_c
;
1194 vratio_l
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vscl_ratio
;
1195 vratio_c
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vscl_ratio_c
;
1197 line_time_in_us
= (htotal
/ pclk_freq_in_mhz
);
1198 vinit_l
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vinit
;
1199 vinit_c
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vinit_c
;
1200 vinit_bot_l
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vinit_bot
;
1201 vinit_bot_c
= e2e_pipe_param
.pipe
.scale_ratio_depth
.vinit_bot_c
;
1203 swath_height_l
= rq_dlg_param
.rq_l
.swath_height
;
1204 swath_width_ub_l
= rq_dlg_param
.rq_l
.swath_width_ub
;
1205 dpte_bytes_per_row_ub_l
= rq_dlg_param
.rq_l
.dpte_bytes_per_row_ub
;
1206 dpte_groups_per_row_ub_l
= rq_dlg_param
.rq_l
.dpte_groups_per_row_ub
;
1207 meta_pte_bytes_per_frame_ub_l
= rq_dlg_param
.rq_l
.meta_pte_bytes_per_frame_ub
;
1208 meta_bytes_per_row_ub_l
= rq_dlg_param
.rq_l
.meta_bytes_per_row_ub
;
1210 swath_height_c
= rq_dlg_param
.rq_c
.swath_height
;
1211 swath_width_ub_c
= rq_dlg_param
.rq_c
.swath_width_ub
;
1212 dpte_bytes_per_row_ub_c
= rq_dlg_param
.rq_c
.dpte_bytes_per_row_ub
;
1213 dpte_groups_per_row_ub_c
= rq_dlg_param
.rq_c
.dpte_groups_per_row_ub
;
1215 meta_chunks_per_row_ub_l
= rq_dlg_param
.rq_l
.meta_chunks_per_row_ub
;
1216 vupdate_offset
= e2e_pipe_param
.pipe
.dest
.vupdate_offset
;
1217 vupdate_width
= e2e_pipe_param
.pipe
.dest
.vupdate_width
;
1218 vready_offset
= e2e_pipe_param
.pipe
.dest
.vready_offset
;
1220 dppclk_delay_subtotal
= mode_lib
->ip
.dppclk_delay_subtotal
;
1221 dispclk_delay_subtotal
= mode_lib
->ip
.dispclk_delay_subtotal
;
1222 pixel_rate_delay_subtotal
= dppclk_delay_subtotal
* pclk_freq_in_mhz
/ dppclk_freq_in_mhz
1223 + dispclk_delay_subtotal
* pclk_freq_in_mhz
/ dispclk_freq_in_mhz
;
1225 vstartup_start
= e2e_pipe_param
.pipe
.dest
.vstartup_start
;
1228 vstartup_start
= vstartup_start
/ 2;
1230 if (vstartup_start
>= min_vblank
) {
1232 "WARNING_DLG: %s: vblank_start=%d vblank_end=%d",
1237 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1241 min_vblank
= vstartup_start
+ 1;
1243 "WARNING_DLG: %s: vstartup_start=%d should be less than min_vblank=%d",
1249 dst_x_after_scaler
= 0;
1250 dst_y_after_scaler
= 0;
1252 if (e2e_pipe_param
.pipe
.src
.is_hsplit
)
1253 dst_x_after_scaler
= pixel_rate_delay_subtotal
1254 + e2e_pipe_param
.pipe
.dest
.recout_width
;
1256 dst_x_after_scaler
= pixel_rate_delay_subtotal
;
1258 if (e2e_pipe_param
.dout
.output_format
== dm_420
)
1259 dst_y_after_scaler
= 1;
1261 dst_y_after_scaler
= 0;
1263 if (dst_x_after_scaler
>= htotal
) {
1264 dst_x_after_scaler
= dst_x_after_scaler
- htotal
;
1265 dst_y_after_scaler
= dst_y_after_scaler
+ 1;
1268 DTRACE("DLG: %s: htotal = %d", __func__
, htotal
);
1270 "DLG: %s: pixel_rate_delay_subtotal = %d",
1272 pixel_rate_delay_subtotal
);
1273 DTRACE("DLG: %s: dst_x_after_scaler = %d", __func__
, dst_x_after_scaler
);
1274 DTRACE("DLG: %s: dst_y_after_scaler = %d", __func__
, dst_y_after_scaler
);
1276 line_wait
= mode_lib
->soc
.urgent_latency_us
;
1278 line_wait
= dml_max(mode_lib
->soc
.sr_enter_plus_exit_time_us
, line_wait
);
1280 line_wait
= dml_max(
1281 mode_lib
->soc
.dram_clock_change_latency_us
1282 + mode_lib
->soc
.urgent_latency_us
,
1284 line_wait
= line_wait
/ line_time_in_us
;
1286 line_o
= (double) dst_y_after_scaler
+ dst_x_after_scaler
/ (double) htotal
;
1287 line_setup
= (double) (vupdate_offset
+ vupdate_width
+ vready_offset
) / (double) htotal
;
1288 line_calc
= t_calc_us
/ line_time_in_us
;
1291 "DLG: %s: soc.sr_enter_plus_exit_time_us = %3.2f",
1293 (double) mode_lib
->soc
.sr_enter_plus_exit_time_us
);
1295 "DLG: %s: soc.dram_clock_change_latency_us = %3.2f",
1297 (double) mode_lib
->soc
.dram_clock_change_latency_us
);
1299 "DLG: %s: soc.urgent_latency_us = %3.2f",
1301 mode_lib
->soc
.urgent_latency_us
);
1303 DTRACE("DLG: %s: swath_height_l = %d", __func__
, swath_height_l
);
1305 DTRACE("DLG: %s: swath_height_c = %d", __func__
, swath_height_c
);
1308 "DLG: %s: t_srx_delay_us = %3.2f",
1310 (double) dlg_sys_param
.t_srx_delay_us
);
1311 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__
, (double) line_time_in_us
);
1312 DTRACE("DLG: %s: vupdate_offset = %d", __func__
, vupdate_offset
);
1313 DTRACE("DLG: %s: vupdate_width = %d", __func__
, vupdate_width
);
1314 DTRACE("DLG: %s: vready_offset = %d", __func__
, vready_offset
);
1315 DTRACE("DLG: %s: line_time_in_us = %3.2f", __func__
, line_time_in_us
);
1316 DTRACE("DLG: %s: line_wait = %3.2f", __func__
, line_wait
);
1317 DTRACE("DLG: %s: line_o = %3.2f", __func__
, line_o
);
1318 DTRACE("DLG: %s: line_setup = %3.2f", __func__
, line_setup
);
1319 DTRACE("DLG: %s: line_calc = %3.2f", __func__
, line_calc
);
1321 dst_y_prefetch
= ((double) min_vblank
- 1.0)
1322 - (line_setup
+ line_calc
+ line_wait
+ line_o
);
1323 DTRACE("DLG: %s: dst_y_prefetch (before rnd) = %3.2f", __func__
, dst_y_prefetch
);
1324 ASSERT(dst_y_prefetch
>= 2.0);
1326 dst_y_prefetch
= dml_floor(4.0 * (dst_y_prefetch
+ 0.125), 1) / 4;
1327 DTRACE("DLG: %s: dst_y_prefetch (after rnd) = %3.2f", __func__
, dst_y_prefetch
);
1329 t_pre_us
= dst_y_prefetch
* line_time_in_us
;
1333 if (dcc_en
&& vm_en
)
1334 vm_bytes
= meta_pte_bytes_per_frame_ub_l
;
1336 meta_row_bytes
= meta_bytes_per_row_ub_l
;
1340 max_partial_sw_l
= 0;
1341 max_partial_sw_c
= 0;
1343 max_vinit_l
= interlaced
? dml_max(vinit_l
, vinit_bot_l
) : vinit_l
;
1344 max_vinit_c
= interlaced
? dml_max(vinit_c
, vinit_bot_c
) : vinit_c
;
1346 get_swath_need(mode_lib
, &max_num_sw_l
, &max_partial_sw_l
, swath_height_l
, max_vinit_l
);
1355 lsw_l
= max_num_sw_l
* swath_height_l
+ max_partial_sw_l
;
1356 lsw_c
= max_num_sw_c
* swath_height_c
+ max_partial_sw_c
;
1357 sw_bytes_ub_l
= lsw_l
* swath_width_ub_l
* bytes_per_element_l
;
1358 sw_bytes_ub_c
= lsw_c
* swath_width_ub_c
* bytes_per_element_c
;
1364 dpte_row_bytes
= dpte_bytes_per_row_ub_l
+ dpte_bytes_per_row_ub_c
;
1366 dpte_row_bytes
= dpte_bytes_per_row_ub_l
;
1372 sw_bytes
= sw_bytes_ub_l
+ sw_bytes_ub_c
;
1374 sw_bytes
= sw_bytes_ub_l
;
1376 DTRACE("DLG: %s: sw_bytes_ub_l = %d", __func__
, sw_bytes_ub_l
);
1377 DTRACE("DLG: %s: sw_bytes_ub_c = %d", __func__
, sw_bytes_ub_c
);
1378 DTRACE("DLG: %s: sw_bytes = %d", __func__
, sw_bytes
);
1379 DTRACE("DLG: %s: vm_bytes = %d", __func__
, vm_bytes
);
1380 DTRACE("DLG: %s: meta_row_bytes = %d", __func__
, meta_row_bytes
);
1381 DTRACE("DLG: %s: dpte_row_bytes = %d", __func__
, dpte_row_bytes
);
1383 prefetch_bw
= (vm_bytes
+ 2 * dpte_row_bytes
+ 2 * meta_row_bytes
+ sw_bytes
) / t_pre_us
;
1384 flip_bw
= ((vm_bytes
+ dpte_row_bytes
+ meta_row_bytes
) * dlg_sys_param
.total_flip_bw
)
1385 / (double) dlg_sys_param
.total_flip_bytes
;
1386 t_vm_us
= line_time_in_us
/ 4.0;
1387 if (vm_en
&& dcc_en
) {
1389 dlg_sys_param
.t_extra_us
,
1390 dml_max((double) vm_bytes
/ prefetch_bw
, t_vm_us
));
1392 if (iflip_en
&& !dual_plane
) {
1393 t_vm_us
= dml_max(mode_lib
->soc
.urgent_latency_us
, t_vm_us
);
1395 t_vm_us
= dml_max(vm_bytes
/ flip_bw
, t_vm_us
);
1399 t_r0_us
= dml_max(dlg_sys_param
.t_extra_us
- t_vm_us
, line_time_in_us
- t_vm_us
);
1401 if (vm_en
|| dcc_en
) {
1403 (double) (dpte_row_bytes
+ meta_row_bytes
) / prefetch_bw
,
1404 dlg_sys_param
.t_extra_us
);
1405 t_r0_us
= dml_max((double) (line_time_in_us
- t_vm_us
), t_r0_us
);
1407 if (iflip_en
&& !dual_plane
) {
1408 t_r0_us
= dml_max(mode_lib
->soc
.urgent_latency_us
* 2.0, t_r0_us
);
1411 (dpte_row_bytes
+ meta_row_bytes
) / flip_bw
,
1416 disp_dlg_regs
->dst_y_after_scaler
= dst_y_after_scaler
; /* in terms of line */
1417 disp_dlg_regs
->refcyc_x_after_scaler
= dst_x_after_scaler
* ref_freq_to_pix_freq
; /* in terms of refclk */
1418 ASSERT(disp_dlg_regs
->refcyc_x_after_scaler
< (unsigned int) dml_pow(2, 13));
1420 "DLG: %s: disp_dlg_regs->dst_y_after_scaler = 0x%0x",
1422 disp_dlg_regs
->dst_y_after_scaler
);
1424 "DLG: %s: disp_dlg_regs->refcyc_x_after_scaler = 0x%0x",
1426 disp_dlg_regs
->refcyc_x_after_scaler
);
1428 disp_dlg_regs
->dst_y_prefetch
= (unsigned int) (dst_y_prefetch
* dml_pow(2, 2));
1430 "DLG: %s: disp_dlg_regs->dst_y_prefetch = %d",
1432 disp_dlg_regs
->dst_y_prefetch
);
1434 dst_y_per_vm_vblank
= 0.0;
1435 dst_y_per_row_vblank
= 0.0;
1437 dst_y_per_vm_vblank
= t_vm_us
/ line_time_in_us
;
1438 dst_y_per_vm_vblank
= dml_floor(4.0 * (dst_y_per_vm_vblank
+ 0.125), 1) / 4.0;
1439 disp_dlg_regs
->dst_y_per_vm_vblank
= (unsigned int) (dst_y_per_vm_vblank
* dml_pow(2, 2));
1441 dst_y_per_row_vblank
= t_r0_us
/ line_time_in_us
;
1442 dst_y_per_row_vblank
= dml_floor(4.0 * (dst_y_per_row_vblank
+ 0.125), 1) / 4.0;
1443 disp_dlg_regs
->dst_y_per_row_vblank
= (unsigned int) (dst_y_per_row_vblank
* dml_pow(2, 2));
1445 DTRACE("DLG: %s: lsw_l = %d", __func__
, lsw_l
);
1446 DTRACE("DLG: %s: lsw_c = %d", __func__
, lsw_c
);
1447 DTRACE("DLG: %s: dpte_bytes_per_row_ub_l = %d", __func__
, dpte_bytes_per_row_ub_l
);
1448 DTRACE("DLG: %s: dpte_bytes_per_row_ub_c = %d", __func__
, dpte_bytes_per_row_ub_c
);
1450 DTRACE("DLG: %s: prefetch_bw = %3.2f", __func__
, prefetch_bw
);
1451 DTRACE("DLG: %s: flip_bw = %3.2f", __func__
, flip_bw
);
1452 DTRACE("DLG: %s: t_pre_us = %3.2f", __func__
, t_pre_us
);
1453 DTRACE("DLG: %s: t_vm_us = %3.2f", __func__
, t_vm_us
);
1454 DTRACE("DLG: %s: t_r0_us = %3.2f", __func__
, t_r0_us
);
1455 DTRACE("DLG: %s: dst_y_per_vm_vblank = %3.2f", __func__
, dst_y_per_vm_vblank
);
1456 DTRACE("DLG: %s: dst_y_per_row_vblank = %3.2f", __func__
, dst_y_per_row_vblank
);
1457 DTRACE("DLG: %s: dst_y_prefetch = %3.2f", __func__
, dst_y_prefetch
);
1459 min_dst_y_per_vm_vblank
= 8.0;
1460 min_dst_y_per_row_vblank
= 16.0;
1463 min_dst_y_per_vm_vblank
= 100.0;
1464 min_dst_y_per_row_vblank
= 100.0;
1467 ASSERT(dst_y_per_vm_vblank
< min_dst_y_per_vm_vblank
);
1468 ASSERT(dst_y_per_row_vblank
< min_dst_y_per_row_vblank
);
1470 ASSERT(dst_y_prefetch
> (dst_y_per_vm_vblank
+ dst_y_per_row_vblank
));
1471 lsw
= dst_y_prefetch
- (dst_y_per_vm_vblank
+ dst_y_per_row_vblank
);
1473 DTRACE("DLG: %s: lsw = %3.2f", __func__
, lsw
);
1475 vratio_pre_l
= get_vratio_pre(
1484 vratio_pre_c
= get_vratio_pre(
1492 DTRACE("DLG: %s: vratio_pre_l=%3.2f", __func__
, vratio_pre_l
);
1493 DTRACE("DLG: %s: vratio_pre_c=%3.2f", __func__
, vratio_pre_c
);
1495 ASSERT(vratio_pre_l
<= 4.0);
1496 if (vratio_pre_l
>= 4.0)
1497 disp_dlg_regs
->vratio_prefetch
= (unsigned int) dml_pow(2, 21) - 1;
1499 disp_dlg_regs
->vratio_prefetch
= (unsigned int) (vratio_pre_l
* dml_pow(2, 19));
1501 ASSERT(vratio_pre_c
<= 4.0);
1502 if (vratio_pre_c
>= 4.0)
1503 disp_dlg_regs
->vratio_prefetch_c
= (unsigned int) dml_pow(2, 21) - 1;
1505 disp_dlg_regs
->vratio_prefetch_c
= (unsigned int) (vratio_pre_c
* dml_pow(2, 19));
1507 disp_dlg_regs
->refcyc_per_pte_group_vblank_l
=
1508 (unsigned int) (dst_y_per_row_vblank
* (double) htotal
1509 * ref_freq_to_pix_freq
/ (double) dpte_groups_per_row_ub_l
);
1510 ASSERT(disp_dlg_regs
->refcyc_per_pte_group_vblank_l
< (unsigned int) dml_pow(2, 13));
1512 disp_dlg_regs
->refcyc_per_pte_group_vblank_c
=
1513 (unsigned int) (dst_y_per_row_vblank
* (double) htotal
1514 * ref_freq_to_pix_freq
/ (double) dpte_groups_per_row_ub_c
);
1515 ASSERT(disp_dlg_regs
->refcyc_per_pte_group_vblank_c
< (unsigned int) dml_pow(2, 13));
1517 disp_dlg_regs
->refcyc_per_meta_chunk_vblank_l
=
1518 (unsigned int) (dst_y_per_row_vblank
* (double) htotal
1519 * ref_freq_to_pix_freq
/ (double) meta_chunks_per_row_ub_l
);
1520 ASSERT(disp_dlg_regs
->refcyc_per_meta_chunk_vblank_l
< (unsigned int) dml_pow(2, 13));
1522 disp_dlg_regs
->refcyc_per_meta_chunk_vblank_c
=
1523 disp_dlg_regs
->refcyc_per_meta_chunk_vblank_l
;/* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
1526 req_per_swath_ub_l
= rq_dlg_param
.rq_l
.req_per_swath_ub
;
1527 req_per_swath_ub_c
= rq_dlg_param
.rq_c
.req_per_swath_ub
;
1528 meta_row_height_l
= rq_dlg_param
.rq_l
.meta_row_height
;
1529 swath_width_pixels_ub_l
= 0;
1530 swath_width_pixels_ub_c
= 0;
1531 scaler_rec_in_width_l
= 0;
1532 scaler_rec_in_width_c
= 0;
1533 dpte_row_height_l
= rq_dlg_param
.rq_l
.dpte_row_height
;
1534 dpte_row_height_c
= rq_dlg_param
.rq_c
.dpte_row_height
;
1536 disp_dlg_regs
->dst_y_per_pte_row_nom_l
= (unsigned int) ((double) dpte_row_height_l
1537 / (double) vratio_l
* dml_pow(2, 2));
1538 ASSERT(disp_dlg_regs
->dst_y_per_pte_row_nom_l
< (unsigned int) dml_pow(2, 17));
1540 disp_dlg_regs
->dst_y_per_pte_row_nom_c
= (unsigned int) ((double) dpte_row_height_c
1541 / (double) vratio_c
* dml_pow(2, 2));
1542 ASSERT(disp_dlg_regs
->dst_y_per_pte_row_nom_c
< (unsigned int) dml_pow(2, 17));
1544 disp_dlg_regs
->dst_y_per_meta_row_nom_l
= (unsigned int) ((double) meta_row_height_l
1545 / (double) vratio_l
* dml_pow(2, 2));
1546 ASSERT(disp_dlg_regs
->dst_y_per_meta_row_nom_l
< (unsigned int) dml_pow(2, 17));
1548 disp_dlg_regs
->dst_y_per_meta_row_nom_c
= disp_dlg_regs
->dst_y_per_meta_row_nom_l
; /* dcc for 4:2:0 is not supported in dcn1.0. assigned to be the same as _l for now */
1550 disp_dlg_regs
->refcyc_per_pte_group_nom_l
= (unsigned int) ((double) dpte_row_height_l
1551 / (double) vratio_l
* (double) htotal
* ref_freq_to_pix_freq
1552 / (double) dpte_groups_per_row_ub_l
);
1553 if (disp_dlg_regs
->refcyc_per_pte_group_nom_l
>= (unsigned int) dml_pow(2, 23))
1554 disp_dlg_regs
->refcyc_per_pte_group_nom_l
= dml_pow(2, 23) - 1;
1556 disp_dlg_regs
->refcyc_per_pte_group_nom_c
= (unsigned int) ((double) dpte_row_height_c
1557 / (double) vratio_c
* (double) htotal
* ref_freq_to_pix_freq
1558 / (double) dpte_groups_per_row_ub_c
);
1559 if (disp_dlg_regs
->refcyc_per_pte_group_nom_c
>= (unsigned int) dml_pow(2, 23))
1560 disp_dlg_regs
->refcyc_per_pte_group_nom_c
= dml_pow(2, 23) - 1;
1562 disp_dlg_regs
->refcyc_per_meta_chunk_nom_l
= (unsigned int) ((double) meta_row_height_l
1563 / (double) vratio_l
* (double) htotal
* ref_freq_to_pix_freq
1564 / (double) meta_chunks_per_row_ub_l
);
1565 if (disp_dlg_regs
->refcyc_per_meta_chunk_nom_l
>= (unsigned int) dml_pow(2, 23))
1566 disp_dlg_regs
->refcyc_per_meta_chunk_nom_l
= dml_pow(2, 23) - 1;
1569 swath_width_pixels_ub_l
= swath_width_ub_l
* 2; /* *2 for 2 pixel per element */
1570 swath_width_pixels_ub_c
= swath_width_ub_c
* 2;
1572 swath_width_pixels_ub_l
= swath_width_ub_l
* 1;
1573 swath_width_pixels_ub_c
= swath_width_ub_c
* 1;
1576 hscale_pixel_rate_l
= 0.;
1577 hscale_pixel_rate_c
= 0.;
1578 min_hratio_fact_l
= 1.0;
1579 min_hratio_fact_c
= 1.0;
1582 min_hratio_fact_l
= 2.0;
1583 else if (htaps_l
<= 6) {
1584 if ((hratios_l
* 2.0) > 4.0)
1585 min_hratio_fact_l
= 4.0;
1587 min_hratio_fact_l
= hratios_l
* 2.0;
1589 if (hratios_l
> 4.0)
1590 min_hratio_fact_l
= 4.0;
1592 min_hratio_fact_l
= hratios_l
;
1595 hscale_pixel_rate_l
= min_hratio_fact_l
* dppclk_freq_in_mhz
;
1598 min_hratio_fact_c
= 2.0;
1599 else if (htaps_c
<= 6) {
1600 if ((hratios_c
* 2.0) > 4.0)
1601 min_hratio_fact_c
= 4.0;
1603 min_hratio_fact_c
= hratios_c
* 2.0;
1605 if (hratios_c
> 4.0)
1606 min_hratio_fact_c
= 4.0;
1608 min_hratio_fact_c
= hratios_c
;
1611 hscale_pixel_rate_c
= min_hratio_fact_c
* dppclk_freq_in_mhz
;
1613 refcyc_per_line_delivery_pre_l
= 0.;
1614 refcyc_per_line_delivery_pre_c
= 0.;
1615 refcyc_per_line_delivery_l
= 0.;
1616 refcyc_per_line_delivery_c
= 0.;
1618 refcyc_per_req_delivery_pre_l
= 0.;
1619 refcyc_per_req_delivery_pre_c
= 0.;
1620 refcyc_per_req_delivery_l
= 0.;
1621 refcyc_per_req_delivery_c
= 0.;
1622 refcyc_per_req_delivery_pre_cur0
= 0.;
1623 refcyc_per_req_delivery_cur0
= 0.;
1625 full_recout_width
= 0;
1626 if (e2e_pipe_param
.pipe
.src
.is_hsplit
) {
1627 if (e2e_pipe_param
.pipe
.dest
.full_recout_width
== 0) {
1628 DTRACE("DLG: %s: Warningfull_recout_width not set in hsplit mode", __func__
);
1629 full_recout_width
= e2e_pipe_param
.pipe
.dest
.recout_width
* 2; /* assume half split for dcn1 */
1631 full_recout_width
= e2e_pipe_param
.pipe
.dest
.full_recout_width
;
1633 full_recout_width
= e2e_pipe_param
.pipe
.dest
.recout_width
;
1635 refcyc_per_line_delivery_pre_l
= get_refcyc_per_delivery(
1641 hscale_pixel_rate_l
,
1642 swath_width_pixels_ub_l
,
1645 refcyc_per_line_delivery_l
= get_refcyc_per_delivery(
1651 hscale_pixel_rate_l
,
1652 swath_width_pixels_ub_l
,
1655 DTRACE("DLG: %s: full_recout_width = %d", __func__
, full_recout_width
);
1656 DTRACE("DLG: %s: hscale_pixel_rate_l = %3.2f", __func__
, hscale_pixel_rate_l
);
1658 "DLG: %s: refcyc_per_line_delivery_pre_l = %3.2f",
1660 refcyc_per_line_delivery_pre_l
);
1662 "DLG: %s: refcyc_per_line_delivery_l = %3.2f",
1664 refcyc_per_line_delivery_l
);
1666 disp_dlg_regs
->refcyc_per_line_delivery_pre_l
= (unsigned int) dml_floor(
1667 refcyc_per_line_delivery_pre_l
,
1669 disp_dlg_regs
->refcyc_per_line_delivery_l
= (unsigned int) dml_floor(
1670 refcyc_per_line_delivery_l
,
1672 ASSERT(disp_dlg_regs
->refcyc_per_line_delivery_pre_l
< (unsigned int) dml_pow(2, 13));
1673 ASSERT(disp_dlg_regs
->refcyc_per_line_delivery_l
< (unsigned int) dml_pow(2, 13));
1676 refcyc_per_line_delivery_pre_c
= get_refcyc_per_delivery(
1682 hscale_pixel_rate_c
,
1683 swath_width_pixels_ub_c
,
1686 refcyc_per_line_delivery_c
= get_refcyc_per_delivery(
1692 hscale_pixel_rate_c
,
1693 swath_width_pixels_ub_c
,
1697 "DLG: %s: refcyc_per_line_delivery_pre_c = %3.2f",
1699 refcyc_per_line_delivery_pre_c
);
1701 "DLG: %s: refcyc_per_line_delivery_c = %3.2f",
1703 refcyc_per_line_delivery_c
);
1705 disp_dlg_regs
->refcyc_per_line_delivery_pre_c
= (unsigned int) dml_floor(
1706 refcyc_per_line_delivery_pre_c
,
1708 disp_dlg_regs
->refcyc_per_line_delivery_c
= (unsigned int) dml_floor(
1709 refcyc_per_line_delivery_c
,
1711 ASSERT(disp_dlg_regs
->refcyc_per_line_delivery_pre_c
< (unsigned int) dml_pow(2, 13));
1712 ASSERT(disp_dlg_regs
->refcyc_per_line_delivery_c
< (unsigned int) dml_pow(2, 13));
1714 disp_dlg_regs
->chunk_hdl_adjust_cur0
= 3;
1716 /* TTU - Luma / Chroma */
1717 if (access_dir
) { /* vertical access */
1718 scaler_rec_in_width_l
= vp_height_l
;
1719 scaler_rec_in_width_c
= vp_height_c
;
1721 scaler_rec_in_width_l
= vp_width_l
;
1722 scaler_rec_in_width_c
= vp_width_c
;
1725 refcyc_per_req_delivery_pre_l
= get_refcyc_per_delivery(
1731 hscale_pixel_rate_l
,
1732 scaler_rec_in_width_l
,
1733 req_per_swath_ub_l
); /* per req */
1734 refcyc_per_req_delivery_l
= get_refcyc_per_delivery(
1740 hscale_pixel_rate_l
,
1741 scaler_rec_in_width_l
,
1742 req_per_swath_ub_l
); /* per req */
1745 "DLG: %s: refcyc_per_req_delivery_pre_l = %3.2f",
1747 refcyc_per_req_delivery_pre_l
);
1749 "DLG: %s: refcyc_per_req_delivery_l = %3.2f",
1751 refcyc_per_req_delivery_l
);
1753 disp_ttu_regs
->refcyc_per_req_delivery_pre_l
= (unsigned int) (refcyc_per_req_delivery_pre_l
1755 disp_ttu_regs
->refcyc_per_req_delivery_l
= (unsigned int) (refcyc_per_req_delivery_l
1758 ASSERT(refcyc_per_req_delivery_pre_l
< dml_pow(2, 13));
1759 ASSERT(refcyc_per_req_delivery_l
< dml_pow(2, 13));
1762 refcyc_per_req_delivery_pre_c
= get_refcyc_per_delivery(
1768 hscale_pixel_rate_c
,
1769 scaler_rec_in_width_c
,
1770 req_per_swath_ub_c
); /* per req */
1771 refcyc_per_req_delivery_c
= get_refcyc_per_delivery(
1777 hscale_pixel_rate_c
,
1778 scaler_rec_in_width_c
,
1779 req_per_swath_ub_c
); /* per req */
1782 "DLG: %s: refcyc_per_req_delivery_pre_c = %3.2f",
1784 refcyc_per_req_delivery_pre_c
);
1786 "DLG: %s: refcyc_per_req_delivery_c = %3.2f",
1788 refcyc_per_req_delivery_c
);
1790 disp_ttu_regs
->refcyc_per_req_delivery_pre_c
=
1791 (unsigned int) (refcyc_per_req_delivery_pre_c
* dml_pow(2, 10));
1792 disp_ttu_regs
->refcyc_per_req_delivery_c
= (unsigned int) (refcyc_per_req_delivery_c
1795 ASSERT(refcyc_per_req_delivery_pre_c
< dml_pow(2, 13));
1796 ASSERT(refcyc_per_req_delivery_c
< dml_pow(2, 13));
1800 hratios_cur0
= e2e_pipe_param
.pipe
.scale_ratio_depth
.hscl_ratio
;
1801 cur0_src_width
= e2e_pipe_param
.pipe
.src
.cur0_src_width
; /* cursor source width */
1802 cur0_bpp
= (enum cursor_bpp
) e2e_pipe_param
.pipe
.src
.cur0_bpp
;
1805 cur0_width_ub
= 0.0;
1806 cur0_req_per_width
= 0.0;
1809 ASSERT(cur0_src_width
<= 256);
1811 if (cur0_src_width
> 0) {
1812 unsigned int cur0_bit_per_pixel
= 0;
1814 if (cur0_bpp
== dm_cur_2bit
) {
1815 cur0_req_size
= 64; /* byte */
1816 cur0_bit_per_pixel
= 2;
1817 } else { /* 32bit */
1818 cur0_bit_per_pixel
= 32;
1819 if (cur0_src_width
>= 1 && cur0_src_width
<= 16)
1821 else if (cur0_src_width
>= 17 && cur0_src_width
<= 31)
1822 cur0_req_size
= 128;
1824 cur0_req_size
= 256;
1827 cur0_req_width
= (double) cur0_req_size
/ ((double) cur0_bit_per_pixel
/ 8.0);
1828 cur0_width_ub
= dml_ceil((double) cur0_src_width
/ (double) cur0_req_width
, 1)
1829 * (double) cur0_req_width
;
1830 cur0_req_per_width
= cur0_width_ub
/ (double) cur0_req_width
;
1831 hactive_cur0
= (double) cur0_src_width
/ hratios_cur0
; /* FIXME: oswin to think about what to do for cursor */
1833 if (vratio_pre_l
<= 1.0) {
1834 refcyc_per_req_delivery_pre_cur0
= hactive_cur0
* ref_freq_to_pix_freq
1835 / (double) cur0_req_per_width
;
1837 refcyc_per_req_delivery_pre_cur0
= (double) refclk_freq_in_mhz
1838 * (double) cur0_src_width
/ hscale_pixel_rate_l
1839 / (double) cur0_req_per_width
;
1842 disp_ttu_regs
->refcyc_per_req_delivery_pre_cur0
=
1843 (unsigned int) (refcyc_per_req_delivery_pre_cur0
* dml_pow(2, 10));
1844 ASSERT(refcyc_per_req_delivery_pre_cur0
< dml_pow(2, 13));
1846 if (vratio_l
<= 1.0) {
1847 refcyc_per_req_delivery_cur0
= hactive_cur0
* ref_freq_to_pix_freq
1848 / (double) cur0_req_per_width
;
1850 refcyc_per_req_delivery_cur0
= (double) refclk_freq_in_mhz
1851 * (double) cur0_src_width
/ hscale_pixel_rate_l
1852 / (double) cur0_req_per_width
;
1855 DTRACE("DLG: %s: cur0_req_width = %d", __func__
, cur0_req_width
);
1857 "DLG: %s: cur0_width_ub = %3.2f",
1861 "DLG: %s: cur0_req_per_width = %3.2f",
1863 cur0_req_per_width
);
1865 "DLG: %s: hactive_cur0 = %3.2f",
1869 "DLG: %s: refcyc_per_req_delivery_pre_cur0 = %3.2f",
1871 refcyc_per_req_delivery_pre_cur0
);
1873 "DLG: %s: refcyc_per_req_delivery_cur0 = %3.2f",
1875 refcyc_per_req_delivery_cur0
);
1877 disp_ttu_regs
->refcyc_per_req_delivery_cur0
=
1878 (unsigned int) (refcyc_per_req_delivery_cur0
* dml_pow(2, 10));
1879 ASSERT(refcyc_per_req_delivery_cur0
< dml_pow(2, 13));
1881 disp_ttu_regs
->refcyc_per_req_delivery_pre_cur0
= 0;
1882 disp_ttu_regs
->refcyc_per_req_delivery_cur0
= 0;
1886 disp_ttu_regs
->qos_level_low_wm
= 0;
1887 ASSERT(disp_ttu_regs
->qos_level_low_wm
< dml_pow(2, 14));
1888 disp_ttu_regs
->qos_level_high_wm
= (unsigned int) (4.0 * (double) htotal
1889 * ref_freq_to_pix_freq
);
1890 ASSERT(disp_ttu_regs
->qos_level_high_wm
< dml_pow(2, 14));
1892 disp_ttu_regs
->qos_level_flip
= 14;
1893 disp_ttu_regs
->qos_level_fixed_l
= 8;
1894 disp_ttu_regs
->qos_level_fixed_c
= 8;
1895 disp_ttu_regs
->qos_level_fixed_cur0
= 8;
1896 disp_ttu_regs
->qos_ramp_disable_l
= 0;
1897 disp_ttu_regs
->qos_ramp_disable_c
= 0;
1898 disp_ttu_regs
->qos_ramp_disable_cur0
= 0;
1900 disp_ttu_regs
->min_ttu_vblank
= min_ttu_vblank
* refclk_freq_in_mhz
;
1901 ASSERT(disp_ttu_regs
->min_ttu_vblank
< dml_pow(2, 24));
1903 print__ttu_regs_st(mode_lib
, *disp_ttu_regs
);
1904 print__dlg_regs_st(mode_lib
, *disp_dlg_regs
);