2 * Copyright 2015 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 <linux/slab.h>
28 #include "dm_services.h"
29 #include "dce_calcs.h"
31 #include "core_types.h"
32 #include "dal_asic_id.h"
33 #include "calcs_logger.h"
37 * This file is gcc-parseable HW gospel, coming straight from HW engineers.
39 * It doesn't adhere to Linux kernel style and sometimes will do things in odd
40 * ways. Unless there is something clearly wrong with it the code should
41 * remain as-is as it provides us with a guarantee from HW that it is correct.
44 /*******************************************************************************
46 ******************************************************************************/
48 static enum bw_calcs_version bw_calcs_version_from_asic_id(struct hw_asic_id asic_id)
50 switch (asic_id.chip_family) {
53 if (ASIC_REV_IS_STONEY(asic_id.hw_internal_rev))
54 return BW_CALCS_VERSION_STONEY;
55 return BW_CALCS_VERSION_CARRIZO;
58 if (ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev))
59 return BW_CALCS_VERSION_POLARIS12;
60 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev))
61 return BW_CALCS_VERSION_POLARIS10;
62 if (ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev))
63 return BW_CALCS_VERSION_POLARIS11;
64 if (ASIC_REV_IS_VEGAM(asic_id.hw_internal_rev))
65 return BW_CALCS_VERSION_VEGAM;
66 return BW_CALCS_VERSION_INVALID;
69 return BW_CALCS_VERSION_VEGA10;
72 return BW_CALCS_VERSION_INVALID;
76 static void calculate_bandwidth(
77 const struct bw_calcs_dceip *dceip,
78 const struct bw_calcs_vbios *vbios,
79 struct bw_calcs_data *data)
82 const int32_t pixels_per_chunk = 512;
83 const int32_t high = 2;
84 const int32_t mid = 1;
85 const int32_t low = 0;
86 const uint32_t s_low = 0;
87 const uint32_t s_mid1 = 1;
88 const uint32_t s_mid2 = 2;
89 const uint32_t s_mid3 = 3;
90 const uint32_t s_mid4 = 4;
91 const uint32_t s_mid5 = 5;
92 const uint32_t s_mid6 = 6;
93 const uint32_t s_high = 7;
94 const uint32_t dmif_chunk_buff_margin = 1;
96 uint32_t max_chunks_fbc_mode;
97 int32_t num_cursor_lines;
100 struct bw_fixed yclk[3];
101 struct bw_fixed sclk[8];
102 bool d0_underlay_enable;
103 bool d1_underlay_enable;
106 enum bw_defines sclk_message;
107 enum bw_defines yclk_message;
108 enum bw_defines v_filter_init_mode[maximum_number_of_surfaces];
109 enum bw_defines tiling_mode[maximum_number_of_surfaces];
110 enum bw_defines surface_type[maximum_number_of_surfaces];
111 enum bw_defines voltage;
112 enum bw_defines pipe_check;
113 enum bw_defines hsr_check;
114 enum bw_defines vsr_check;
115 enum bw_defines lb_size_check;
116 enum bw_defines fbc_check;
117 enum bw_defines rotation_check;
118 enum bw_defines mode_check;
119 enum bw_defines nbp_state_change_enable_blank;
120 /*initialize variables*/
121 int32_t number_of_displays_enabled = 0;
122 int32_t number_of_displays_enabled_with_margin = 0;
123 int32_t number_of_aligned_displays_with_no_margin = 0;
125 yclk[low] = vbios->low_yclk;
126 yclk[mid] = vbios->mid_yclk;
127 yclk[high] = vbios->high_yclk;
128 sclk[s_low] = vbios->low_sclk;
129 sclk[s_mid1] = vbios->mid1_sclk;
130 sclk[s_mid2] = vbios->mid2_sclk;
131 sclk[s_mid3] = vbios->mid3_sclk;
132 sclk[s_mid4] = vbios->mid4_sclk;
133 sclk[s_mid5] = vbios->mid5_sclk;
134 sclk[s_mid6] = vbios->mid6_sclk;
135 sclk[s_high] = vbios->high_sclk;
136 /*''''''''''''''''''*/
137 /* surface assignment:*/
138 /* 0: d0 underlay or underlay luma*/
139 /* 1: d0 underlay chroma*/
140 /* 2: d1 underlay or underlay luma*/
141 /* 3: d1 underlay chroma*/
145 /* 7: d3 graphics, same mode as d2*/
146 /* 8: d4 graphics, same mode as d2*/
147 /* 9: d5 graphics, same mode as d2*/
149 /* maximum_number_of_surfaces-2: d1 display_write_back420 luma*/
150 /* maximum_number_of_surfaces-1: d1 display_write_back420 chroma*/
151 /* underlay luma and chroma surface parameters from spreadsheet*/
156 if (data->d0_underlay_mode == bw_def_none) { d0_underlay_enable = 0; }
158 d0_underlay_enable = 1;
160 if (data->d1_underlay_mode == bw_def_none) { d1_underlay_enable = 0; }
162 d1_underlay_enable = 1;
164 data->number_of_underlay_surfaces = d0_underlay_enable + d1_underlay_enable;
165 switch (data->underlay_surface_type) {
167 surface_type[0] = bw_def_underlay420_luma;
168 surface_type[2] = bw_def_underlay420_luma;
169 data->bytes_per_pixel[0] = 1;
170 data->bytes_per_pixel[2] = 1;
171 surface_type[1] = bw_def_underlay420_chroma;
172 surface_type[3] = bw_def_underlay420_chroma;
173 data->bytes_per_pixel[1] = 2;
174 data->bytes_per_pixel[3] = 2;
175 data->lb_size_per_component[0] = dceip->underlay420_luma_lb_size_per_component;
176 data->lb_size_per_component[1] = dceip->underlay420_chroma_lb_size_per_component;
177 data->lb_size_per_component[2] = dceip->underlay420_luma_lb_size_per_component;
178 data->lb_size_per_component[3] = dceip->underlay420_chroma_lb_size_per_component;
181 surface_type[0] = bw_def_underlay422;
182 surface_type[2] = bw_def_underlay422;
183 data->bytes_per_pixel[0] = 2;
184 data->bytes_per_pixel[2] = 2;
185 data->lb_size_per_component[0] = dceip->underlay422_lb_size_per_component;
186 data->lb_size_per_component[2] = dceip->underlay422_lb_size_per_component;
189 surface_type[0] = bw_def_underlay444;
190 surface_type[2] = bw_def_underlay444;
191 data->bytes_per_pixel[0] = 4;
192 data->bytes_per_pixel[2] = 4;
193 data->lb_size_per_component[0] = dceip->lb_size_per_component444;
194 data->lb_size_per_component[2] = dceip->lb_size_per_component444;
197 if (d0_underlay_enable) {
198 switch (data->underlay_surface_type) {
213 if (d1_underlay_enable) {
214 switch (data->underlay_surface_type) {
229 data->use_alpha[0] = 0;
230 data->use_alpha[1] = 0;
231 data->use_alpha[2] = 0;
232 data->use_alpha[3] = 0;
233 data->scatter_gather_enable_for_pipe[0] = vbios->scatter_gather_enable;
234 data->scatter_gather_enable_for_pipe[1] = vbios->scatter_gather_enable;
235 data->scatter_gather_enable_for_pipe[2] = vbios->scatter_gather_enable;
236 data->scatter_gather_enable_for_pipe[3] = vbios->scatter_gather_enable;
237 /*underlay0 same and graphics display pipe0*/
238 data->interlace_mode[0] = data->interlace_mode[4];
239 data->interlace_mode[1] = data->interlace_mode[4];
240 /*underlay1 same and graphics display pipe1*/
241 data->interlace_mode[2] = data->interlace_mode[5];
242 data->interlace_mode[3] = data->interlace_mode[5];
243 /*underlay0 same and graphics display pipe0*/
244 data->h_total[0] = data->h_total[4];
245 data->v_total[0] = data->v_total[4];
246 data->h_total[1] = data->h_total[4];
247 data->v_total[1] = data->v_total[4];
248 /*underlay1 same and graphics display pipe1*/
249 data->h_total[2] = data->h_total[5];
250 data->v_total[2] = data->v_total[5];
251 data->h_total[3] = data->h_total[5];
252 data->v_total[3] = data->v_total[5];
253 /*underlay0 same and graphics display pipe0*/
254 data->pixel_rate[0] = data->pixel_rate[4];
255 data->pixel_rate[1] = data->pixel_rate[4];
256 /*underlay1 same and graphics display pipe1*/
257 data->pixel_rate[2] = data->pixel_rate[5];
258 data->pixel_rate[3] = data->pixel_rate[5];
259 if ((data->underlay_tiling_mode == bw_def_array_linear_general || data->underlay_tiling_mode == bw_def_array_linear_aligned)) {
260 tiling_mode[0] = bw_def_linear;
261 tiling_mode[1] = bw_def_linear;
262 tiling_mode[2] = bw_def_linear;
263 tiling_mode[3] = bw_def_linear;
266 tiling_mode[0] = bw_def_landscape;
267 tiling_mode[1] = bw_def_landscape;
268 tiling_mode[2] = bw_def_landscape;
269 tiling_mode[3] = bw_def_landscape;
271 data->lb_bpc[0] = data->underlay_lb_bpc;
272 data->lb_bpc[1] = data->underlay_lb_bpc;
273 data->lb_bpc[2] = data->underlay_lb_bpc;
274 data->lb_bpc[3] = data->underlay_lb_bpc;
275 data->compression_rate[0] = bw_int_to_fixed(1);
276 data->compression_rate[1] = bw_int_to_fixed(1);
277 data->compression_rate[2] = bw_int_to_fixed(1);
278 data->compression_rate[3] = bw_int_to_fixed(1);
279 data->access_one_channel_only[0] = 0;
280 data->access_one_channel_only[1] = 0;
281 data->access_one_channel_only[2] = 0;
282 data->access_one_channel_only[3] = 0;
283 data->cursor_width_pixels[0] = bw_int_to_fixed(0);
284 data->cursor_width_pixels[1] = bw_int_to_fixed(0);
285 data->cursor_width_pixels[2] = bw_int_to_fixed(0);
286 data->cursor_width_pixels[3] = bw_int_to_fixed(0);
287 /* graphics surface parameters from spreadsheet*/
290 for (i = 4; i <= maximum_number_of_surfaces - 3; i++) {
291 if (i < data->number_of_displays + 4) {
292 if (i == 4 && data->d0_underlay_mode == bw_def_underlay_only) {
294 data->use_alpha[i] = 0;
296 else if (i == 4 && data->d0_underlay_mode == bw_def_blend) {
298 data->use_alpha[i] = 1;
302 data->use_alpha[i] = 0;
304 else if (i == 5 && data->d1_underlay_mode == bw_def_underlay_only) {
306 data->use_alpha[i] = 0;
308 else if (i == 5 && data->d1_underlay_mode == bw_def_blend) {
310 data->use_alpha[i] = 1;
314 data->use_alpha[i] = 0;
319 data->use_alpha[i] = 0;
321 data->scatter_gather_enable_for_pipe[i] = vbios->scatter_gather_enable;
322 surface_type[i] = bw_def_graphics;
323 data->lb_size_per_component[i] = dceip->lb_size_per_component444;
324 if (data->graphics_tiling_mode == bw_def_array_linear_general || data->graphics_tiling_mode == bw_def_array_linear_aligned) {
325 tiling_mode[i] = bw_def_linear;
328 tiling_mode[i] = bw_def_tiled;
330 data->lb_bpc[i] = data->graphics_lb_bpc;
331 if ((data->fbc_en[i] == 1 && (dceip->argb_compression_support || data->d0_underlay_mode != bw_def_blended))) {
332 data->compression_rate[i] = bw_int_to_fixed(vbios->average_compression_rate);
333 data->access_one_channel_only[i] = data->lpt_en[i];
336 data->compression_rate[i] = bw_int_to_fixed(1);
337 data->access_one_channel_only[i] = 0;
339 if (data->fbc_en[i] == 1) {
341 if (data->lpt_en[i] == 1) {
345 data->cursor_width_pixels[i] = bw_int_to_fixed(vbios->cursor_width);
347 /* display_write_back420*/
348 data->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 2] = 0;
349 data->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 1] = 0;
350 if (data->d1_display_write_back_dwb_enable == 1) {
351 data->enable[maximum_number_of_surfaces - 2] = 1;
352 data->enable[maximum_number_of_surfaces - 1] = 1;
355 data->enable[maximum_number_of_surfaces - 2] = 0;
356 data->enable[maximum_number_of_surfaces - 1] = 0;
358 surface_type[maximum_number_of_surfaces - 2] = bw_def_display_write_back420_luma;
359 surface_type[maximum_number_of_surfaces - 1] = bw_def_display_write_back420_chroma;
360 data->lb_size_per_component[maximum_number_of_surfaces - 2] = dceip->underlay420_luma_lb_size_per_component;
361 data->lb_size_per_component[maximum_number_of_surfaces - 1] = dceip->underlay420_chroma_lb_size_per_component;
362 data->bytes_per_pixel[maximum_number_of_surfaces - 2] = 1;
363 data->bytes_per_pixel[maximum_number_of_surfaces - 1] = 2;
364 data->interlace_mode[maximum_number_of_surfaces - 2] = data->interlace_mode[5];
365 data->interlace_mode[maximum_number_of_surfaces - 1] = data->interlace_mode[5];
366 data->h_taps[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
367 data->h_taps[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
368 data->v_taps[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
369 data->v_taps[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
370 data->rotation_angle[maximum_number_of_surfaces - 2] = bw_int_to_fixed(0);
371 data->rotation_angle[maximum_number_of_surfaces - 1] = bw_int_to_fixed(0);
372 tiling_mode[maximum_number_of_surfaces - 2] = bw_def_linear;
373 tiling_mode[maximum_number_of_surfaces - 1] = bw_def_linear;
374 data->lb_bpc[maximum_number_of_surfaces - 2] = 8;
375 data->lb_bpc[maximum_number_of_surfaces - 1] = 8;
376 data->compression_rate[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
377 data->compression_rate[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
378 data->access_one_channel_only[maximum_number_of_surfaces - 2] = 0;
379 data->access_one_channel_only[maximum_number_of_surfaces - 1] = 0;
380 /*assume display pipe1 has dwb enabled*/
381 data->h_total[maximum_number_of_surfaces - 2] = data->h_total[5];
382 data->h_total[maximum_number_of_surfaces - 1] = data->h_total[5];
383 data->v_total[maximum_number_of_surfaces - 2] = data->v_total[5];
384 data->v_total[maximum_number_of_surfaces - 1] = data->v_total[5];
385 data->pixel_rate[maximum_number_of_surfaces - 2] = data->pixel_rate[5];
386 data->pixel_rate[maximum_number_of_surfaces - 1] = data->pixel_rate[5];
387 data->src_width[maximum_number_of_surfaces - 2] = data->src_width[5];
388 data->src_width[maximum_number_of_surfaces - 1] = data->src_width[5];
389 data->src_height[maximum_number_of_surfaces - 2] = data->src_height[5];
390 data->src_height[maximum_number_of_surfaces - 1] = data->src_height[5];
391 data->pitch_in_pixels[maximum_number_of_surfaces - 2] = data->src_width[5];
392 data->pitch_in_pixels[maximum_number_of_surfaces - 1] = data->src_width[5];
393 data->h_scale_ratio[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
394 data->h_scale_ratio[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
395 data->v_scale_ratio[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
396 data->v_scale_ratio[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
397 data->stereo_mode[maximum_number_of_surfaces - 2] = bw_def_mono;
398 data->stereo_mode[maximum_number_of_surfaces - 1] = bw_def_mono;
399 data->cursor_width_pixels[maximum_number_of_surfaces - 2] = bw_int_to_fixed(0);
400 data->cursor_width_pixels[maximum_number_of_surfaces - 1] = bw_int_to_fixed(0);
401 data->use_alpha[maximum_number_of_surfaces - 2] = 0;
402 data->use_alpha[maximum_number_of_surfaces - 1] = 0;
403 /*mode check calculations:*/
404 /* mode within dce ip capabilities*/
409 /*effective scaling source and ratios:*/
410 /*for graphics, non-stereo, non-interlace surfaces when the size of the source and destination are the same, only one tap is used*/
411 /*420 chroma has half the width, height, horizontal and vertical scaling ratios than luma*/
412 /*rotating a graphic or underlay surface swaps the width, height, horizontal and vertical scaling ratios*/
413 /*in top-bottom stereo mode there is 2:1 vertical downscaling for each eye*/
414 /*in side-by-side stereo mode there is 2:1 horizontal downscaling for each eye*/
415 /*in interlace mode there is 2:1 vertical downscaling for each field*/
416 /*in panning or bezel adjustment mode the source width has an extra 128 pixels*/
417 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
418 if (data->enable[i]) {
419 if (bw_equ(data->h_scale_ratio[i], bw_int_to_fixed(1)) && bw_equ(data->v_scale_ratio[i], bw_int_to_fixed(1)) && surface_type[i] == bw_def_graphics && data->stereo_mode[i] == bw_def_mono && data->interlace_mode[i] == 0) {
420 data->h_taps[i] = bw_int_to_fixed(1);
421 data->v_taps[i] = bw_int_to_fixed(1);
423 if (surface_type[i] == bw_def_display_write_back420_chroma || surface_type[i] == bw_def_underlay420_chroma) {
424 data->pitch_in_pixels_after_surface_type[i] = bw_div(data->pitch_in_pixels[i], bw_int_to_fixed(2));
425 data->src_width_after_surface_type = bw_div(data->src_width[i], bw_int_to_fixed(2));
426 data->src_height_after_surface_type = bw_div(data->src_height[i], bw_int_to_fixed(2));
427 data->hsr_after_surface_type = bw_div(data->h_scale_ratio[i], bw_int_to_fixed(2));
428 data->vsr_after_surface_type = bw_div(data->v_scale_ratio[i], bw_int_to_fixed(2));
431 data->pitch_in_pixels_after_surface_type[i] = data->pitch_in_pixels[i];
432 data->src_width_after_surface_type = data->src_width[i];
433 data->src_height_after_surface_type = data->src_height[i];
434 data->hsr_after_surface_type = data->h_scale_ratio[i];
435 data->vsr_after_surface_type = data->v_scale_ratio[i];
437 if ((bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270))) && surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
438 data->src_width_after_rotation = data->src_height_after_surface_type;
439 data->src_height_after_rotation = data->src_width_after_surface_type;
440 data->hsr_after_rotation = data->vsr_after_surface_type;
441 data->vsr_after_rotation = data->hsr_after_surface_type;
444 data->src_width_after_rotation = data->src_width_after_surface_type;
445 data->src_height_after_rotation = data->src_height_after_surface_type;
446 data->hsr_after_rotation = data->hsr_after_surface_type;
447 data->vsr_after_rotation = data->vsr_after_surface_type;
449 switch (data->stereo_mode[i]) {
450 case bw_def_top_bottom:
451 data->source_width_pixels[i] = data->src_width_after_rotation;
452 data->source_height_pixels = bw_mul(bw_int_to_fixed(2), data->src_height_after_rotation);
453 data->hsr_after_stereo = data->hsr_after_rotation;
454 data->vsr_after_stereo = bw_mul(bw_int_to_fixed(1), data->vsr_after_rotation);
456 case bw_def_side_by_side:
457 data->source_width_pixels[i] = bw_mul(bw_int_to_fixed(2), data->src_width_after_rotation);
458 data->source_height_pixels = data->src_height_after_rotation;
459 data->hsr_after_stereo = bw_mul(bw_int_to_fixed(1), data->hsr_after_rotation);
460 data->vsr_after_stereo = data->vsr_after_rotation;
463 data->source_width_pixels[i] = data->src_width_after_rotation;
464 data->source_height_pixels = data->src_height_after_rotation;
465 data->hsr_after_stereo = data->hsr_after_rotation;
466 data->vsr_after_stereo = data->vsr_after_rotation;
469 data->hsr[i] = data->hsr_after_stereo;
470 if (data->interlace_mode[i]) {
471 data->vsr[i] = bw_mul(data->vsr_after_stereo, bw_int_to_fixed(2));
474 data->vsr[i] = data->vsr_after_stereo;
476 if (data->panning_and_bezel_adjustment != bw_def_none) {
477 data->source_width_rounded_up_to_chunks[i] = bw_add(bw_floor2(bw_sub(data->source_width_pixels[i], bw_int_to_fixed(1)), bw_int_to_fixed(128)), bw_int_to_fixed(256));
480 data->source_width_rounded_up_to_chunks[i] = bw_ceil2(data->source_width_pixels[i], bw_int_to_fixed(128));
482 data->source_height_rounded_up_to_chunks[i] = data->source_height_pixels;
485 /*mode support checks:*/
486 /*the number of graphics and underlay pipes is limited by the ip support*/
487 /*maximum horizontal and vertical scale ratio is 4, and should not exceed the number of taps*/
488 /*for downscaling with the pre-downscaler, the horizontal scale ratio must be more than the ceiling of one quarter of the number of taps*/
489 /*the pre-downscaler reduces the line buffer source by the horizontal scale ratio*/
490 /*the number of lines in the line buffer has to exceed the number of vertical taps*/
491 /*the size of the line in the line buffer is the product of the source width and the bits per component, rounded up to a multiple of 48*/
492 /*the size of the line in the line buffer in the case of 10 bit per component is the product of the source width rounded up to multiple of 8 and 30.023438 / 3, rounded up to a multiple of 48*/
493 /*the size of the line in the line buffer in the case of 8 bit per component is the product of the source width rounded up to multiple of 8 and 30.023438 / 3, rounded up to a multiple of 48*/
494 /*frame buffer compression is not supported with stereo mode, rotation, or non- 888 formats*/
495 /*rotation is not supported with linear of stereo modes*/
496 if (dceip->number_of_graphics_pipes >= data->number_of_displays && dceip->number_of_underlay_pipes >= data->number_of_underlay_surfaces && !(dceip->display_write_back_supported == 0 && data->d1_display_write_back_dwb_enable == 1)) {
497 pipe_check = bw_def_ok;
500 pipe_check = bw_def_notok;
502 hsr_check = bw_def_ok;
503 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
504 if (data->enable[i]) {
505 if (bw_neq(data->hsr[i], bw_int_to_fixed(1))) {
506 if (bw_mtn(data->hsr[i], bw_int_to_fixed(4))) {
507 hsr_check = bw_def_hsr_mtn_4;
510 if (bw_mtn(data->hsr[i], data->h_taps[i])) {
511 hsr_check = bw_def_hsr_mtn_h_taps;
514 if (dceip->pre_downscaler_enabled == 1 && bw_mtn(data->hsr[i], bw_int_to_fixed(1)) && bw_leq(data->hsr[i], bw_ceil2(bw_div(data->h_taps[i], bw_int_to_fixed(4)), bw_int_to_fixed(1)))) {
515 hsr_check = bw_def_ceiling__h_taps_div_4___meq_hsr;
522 vsr_check = bw_def_ok;
523 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
524 if (data->enable[i]) {
525 if (bw_neq(data->vsr[i], bw_int_to_fixed(1))) {
526 if (bw_mtn(data->vsr[i], bw_int_to_fixed(4))) {
527 vsr_check = bw_def_vsr_mtn_4;
530 if (bw_mtn(data->vsr[i], data->v_taps[i])) {
531 vsr_check = bw_def_vsr_mtn_v_taps;
537 lb_size_check = bw_def_ok;
538 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
539 if (data->enable[i]) {
540 if ((dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1)))) {
541 data->source_width_in_lb = bw_div(data->source_width_pixels[i], data->hsr[i]);
544 data->source_width_in_lb = data->source_width_pixels[i];
546 switch (data->lb_bpc[i]) {
548 data->lb_line_pitch = bw_ceil2(bw_mul(bw_div(bw_frc_to_fixed(2401171875ul, 100000000), bw_int_to_fixed(3)), bw_ceil2(data->source_width_in_lb, bw_int_to_fixed(8))), bw_int_to_fixed(48));
551 data->lb_line_pitch = bw_ceil2(bw_mul(bw_div(bw_frc_to_fixed(300234375, 10000000), bw_int_to_fixed(3)), bw_ceil2(data->source_width_in_lb, bw_int_to_fixed(8))), bw_int_to_fixed(48));
554 data->lb_line_pitch = bw_ceil2(bw_mul(bw_int_to_fixed(data->lb_bpc[i]), data->source_width_in_lb), bw_int_to_fixed(48));
557 data->lb_partitions[i] = bw_floor2(bw_div(data->lb_size_per_component[i], data->lb_line_pitch), bw_int_to_fixed(1));
558 /*clamp the partitions to the maxium number supported by the lb*/
559 if ((surface_type[i] != bw_def_graphics || dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1)) {
560 data->lb_partitions_max[i] = bw_int_to_fixed(10);
563 data->lb_partitions_max[i] = bw_int_to_fixed(7);
565 data->lb_partitions[i] = bw_min2(data->lb_partitions_max[i], data->lb_partitions[i]);
566 if (bw_mtn(bw_add(data->v_taps[i], bw_int_to_fixed(1)), data->lb_partitions[i])) {
567 lb_size_check = bw_def_notok;
571 fbc_check = bw_def_ok;
572 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
573 if (data->enable[i] && data->fbc_en[i] == 1 && (bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270)) || data->stereo_mode[i] != bw_def_mono || data->bytes_per_pixel[i] != 4)) {
574 fbc_check = bw_def_invalid_rotation_or_bpp_or_stereo;
577 rotation_check = bw_def_ok;
578 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
579 if (data->enable[i]) {
580 if ((bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270))) && (tiling_mode[i] == bw_def_linear || data->stereo_mode[i] != bw_def_mono)) {
581 rotation_check = bw_def_invalid_linear_or_stereo_mode;
585 if (pipe_check == bw_def_ok && hsr_check == bw_def_ok && vsr_check == bw_def_ok && lb_size_check == bw_def_ok && fbc_check == bw_def_ok && rotation_check == bw_def_ok) {
586 mode_check = bw_def_ok;
589 mode_check = bw_def_notok;
591 /*number of memory channels for write-back client*/
592 data->number_of_dram_wrchannels = vbios->number_of_dram_channels;
593 data->number_of_dram_channels = vbios->number_of_dram_channels;
594 /*modify number of memory channels if lpt mode is enabled*/
595 /* low power tiling mode register*/
596 /* 0 = use channel 0*/
597 /* 1 = use channel 0 and 1*/
598 /* 2 = use channel 0,1,2,3*/
599 if ((fbc_enabled == 1 && lpt_enabled == 1)) {
600 if (vbios->memory_type == bw_def_hbm)
601 data->dram_efficiency = bw_frc_to_fixed(5, 10);
603 data->dram_efficiency = bw_int_to_fixed(1);
606 if (dceip->low_power_tiling_mode == 0) {
607 data->number_of_dram_channels = 1;
609 else if (dceip->low_power_tiling_mode == 1) {
610 data->number_of_dram_channels = 2;
612 else if (dceip->low_power_tiling_mode == 2) {
613 data->number_of_dram_channels = 4;
616 data->number_of_dram_channels = 1;
620 if (vbios->memory_type == bw_def_hbm)
621 data->dram_efficiency = bw_frc_to_fixed(5, 10);
623 data->dram_efficiency = bw_frc_to_fixed(8, 10);
625 /*memory request size and latency hiding:*/
626 /*request size is normally 64 byte, 2-line interleaved, with full latency hiding*/
627 /*the display write-back requests are single line*/
628 /*for tiled graphics surfaces, or undelay surfaces with width higher than the maximum size for full efficiency, request size is 32 byte in 8 and 16 bpp or if the rotation is orthogonal to the tiling grain. only half is useful of the bytes in the request size in 8 bpp or in 32 bpp if the rotation is orthogonal to the tiling grain.*/
629 /*for undelay surfaces with width lower than the maximum size for full efficiency, requests are 4-line interleaved in 16bpp if the rotation is parallel to the tiling grain, and 8-line interleaved with 4-line latency hiding in 8bpp or if the rotation is orthogonal to the tiling grain.*/
630 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
631 if (data->enable[i]) {
632 if ((bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270)))) {
634 /*underlay portrait tiling mode is not supported*/
635 data->orthogonal_rotation[i] = 1;
638 /*graphics portrait tiling mode*/
639 if (data->graphics_micro_tile_mode == bw_def_rotated_micro_tiling) {
640 data->orthogonal_rotation[i] = 0;
643 data->orthogonal_rotation[i] = 1;
649 /*underlay landscape tiling mode is only supported*/
650 if (data->underlay_micro_tile_mode == bw_def_display_micro_tiling) {
651 data->orthogonal_rotation[i] = 0;
654 data->orthogonal_rotation[i] = 1;
658 /*graphics landscape tiling mode*/
659 if (data->graphics_micro_tile_mode == bw_def_display_micro_tiling) {
660 data->orthogonal_rotation[i] = 0;
663 data->orthogonal_rotation[i] = 1;
667 if (bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270))) {
668 data->underlay_maximum_source_efficient_for_tiling = dceip->underlay_maximum_height_efficient_for_tiling;
671 data->underlay_maximum_source_efficient_for_tiling = dceip->underlay_maximum_width_efficient_for_tiling;
673 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
674 data->bytes_per_request[i] = bw_int_to_fixed(64);
675 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
676 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(1);
677 data->latency_hiding_lines[i] = bw_int_to_fixed(1);
679 else if (tiling_mode[i] == bw_def_linear) {
680 data->bytes_per_request[i] = bw_int_to_fixed(64);
681 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
682 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
683 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
686 if (surface_type[i] == bw_def_graphics || (bw_mtn(data->source_width_rounded_up_to_chunks[i], bw_ceil2(data->underlay_maximum_source_efficient_for_tiling, bw_int_to_fixed(256))))) {
687 switch (data->bytes_per_pixel[i]) {
689 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
690 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
691 if (data->orthogonal_rotation[i]) {
692 data->bytes_per_request[i] = bw_int_to_fixed(32);
693 data->useful_bytes_per_request[i] = bw_int_to_fixed(32);
696 data->bytes_per_request[i] = bw_int_to_fixed(64);
697 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
701 if (data->orthogonal_rotation[i]) {
702 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
703 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
704 data->bytes_per_request[i] = bw_int_to_fixed(32);
705 data->useful_bytes_per_request[i] = bw_int_to_fixed(16);
708 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
709 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
710 data->bytes_per_request[i] = bw_int_to_fixed(64);
711 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
715 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
716 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
717 data->bytes_per_request[i] = bw_int_to_fixed(32);
718 data->useful_bytes_per_request[i] = bw_int_to_fixed(32);
721 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
722 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
723 data->bytes_per_request[i] = bw_int_to_fixed(32);
724 data->useful_bytes_per_request[i] = bw_int_to_fixed(16);
729 data->bytes_per_request[i] = bw_int_to_fixed(64);
730 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
731 if (data->orthogonal_rotation[i]) {
732 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(8);
733 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
736 switch (data->bytes_per_pixel[i]) {
738 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
739 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
742 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(4);
743 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
746 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(8);
747 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
755 /*requested peak bandwidth:*/
756 /*the peak request-per-second bandwidth is the product of the maximum source lines in per line out in the beginning*/
757 /*and in the middle of the frame, the ratio of the source width to the line time, the ratio of line interleaving*/
758 /*in memory to lines of latency hiding, and the ratio of bytes per pixel to useful bytes per request.*/
760 /*if the dmif data buffer size holds more than vta_ps worth of source lines, then only vsr is used.*/
761 /*the peak bandwidth is the peak request-per-second bandwidth times the request size.*/
763 /*the line buffer lines in per line out in the beginning of the frame is the vertical filter initialization value*/
764 /*rounded up to even and divided by the line times for initialization, which is normally three.*/
765 /*the line buffer lines in per line out in the middle of the frame is at least one, or the vertical scale ratio,*/
766 /*rounded up to line pairs if not doing line buffer prefetching.*/
768 /*the non-prefetching rounding up of the vertical scale ratio can also be done up to 1 (for a 0,2 pattern), 4/3 (for a 0,2,2 pattern),*/
769 /*6/4 (for a 0,2,2,2 pattern), or 3 (for a 2,4 pattern).*/
771 /*the scaler vertical filter initialization value is calculated by the hardware as the floor of the average of the*/
772 /*vertical scale ratio and the number of vertical taps increased by one. add one more for possible odd line*/
773 /*panning/bezel adjustment mode.*/
775 /*for the bottom interlace field an extra 50% of the vertical scale ratio is considered for this calculation.*/
776 /*in top-bottom stereo mode software has to set the filter initialization value manually and explicitly limit it to 4.*/
777 /*furthermore, there is only one line time for initialization.*/
779 /*line buffer prefetching is done when the number of lines in the line buffer exceeds the number of taps plus*/
780 /*the ceiling of the vertical scale ratio.*/
782 /*multi-line buffer prefetching is only done in the graphics pipe when the scaler is disabled or when upscaling and the vsr <= 0.8.'*/
784 /*the horizontal blank and chunk granularity factor is indirectly used indicate the interval of time required to transfer the source pixels.*/
785 /*the denominator of this term represents the total number of destination output pixels required for the input source pixels.*/
786 /*it applies when the lines in per line out is not 2 or 4. it does not apply when there is a line buffer between the scl and blnd.*/
787 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
788 if (data->enable[i]) {
789 data->v_filter_init[i] = bw_floor2(bw_div((bw_add(bw_add(bw_add(bw_int_to_fixed(1), data->v_taps[i]), data->vsr[i]), bw_mul(bw_mul(bw_int_to_fixed(data->interlace_mode[i]), bw_frc_to_fixed(5, 10)), data->vsr[i]))), bw_int_to_fixed(2)), bw_int_to_fixed(1));
790 if (data->panning_and_bezel_adjustment == bw_def_any_lines) {
791 data->v_filter_init[i] = bw_add(data->v_filter_init[i], bw_int_to_fixed(1));
793 if (data->stereo_mode[i] == bw_def_top_bottom) {
794 v_filter_init_mode[i] = bw_def_manual;
795 data->v_filter_init[i] = bw_min2(data->v_filter_init[i], bw_int_to_fixed(4));
798 v_filter_init_mode[i] = bw_def_auto;
800 if (data->stereo_mode[i] == bw_def_top_bottom) {
801 data->num_lines_at_frame_start = bw_int_to_fixed(1);
804 data->num_lines_at_frame_start = bw_int_to_fixed(3);
806 if ((bw_mtn(data->vsr[i], bw_int_to_fixed(1)) && surface_type[i] == bw_def_graphics) || data->panning_and_bezel_adjustment == bw_def_any_lines) {
807 data->line_buffer_prefetch[i] = 0;
809 else if ((((dceip->underlay_downscale_prefetch_enabled == 1 && surface_type[i] != bw_def_graphics) || surface_type[i] == bw_def_graphics) && (bw_mtn(data->lb_partitions[i], bw_add(data->v_taps[i], bw_ceil2(data->vsr[i], bw_int_to_fixed(1))))))) {
810 data->line_buffer_prefetch[i] = 1;
813 data->line_buffer_prefetch[i] = 0;
815 data->lb_lines_in_per_line_out_in_beginning_of_frame[i] = bw_div(bw_ceil2(data->v_filter_init[i], bw_int_to_fixed(dceip->lines_interleaved_into_lb)), data->num_lines_at_frame_start);
816 if (data->line_buffer_prefetch[i] == 1) {
817 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_max2(bw_int_to_fixed(1), data->vsr[i]);
819 else if (bw_leq(data->vsr[i], bw_int_to_fixed(1))) {
820 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(1);
821 } else if (bw_leq(data->vsr[i],
822 bw_frc_to_fixed(4, 3))) {
823 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_div(bw_int_to_fixed(4), bw_int_to_fixed(3));
824 } else if (bw_leq(data->vsr[i],
825 bw_frc_to_fixed(6, 4))) {
826 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_div(bw_int_to_fixed(6), bw_int_to_fixed(4));
828 else if (bw_leq(data->vsr[i], bw_int_to_fixed(2))) {
829 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(2);
831 else if (bw_leq(data->vsr[i], bw_int_to_fixed(3))) {
832 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(3);
835 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(4);
837 if (data->line_buffer_prefetch[i] == 1 || bw_equ(data->lb_lines_in_per_line_out_in_middle_of_frame[i], bw_int_to_fixed(2)) || bw_equ(data->lb_lines_in_per_line_out_in_middle_of_frame[i], bw_int_to_fixed(4))) {
838 data->horizontal_blank_and_chunk_granularity_factor[i] = bw_int_to_fixed(1);
841 data->horizontal_blank_and_chunk_granularity_factor[i] = bw_div(data->h_total[i], (bw_div((bw_add(data->h_total[i], bw_div((bw_sub(data->source_width_pixels[i], bw_int_to_fixed(dceip->chunk_width))), data->hsr[i]))), bw_int_to_fixed(2))));
843 data->request_bandwidth[i] = bw_div(bw_mul(bw_div(bw_mul(bw_div(bw_mul(bw_max2(data->lb_lines_in_per_line_out_in_beginning_of_frame[i], data->lb_lines_in_per_line_out_in_middle_of_frame[i]), data->source_width_rounded_up_to_chunks[i]), (bw_div(data->h_total[i], data->pixel_rate[i]))), bw_int_to_fixed(data->bytes_per_pixel[i])), data->useful_bytes_per_request[i]), data->lines_interleaved_in_mem_access[i]), data->latency_hiding_lines[i]);
844 data->display_bandwidth[i] = bw_mul(data->request_bandwidth[i], data->bytes_per_request[i]);
847 /*outstanding chunk request limit*/
848 /*if underlay buffer sharing is enabled, the data buffer size for underlay in 422 or 444 is the sum of the luma and chroma data buffer sizes.*/
849 /*underlay buffer sharing mode is only permitted in orthogonal rotation modes.*/
851 /*if there is only one display enabled, the dmif data buffer size for the graphics surface is increased by concatenating the adjacent buffers.*/
853 /*the memory chunk size in bytes is 1024 for the writeback, and 256 times the memory line interleaving and the bytes per pixel for graphics*/
856 /*the pipe chunk size uses 2 for line interleaving, except for the write back, in which case it is 1.*/
857 /*graphics and underlay data buffer size is adjusted (limited) using the outstanding chunk request limit if there is more than one*/
858 /*display enabled or if the dmif request buffer is not large enough for the total data buffer size.*/
859 /*the outstanding chunk request limit is the ceiling of the adjusted data buffer size divided by the chunk size in bytes*/
860 /*the adjusted data buffer size is the product of the display bandwidth and the minimum effective data buffer size in terms of time,*/
861 /*rounded up to the chunk size in bytes, but should not exceed the original data buffer size*/
862 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
863 if (data->enable[i]) {
864 if ((dceip->dmif_pipe_en_fbc_chunk_tracker + 3 == i && fbc_enabled == 0 && tiling_mode[i] != bw_def_linear)) {
865 data->max_chunks_non_fbc_mode[i] = 128 - dmif_chunk_buff_margin;
868 data->max_chunks_non_fbc_mode[i] = 16 - dmif_chunk_buff_margin;
871 if (data->fbc_en[i] == 1) {
872 max_chunks_fbc_mode = 128 - dmif_chunk_buff_margin;
875 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
876 if (data->enable[i]) {
877 switch (surface_type[i]) {
878 case bw_def_display_write_back420_luma:
879 data->data_buffer_size[i] = bw_int_to_fixed(dceip->display_write_back420_luma_mcifwr_buffer_size);
881 case bw_def_display_write_back420_chroma:
882 data->data_buffer_size[i] = bw_int_to_fixed(dceip->display_write_back420_chroma_mcifwr_buffer_size);
884 case bw_def_underlay420_luma:
885 data->data_buffer_size[i] = bw_int_to_fixed(dceip->underlay_luma_dmif_size);
887 case bw_def_underlay420_chroma:
888 data->data_buffer_size[i] = bw_div(bw_int_to_fixed(dceip->underlay_chroma_dmif_size), bw_int_to_fixed(2));
890 case bw_def_underlay422:case bw_def_underlay444:
891 if (data->orthogonal_rotation[i] == 0) {
892 data->data_buffer_size[i] = bw_int_to_fixed(dceip->underlay_luma_dmif_size);
895 data->data_buffer_size[i] = bw_add(bw_int_to_fixed(dceip->underlay_luma_dmif_size), bw_int_to_fixed(dceip->underlay_chroma_dmif_size));
899 if (data->fbc_en[i] == 1) {
900 /*data_buffer_size(i) = max_dmif_buffer_allocated * graphics_dmif_size*/
901 if (data->number_of_displays == 1) {
902 data->data_buffer_size[i] = bw_min2(bw_mul(bw_mul(bw_int_to_fixed(max_chunks_fbc_mode), bw_int_to_fixed(pixels_per_chunk)), bw_int_to_fixed(data->bytes_per_pixel[i])), bw_mul(bw_int_to_fixed(dceip->max_dmif_buffer_allocated), bw_int_to_fixed(dceip->graphics_dmif_size)));
905 data->data_buffer_size[i] = bw_min2(bw_mul(bw_mul(bw_int_to_fixed(max_chunks_fbc_mode), bw_int_to_fixed(pixels_per_chunk)), bw_int_to_fixed(data->bytes_per_pixel[i])), bw_int_to_fixed(dceip->graphics_dmif_size));
909 /*the effective dmif buffer size in non-fbc mode is limited by the 16 entry chunk tracker*/
910 if (data->number_of_displays == 1) {
911 data->data_buffer_size[i] = bw_min2(bw_mul(bw_mul(bw_int_to_fixed(data->max_chunks_non_fbc_mode[i]), bw_int_to_fixed(pixels_per_chunk)), bw_int_to_fixed(data->bytes_per_pixel[i])), bw_mul(bw_int_to_fixed(dceip->max_dmif_buffer_allocated), bw_int_to_fixed(dceip->graphics_dmif_size)));
914 data->data_buffer_size[i] = bw_min2(bw_mul(bw_mul(bw_int_to_fixed(data->max_chunks_non_fbc_mode[i]), bw_int_to_fixed(pixels_per_chunk)), bw_int_to_fixed(data->bytes_per_pixel[i])), bw_int_to_fixed(dceip->graphics_dmif_size));
919 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
920 data->memory_chunk_size_in_bytes[i] = bw_int_to_fixed(1024);
921 data->pipe_chunk_size_in_bytes[i] = bw_int_to_fixed(1024);
924 data->memory_chunk_size_in_bytes[i] = bw_mul(bw_mul(bw_int_to_fixed(dceip->chunk_width), data->lines_interleaved_in_mem_access[i]), bw_int_to_fixed(data->bytes_per_pixel[i]));
925 data->pipe_chunk_size_in_bytes[i] = bw_mul(bw_mul(bw_int_to_fixed(dceip->chunk_width), bw_int_to_fixed(dceip->lines_interleaved_into_lb)), bw_int_to_fixed(data->bytes_per_pixel[i]));
929 data->min_dmif_size_in_time = bw_int_to_fixed(9999);
930 data->min_mcifwr_size_in_time = bw_int_to_fixed(9999);
931 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
932 if (data->enable[i]) {
933 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
934 if (bw_ltn(bw_div(bw_div(bw_mul(data->data_buffer_size[i], data->bytes_per_request[i]), data->useful_bytes_per_request[i]), data->display_bandwidth[i]), data->min_dmif_size_in_time)) {
935 data->min_dmif_size_in_time = bw_div(bw_div(bw_mul(data->data_buffer_size[i], data->bytes_per_request[i]), data->useful_bytes_per_request[i]), data->display_bandwidth[i]);
939 if (bw_ltn(bw_div(bw_div(bw_mul(data->data_buffer_size[i], data->bytes_per_request[i]), data->useful_bytes_per_request[i]), data->display_bandwidth[i]), data->min_mcifwr_size_in_time)) {
940 data->min_mcifwr_size_in_time = bw_div(bw_div(bw_mul(data->data_buffer_size[i], data->bytes_per_request[i]), data->useful_bytes_per_request[i]), data->display_bandwidth[i]);
945 data->total_requests_for_dmif_size = bw_int_to_fixed(0);
946 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
947 if (data->enable[i] && surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
948 data->total_requests_for_dmif_size = bw_add(data->total_requests_for_dmif_size, bw_div(data->data_buffer_size[i], data->useful_bytes_per_request[i]));
951 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
952 if (data->enable[i]) {
953 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma && dceip->limit_excessive_outstanding_dmif_requests && (data->number_of_displays > 1 || bw_mtn(data->total_requests_for_dmif_size, dceip->dmif_request_buffer_size))) {
954 data->adjusted_data_buffer_size[i] = bw_min2(data->data_buffer_size[i], bw_ceil2(bw_mul(data->min_dmif_size_in_time, data->display_bandwidth[i]), data->memory_chunk_size_in_bytes[i]));
957 data->adjusted_data_buffer_size[i] = data->data_buffer_size[i];
961 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
962 if (data->enable[i]) {
963 if (data->number_of_displays == 1 && data->number_of_underlay_surfaces == 0) {
964 /*set maximum chunk limit if only one graphic pipe is enabled*/
965 data->outstanding_chunk_request_limit[i] = bw_int_to_fixed(127);
968 data->outstanding_chunk_request_limit[i] = bw_ceil2(bw_div(data->adjusted_data_buffer_size[i], data->pipe_chunk_size_in_bytes[i]), bw_int_to_fixed(1));
969 /*clamp maximum chunk limit in the graphic display pipe*/
971 data->outstanding_chunk_request_limit[i] = bw_max2(bw_int_to_fixed(127), data->outstanding_chunk_request_limit[i]);
976 /*outstanding pte request limit*/
977 /*in tiling mode with no rotation the sg pte requests are 8 useful pt_es, the sg row height is the page height and the sg page width x height is 64x64 for 8bpp, 64x32 for 16 bpp, 32x32 for 32 bpp*/
978 /*in tiling mode with rotation the sg pte requests are only one useful pte, and the sg row height is also the page height, but the sg page width and height are swapped*/
979 /*in linear mode the pte requests are 8 useful pt_es, the sg page width is 4096 divided by the bytes per pixel, the sg page height is 1, but there is just one row whose height is the lines of pte prefetching*/
980 /*the outstanding pte request limit is obtained by multiplying the outstanding chunk request limit by the peak pte request to eviction limiting ratio, rounding up to integer, multiplying by the pte requests per chunk, and rounding up to integer again*/
981 /*if not using peak pte request to eviction limiting, the outstanding pte request limit is the pte requests in the vblank*/
982 /*the pte requests in the vblank is the product of the number of pte request rows times the number of pte requests in a row*/
983 /*the number of pte requests in a row is the quotient of the source width divided by 256, multiplied by the pte requests per chunk, rounded up to even, multiplied by the scatter-gather row height and divided by the scatter-gather page height*/
984 /*the pte requests per chunk is 256 divided by the scatter-gather page width and the useful pt_es per pte request*/
985 if (data->number_of_displays > 1 || (bw_neq(data->rotation_angle[4], bw_int_to_fixed(0)) && bw_neq(data->rotation_angle[4], bw_int_to_fixed(180)))) {
986 data->peak_pte_request_to_eviction_ratio_limiting = dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display;
989 data->peak_pte_request_to_eviction_ratio_limiting = dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation;
991 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
992 if (data->enable[i] && data->scatter_gather_enable_for_pipe[i] == 1) {
993 if (tiling_mode[i] == bw_def_linear) {
994 data->useful_pte_per_pte_request = bw_int_to_fixed(8);
995 data->scatter_gather_page_width[i] = bw_div(bw_int_to_fixed(4096), bw_int_to_fixed(data->bytes_per_pixel[i]));
996 data->scatter_gather_page_height[i] = bw_int_to_fixed(1);
997 data->scatter_gather_pte_request_rows = bw_int_to_fixed(1);
998 data->scatter_gather_row_height = bw_int_to_fixed(dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode);
1000 else if (bw_equ(data->rotation_angle[i], bw_int_to_fixed(0)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(180))) {
1001 data->useful_pte_per_pte_request = bw_int_to_fixed(8);
1002 switch (data->bytes_per_pixel[i]) {
1004 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
1005 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1008 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1009 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1012 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1013 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1016 data->scatter_gather_pte_request_rows = bw_int_to_fixed(dceip->scatter_gather_pte_request_rows_in_tiling_mode);
1017 data->scatter_gather_row_height = data->scatter_gather_page_height[i];
1020 data->useful_pte_per_pte_request = bw_int_to_fixed(1);
1021 switch (data->bytes_per_pixel[i]) {
1023 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
1024 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1027 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
1028 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1031 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1032 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1035 data->scatter_gather_pte_request_rows = bw_int_to_fixed(dceip->scatter_gather_pte_request_rows_in_tiling_mode);
1036 data->scatter_gather_row_height = data->scatter_gather_page_height[i];
1038 data->pte_request_per_chunk[i] = bw_div(bw_div(bw_int_to_fixed(dceip->chunk_width), data->scatter_gather_page_width[i]), data->useful_pte_per_pte_request);
1039 data->scatter_gather_pte_requests_in_row[i] = bw_div(bw_mul(bw_ceil2(bw_mul(bw_div(data->source_width_rounded_up_to_chunks[i], bw_int_to_fixed(dceip->chunk_width)), data->pte_request_per_chunk[i]), bw_int_to_fixed(1)), data->scatter_gather_row_height), data->scatter_gather_page_height[i]);
1040 data->scatter_gather_pte_requests_in_vblank = bw_mul(data->scatter_gather_pte_request_rows, data->scatter_gather_pte_requests_in_row[i]);
1041 if (bw_equ(data->peak_pte_request_to_eviction_ratio_limiting, bw_int_to_fixed(0))) {
1042 data->scatter_gather_pte_request_limit[i] = data->scatter_gather_pte_requests_in_vblank;
1045 data->scatter_gather_pte_request_limit[i] = bw_max2(dceip->minimum_outstanding_pte_request_limit, bw_min2(data->scatter_gather_pte_requests_in_vblank, bw_ceil2(bw_mul(bw_mul(bw_div(bw_ceil2(data->adjusted_data_buffer_size[i], data->memory_chunk_size_in_bytes[i]), data->memory_chunk_size_in_bytes[i]), data->pte_request_per_chunk[i]), data->peak_pte_request_to_eviction_ratio_limiting), bw_int_to_fixed(1))));
1049 /*pitch padding recommended for efficiency in linear mode*/
1050 /*in linear mode graphics or underlay with scatter gather, a pitch that is a multiple of the channel interleave (256 bytes) times the channel-bank rotation is not efficient*/
1051 /*if that is the case it is recommended to pad the pitch by at least 256 pixels*/
1052 data->inefficient_linear_pitch_in_bytes = bw_mul(bw_mul(bw_int_to_fixed(256), bw_int_to_fixed(vbios->number_of_dram_banks)), bw_int_to_fixed(data->number_of_dram_channels));
1054 /*pixel transfer time*/
1055 /*the dmif and mcifwr yclk(pclk) required is the one that allows the transfer of all pipe's data buffer size in memory in the time for data transfer*/
1056 /*for dmif, pte and cursor requests have to be included.*/
1057 /*the dram data requirement is doubled when the data request size in bytes is less than the dram channel width times the burst size (8)*/
1058 /*the dram data requirement is also multiplied by the number of channels in the case of low power tiling*/
1059 /*the page close-open time is determined by trc and the number of page close-opens*/
1060 /*in tiled mode graphics or underlay with scatter-gather enabled the bytes per page close-open is the product of the memory line interleave times the maximum of the scatter-gather page width and the product of the tile width (8 pixels) times the number of channels times the number of banks.*/
1061 /*in linear mode graphics or underlay with scatter-gather enabled and inefficient pitch, the bytes per page close-open is the line request alternation slice, because different lines are in completely different 4k address bases.*/
1062 /*otherwise, the bytes page close-open is the chunk size because that is the arbitration slice.*/
1063 /*pte requests are grouped by pte requests per chunk if that is more than 1. each group costs a page close-open time for dmif reads*/
1064 /*cursor requests outstanding are limited to a group of two source lines. each group costs a page close-open time for dmif reads*/
1065 /*the display reads and writes time for data transfer is the minimum data or cursor buffer size in time minus the mc urgent latency*/
1066 /*the mc urgent latency is experienced more than one time if the number of dmif requests in the data buffer exceeds the request buffer size plus the request slots reserved for dmif in the dram channel arbiter queues*/
1067 /*the dispclk required is the maximum for all surfaces of the maximum of the source pixels for first output pixel times the throughput factor, divided by the pixels per dispclk, and divided by the minimum latency hiding minus the dram speed/p-state change latency minus the burst time, and the source pixels for last output pixel, times the throughput factor, divided by the pixels per dispclk, and divided by the minimum latency hiding minus the dram speed/p-state change latency minus the burst time, plus the active time.*/
1068 /*the data burst time is the maximum of the total page close-open time, total dmif/mcifwr buffer size in memory divided by the dram bandwidth, and the total dmif/mcifwr buffer size in memory divided by the 32 byte sclk data bus bandwidth, each multiplied by its efficiency.*/
1069 /*the source line transfer time is the maximum for all surfaces of the maximum of the burst time plus the urgent latency times the floor of the data required divided by the buffer size for the fist pixel, and the burst time plus the urgent latency times the floor of the data required divided by the buffer size for the last pixel plus the active time.*/
1070 /*the source pixels for the first output pixel is 512 if the scaler vertical filter initialization value is greater than 2, and it is 4 times the source width if it is greater than 4.*/
1071 /*the source pixels for the last output pixel is the source width times the scaler vertical filter initialization value rounded up to even*/
1072 /*the source data for these pixels is the number of pixels times the bytes per pixel times the bytes per request divided by the useful bytes per request.*/
1073 data->cursor_total_data = bw_int_to_fixed(0);
1074 data->cursor_total_request_groups = bw_int_to_fixed(0);
1075 data->scatter_gather_total_pte_requests = bw_int_to_fixed(0);
1076 data->scatter_gather_total_pte_request_groups = bw_int_to_fixed(0);
1077 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1078 if (data->enable[i]) {
1079 data->cursor_total_data = bw_add(data->cursor_total_data, bw_mul(bw_mul(bw_int_to_fixed(2), data->cursor_width_pixels[i]), bw_int_to_fixed(4)));
1080 if (dceip->large_cursor == 1) {
1081 data->cursor_total_request_groups = bw_add(data->cursor_total_request_groups, bw_int_to_fixed((dceip->cursor_max_outstanding_group_num + 1)));
1084 data->cursor_total_request_groups = bw_add(data->cursor_total_request_groups, bw_ceil2(bw_div(data->cursor_width_pixels[i], dceip->cursor_chunk_width), bw_int_to_fixed(1)));
1086 if (data->scatter_gather_enable_for_pipe[i]) {
1087 data->scatter_gather_total_pte_requests = bw_add(data->scatter_gather_total_pte_requests, data->scatter_gather_pte_request_limit[i]);
1088 data->scatter_gather_total_pte_request_groups = bw_add(data->scatter_gather_total_pte_request_groups, bw_ceil2(bw_div(data->scatter_gather_pte_request_limit[i], bw_ceil2(data->pte_request_per_chunk[i], bw_int_to_fixed(1))), bw_int_to_fixed(1)));
1092 data->tile_width_in_pixels = bw_int_to_fixed(8);
1093 data->dmif_total_number_of_data_request_page_close_open = bw_int_to_fixed(0);
1094 data->mcifwr_total_number_of_data_request_page_close_open = bw_int_to_fixed(0);
1095 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1096 if (data->enable[i]) {
1097 if (data->scatter_gather_enable_for_pipe[i] == 1 && tiling_mode[i] != bw_def_linear) {
1098 data->bytes_per_page_close_open = bw_mul(data->lines_interleaved_in_mem_access[i], bw_max2(bw_mul(bw_mul(bw_mul(bw_int_to_fixed(data->bytes_per_pixel[i]), data->tile_width_in_pixels), bw_int_to_fixed(vbios->number_of_dram_banks)), bw_int_to_fixed(data->number_of_dram_channels)), bw_mul(bw_int_to_fixed(data->bytes_per_pixel[i]), data->scatter_gather_page_width[i])));
1100 else if (data->scatter_gather_enable_for_pipe[i] == 1 && tiling_mode[i] == bw_def_linear && bw_equ(bw_mod((bw_mul(data->pitch_in_pixels_after_surface_type[i], bw_int_to_fixed(data->bytes_per_pixel[i]))), data->inefficient_linear_pitch_in_bytes), bw_int_to_fixed(0))) {
1101 data->bytes_per_page_close_open = dceip->linear_mode_line_request_alternation_slice;
1104 data->bytes_per_page_close_open = data->memory_chunk_size_in_bytes[i];
1106 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1107 data->dmif_total_number_of_data_request_page_close_open = bw_add(data->dmif_total_number_of_data_request_page_close_open, bw_div(bw_ceil2(data->adjusted_data_buffer_size[i], data->memory_chunk_size_in_bytes[i]), data->bytes_per_page_close_open));
1110 data->mcifwr_total_number_of_data_request_page_close_open = bw_add(data->mcifwr_total_number_of_data_request_page_close_open, bw_div(bw_ceil2(data->adjusted_data_buffer_size[i], data->memory_chunk_size_in_bytes[i]), data->bytes_per_page_close_open));
1114 data->dmif_total_page_close_open_time = bw_div(bw_mul((bw_add(bw_add(data->dmif_total_number_of_data_request_page_close_open, data->scatter_gather_total_pte_request_groups), data->cursor_total_request_groups)), vbios->trc), bw_int_to_fixed(1000));
1115 data->mcifwr_total_page_close_open_time = bw_div(bw_mul(data->mcifwr_total_number_of_data_request_page_close_open, vbios->trc), bw_int_to_fixed(1000));
1116 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1117 if (data->enable[i]) {
1118 data->adjusted_data_buffer_size_in_memory[i] = bw_div(bw_mul(data->adjusted_data_buffer_size[i], data->bytes_per_request[i]), data->useful_bytes_per_request[i]);
1121 data->total_requests_for_adjusted_dmif_size = bw_int_to_fixed(0);
1122 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1123 if (data->enable[i]) {
1124 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1125 data->total_requests_for_adjusted_dmif_size = bw_add(data->total_requests_for_adjusted_dmif_size, bw_div(data->adjusted_data_buffer_size[i], data->useful_bytes_per_request[i]));
1129 data->total_dmifmc_urgent_trips = bw_ceil2(bw_div(data->total_requests_for_adjusted_dmif_size, (bw_add(dceip->dmif_request_buffer_size, bw_int_to_fixed(vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel * data->number_of_dram_channels)))), bw_int_to_fixed(1));
1130 data->total_dmifmc_urgent_latency = bw_mul(vbios->dmifmc_urgent_latency, data->total_dmifmc_urgent_trips);
1131 data->total_display_reads_required_data = bw_int_to_fixed(0);
1132 data->total_display_reads_required_dram_access_data = bw_int_to_fixed(0);
1133 data->total_display_writes_required_data = bw_int_to_fixed(0);
1134 data->total_display_writes_required_dram_access_data = bw_int_to_fixed(0);
1135 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1136 if (data->enable[i]) {
1137 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1138 data->display_reads_required_data = data->adjusted_data_buffer_size_in_memory[i];
1139 /*for hbm memories, each channel is split into 2 pseudo-channels that are each 64 bits in width. each*/
1140 /*pseudo-channel may be read independently of one another.*/
1141 /*the read burst length (bl) for hbm memories is 4, so each read command will access 32 bytes of data.*/
1142 /*the 64 or 32 byte sized data is stored in one pseudo-channel.*/
1143 /*it will take 4 memclk cycles or 8 yclk cycles to fetch 64 bytes of data from the hbm memory (2 read commands).*/
1144 /*it will take 2 memclk cycles or 4 yclk cycles to fetch 32 bytes of data from the hbm memory (1 read command).*/
1145 /*for gddr5/ddr4 memories, there is additional overhead if the size of the request is smaller than 64 bytes.*/
1146 /*the read burst length (bl) for gddr5/ddr4 memories is 8, regardless of the size of the data request.*/
1147 /*therefore it will require 8 cycles to fetch 64 or 32 bytes of data from the memory.*/
1148 /*the memory efficiency will be 50% for the 32 byte sized data.*/
1149 if (vbios->memory_type == bw_def_hbm) {
1150 data->display_reads_required_dram_access_data = data->adjusted_data_buffer_size_in_memory[i];
1153 data->display_reads_required_dram_access_data = bw_mul(data->adjusted_data_buffer_size_in_memory[i], bw_ceil2(bw_div(bw_int_to_fixed((8 * vbios->dram_channel_width_in_bits / 8)), data->bytes_per_request[i]), bw_int_to_fixed(1)));
1155 data->total_display_reads_required_data = bw_add(data->total_display_reads_required_data, data->display_reads_required_data);
1156 data->total_display_reads_required_dram_access_data = bw_add(data->total_display_reads_required_dram_access_data, data->display_reads_required_dram_access_data);
1159 data->total_display_writes_required_data = bw_add(data->total_display_writes_required_data, data->adjusted_data_buffer_size_in_memory[i]);
1160 data->total_display_writes_required_dram_access_data = bw_add(data->total_display_writes_required_dram_access_data, bw_mul(data->adjusted_data_buffer_size_in_memory[i], bw_ceil2(bw_div(bw_int_to_fixed(vbios->dram_channel_width_in_bits), data->bytes_per_request[i]), bw_int_to_fixed(1))));
1164 data->total_display_reads_required_data = bw_add(bw_add(data->total_display_reads_required_data, data->cursor_total_data), bw_mul(data->scatter_gather_total_pte_requests, bw_int_to_fixed(64)));
1165 data->total_display_reads_required_dram_access_data = bw_add(bw_add(data->total_display_reads_required_dram_access_data, data->cursor_total_data), bw_mul(data->scatter_gather_total_pte_requests, bw_int_to_fixed(64)));
1166 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1167 if (data->enable[i]) {
1168 if (bw_mtn(data->v_filter_init[i], bw_int_to_fixed(4))) {
1169 data->src_pixels_for_first_output_pixel[i] = bw_mul(bw_int_to_fixed(4), data->source_width_rounded_up_to_chunks[i]);
1172 if (bw_mtn(data->v_filter_init[i], bw_int_to_fixed(2))) {
1173 data->src_pixels_for_first_output_pixel[i] = bw_int_to_fixed(512);
1176 data->src_pixels_for_first_output_pixel[i] = bw_int_to_fixed(0);
1179 data->src_data_for_first_output_pixel[i] = bw_div(bw_mul(bw_mul(data->src_pixels_for_first_output_pixel[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->bytes_per_request[i]), data->useful_bytes_per_request[i]);
1180 data->src_pixels_for_last_output_pixel[i] = bw_mul(data->source_width_rounded_up_to_chunks[i], bw_max2(bw_ceil2(data->v_filter_init[i], bw_int_to_fixed(dceip->lines_interleaved_into_lb)), bw_mul(bw_ceil2(data->vsr[i], bw_int_to_fixed(dceip->lines_interleaved_into_lb)), data->horizontal_blank_and_chunk_granularity_factor[i])));
1181 data->src_data_for_last_output_pixel[i] = bw_div(bw_mul(bw_mul(bw_mul(data->source_width_rounded_up_to_chunks[i], bw_max2(bw_ceil2(data->v_filter_init[i], bw_int_to_fixed(dceip->lines_interleaved_into_lb)), data->lines_interleaved_in_mem_access[i])), bw_int_to_fixed(data->bytes_per_pixel[i])), data->bytes_per_request[i]), data->useful_bytes_per_request[i]);
1182 data->active_time[i] = bw_div(bw_div(data->source_width_rounded_up_to_chunks[i], data->hsr[i]), data->pixel_rate[i]);
1185 for (i = 0; i <= 2; i++) {
1186 for (j = 0; j <= 7; j++) {
1187 data->dmif_burst_time[i][j] = bw_max3(data->dmif_total_page_close_open_time, bw_div(data->total_display_reads_required_dram_access_data, (bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[i]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels)))), bw_div(data->total_display_reads_required_data, (bw_mul(bw_mul(sclk[j], vbios->data_return_bus_width), bw_frc_to_fixed(dceip->percent_of_ideal_port_bw_received_after_urgent_latency, 100)))));
1188 if (data->d1_display_write_back_dwb_enable == 1) {
1189 data->mcifwr_burst_time[i][j] = bw_max3(data->mcifwr_total_page_close_open_time, bw_div(data->total_display_writes_required_dram_access_data, (bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[i]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_wrchannels)))), bw_div(data->total_display_writes_required_data, (bw_mul(sclk[j], vbios->data_return_bus_width))));
1193 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1194 for (j = 0; j <= 2; j++) {
1195 for (k = 0; k <= 7; k++) {
1196 if (data->enable[i]) {
1197 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1198 /*time to transfer data from the dmif buffer to the lb. since the mc to dmif transfer time overlaps*/
1199 /*with the dmif to lb transfer time, only time to transfer the last chunk is considered.*/
1200 data->dmif_buffer_transfer_time[i] = bw_mul(data->source_width_rounded_up_to_chunks[i], (bw_div(dceip->lb_write_pixels_per_dispclk, (bw_div(vbios->low_voltage_max_dispclk, dceip->display_pipe_throughput_factor)))));
1201 data->line_source_transfer_time[i][j][k] = bw_max2(bw_mul((bw_add(data->total_dmifmc_urgent_latency, data->dmif_burst_time[j][k])), bw_floor2(bw_div(data->src_data_for_first_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), bw_sub(bw_add(bw_mul((bw_add(data->total_dmifmc_urgent_latency, data->dmif_burst_time[j][k])), bw_floor2(bw_div(data->src_data_for_last_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), data->dmif_buffer_transfer_time[i]), data->active_time[i]));
1202 /*during an mclk switch the requests from the dce ip are stored in the gmc/arb. these requests should be serviced immediately*/
1203 /*after the mclk switch sequence and not incur an urgent latency penalty. it is assumed that the gmc/arb can hold up to 256 requests*/
1204 /*per memory channel. if the dce ip is urgent after the mclk switch sequence, all pending requests and subsequent requests should be*/
1205 /*immediately serviced without a gap in the urgent requests.*/
1206 /*the latency incurred would be the time to issue the requests and return the data for the first or last output pixel.*/
1207 if (surface_type[i] == bw_def_graphics) {
1208 switch (data->lb_bpc[i]) {
1210 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency6_bit_per_component;
1213 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency8_bit_per_component;
1216 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency10_bit_per_component;
1219 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency12_bit_per_component;
1222 if (data->use_alpha[i] == 1) {
1223 data->v_scaler_efficiency = bw_min2(data->v_scaler_efficiency, dceip->alpha_vscaler_efficiency);
1227 switch (data->lb_bpc[i]) {
1229 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency6_bit_per_component;
1232 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency8_bit_per_component;
1235 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency10_bit_per_component;
1238 data->v_scaler_efficiency = bw_int_to_fixed(3);
1242 if (dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1))) {
1243 data->scaler_limits_factor = bw_max2(bw_div(data->v_taps[i], data->v_scaler_efficiency), bw_div(data->source_width_rounded_up_to_chunks[i], data->h_total[i]));
1246 data->scaler_limits_factor = bw_max3(bw_int_to_fixed(1), bw_ceil2(bw_div(data->h_taps[i], bw_int_to_fixed(4)), bw_int_to_fixed(1)), bw_mul(data->hsr[i], bw_max2(bw_div(data->v_taps[i], data->v_scaler_efficiency), bw_int_to_fixed(1))));
1248 data->dram_speed_change_line_source_transfer_time[i][j][k] = bw_mul(bw_int_to_fixed(2), bw_max2((bw_add((bw_div(data->src_data_for_first_output_pixel[i], bw_min2(bw_mul(data->bytes_per_request[i], sclk[k]), bw_div(bw_mul(bw_mul(data->bytes_per_request[i], data->pixel_rate[i]), data->scaler_limits_factor), bw_int_to_fixed(2))))), (bw_mul(data->dmif_burst_time[j][k], bw_floor2(bw_div(data->src_data_for_first_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1)))))), (bw_add((bw_div(data->src_data_for_last_output_pixel[i], bw_min2(bw_mul(data->bytes_per_request[i], sclk[k]), bw_div(bw_mul(bw_mul(data->bytes_per_request[i], data->pixel_rate[i]), data->scaler_limits_factor), bw_int_to_fixed(2))))), (bw_sub(bw_mul(data->dmif_burst_time[j][k], bw_floor2(bw_div(data->src_data_for_last_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), data->active_time[i]))))));
1251 data->line_source_transfer_time[i][j][k] = bw_max2(bw_mul((bw_add(vbios->mcifwrmc_urgent_latency, data->mcifwr_burst_time[j][k])), bw_floor2(bw_div(data->src_data_for_first_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), bw_sub(bw_mul((bw_add(vbios->mcifwrmc_urgent_latency, data->mcifwr_burst_time[j][k])), bw_floor2(bw_div(data->src_data_for_last_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), data->active_time[i]));
1252 /*during an mclk switch the requests from the dce ip are stored in the gmc/arb. these requests should be serviced immediately*/
1253 /*after the mclk switch sequence and not incur an urgent latency penalty. it is assumed that the gmc/arb can hold up to 256 requests*/
1254 /*per memory channel. if the dce ip is urgent after the mclk switch sequence, all pending requests and subsequent requests should be*/
1255 /*immediately serviced without a gap in the urgent requests.*/
1256 /*the latency incurred would be the time to issue the requests and return the data for the first or last output pixel.*/
1257 data->dram_speed_change_line_source_transfer_time[i][j][k] = bw_max2((bw_add((bw_div(data->src_data_for_first_output_pixel[i], bw_min2(bw_mul(data->bytes_per_request[i], sclk[k]), bw_div(bw_mul(data->bytes_per_request[i], vbios->low_voltage_max_dispclk), bw_int_to_fixed(2))))), (bw_mul(data->mcifwr_burst_time[j][k], bw_floor2(bw_div(data->src_data_for_first_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1)))))), (bw_add((bw_div(data->src_data_for_last_output_pixel[i], bw_min2(bw_mul(data->bytes_per_request[i], sclk[k]), bw_div(bw_mul(data->bytes_per_request[i], vbios->low_voltage_max_dispclk), bw_int_to_fixed(2))))), (bw_sub(bw_mul(data->mcifwr_burst_time[j][k], bw_floor2(bw_div(data->src_data_for_last_output_pixel[i], data->adjusted_data_buffer_size_in_memory[i]), bw_int_to_fixed(1))), data->active_time[i])))));
1263 /*cpu c-state and p-state change enable*/
1264 /*for cpu p-state change to be possible for a yclk(pclk) and sclk level the dispclk required has to be enough for the blackout duration*/
1265 /*for cpu c-state change to be possible for a yclk(pclk) and sclk level the dispclk required has to be enough for the blackout duration and recovery*/
1266 /*condition for the blackout duration:*/
1267 /* minimum latency hiding > blackout duration + dmif burst time + line source transfer time*/
1268 /*condition for the blackout recovery:*/
1269 /* recovery time > dmif burst time + 2 * urgent latency*/
1270 /* recovery time > (display bw * blackout duration + (2 * urgent latency + dmif burst time)*dispclk - dmif size )*/
1271 /* / (dispclk - display bw)*/
1272 /*the minimum latency hiding is the minimum for all pipes of one screen line time, plus one more line time if doing lb prefetch, plus the dmif data buffer size equivalent in time, minus the urgent latency.*/
1273 /*the minimum latency hiding is further limited by the cursor. the cursor latency hiding is the number of lines of the cursor buffer, minus one if the downscaling is less than two, or minus three if it is more*/
1275 /*initialize variables*/
1276 number_of_displays_enabled = 0;
1277 number_of_displays_enabled_with_margin = 0;
1278 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1279 if (data->enable[k]) {
1280 number_of_displays_enabled = number_of_displays_enabled + 1;
1282 data->display_pstate_change_enable[k] = 0;
1284 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1285 if (data->enable[i]) {
1286 if ((bw_equ(dceip->stutter_and_dram_clock_state_change_gated_before_cursor, bw_int_to_fixed(0)) && bw_mtn(data->cursor_width_pixels[i], bw_int_to_fixed(0)))) {
1287 if (bw_ltn(data->vsr[i], bw_int_to_fixed(2))) {
1288 data->cursor_latency_hiding[i] = bw_div(bw_div(bw_mul((bw_sub(dceip->cursor_dcp_buffer_lines, bw_int_to_fixed(1))), data->h_total[i]), data->vsr[i]), data->pixel_rate[i]);
1291 data->cursor_latency_hiding[i] = bw_div(bw_div(bw_mul((bw_sub(dceip->cursor_dcp_buffer_lines, bw_int_to_fixed(3))), data->h_total[i]), data->vsr[i]), data->pixel_rate[i]);
1295 data->cursor_latency_hiding[i] = bw_int_to_fixed(9999);
1299 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1300 if (data->enable[i]) {
1301 if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1 && (bw_equ(data->vsr[i], bw_int_to_fixed(1)) || (bw_leq(data->vsr[i], bw_frc_to_fixed(8, 10)) && bw_leq(data->v_taps[i], bw_int_to_fixed(2)) && data->lb_bpc[i] == 8)) && surface_type[i] == bw_def_graphics) {
1302 if (number_of_displays_enabled > 2)
1303 data->minimum_latency_hiding[i] = bw_sub(bw_div(bw_mul((bw_div((bw_add(bw_sub(data->lb_partitions[i], bw_int_to_fixed(2)), bw_div(bw_div(data->data_buffer_size[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->source_width_pixels[i]))), data->vsr[i])), data->h_total[i]), data->pixel_rate[i]), data->total_dmifmc_urgent_latency);
1305 data->minimum_latency_hiding[i] = bw_sub(bw_div(bw_mul((bw_div((bw_add(bw_sub(data->lb_partitions[i], bw_int_to_fixed(1)), bw_div(bw_div(data->data_buffer_size[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->source_width_pixels[i]))), data->vsr[i])), data->h_total[i]), data->pixel_rate[i]), data->total_dmifmc_urgent_latency);
1308 data->minimum_latency_hiding[i] = bw_sub(bw_div(bw_mul((bw_div((bw_add(bw_int_to_fixed(1 + data->line_buffer_prefetch[i]), bw_div(bw_div(data->data_buffer_size[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->source_width_pixels[i]))), data->vsr[i])), data->h_total[i]), data->pixel_rate[i]), data->total_dmifmc_urgent_latency);
1310 data->minimum_latency_hiding_with_cursor[i] = bw_min2(data->minimum_latency_hiding[i], data->cursor_latency_hiding[i]);
1313 for (i = 0; i <= 2; i++) {
1314 for (j = 0; j <= 7; j++) {
1315 data->blackout_duration_margin[i][j] = bw_int_to_fixed(9999);
1316 data->dispclk_required_for_blackout_duration[i][j] = bw_int_to_fixed(0);
1317 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(0);
1318 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1319 if (data->enable[k] && bw_mtn(vbios->blackout_duration, bw_int_to_fixed(0))) {
1320 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1321 data->blackout_duration_margin[i][j] = bw_min2(data->blackout_duration_margin[i][j], bw_sub(bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]), data->line_source_transfer_time[k][i][j]));
1322 data->dispclk_required_for_blackout_duration[i][j] = bw_max3(data->dispclk_required_for_blackout_duration[i][j], bw_div(bw_div(bw_mul(data->src_pixels_for_first_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]))), bw_div(bw_div(bw_mul(data->src_pixels_for_last_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_add(bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]), data->active_time[k]))));
1323 if (bw_leq(vbios->maximum_blackout_recovery_time, bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[i][j]))) {
1324 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(9999);
1326 else if (bw_ltn(data->adjusted_data_buffer_size[k], bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[i][j])))))) {
1327 data->dispclk_required_for_blackout_recovery[i][j] = bw_max2(data->dispclk_required_for_blackout_recovery[i][j], bw_div(bw_mul(bw_div(bw_div((bw_sub(bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, vbios->maximum_blackout_recovery_time))), data->adjusted_data_buffer_size[k])), bw_int_to_fixed(data->bytes_per_pixel[k])), (bw_sub(vbios->maximum_blackout_recovery_time, bw_sub(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[i][j])))), data->latency_hiding_lines[k]), data->lines_interleaved_in_mem_access[k]));
1331 data->blackout_duration_margin[i][j] = bw_min2(data->blackout_duration_margin[i][j], bw_sub(bw_sub(bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]), data->mcifwr_burst_time[i][j]), data->line_source_transfer_time[k][i][j]));
1332 data->dispclk_required_for_blackout_duration[i][j] = bw_max3(data->dispclk_required_for_blackout_duration[i][j], bw_div(bw_div(bw_mul(data->src_pixels_for_first_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_sub(bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]), data->mcifwr_burst_time[i][j]))), bw_div(bw_div(bw_mul(data->src_pixels_for_last_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_add(bw_sub(bw_sub(bw_sub(data->minimum_latency_hiding_with_cursor[k], vbios->blackout_duration), data->dmif_burst_time[i][j]), data->mcifwr_burst_time[i][j]), data->active_time[k]))));
1333 if (bw_ltn(vbios->maximum_blackout_recovery_time, bw_add(bw_add(bw_mul(bw_int_to_fixed(2), vbios->mcifwrmc_urgent_latency), data->dmif_burst_time[i][j]), data->mcifwr_burst_time[i][j]))) {
1334 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(9999);
1336 else if (bw_ltn(data->adjusted_data_buffer_size[k], bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[i][j])))))) {
1337 data->dispclk_required_for_blackout_recovery[i][j] = bw_max2(data->dispclk_required_for_blackout_recovery[i][j], bw_div(bw_mul(bw_div(bw_div((bw_sub(bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, vbios->maximum_blackout_recovery_time))), data->adjusted_data_buffer_size[k])), bw_int_to_fixed(data->bytes_per_pixel[k])), (bw_sub(vbios->maximum_blackout_recovery_time, (bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[i][j]))))), data->latency_hiding_lines[k]), data->lines_interleaved_in_mem_access[k]));
1344 if (bw_mtn(data->blackout_duration_margin[high][s_high], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[high][s_high], vbios->high_voltage_max_dispclk)) {
1345 data->cpup_state_change_enable = bw_def_yes;
1346 if (bw_ltn(data->dispclk_required_for_blackout_recovery[high][s_high], vbios->high_voltage_max_dispclk)) {
1347 data->cpuc_state_change_enable = bw_def_yes;
1350 data->cpuc_state_change_enable = bw_def_no;
1354 data->cpup_state_change_enable = bw_def_no;
1355 data->cpuc_state_change_enable = bw_def_no;
1357 /*nb p-state change enable*/
1358 /*for dram speed/p-state change to be possible for a yclk(pclk) and sclk level there has to be positive margin and the dispclk required has to be*/
1359 /*below the maximum.*/
1360 /*the dram speed/p-state change margin is the minimum for all surfaces of the maximum latency hiding minus the dram speed/p-state change latency,*/
1361 /*minus the dmif burst time, minus the source line transfer time*/
1362 /*the maximum latency hiding is the minimum latency hiding plus one source line used for de-tiling in the line buffer, plus half the urgent latency*/
1363 /*if stutter and dram clock state change are gated before cursor then the cursor latency hiding does not limit stutter or dram clock state change*/
1364 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1365 if (data->enable[i]) {
1366 if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1) {
1367 data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency));
1370 /*maximum_latency_hiding(i) = minimum_latency_hiding(i) + 1 / vsr(i) * h_total(i) / pixel_rate(i) + 0.5 * total_dmifmc_urgent_latency*/
1371 data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency));
1373 data->maximum_latency_hiding_with_cursor[i] = bw_min2(data->maximum_latency_hiding[i], data->cursor_latency_hiding[i]);
1376 for (i = 0; i <= 2; i++) {
1377 for (j = 0; j <= 7; j++) {
1378 data->min_dram_speed_change_margin[i][j] = bw_int_to_fixed(9999);
1379 data->dram_speed_change_margin = bw_int_to_fixed(9999);
1380 data->dispclk_required_for_dram_speed_change[i][j] = bw_int_to_fixed(0);
1381 data->num_displays_with_margin[i][j] = 0;
1382 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1383 if (data->enable[k]) {
1384 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1385 data->dram_speed_change_margin = bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]);
1386 if ((bw_mtn(data->dram_speed_change_margin, bw_int_to_fixed(0)) && bw_ltn(data->dram_speed_change_margin, bw_int_to_fixed(9999)))) {
1387 /*determine the minimum dram clock change margin for each set of clock frequencies*/
1388 data->min_dram_speed_change_margin[i][j] = bw_min2(data->min_dram_speed_change_margin[i][j], data->dram_speed_change_margin);
1389 /*compute the maximum clock frequuency required for the dram clock change at each set of clock frequencies*/
1390 data->dispclk_required_for_dram_speed_change_pipe[i][j] = bw_max2(bw_div(bw_div(bw_mul(data->src_pixels_for_first_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]))), bw_div(bw_div(bw_mul(data->src_pixels_for_last_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_add(bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]), data->active_time[k]))));
1391 if ((bw_ltn(data->dispclk_required_for_dram_speed_change_pipe[i][j], vbios->high_voltage_max_dispclk))) {
1392 data->display_pstate_change_enable[k] = 1;
1393 data->num_displays_with_margin[i][j] = data->num_displays_with_margin[i][j] + 1;
1394 data->dispclk_required_for_dram_speed_change[i][j] = bw_max2(data->dispclk_required_for_dram_speed_change[i][j], data->dispclk_required_for_dram_speed_change_pipe[i][j]);
1399 data->dram_speed_change_margin = bw_sub(bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->mcifwr_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]);
1400 if ((bw_mtn(data->dram_speed_change_margin, bw_int_to_fixed(0)) && bw_ltn(data->dram_speed_change_margin, bw_int_to_fixed(9999)))) {
1401 /*determine the minimum dram clock change margin for each display pipe*/
1402 data->min_dram_speed_change_margin[i][j] = bw_min2(data->min_dram_speed_change_margin[i][j], data->dram_speed_change_margin);
1403 /*compute the maximum clock frequuency required for the dram clock change at each set of clock frequencies*/
1404 data->dispclk_required_for_dram_speed_change_pipe[i][j] = bw_max2(bw_div(bw_div(bw_mul(data->src_pixels_for_first_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_sub(bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]), data->mcifwr_burst_time[i][j]))), bw_div(bw_div(bw_mul(data->src_pixels_for_last_output_pixel[k], dceip->display_pipe_throughput_factor), dceip->lb_write_pixels_per_dispclk), (bw_add(bw_sub(bw_sub(bw_sub(bw_sub(data->maximum_latency_hiding_with_cursor[k], vbios->nbp_state_change_latency), data->dmif_burst_time[i][j]), data->dram_speed_change_line_source_transfer_time[k][i][j]), data->mcifwr_burst_time[i][j]), data->active_time[k]))));
1405 if ((bw_ltn(data->dispclk_required_for_dram_speed_change_pipe[i][j], vbios->high_voltage_max_dispclk))) {
1406 data->display_pstate_change_enable[k] = 1;
1407 data->num_displays_with_margin[i][j] = data->num_displays_with_margin[i][j] + 1;
1408 data->dispclk_required_for_dram_speed_change[i][j] = bw_max2(data->dispclk_required_for_dram_speed_change[i][j], data->dispclk_required_for_dram_speed_change_pipe[i][j]);
1416 /*determine the number of displays with margin to switch in the v_active region*/
1417 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1418 if (data->enable[k] == 1 && data->display_pstate_change_enable[k] == 1) {
1419 number_of_displays_enabled_with_margin = number_of_displays_enabled_with_margin + 1;
1422 /*determine the number of displays that don't have any dram clock change margin, but*/
1423 /*have the same resolution. these displays can switch in a common vblank region if*/
1424 /*their frames are aligned.*/
1425 data->min_vblank_dram_speed_change_margin = bw_int_to_fixed(9999);
1426 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1427 if (data->enable[k]) {
1428 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1429 data->v_blank_dram_speed_change_margin[k] = bw_sub(bw_sub(bw_sub(bw_div(bw_mul((bw_sub(data->v_total[k], bw_sub(bw_div(data->src_height[k], data->v_scale_ratio[k]), bw_int_to_fixed(4)))), data->h_total[k]), data->pixel_rate[k]), vbios->nbp_state_change_latency), data->dmif_burst_time[low][s_low]), data->dram_speed_change_line_source_transfer_time[k][low][s_low]);
1430 data->min_vblank_dram_speed_change_margin = bw_min2(data->min_vblank_dram_speed_change_margin, data->v_blank_dram_speed_change_margin[k]);
1433 data->v_blank_dram_speed_change_margin[k] = bw_sub(bw_sub(bw_sub(bw_sub(bw_div(bw_mul((bw_sub(data->v_total[k], bw_sub(bw_div(data->src_height[k], data->v_scale_ratio[k]), bw_int_to_fixed(4)))), data->h_total[k]), data->pixel_rate[k]), vbios->nbp_state_change_latency), data->dmif_burst_time[low][s_low]), data->mcifwr_burst_time[low][s_low]), data->dram_speed_change_line_source_transfer_time[k][low][s_low]);
1434 data->min_vblank_dram_speed_change_margin = bw_min2(data->min_vblank_dram_speed_change_margin, data->v_blank_dram_speed_change_margin[k]);
1438 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1439 data->displays_with_same_mode[i] = bw_int_to_fixed(0);
1440 if (data->enable[i] == 1 && data->display_pstate_change_enable[i] == 0 && bw_mtn(data->v_blank_dram_speed_change_margin[i], bw_int_to_fixed(0))) {
1441 for (j = 0; j <= maximum_number_of_surfaces - 1; j++) {
1442 if ((i == j || data->display_synchronization_enabled) && (data->enable[j] == 1 && bw_equ(data->source_width_rounded_up_to_chunks[i], data->source_width_rounded_up_to_chunks[j]) && bw_equ(data->source_height_rounded_up_to_chunks[i], data->source_height_rounded_up_to_chunks[j]) && bw_equ(data->vsr[i], data->vsr[j]) && bw_equ(data->hsr[i], data->hsr[j]) && bw_equ(data->pixel_rate[i], data->pixel_rate[j]))) {
1443 data->displays_with_same_mode[i] = bw_add(data->displays_with_same_mode[i], bw_int_to_fixed(1));
1448 /*compute the maximum number of aligned displays with no margin*/
1449 number_of_aligned_displays_with_no_margin = 0;
1450 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1451 number_of_aligned_displays_with_no_margin = bw_fixed_to_int(bw_max2(bw_int_to_fixed(number_of_aligned_displays_with_no_margin), data->displays_with_same_mode[i]));
1453 /*dram clock change is possible, if all displays have positive margin except for one display or a group of*/
1454 /*aligned displays with the same timing.*/
1455 /*the display(s) with the negative margin can be switched in the v_blank region while the other*/
1456 /*displays are in v_blank or v_active.*/
1457 if (number_of_displays_enabled_with_margin > 0 && (number_of_displays_enabled_with_margin + number_of_aligned_displays_with_no_margin) == number_of_displays_enabled && bw_mtn(data->min_dram_speed_change_margin[high][s_high], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[high][s_high], bw_int_to_fixed(9999)) && bw_ltn(data->dispclk_required_for_dram_speed_change[high][s_high], vbios->high_voltage_max_dispclk)) {
1458 data->nbp_state_change_enable = bw_def_yes;
1461 data->nbp_state_change_enable = bw_def_no;
1463 /*dram clock change is possible only in vblank if all displays are aligned and have no margin*/
1464 if (number_of_aligned_displays_with_no_margin == number_of_displays_enabled) {
1465 nbp_state_change_enable_blank = bw_def_yes;
1468 nbp_state_change_enable_blank = bw_def_no;
1471 /*average bandwidth*/
1472 /*the average bandwidth with no compression is the vertical active time is the source width times the bytes per pixel divided by the line time, multiplied by the vertical scale ratio and the ratio of bytes per request divided by the useful bytes per request.*/
1473 /*the average bandwidth with compression is the same, divided by the compression ratio*/
1474 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1475 if (data->enable[i]) {
1476 data->average_bandwidth_no_compression[i] = bw_div(bw_mul(bw_mul(bw_div(bw_mul(data->source_width_rounded_up_to_chunks[i], bw_int_to_fixed(data->bytes_per_pixel[i])), (bw_div(data->h_total[i], data->pixel_rate[i]))), data->vsr[i]), data->bytes_per_request[i]), data->useful_bytes_per_request[i]);
1477 data->average_bandwidth[i] = bw_div(data->average_bandwidth_no_compression[i], data->compression_rate[i]);
1480 data->total_average_bandwidth_no_compression = bw_int_to_fixed(0);
1481 data->total_average_bandwidth = bw_int_to_fixed(0);
1482 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1483 if (data->enable[i]) {
1484 data->total_average_bandwidth_no_compression = bw_add(data->total_average_bandwidth_no_compression, data->average_bandwidth_no_compression[i]);
1485 data->total_average_bandwidth = bw_add(data->total_average_bandwidth, data->average_bandwidth[i]);
1489 /*required yclk(pclk)*/
1490 /*yclk requirement only makes sense if the dmif and mcifwr data total page close-open time is less than the time for data transfer and the total pte requests fit in the scatter-gather saw queque size*/
1491 /*if that is the case, the yclk requirement is the maximum of the ones required by dmif and mcifwr, and the high/low yclk(pclk) is chosen accordingly*/
1492 /*high yclk(pclk) has to be selected when dram speed/p-state change is not possible.*/
1493 data->min_cursor_memory_interface_buffer_size_in_time = bw_int_to_fixed(9999);
1494 /* number of cursor lines stored in the cursor data return buffer*/
1495 num_cursor_lines = 0;
1496 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1497 if (data->enable[i]) {
1498 if (bw_mtn(data->cursor_width_pixels[i], bw_int_to_fixed(0))) {
1499 /*compute number of cursor lines stored in data return buffer*/
1500 if (bw_leq(data->cursor_width_pixels[i], bw_int_to_fixed(64)) && dceip->large_cursor == 1) {
1501 num_cursor_lines = 4;
1504 num_cursor_lines = 2;
1506 data->min_cursor_memory_interface_buffer_size_in_time = bw_min2(data->min_cursor_memory_interface_buffer_size_in_time, bw_div(bw_mul(bw_div(bw_int_to_fixed(num_cursor_lines), data->vsr[i]), data->h_total[i]), data->pixel_rate[i]));
1510 /*compute minimum time to read one chunk from the dmif buffer*/
1511 if (number_of_displays_enabled > 2) {
1512 data->chunk_request_delay = 0;
1515 data->chunk_request_delay = bw_fixed_to_int(bw_div(bw_int_to_fixed(512), vbios->high_voltage_max_dispclk));
1517 data->min_read_buffer_size_in_time = bw_min2(data->min_cursor_memory_interface_buffer_size_in_time, data->min_dmif_size_in_time);
1518 data->display_reads_time_for_data_transfer = bw_sub(bw_sub(data->min_read_buffer_size_in_time, data->total_dmifmc_urgent_latency), bw_int_to_fixed(data->chunk_request_delay));
1519 data->display_writes_time_for_data_transfer = bw_sub(data->min_mcifwr_size_in_time, vbios->mcifwrmc_urgent_latency);
1520 data->dmif_required_dram_bandwidth = bw_div(data->total_display_reads_required_dram_access_data, data->display_reads_time_for_data_transfer);
1521 data->mcifwr_required_dram_bandwidth = bw_div(data->total_display_writes_required_dram_access_data, data->display_writes_time_for_data_transfer);
1522 data->required_dmifmc_urgent_latency_for_page_close_open = bw_div((bw_sub(data->min_read_buffer_size_in_time, data->dmif_total_page_close_open_time)), data->total_dmifmc_urgent_trips);
1523 data->required_mcifmcwr_urgent_latency = bw_sub(data->min_mcifwr_size_in_time, data->mcifwr_total_page_close_open_time);
1524 if (bw_mtn(data->scatter_gather_total_pte_requests, dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
1525 data->required_dram_bandwidth_gbyte_per_second = bw_int_to_fixed(9999);
1526 yclk_message = bw_def_exceeded_allowed_outstanding_pte_req_queue_size;
1527 data->y_clk_level = high;
1528 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[high]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1530 else if (bw_mtn(vbios->dmifmc_urgent_latency, data->required_dmifmc_urgent_latency_for_page_close_open) || bw_mtn(vbios->mcifwrmc_urgent_latency, data->required_mcifmcwr_urgent_latency)) {
1531 data->required_dram_bandwidth_gbyte_per_second = bw_int_to_fixed(9999);
1532 yclk_message = bw_def_exceeded_allowed_page_close_open;
1533 data->y_clk_level = high;
1534 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[high]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1537 data->required_dram_bandwidth_gbyte_per_second = bw_div(bw_max2(data->dmif_required_dram_bandwidth, data->mcifwr_required_dram_bandwidth), bw_int_to_fixed(1000));
1538 if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation, 100),yclk[low]),bw_div(bw_int_to_fixed(vbios->dram_channel_width_in_bits),bw_int_to_fixed(8))),bw_int_to_fixed(vbios->number_of_dram_channels)))
1539 && bw_ltn(bw_mul(data->required_dram_bandwidth_gbyte_per_second, bw_int_to_fixed(1000)), bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[low]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels))) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[low][s_high], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[low][s_high], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[low][s_high], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[low][s_high], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[low][s_high], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[low][s_high], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[low][s_high], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[low][s_high], vbios->high_voltage_max_dispclk) && data->num_displays_with_margin[low][s_high] == number_of_displays_enabled_with_margin))) {
1540 yclk_message = bw_fixed_to_int(vbios->low_yclk);
1541 data->y_clk_level = low;
1542 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[low]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1544 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation, 100),yclk[mid]),bw_div(bw_int_to_fixed(vbios->dram_channel_width_in_bits),bw_int_to_fixed(8))),bw_int_to_fixed(vbios->number_of_dram_channels)))
1545 && bw_ltn(bw_mul(data->required_dram_bandwidth_gbyte_per_second, bw_int_to_fixed(1000)), bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[mid]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels))) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[mid][s_high], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[mid][s_high], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[mid][s_high], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[mid][s_high], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[mid][s_high], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[mid][s_high], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[mid][s_high], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[mid][s_high], vbios->high_voltage_max_dispclk) && data->num_displays_with_margin[mid][s_high] == number_of_displays_enabled_with_margin))) {
1546 yclk_message = bw_fixed_to_int(vbios->mid_yclk);
1547 data->y_clk_level = mid;
1548 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[mid]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1550 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation, 100),yclk[high]),bw_div(bw_int_to_fixed(vbios->dram_channel_width_in_bits),bw_int_to_fixed(8))),bw_int_to_fixed(vbios->number_of_dram_channels)))
1551 && bw_ltn(bw_mul(data->required_dram_bandwidth_gbyte_per_second, bw_int_to_fixed(1000)), bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[high]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels)))) {
1552 yclk_message = bw_fixed_to_int(vbios->high_yclk);
1553 data->y_clk_level = high;
1554 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[high]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1557 yclk_message = bw_def_exceeded_allowed_maximum_bw;
1558 data->y_clk_level = high;
1559 data->dram_bandwidth = bw_mul(bw_div(bw_mul(bw_mul(data->dram_efficiency, yclk[high]), bw_int_to_fixed(vbios->dram_channel_width_in_bits)), bw_int_to_fixed(8)), bw_int_to_fixed(data->number_of_dram_channels));
1563 /*sclk requirement only makes sense if the total pte requests fit in the scatter-gather saw queque size*/
1564 /*if that is the case, the sclk requirement is the maximum of the ones required by dmif and mcifwr, and the high/mid/low sclk is chosen accordingly, unless that choice results in foresaking dram speed/nb p-state change.*/
1565 /*the dmif and mcifwr sclk required is the one that allows the transfer of all pipe's data buffer size through the sclk bus in the time for data transfer*/
1566 /*for dmif, pte and cursor requests have to be included.*/
1567 data->dmif_required_sclk = bw_div(bw_div(data->total_display_reads_required_data, data->display_reads_time_for_data_transfer), (bw_mul(vbios->data_return_bus_width, bw_frc_to_fixed(dceip->percent_of_ideal_port_bw_received_after_urgent_latency, 100))));
1568 data->mcifwr_required_sclk = bw_div(bw_div(data->total_display_writes_required_data, data->display_writes_time_for_data_transfer), vbios->data_return_bus_width);
1569 if (bw_mtn(data->scatter_gather_total_pte_requests, dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
1570 data->required_sclk = bw_int_to_fixed(9999);
1571 sclk_message = bw_def_exceeded_allowed_outstanding_pte_req_queue_size;
1572 data->sclk_level = s_high;
1574 else if (bw_mtn(vbios->dmifmc_urgent_latency, data->required_dmifmc_urgent_latency_for_page_close_open) || bw_mtn(vbios->mcifwrmc_urgent_latency, data->required_mcifmcwr_urgent_latency)) {
1575 data->required_sclk = bw_int_to_fixed(9999);
1576 sclk_message = bw_def_exceeded_allowed_page_close_open;
1577 data->sclk_level = s_high;
1580 data->required_sclk = bw_max2(data->dmif_required_sclk, data->mcifwr_required_sclk);
1581 if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[low]),vbios->data_return_bus_width))
1582 && bw_ltn(data->required_sclk, sclk[s_low]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_low], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_low], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_low], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_low], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_low], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_low], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_low], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_low], vbios->low_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_low] == number_of_displays_enabled_with_margin))) {
1583 sclk_message = bw_def_low;
1584 data->sclk_level = s_low;
1585 data->required_sclk = vbios->low_sclk;
1587 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[mid]),vbios->data_return_bus_width))
1588 && bw_ltn(data->required_sclk, sclk[s_mid1]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid1], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid1], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid1], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid1], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid1], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid1], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid1], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid1], vbios->mid_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid1] == number_of_displays_enabled_with_margin))) {
1589 sclk_message = bw_def_mid;
1590 data->sclk_level = s_mid1;
1591 data->required_sclk = vbios->mid1_sclk;
1593 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_mid2]),vbios->data_return_bus_width))
1594 && bw_ltn(data->required_sclk, sclk[s_mid2]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid2], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid2], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid2], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid2], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid2], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid2], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid2], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid2], vbios->mid_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid2] == number_of_displays_enabled_with_margin))) {
1595 sclk_message = bw_def_mid;
1596 data->sclk_level = s_mid2;
1597 data->required_sclk = vbios->mid2_sclk;
1599 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_mid3]),vbios->data_return_bus_width))
1600 && bw_ltn(data->required_sclk, sclk[s_mid3]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid3], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid3], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid3], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid3], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid3], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid3], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid3], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid3], vbios->mid_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid3] == number_of_displays_enabled_with_margin))) {
1601 sclk_message = bw_def_mid;
1602 data->sclk_level = s_mid3;
1603 data->required_sclk = vbios->mid3_sclk;
1605 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_mid4]),vbios->data_return_bus_width))
1606 && bw_ltn(data->required_sclk, sclk[s_mid4]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid4], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid4], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid4], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid4], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid4], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid4], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid4], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid4], vbios->mid_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid4] == number_of_displays_enabled_with_margin))) {
1607 sclk_message = bw_def_mid;
1608 data->sclk_level = s_mid4;
1609 data->required_sclk = vbios->mid4_sclk;
1611 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_mid5]),vbios->data_return_bus_width))
1612 && bw_ltn(data->required_sclk, sclk[s_mid5]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid5], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid5], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid5], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid5], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid5], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid5], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid5], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid5], vbios->mid_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid5] == number_of_displays_enabled_with_margin))) {
1613 sclk_message = bw_def_mid;
1614 data->sclk_level = s_mid5;
1615 data->required_sclk = vbios->mid5_sclk;
1617 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_mid6]),vbios->data_return_bus_width))
1618 && bw_ltn(data->required_sclk, sclk[s_mid6]) && (data->cpup_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid6], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid6], vbios->high_voltage_max_dispclk))) && (data->cpuc_state_change_enable == bw_def_no || (bw_mtn(data->blackout_duration_margin[data->y_clk_level][s_mid6], bw_int_to_fixed(0)) && bw_ltn(data->dispclk_required_for_blackout_duration[data->y_clk_level][s_mid6], vbios->high_voltage_max_dispclk) && bw_ltn(data->dispclk_required_for_blackout_recovery[data->y_clk_level][s_mid6], vbios->high_voltage_max_dispclk))) && (!data->increase_voltage_to_support_mclk_switch || data->nbp_state_change_enable == bw_def_no || (bw_mtn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid6], bw_int_to_fixed(0)) && bw_ltn(data->min_dram_speed_change_margin[data->y_clk_level][s_mid6], bw_int_to_fixed(9999)) && bw_leq(data->dispclk_required_for_dram_speed_change[data->y_clk_level][s_mid6], vbios->high_voltage_max_dispclk) && data->num_displays_with_margin[data->y_clk_level][s_mid6] == number_of_displays_enabled_with_margin))) {
1619 sclk_message = bw_def_mid;
1620 data->sclk_level = s_mid6;
1621 data->required_sclk = vbios->mid6_sclk;
1623 else if (bw_ltn(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_high]),vbios->data_return_bus_width))
1624 && bw_ltn(data->required_sclk, sclk[s_high])) {
1625 sclk_message = bw_def_high;
1626 data->sclk_level = s_high;
1627 data->required_sclk = vbios->high_sclk;
1629 else if (bw_meq(data->total_average_bandwidth_no_compression, bw_mul(bw_mul(bw_frc_to_fixed(dceip->max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation, 100),sclk[s_high]),vbios->data_return_bus_width))
1630 && bw_ltn(data->required_sclk, sclk[s_high])) {
1631 sclk_message = bw_def_high;
1632 data->sclk_level = s_high;
1633 data->required_sclk = vbios->high_sclk;
1636 sclk_message = bw_def_exceeded_allowed_maximum_sclk;
1637 data->sclk_level = s_high;
1638 /*required_sclk = high_sclk*/
1642 /*if dispclk is set to the maximum, ramping is not required. dispclk required without ramping is less than the dispclk required with ramping.*/
1643 /*if dispclk required without ramping is more than the maximum dispclk, that is the dispclk required, and the mode is not supported*/
1644 /*if that does not happen, but dispclk required with ramping is more than the maximum dispclk, dispclk required is just the maximum dispclk*/
1645 /*if that does not happen either, dispclk required is the dispclk required with ramping.*/
1646 /*dispclk required without ramping is the maximum of the one required for display pipe pixel throughput, for scaler throughput, for total read request thrrougput and for dram/np p-state change if enabled.*/
1647 /*the display pipe pixel throughput is the maximum of lines in per line out in the beginning of the frame and lines in per line out in the middle of the frame multiplied by the horizontal blank and chunk granularity factor, altogether multiplied by the ratio of the source width to the line time, divided by the line buffer pixels per dispclk throughput, and multiplied by the display pipe throughput factor.*/
1648 /*the horizontal blank and chunk granularity factor is the ratio of the line time divided by the line time minus half the horizontal blank and chunk time. it applies when the lines in per line out is not 2 or 4.*/
1649 /*the dispclk required for scaler throughput is the product of the pixel rate and the scaling limits factor.*/
1650 /*the dispclk required for total read request throughput is the product of the peak request-per-second bandwidth and the dispclk cycles per request, divided by the request efficiency.*/
1651 /*for the dispclk required with ramping, instead of multiplying just the pipe throughput by the display pipe throughput factor, we multiply the scaler and pipe throughput by the ramping factor.*/
1652 /*the scaling limits factor is the product of the horizontal scale ratio, and the ratio of the vertical taps divided by the scaler efficiency clamped to at least 1.*/
1653 /*the scaling limits factor itself it also clamped to at least 1*/
1654 /*if doing downscaling with the pre-downscaler enabled, the horizontal scale ratio should not be considered above (use "1")*/
1655 data->downspread_factor = bw_add(bw_int_to_fixed(1), bw_div(vbios->down_spread_percentage, bw_int_to_fixed(100)));
1656 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1657 if (data->enable[i]) {
1658 if (surface_type[i] == bw_def_graphics) {
1659 switch (data->lb_bpc[i]) {
1661 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency6_bit_per_component;
1664 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency8_bit_per_component;
1667 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency10_bit_per_component;
1670 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency12_bit_per_component;
1673 if (data->use_alpha[i] == 1) {
1674 data->v_scaler_efficiency = bw_min2(data->v_scaler_efficiency, dceip->alpha_vscaler_efficiency);
1678 switch (data->lb_bpc[i]) {
1680 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency6_bit_per_component;
1683 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency8_bit_per_component;
1686 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency10_bit_per_component;
1689 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency12_bit_per_component;
1693 if (dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1))) {
1694 data->scaler_limits_factor = bw_max2(bw_div(data->v_taps[i], data->v_scaler_efficiency), bw_div(data->source_width_rounded_up_to_chunks[i], data->h_total[i]));
1697 data->scaler_limits_factor = bw_max3(bw_int_to_fixed(1), bw_ceil2(bw_div(data->h_taps[i], bw_int_to_fixed(4)), bw_int_to_fixed(1)), bw_mul(data->hsr[i], bw_max2(bw_div(data->v_taps[i], data->v_scaler_efficiency), bw_int_to_fixed(1))));
1699 data->display_pipe_pixel_throughput = bw_div(bw_div(bw_mul(bw_max2(data->lb_lines_in_per_line_out_in_beginning_of_frame[i], bw_mul(data->lb_lines_in_per_line_out_in_middle_of_frame[i], data->horizontal_blank_and_chunk_granularity_factor[i])), data->source_width_rounded_up_to_chunks[i]), (bw_div(data->h_total[i], data->pixel_rate[i]))), dceip->lb_write_pixels_per_dispclk);
1700 data->dispclk_required_without_ramping[i] = bw_mul(data->downspread_factor, bw_max2(bw_mul(data->pixel_rate[i], data->scaler_limits_factor), bw_mul(dceip->display_pipe_throughput_factor, data->display_pipe_pixel_throughput)));
1701 data->dispclk_required_with_ramping[i] = bw_mul(dceip->dispclk_ramping_factor, bw_max2(bw_mul(data->pixel_rate[i], data->scaler_limits_factor), data->display_pipe_pixel_throughput));
1704 data->total_dispclk_required_with_ramping = bw_int_to_fixed(0);
1705 data->total_dispclk_required_without_ramping = bw_int_to_fixed(0);
1706 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1707 if (data->enable[i]) {
1708 if (bw_ltn(data->total_dispclk_required_with_ramping, data->dispclk_required_with_ramping[i])) {
1709 data->total_dispclk_required_with_ramping = data->dispclk_required_with_ramping[i];
1711 if (bw_ltn(data->total_dispclk_required_without_ramping, data->dispclk_required_without_ramping[i])) {
1712 data->total_dispclk_required_without_ramping = data->dispclk_required_without_ramping[i];
1716 data->total_read_request_bandwidth = bw_int_to_fixed(0);
1717 data->total_write_request_bandwidth = bw_int_to_fixed(0);
1718 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1719 if (data->enable[i]) {
1720 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1721 data->total_read_request_bandwidth = bw_add(data->total_read_request_bandwidth, data->request_bandwidth[i]);
1724 data->total_write_request_bandwidth = bw_add(data->total_write_request_bandwidth, data->request_bandwidth[i]);
1728 data->dispclk_required_for_total_read_request_bandwidth = bw_div(bw_mul(data->total_read_request_bandwidth, dceip->dispclk_per_request), dceip->request_efficiency);
1729 data->total_dispclk_required_with_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_with_ramping, data->dispclk_required_for_total_read_request_bandwidth);
1730 data->total_dispclk_required_without_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_without_ramping, data->dispclk_required_for_total_read_request_bandwidth);
1731 if (data->cpuc_state_change_enable == bw_def_yes) {
1732 data->total_dispclk_required_with_ramping_with_request_bandwidth = bw_max3(data->total_dispclk_required_with_ramping_with_request_bandwidth, data->dispclk_required_for_blackout_duration[data->y_clk_level][data->sclk_level], data->dispclk_required_for_blackout_recovery[data->y_clk_level][data->sclk_level]);
1733 data->total_dispclk_required_without_ramping_with_request_bandwidth = bw_max3(data->total_dispclk_required_without_ramping_with_request_bandwidth, data->dispclk_required_for_blackout_duration[data->y_clk_level][data->sclk_level], data->dispclk_required_for_blackout_recovery[data->y_clk_level][data->sclk_level]);
1735 if (data->cpup_state_change_enable == bw_def_yes) {
1736 data->total_dispclk_required_with_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_with_ramping_with_request_bandwidth, data->dispclk_required_for_blackout_duration[data->y_clk_level][data->sclk_level]);
1737 data->total_dispclk_required_without_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_without_ramping_with_request_bandwidth, data->dispclk_required_for_blackout_duration[data->y_clk_level][data->sclk_level]);
1739 if (data->nbp_state_change_enable == bw_def_yes && data->increase_voltage_to_support_mclk_switch) {
1740 data->total_dispclk_required_with_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_with_ramping_with_request_bandwidth, data->dispclk_required_for_dram_speed_change[data->y_clk_level][data->sclk_level]);
1741 data->total_dispclk_required_without_ramping_with_request_bandwidth = bw_max2(data->total_dispclk_required_without_ramping_with_request_bandwidth, data->dispclk_required_for_dram_speed_change[data->y_clk_level][data->sclk_level]);
1743 if (bw_ltn(data->total_dispclk_required_with_ramping_with_request_bandwidth, vbios->high_voltage_max_dispclk)) {
1744 data->dispclk = data->total_dispclk_required_with_ramping_with_request_bandwidth;
1746 else if (bw_ltn(data->total_dispclk_required_without_ramping_with_request_bandwidth, vbios->high_voltage_max_dispclk)) {
1747 data->dispclk = vbios->high_voltage_max_dispclk;
1750 data->dispclk = data->total_dispclk_required_without_ramping_with_request_bandwidth;
1752 /* required core voltage*/
1753 /* the core voltage required is low if sclk, yclk(pclk)and dispclk are within the low limits*/
1754 /* otherwise, the core voltage required is medium if yclk (pclk) is within the low limit and sclk and dispclk are within the medium limit*/
1755 /* otherwise, the core voltage required is high if the three clocks are within the high limits*/
1756 /* otherwise, or if the mode is not supported, core voltage requirement is not applicable*/
1757 if (pipe_check == bw_def_notok) {
1758 voltage = bw_def_na;
1760 else if (mode_check == bw_def_notok) {
1761 voltage = bw_def_notok;
1763 else if (bw_equ(bw_int_to_fixed(yclk_message), vbios->low_yclk) && sclk_message == bw_def_low && bw_ltn(data->dispclk, vbios->low_voltage_max_dispclk)) {
1764 voltage = bw_def_0_72;
1766 else if ((bw_equ(bw_int_to_fixed(yclk_message), vbios->low_yclk) || bw_equ(bw_int_to_fixed(yclk_message), vbios->mid_yclk)) && (sclk_message == bw_def_low || sclk_message == bw_def_mid) && bw_ltn(data->dispclk, vbios->mid_voltage_max_dispclk)) {
1767 voltage = bw_def_0_8;
1769 else if ((bw_equ(bw_int_to_fixed(yclk_message), vbios->low_yclk) || bw_equ(bw_int_to_fixed(yclk_message), vbios->mid_yclk) || bw_equ(bw_int_to_fixed(yclk_message), vbios->high_yclk)) && (sclk_message == bw_def_low || sclk_message == bw_def_mid || sclk_message == bw_def_high) && bw_leq(data->dispclk, vbios->high_voltage_max_dispclk)) {
1770 if ((data->nbp_state_change_enable == bw_def_no && nbp_state_change_enable_blank == bw_def_no)) {
1771 voltage = bw_def_high_no_nbp_state_change;
1774 voltage = bw_def_0_9;
1778 voltage = bw_def_notok;
1780 if (voltage == bw_def_0_72) {
1781 data->max_phyclk = vbios->low_voltage_max_phyclk;
1783 else if (voltage == bw_def_0_8) {
1784 data->max_phyclk = vbios->mid_voltage_max_phyclk;
1787 data->max_phyclk = vbios->high_voltage_max_phyclk;
1789 /*required blackout recovery time*/
1790 data->blackout_recovery_time = bw_int_to_fixed(0);
1791 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1792 if (data->enable[k] && bw_mtn(vbios->blackout_duration, bw_int_to_fixed(0)) && data->cpup_state_change_enable == bw_def_yes) {
1793 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1794 data->blackout_recovery_time = bw_max2(data->blackout_recovery_time, bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[data->y_clk_level][data->sclk_level]));
1795 if (bw_ltn(data->adjusted_data_buffer_size[k], bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[data->y_clk_level][data->sclk_level])))))) {
1796 data->blackout_recovery_time = bw_max2(data->blackout_recovery_time, bw_div((bw_add(bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), vbios->blackout_duration), bw_sub(bw_div(bw_mul(bw_mul(bw_mul((bw_add(bw_mul(bw_int_to_fixed(2), data->total_dmifmc_urgent_latency), data->dmif_burst_time[data->y_clk_level][data->sclk_level])), data->dispclk), bw_int_to_fixed(data->bytes_per_pixel[k])), data->lines_interleaved_in_mem_access[k]), data->latency_hiding_lines[k]), data->adjusted_data_buffer_size[k]))), (bw_sub(bw_div(bw_mul(bw_mul(data->dispclk, bw_int_to_fixed(data->bytes_per_pixel[k])), data->lines_interleaved_in_mem_access[k]), data->latency_hiding_lines[k]), bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k])))));
1800 data->blackout_recovery_time = bw_max2(data->blackout_recovery_time, bw_add(bw_mul(bw_int_to_fixed(2), vbios->mcifwrmc_urgent_latency), data->mcifwr_burst_time[data->y_clk_level][data->sclk_level]));
1801 if (bw_ltn(data->adjusted_data_buffer_size[k], bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), (bw_add(vbios->blackout_duration, bw_add(bw_mul(bw_int_to_fixed(2), vbios->mcifwrmc_urgent_latency), data->mcifwr_burst_time[data->y_clk_level][data->sclk_level])))))) {
1802 data->blackout_recovery_time = bw_max2(data->blackout_recovery_time, bw_div((bw_add(bw_mul(bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k]), vbios->blackout_duration), bw_sub(bw_div(bw_mul(bw_mul(bw_mul((bw_add(bw_add(bw_mul(bw_int_to_fixed(2), vbios->mcifwrmc_urgent_latency), data->dmif_burst_time[data->y_clk_level][data->sclk_level]), data->mcifwr_burst_time[data->y_clk_level][data->sclk_level])), data->dispclk), bw_int_to_fixed(data->bytes_per_pixel[k])), data->lines_interleaved_in_mem_access[k]), data->latency_hiding_lines[k]), data->adjusted_data_buffer_size[k]))), (bw_sub(bw_div(bw_mul(bw_mul(data->dispclk, bw_int_to_fixed(data->bytes_per_pixel[k])), data->lines_interleaved_in_mem_access[k]), data->latency_hiding_lines[k]), bw_div(bw_mul(data->display_bandwidth[k], data->useful_bytes_per_request[k]), data->bytes_per_request[k])))));
1808 /*during self-refresh, sclk can be reduced to dispclk divided by the minimum pixels in the data fifo entry, with 15% margin, but shoudl not be set to less than the request bandwidth.*/
1809 /*the data fifo entry is 16 pixels for the writeback, 64 bytes/bytes_per_pixel for the graphics, 16 pixels for the parallel rotation underlay,*/
1810 /*and 16 bytes/bytes_per_pixel for the orthogonal rotation underlay.*/
1811 /*in parallel mode (underlay pipe), the data read from the dmifv buffer is variable and based on the pixel depth (8bbp - 16 bytes, 16 bpp - 32 bytes, 32 bpp - 64 bytes)*/
1812 /*in orthogonal mode (underlay pipe), the data read from the dmifv buffer is fixed at 16 bytes.*/
1813 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1814 if (data->enable[i]) {
1815 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
1816 data->pixels_per_data_fifo_entry[i] = bw_int_to_fixed(16);
1818 else if (surface_type[i] == bw_def_graphics) {
1819 data->pixels_per_data_fifo_entry[i] = bw_div(bw_int_to_fixed(64), bw_int_to_fixed(data->bytes_per_pixel[i]));
1821 else if (data->orthogonal_rotation[i] == 0) {
1822 data->pixels_per_data_fifo_entry[i] = bw_int_to_fixed(16);
1825 data->pixels_per_data_fifo_entry[i] = bw_div(bw_int_to_fixed(16), bw_int_to_fixed(data->bytes_per_pixel[i]));
1829 data->min_pixels_per_data_fifo_entry = bw_int_to_fixed(9999);
1830 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1831 if (data->enable[i]) {
1832 if (bw_mtn(data->min_pixels_per_data_fifo_entry, data->pixels_per_data_fifo_entry[i])) {
1833 data->min_pixels_per_data_fifo_entry = data->pixels_per_data_fifo_entry[i];
1837 data->sclk_deep_sleep = bw_max2(bw_div(bw_mul(data->dispclk, bw_frc_to_fixed(115, 100)), data->min_pixels_per_data_fifo_entry), data->total_read_request_bandwidth);
1838 /*urgent, stutter and nb-p_state watermark*/
1839 /*the urgent watermark is the maximum of the urgent trip time plus the pixel transfer time, the urgent trip times to get data for the first pixel, and the urgent trip times to get data for the last pixel.*/
1840 /*the stutter exit watermark is the self refresh exit time plus the maximum of the data burst time plus the pixel transfer time, the data burst times to get data for the first pixel, and the data burst times to get data for the last pixel. it does not apply to the writeback.*/
1841 /*the nb p-state change watermark is the dram speed/p-state change time plus the maximum of the data burst time plus the pixel transfer time, the data burst times to get data for the first pixel, and the data burst times to get data for the last pixel.*/
1842 /*the pixel transfer time is the maximum of the time to transfer the source pixels required for the first output pixel, and the time to transfer the pixels for the last output pixel minus the active line time.*/
1843 /*blackout_duration is added to the urgent watermark*/
1844 data->chunk_request_time = bw_int_to_fixed(0);
1845 data->cursor_request_time = bw_int_to_fixed(0);
1846 /*compute total time to request one chunk from each active display pipe*/
1847 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1848 if (data->enable[i]) {
1849 data->chunk_request_time = bw_add(data->chunk_request_time, (bw_div((bw_div(bw_int_to_fixed(pixels_per_chunk * data->bytes_per_pixel[i]), data->useful_bytes_per_request[i])), bw_min2(sclk[data->sclk_level], bw_div(data->dispclk, bw_int_to_fixed(2))))));
1852 /*compute total time to request cursor data*/
1853 data->cursor_request_time = (bw_div(data->cursor_total_data, (bw_mul(bw_int_to_fixed(32), sclk[data->sclk_level]))));
1854 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1855 if (data->enable[i]) {
1856 data->line_source_pixels_transfer_time = bw_max2(bw_div(bw_div(data->src_pixels_for_first_output_pixel[i], dceip->lb_write_pixels_per_dispclk), (bw_div(data->dispclk, dceip->display_pipe_throughput_factor))), bw_sub(bw_div(bw_div(data->src_pixels_for_last_output_pixel[i], dceip->lb_write_pixels_per_dispclk), (bw_div(data->dispclk, dceip->display_pipe_throughput_factor))), data->active_time[i]));
1857 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1858 data->urgent_watermark[i] = bw_add(bw_add(bw_add(bw_add(bw_add(data->total_dmifmc_urgent_latency, data->dmif_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->line_source_transfer_time[i][data->y_clk_level][data->sclk_level])), vbios->blackout_duration), data->chunk_request_time), data->cursor_request_time);
1859 data->stutter_exit_watermark[i] = bw_add(bw_sub(vbios->stutter_self_refresh_exit_latency, data->total_dmifmc_urgent_latency), data->urgent_watermark[i]);
1860 data->stutter_entry_watermark[i] = bw_add(bw_sub(bw_add(vbios->stutter_self_refresh_exit_latency, vbios->stutter_self_refresh_entry_latency), data->total_dmifmc_urgent_latency), data->urgent_watermark[i]);
1861 /*unconditionally remove black out time from the nb p_state watermark*/
1862 if (data->display_pstate_change_enable[i] == 1) {
1863 data->nbp_state_change_watermark[i] = bw_add(bw_add(vbios->nbp_state_change_latency, data->dmif_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->dram_speed_change_line_source_transfer_time[i][data->y_clk_level][data->sclk_level]));
1866 /*maximize the watermark to force the switch in the vb_lank region of the frame*/
1867 data->nbp_state_change_watermark[i] = bw_int_to_fixed(131000);
1871 data->urgent_watermark[i] = bw_add(bw_add(bw_add(bw_add(bw_add(vbios->mcifwrmc_urgent_latency, data->mcifwr_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->line_source_transfer_time[i][data->y_clk_level][data->sclk_level])), vbios->blackout_duration), data->chunk_request_time), data->cursor_request_time);
1872 data->stutter_exit_watermark[i] = bw_int_to_fixed(0);
1873 data->stutter_entry_watermark[i] = bw_int_to_fixed(0);
1874 if (data->display_pstate_change_enable[i] == 1) {
1875 data->nbp_state_change_watermark[i] = bw_add(bw_add(vbios->nbp_state_change_latency, data->mcifwr_burst_time[data->y_clk_level][data->sclk_level]), bw_max2(data->line_source_pixels_transfer_time, data->dram_speed_change_line_source_transfer_time[i][data->y_clk_level][data->sclk_level]));
1878 /*maximize the watermark to force the switch in the vb_lank region of the frame*/
1879 data->nbp_state_change_watermark[i] = bw_int_to_fixed(131000);
1884 /*stutter mode enable*/
1885 /*in the multi-display case the stutter exit or entry watermark cannot exceed the minimum latency hiding capabilities of the*/
1887 data->stutter_mode_enable = data->cpuc_state_change_enable;
1888 if (data->number_of_displays > 1) {
1889 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1890 if (data->enable[i]) {
1891 if ((bw_mtn(data->stutter_exit_watermark[i], data->minimum_latency_hiding[i]) || bw_mtn(data->stutter_entry_watermark[i], data->minimum_latency_hiding[i]))) {
1892 data->stutter_mode_enable = bw_def_no;
1897 /*performance metrics*/
1898 /* display read access efficiency (%)*/
1899 /* display write back access efficiency (%)*/
1900 /* stutter efficiency (%)*/
1901 /* extra underlay pitch recommended for efficiency (pixels)*/
1902 /* immediate flip time (us)*/
1903 /* latency for other clients due to urgent display read (us)*/
1904 /* latency for other clients due to urgent display write (us)*/
1905 /* average bandwidth consumed by display (no compression) (gb/s)*/
1906 /* required dram bandwidth (gb/s)*/
1907 /* required sclk (m_hz)*/
1908 /* required rd urgent latency (us)*/
1909 /* nb p-state change margin (us)*/
1910 /*dmif and mcifwr dram access efficiency*/
1911 /*is the ratio between the ideal dram access time (which is the data buffer size in memory divided by the dram bandwidth), and the actual time which is the total page close-open time. but it cannot exceed the dram efficiency provided by the memory subsystem*/
1912 data->dmifdram_access_efficiency = bw_min2(bw_div(bw_div(data->total_display_reads_required_dram_access_data, data->dram_bandwidth), data->dmif_total_page_close_open_time), bw_int_to_fixed(1));
1913 if (bw_mtn(data->total_display_writes_required_dram_access_data, bw_int_to_fixed(0))) {
1914 data->mcifwrdram_access_efficiency = bw_min2(bw_div(bw_div(data->total_display_writes_required_dram_access_data, data->dram_bandwidth), data->mcifwr_total_page_close_open_time), bw_int_to_fixed(1));
1917 data->mcifwrdram_access_efficiency = bw_int_to_fixed(0);
1919 /*stutter efficiency*/
1920 /*the stutter efficiency is the frame-average time in self-refresh divided by the frame-average stutter cycle duration. only applies if the display write-back is not enabled.*/
1921 /*the frame-average stutter cycle used is the minimum for all pipes of the frame-average data buffer size in time, times the compression rate*/
1922 /*the frame-average time in self-refresh is the stutter cycle minus the self refresh exit latency and the burst time*/
1923 /*the stutter cycle is the dmif buffer size reduced by the excess of the stutter exit watermark over the lb size in time.*/
1924 /*the burst time is the data needed during the stutter cycle divided by the available bandwidth*/
1925 /*compute the time read all the data from the dmif buffer to the lb (dram refresh period)*/
1926 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1927 if (data->enable[i]) {
1928 data->stutter_refresh_duration[i] = bw_sub(bw_mul(bw_div(bw_div(bw_mul(bw_div(bw_div(data->adjusted_data_buffer_size[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->source_width_rounded_up_to_chunks[i]), data->h_total[i]), data->vsr[i]), data->pixel_rate[i]), data->compression_rate[i]), bw_max2(bw_int_to_fixed(0), bw_sub(data->stutter_exit_watermark[i], bw_div(bw_mul((bw_sub(data->lb_partitions[i], bw_int_to_fixed(1))), data->h_total[i]), data->pixel_rate[i]))));
1929 data->stutter_dmif_buffer_size[i] = bw_div(bw_mul(bw_mul(bw_div(bw_mul(bw_mul(data->stutter_refresh_duration[i], bw_int_to_fixed(data->bytes_per_pixel[i])), data->source_width_rounded_up_to_chunks[i]), data->h_total[i]), data->vsr[i]), data->pixel_rate[i]), data->compression_rate[i]);
1932 data->min_stutter_refresh_duration = bw_int_to_fixed(9999);
1933 data->total_stutter_dmif_buffer_size = 0;
1934 data->total_bytes_requested = 0;
1935 data->min_stutter_dmif_buffer_size = 9999;
1936 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1937 if (data->enable[i]) {
1938 if (bw_mtn(data->min_stutter_refresh_duration, data->stutter_refresh_duration[i])) {
1939 data->min_stutter_refresh_duration = data->stutter_refresh_duration[i];
1940 data->total_bytes_requested = bw_fixed_to_int(bw_add(bw_int_to_fixed(data->total_bytes_requested), (bw_mul(bw_mul(data->source_height_rounded_up_to_chunks[i], data->source_width_rounded_up_to_chunks[i]), bw_int_to_fixed(data->bytes_per_pixel[i])))));
1941 data->min_stutter_dmif_buffer_size = bw_fixed_to_int(data->stutter_dmif_buffer_size[i]);
1943 data->total_stutter_dmif_buffer_size = bw_fixed_to_int(bw_add(data->stutter_dmif_buffer_size[i], bw_int_to_fixed(data->total_stutter_dmif_buffer_size)));
1946 data->stutter_burst_time = bw_div(bw_int_to_fixed(data->total_stutter_dmif_buffer_size), bw_mul(sclk[data->sclk_level], vbios->data_return_bus_width));
1947 data->num_stutter_bursts = data->total_bytes_requested / data->min_stutter_dmif_buffer_size;
1948 data->total_stutter_cycle_duration = bw_add(bw_add(data->min_stutter_refresh_duration, vbios->stutter_self_refresh_exit_latency), data->stutter_burst_time);
1949 data->time_in_self_refresh = data->min_stutter_refresh_duration;
1950 if (data->d1_display_write_back_dwb_enable == 1) {
1951 data->stutter_efficiency = bw_int_to_fixed(0);
1953 else if (bw_ltn(data->time_in_self_refresh, bw_int_to_fixed(0))) {
1954 data->stutter_efficiency = bw_int_to_fixed(0);
1957 /*compute stutter efficiency assuming 60 hz refresh rate*/
1958 data->stutter_efficiency = bw_max2(bw_int_to_fixed(0), bw_mul((bw_sub(bw_int_to_fixed(1), (bw_div(bw_mul((bw_add(vbios->stutter_self_refresh_exit_latency, data->stutter_burst_time)), bw_int_to_fixed(data->num_stutter_bursts)), bw_frc_to_fixed(166666667, 10000))))), bw_int_to_fixed(100)));
1960 /*immediate flip time*/
1961 /*if scatter gather is enabled, the immediate flip takes a number of urgent memory trips equivalent to the pte requests in a row divided by the pte request limit.*/
1962 /*otherwise, it may take just one urgenr memory trip*/
1963 data->worst_number_of_trips_to_memory = bw_int_to_fixed(1);
1964 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1965 if (data->enable[i] && data->scatter_gather_enable_for_pipe[i] == 1) {
1966 data->number_of_trips_to_memory_for_getting_apte_row[i] = bw_ceil2(bw_div(data->scatter_gather_pte_requests_in_row[i], data->scatter_gather_pte_request_limit[i]), bw_int_to_fixed(1));
1967 if (bw_ltn(data->worst_number_of_trips_to_memory, data->number_of_trips_to_memory_for_getting_apte_row[i])) {
1968 data->worst_number_of_trips_to_memory = data->number_of_trips_to_memory_for_getting_apte_row[i];
1972 data->immediate_flip_time = bw_mul(data->worst_number_of_trips_to_memory, data->total_dmifmc_urgent_latency);
1973 /*worst latency for other clients*/
1974 /*it is the urgent latency plus the urgent burst time*/
1975 data->latency_for_non_dmif_clients = bw_add(data->total_dmifmc_urgent_latency, data->dmif_burst_time[data->y_clk_level][data->sclk_level]);
1976 if (data->d1_display_write_back_dwb_enable == 1) {
1977 data->latency_for_non_mcifwr_clients = bw_add(vbios->mcifwrmc_urgent_latency, dceip->mcifwr_all_surfaces_burst_time);
1980 data->latency_for_non_mcifwr_clients = bw_int_to_fixed(0);
1982 /*dmif mc urgent latency suppported in high sclk and yclk*/
1983 data->dmifmc_urgent_latency_supported_in_high_sclk_and_yclk = bw_div((bw_sub(data->min_read_buffer_size_in_time, data->dmif_burst_time[high][s_high])), data->total_dmifmc_urgent_trips);
1984 /*dram speed/p-state change margin*/
1985 /*in the multi-display case the nb p-state change watermark cannot exceed the average lb size plus the dmif size or the cursor dcp buffer size*/
1986 data->v_blank_nbp_state_dram_speed_change_latency_supported = bw_int_to_fixed(99999);
1987 data->nbp_state_dram_speed_change_latency_supported = bw_int_to_fixed(99999);
1988 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1989 if (data->enable[i]) {
1990 data->nbp_state_dram_speed_change_latency_supported = bw_min2(data->nbp_state_dram_speed_change_latency_supported, bw_add(bw_sub(data->maximum_latency_hiding_with_cursor[i], data->nbp_state_change_watermark[i]), vbios->nbp_state_change_latency));
1991 data->v_blank_nbp_state_dram_speed_change_latency_supported = bw_min2(data->v_blank_nbp_state_dram_speed_change_latency_supported, bw_add(bw_sub(bw_div(bw_mul((bw_sub(data->v_total[i], bw_sub(bw_div(data->src_height[i], data->v_scale_ratio[i]), bw_int_to_fixed(4)))), data->h_total[i]), data->pixel_rate[i]), data->nbp_state_change_watermark[i]), vbios->nbp_state_change_latency));
1994 /*sclk required vs urgent latency*/
1995 for (i = 1; i <= 5; i++) {
1996 data->display_reads_time_for_data_transfer_and_urgent_latency = bw_sub(data->min_read_buffer_size_in_time, bw_mul(data->total_dmifmc_urgent_trips, bw_int_to_fixed(i)));
1997 if (pipe_check == bw_def_ok && (bw_mtn(data->display_reads_time_for_data_transfer_and_urgent_latency, data->dmif_total_page_close_open_time))) {
1998 data->dmif_required_sclk_for_urgent_latency[i] = bw_div(bw_div(data->total_display_reads_required_data, data->display_reads_time_for_data_transfer_and_urgent_latency), (bw_mul(vbios->data_return_bus_width, bw_frc_to_fixed(dceip->percent_of_ideal_port_bw_received_after_urgent_latency, 100))));
2001 data->dmif_required_sclk_for_urgent_latency[i] = bw_int_to_fixed(bw_def_na);
2004 /*output link bit per pixel supported*/
2005 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
2006 data->output_bpphdmi[k] = bw_def_na;
2007 data->output_bppdp4_lane_hbr[k] = bw_def_na;
2008 data->output_bppdp4_lane_hbr2[k] = bw_def_na;
2009 data->output_bppdp4_lane_hbr3[k] = bw_def_na;
2010 if (data->enable[k]) {
2011 data->output_bpphdmi[k] = bw_fixed_to_int(bw_mul(bw_div(bw_min2(bw_int_to_fixed(600), data->max_phyclk), data->pixel_rate[k]), bw_int_to_fixed(24)));
2012 if (bw_meq(data->max_phyclk, bw_int_to_fixed(270))) {
2013 data->output_bppdp4_lane_hbr[k] = bw_fixed_to_int(bw_mul(bw_div(bw_mul(bw_int_to_fixed(270), bw_int_to_fixed(4)), data->pixel_rate[k]), bw_int_to_fixed(8)));
2015 if (bw_meq(data->max_phyclk, bw_int_to_fixed(540))) {
2016 data->output_bppdp4_lane_hbr2[k] = bw_fixed_to_int(bw_mul(bw_div(bw_mul(bw_int_to_fixed(540), bw_int_to_fixed(4)), data->pixel_rate[k]), bw_int_to_fixed(8)));
2018 if (bw_meq(data->max_phyclk, bw_int_to_fixed(810))) {
2019 data->output_bppdp4_lane_hbr3[k] = bw_fixed_to_int(bw_mul(bw_div(bw_mul(bw_int_to_fixed(810), bw_int_to_fixed(4)), data->pixel_rate[k]), bw_int_to_fixed(8)));
2025 /*******************************************************************************
2027 ******************************************************************************/
2028 void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
2029 struct bw_calcs_vbios *bw_vbios,
2030 struct hw_asic_id asic_id)
2032 struct bw_calcs_dceip dceip = { 0 };
2033 struct bw_calcs_vbios vbios = { 0 };
2035 enum bw_calcs_version version = bw_calcs_version_from_asic_id(asic_id);
2037 dceip.version = version;
2040 case BW_CALCS_VERSION_CARRIZO:
2041 vbios.memory_type = bw_def_gddr5;
2042 vbios.dram_channel_width_in_bits = 64;
2043 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2044 vbios.number_of_dram_banks = 8;
2045 vbios.high_yclk = bw_int_to_fixed(1600);
2046 vbios.mid_yclk = bw_int_to_fixed(1600);
2047 vbios.low_yclk = bw_frc_to_fixed(66666, 100);
2048 vbios.low_sclk = bw_int_to_fixed(200);
2049 vbios.mid1_sclk = bw_int_to_fixed(300);
2050 vbios.mid2_sclk = bw_int_to_fixed(300);
2051 vbios.mid3_sclk = bw_int_to_fixed(300);
2052 vbios.mid4_sclk = bw_int_to_fixed(300);
2053 vbios.mid5_sclk = bw_int_to_fixed(300);
2054 vbios.mid6_sclk = bw_int_to_fixed(300);
2055 vbios.high_sclk = bw_frc_to_fixed(62609, 100);
2056 vbios.low_voltage_max_dispclk = bw_int_to_fixed(352);
2057 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467);
2058 vbios.high_voltage_max_dispclk = bw_int_to_fixed(643);
2059 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2060 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2061 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2062 vbios.data_return_bus_width = bw_int_to_fixed(32);
2063 vbios.trc = bw_int_to_fixed(50);
2064 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2065 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(153, 10);
2066 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2067 vbios.nbp_state_change_latency = bw_frc_to_fixed(19649, 1000);
2068 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2069 vbios.scatter_gather_enable = true;
2070 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2071 vbios.cursor_width = 32;
2072 vbios.average_compression_rate = 4;
2073 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2074 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2075 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2077 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2078 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2079 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2080 dceip.large_cursor = false;
2081 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2082 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2083 dceip.cursor_max_outstanding_group_num = 1;
2084 dceip.lines_interleaved_into_lb = 2;
2085 dceip.chunk_width = 256;
2086 dceip.number_of_graphics_pipes = 3;
2087 dceip.number_of_underlay_pipes = 1;
2088 dceip.low_power_tiling_mode = 0;
2089 dceip.display_write_back_supported = false;
2090 dceip.argb_compression_support = false;
2091 dceip.underlay_vscaler_efficiency6_bit_per_component =
2092 bw_frc_to_fixed(35556, 10000);
2093 dceip.underlay_vscaler_efficiency8_bit_per_component =
2094 bw_frc_to_fixed(34286, 10000);
2095 dceip.underlay_vscaler_efficiency10_bit_per_component =
2096 bw_frc_to_fixed(32, 10);
2097 dceip.underlay_vscaler_efficiency12_bit_per_component =
2099 dceip.graphics_vscaler_efficiency6_bit_per_component =
2100 bw_frc_to_fixed(35, 10);
2101 dceip.graphics_vscaler_efficiency8_bit_per_component =
2102 bw_frc_to_fixed(34286, 10000);
2103 dceip.graphics_vscaler_efficiency10_bit_per_component =
2104 bw_frc_to_fixed(32, 10);
2105 dceip.graphics_vscaler_efficiency12_bit_per_component =
2107 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2108 dceip.max_dmif_buffer_allocated = 2;
2109 dceip.graphics_dmif_size = 12288;
2110 dceip.underlay_luma_dmif_size = 19456;
2111 dceip.underlay_chroma_dmif_size = 23552;
2112 dceip.pre_downscaler_enabled = true;
2113 dceip.underlay_downscale_prefetch_enabled = true;
2114 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2115 dceip.lb_size_per_component444 = bw_int_to_fixed(82176);
2116 dceip.graphics_lb_nodownscaling_multi_line_prefetching = false;
2117 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2119 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2121 dceip.underlay420_chroma_lb_size_per_component =
2122 bw_int_to_fixed(164352);
2123 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2125 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2126 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2127 dceip.underlay_maximum_width_efficient_for_tiling =
2128 bw_int_to_fixed(1920);
2129 dceip.underlay_maximum_height_efficient_for_tiling =
2130 bw_int_to_fixed(1080);
2131 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2132 bw_frc_to_fixed(3, 10);
2133 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2134 bw_int_to_fixed(25);
2135 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2137 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2138 bw_int_to_fixed(128);
2139 dceip.limit_excessive_outstanding_dmif_requests = true;
2140 dceip.linear_mode_line_request_alternation_slice =
2141 bw_int_to_fixed(64);
2142 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2144 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2145 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2146 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2147 dceip.dispclk_per_request = bw_int_to_fixed(2);
2148 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2149 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2150 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2151 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/
2153 case BW_CALCS_VERSION_POLARIS10:
2154 /* TODO: Treat VEGAM the same as P10 for now
2155 * Need to tune the para for VEGAM if needed */
2156 case BW_CALCS_VERSION_VEGAM:
2157 vbios.memory_type = bw_def_gddr5;
2158 vbios.dram_channel_width_in_bits = 32;
2159 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2160 vbios.number_of_dram_banks = 8;
2161 vbios.high_yclk = bw_int_to_fixed(6000);
2162 vbios.mid_yclk = bw_int_to_fixed(3200);
2163 vbios.low_yclk = bw_int_to_fixed(1000);
2164 vbios.low_sclk = bw_int_to_fixed(300);
2165 vbios.mid1_sclk = bw_int_to_fixed(400);
2166 vbios.mid2_sclk = bw_int_to_fixed(500);
2167 vbios.mid3_sclk = bw_int_to_fixed(600);
2168 vbios.mid4_sclk = bw_int_to_fixed(700);
2169 vbios.mid5_sclk = bw_int_to_fixed(800);
2170 vbios.mid6_sclk = bw_int_to_fixed(974);
2171 vbios.high_sclk = bw_int_to_fixed(1154);
2172 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2173 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2174 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2175 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2176 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2177 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2178 vbios.data_return_bus_width = bw_int_to_fixed(32);
2179 vbios.trc = bw_int_to_fixed(48);
2180 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2181 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2182 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2183 vbios.nbp_state_change_latency = bw_int_to_fixed(45);
2184 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2185 vbios.scatter_gather_enable = true;
2186 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2187 vbios.cursor_width = 32;
2188 vbios.average_compression_rate = 4;
2189 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2190 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2191 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2193 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2194 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2195 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2196 dceip.large_cursor = false;
2197 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2198 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2199 dceip.cursor_max_outstanding_group_num = 1;
2200 dceip.lines_interleaved_into_lb = 2;
2201 dceip.chunk_width = 256;
2202 dceip.number_of_graphics_pipes = 6;
2203 dceip.number_of_underlay_pipes = 0;
2204 dceip.low_power_tiling_mode = 0;
2205 dceip.display_write_back_supported = false;
2206 dceip.argb_compression_support = true;
2207 dceip.underlay_vscaler_efficiency6_bit_per_component =
2208 bw_frc_to_fixed(35556, 10000);
2209 dceip.underlay_vscaler_efficiency8_bit_per_component =
2210 bw_frc_to_fixed(34286, 10000);
2211 dceip.underlay_vscaler_efficiency10_bit_per_component =
2212 bw_frc_to_fixed(32, 10);
2213 dceip.underlay_vscaler_efficiency12_bit_per_component =
2215 dceip.graphics_vscaler_efficiency6_bit_per_component =
2216 bw_frc_to_fixed(35, 10);
2217 dceip.graphics_vscaler_efficiency8_bit_per_component =
2218 bw_frc_to_fixed(34286, 10000);
2219 dceip.graphics_vscaler_efficiency10_bit_per_component =
2220 bw_frc_to_fixed(32, 10);
2221 dceip.graphics_vscaler_efficiency12_bit_per_component =
2223 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2224 dceip.max_dmif_buffer_allocated = 4;
2225 dceip.graphics_dmif_size = 12288;
2226 dceip.underlay_luma_dmif_size = 19456;
2227 dceip.underlay_chroma_dmif_size = 23552;
2228 dceip.pre_downscaler_enabled = true;
2229 dceip.underlay_downscale_prefetch_enabled = true;
2230 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2231 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2232 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2233 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2235 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2237 dceip.underlay420_chroma_lb_size_per_component =
2238 bw_int_to_fixed(164352);
2239 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2241 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2242 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2243 dceip.underlay_maximum_width_efficient_for_tiling =
2244 bw_int_to_fixed(1920);
2245 dceip.underlay_maximum_height_efficient_for_tiling =
2246 bw_int_to_fixed(1080);
2247 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2248 bw_frc_to_fixed(3, 10);
2249 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2250 bw_int_to_fixed(25);
2251 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2253 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2254 bw_int_to_fixed(128);
2255 dceip.limit_excessive_outstanding_dmif_requests = true;
2256 dceip.linear_mode_line_request_alternation_slice =
2257 bw_int_to_fixed(64);
2258 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2260 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2261 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2262 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2263 dceip.dispclk_per_request = bw_int_to_fixed(2);
2264 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2265 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2266 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2267 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2269 case BW_CALCS_VERSION_POLARIS11:
2270 vbios.memory_type = bw_def_gddr5;
2271 vbios.dram_channel_width_in_bits = 32;
2272 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2273 vbios.number_of_dram_banks = 8;
2274 vbios.high_yclk = bw_int_to_fixed(6000);
2275 vbios.mid_yclk = bw_int_to_fixed(3200);
2276 vbios.low_yclk = bw_int_to_fixed(1000);
2277 vbios.low_sclk = bw_int_to_fixed(300);
2278 vbios.mid1_sclk = bw_int_to_fixed(400);
2279 vbios.mid2_sclk = bw_int_to_fixed(500);
2280 vbios.mid3_sclk = bw_int_to_fixed(600);
2281 vbios.mid4_sclk = bw_int_to_fixed(700);
2282 vbios.mid5_sclk = bw_int_to_fixed(800);
2283 vbios.mid6_sclk = bw_int_to_fixed(974);
2284 vbios.high_sclk = bw_int_to_fixed(1154);
2285 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2286 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2287 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2288 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2289 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2290 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2291 vbios.data_return_bus_width = bw_int_to_fixed(32);
2292 vbios.trc = bw_int_to_fixed(48);
2293 if (vbios.number_of_dram_channels == 2) // 64-bit
2294 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2296 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2297 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2298 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2299 vbios.nbp_state_change_latency = bw_int_to_fixed(45);
2300 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2301 vbios.scatter_gather_enable = true;
2302 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2303 vbios.cursor_width = 32;
2304 vbios.average_compression_rate = 4;
2305 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2306 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2307 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2309 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2310 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2311 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2312 dceip.large_cursor = false;
2313 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2314 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2315 dceip.cursor_max_outstanding_group_num = 1;
2316 dceip.lines_interleaved_into_lb = 2;
2317 dceip.chunk_width = 256;
2318 dceip.number_of_graphics_pipes = 5;
2319 dceip.number_of_underlay_pipes = 0;
2320 dceip.low_power_tiling_mode = 0;
2321 dceip.display_write_back_supported = false;
2322 dceip.argb_compression_support = true;
2323 dceip.underlay_vscaler_efficiency6_bit_per_component =
2324 bw_frc_to_fixed(35556, 10000);
2325 dceip.underlay_vscaler_efficiency8_bit_per_component =
2326 bw_frc_to_fixed(34286, 10000);
2327 dceip.underlay_vscaler_efficiency10_bit_per_component =
2328 bw_frc_to_fixed(32, 10);
2329 dceip.underlay_vscaler_efficiency12_bit_per_component =
2331 dceip.graphics_vscaler_efficiency6_bit_per_component =
2332 bw_frc_to_fixed(35, 10);
2333 dceip.graphics_vscaler_efficiency8_bit_per_component =
2334 bw_frc_to_fixed(34286, 10000);
2335 dceip.graphics_vscaler_efficiency10_bit_per_component =
2336 bw_frc_to_fixed(32, 10);
2337 dceip.graphics_vscaler_efficiency12_bit_per_component =
2339 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2340 dceip.max_dmif_buffer_allocated = 4;
2341 dceip.graphics_dmif_size = 12288;
2342 dceip.underlay_luma_dmif_size = 19456;
2343 dceip.underlay_chroma_dmif_size = 23552;
2344 dceip.pre_downscaler_enabled = true;
2345 dceip.underlay_downscale_prefetch_enabled = true;
2346 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2347 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2348 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2349 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2351 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2353 dceip.underlay420_chroma_lb_size_per_component =
2354 bw_int_to_fixed(164352);
2355 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2357 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2358 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2359 dceip.underlay_maximum_width_efficient_for_tiling =
2360 bw_int_to_fixed(1920);
2361 dceip.underlay_maximum_height_efficient_for_tiling =
2362 bw_int_to_fixed(1080);
2363 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2364 bw_frc_to_fixed(3, 10);
2365 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2366 bw_int_to_fixed(25);
2367 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2369 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2370 bw_int_to_fixed(128);
2371 dceip.limit_excessive_outstanding_dmif_requests = true;
2372 dceip.linear_mode_line_request_alternation_slice =
2373 bw_int_to_fixed(64);
2374 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2376 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2377 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2378 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2379 dceip.dispclk_per_request = bw_int_to_fixed(2);
2380 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2381 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2382 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2383 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2385 case BW_CALCS_VERSION_POLARIS12:
2386 vbios.memory_type = bw_def_gddr5;
2387 vbios.dram_channel_width_in_bits = 32;
2388 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2389 vbios.number_of_dram_banks = 8;
2390 vbios.high_yclk = bw_int_to_fixed(6000);
2391 vbios.mid_yclk = bw_int_to_fixed(3200);
2392 vbios.low_yclk = bw_int_to_fixed(1000);
2393 vbios.low_sclk = bw_int_to_fixed(678);
2394 vbios.mid1_sclk = bw_int_to_fixed(864);
2395 vbios.mid2_sclk = bw_int_to_fixed(900);
2396 vbios.mid3_sclk = bw_int_to_fixed(920);
2397 vbios.mid4_sclk = bw_int_to_fixed(940);
2398 vbios.mid5_sclk = bw_int_to_fixed(960);
2399 vbios.mid6_sclk = bw_int_to_fixed(980);
2400 vbios.high_sclk = bw_int_to_fixed(1049);
2401 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2402 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2403 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2404 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2405 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2406 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2407 vbios.data_return_bus_width = bw_int_to_fixed(32);
2408 vbios.trc = bw_int_to_fixed(48);
2409 if (vbios.number_of_dram_channels == 2) // 64-bit
2410 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2412 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2413 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2414 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2415 vbios.nbp_state_change_latency = bw_int_to_fixed(250);
2416 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2417 vbios.scatter_gather_enable = false;
2418 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2419 vbios.cursor_width = 32;
2420 vbios.average_compression_rate = 4;
2421 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2422 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2423 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2425 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2426 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2427 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2428 dceip.large_cursor = false;
2429 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2430 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2431 dceip.cursor_max_outstanding_group_num = 1;
2432 dceip.lines_interleaved_into_lb = 2;
2433 dceip.chunk_width = 256;
2434 dceip.number_of_graphics_pipes = 5;
2435 dceip.number_of_underlay_pipes = 0;
2436 dceip.low_power_tiling_mode = 0;
2437 dceip.display_write_back_supported = true;
2438 dceip.argb_compression_support = true;
2439 dceip.underlay_vscaler_efficiency6_bit_per_component =
2440 bw_frc_to_fixed(35556, 10000);
2441 dceip.underlay_vscaler_efficiency8_bit_per_component =
2442 bw_frc_to_fixed(34286, 10000);
2443 dceip.underlay_vscaler_efficiency10_bit_per_component =
2444 bw_frc_to_fixed(32, 10);
2445 dceip.underlay_vscaler_efficiency12_bit_per_component =
2447 dceip.graphics_vscaler_efficiency6_bit_per_component =
2448 bw_frc_to_fixed(35, 10);
2449 dceip.graphics_vscaler_efficiency8_bit_per_component =
2450 bw_frc_to_fixed(34286, 10000);
2451 dceip.graphics_vscaler_efficiency10_bit_per_component =
2452 bw_frc_to_fixed(32, 10);
2453 dceip.graphics_vscaler_efficiency12_bit_per_component =
2455 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2456 dceip.max_dmif_buffer_allocated = 4;
2457 dceip.graphics_dmif_size = 12288;
2458 dceip.underlay_luma_dmif_size = 19456;
2459 dceip.underlay_chroma_dmif_size = 23552;
2460 dceip.pre_downscaler_enabled = true;
2461 dceip.underlay_downscale_prefetch_enabled = true;
2462 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2463 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2464 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2465 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2467 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2469 dceip.underlay420_chroma_lb_size_per_component =
2470 bw_int_to_fixed(164352);
2471 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2473 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2474 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2475 dceip.underlay_maximum_width_efficient_for_tiling =
2476 bw_int_to_fixed(1920);
2477 dceip.underlay_maximum_height_efficient_for_tiling =
2478 bw_int_to_fixed(1080);
2479 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2480 bw_frc_to_fixed(3, 10);
2481 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2482 bw_int_to_fixed(25);
2483 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2485 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2486 bw_int_to_fixed(128);
2487 dceip.limit_excessive_outstanding_dmif_requests = true;
2488 dceip.linear_mode_line_request_alternation_slice =
2489 bw_int_to_fixed(64);
2490 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2492 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2493 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2494 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2495 dceip.dispclk_per_request = bw_int_to_fixed(2);
2496 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2497 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2498 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2499 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2501 case BW_CALCS_VERSION_STONEY:
2502 vbios.memory_type = bw_def_gddr5;
2503 vbios.dram_channel_width_in_bits = 64;
2504 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2505 vbios.number_of_dram_banks = 8;
2506 vbios.high_yclk = bw_int_to_fixed(1866);
2507 vbios.mid_yclk = bw_int_to_fixed(1866);
2508 vbios.low_yclk = bw_int_to_fixed(1333);
2509 vbios.low_sclk = bw_int_to_fixed(200);
2510 vbios.mid1_sclk = bw_int_to_fixed(600);
2511 vbios.mid2_sclk = bw_int_to_fixed(600);
2512 vbios.mid3_sclk = bw_int_to_fixed(600);
2513 vbios.mid4_sclk = bw_int_to_fixed(600);
2514 vbios.mid5_sclk = bw_int_to_fixed(600);
2515 vbios.mid6_sclk = bw_int_to_fixed(600);
2516 vbios.high_sclk = bw_int_to_fixed(800);
2517 vbios.low_voltage_max_dispclk = bw_int_to_fixed(352);
2518 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467);
2519 vbios.high_voltage_max_dispclk = bw_int_to_fixed(643);
2520 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2521 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2522 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2523 vbios.data_return_bus_width = bw_int_to_fixed(32);
2524 vbios.trc = bw_int_to_fixed(50);
2525 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2526 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(158, 10);
2527 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2528 vbios.nbp_state_change_latency = bw_frc_to_fixed(2008, 100);
2529 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2530 vbios.scatter_gather_enable = true;
2531 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2532 vbios.cursor_width = 32;
2533 vbios.average_compression_rate = 4;
2534 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2535 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2536 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2538 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2539 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2540 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2541 dceip.large_cursor = false;
2542 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2543 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2544 dceip.cursor_max_outstanding_group_num = 1;
2545 dceip.lines_interleaved_into_lb = 2;
2546 dceip.chunk_width = 256;
2547 dceip.number_of_graphics_pipes = 2;
2548 dceip.number_of_underlay_pipes = 1;
2549 dceip.low_power_tiling_mode = 0;
2550 dceip.display_write_back_supported = false;
2551 dceip.argb_compression_support = true;
2552 dceip.underlay_vscaler_efficiency6_bit_per_component =
2553 bw_frc_to_fixed(35556, 10000);
2554 dceip.underlay_vscaler_efficiency8_bit_per_component =
2555 bw_frc_to_fixed(34286, 10000);
2556 dceip.underlay_vscaler_efficiency10_bit_per_component =
2557 bw_frc_to_fixed(32, 10);
2558 dceip.underlay_vscaler_efficiency12_bit_per_component =
2560 dceip.graphics_vscaler_efficiency6_bit_per_component =
2561 bw_frc_to_fixed(35, 10);
2562 dceip.graphics_vscaler_efficiency8_bit_per_component =
2563 bw_frc_to_fixed(34286, 10000);
2564 dceip.graphics_vscaler_efficiency10_bit_per_component =
2565 bw_frc_to_fixed(32, 10);
2566 dceip.graphics_vscaler_efficiency12_bit_per_component =
2568 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2569 dceip.max_dmif_buffer_allocated = 2;
2570 dceip.graphics_dmif_size = 12288;
2571 dceip.underlay_luma_dmif_size = 19456;
2572 dceip.underlay_chroma_dmif_size = 23552;
2573 dceip.pre_downscaler_enabled = true;
2574 dceip.underlay_downscale_prefetch_enabled = true;
2575 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2576 dceip.lb_size_per_component444 = bw_int_to_fixed(82176);
2577 dceip.graphics_lb_nodownscaling_multi_line_prefetching = false;
2578 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2580 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2582 dceip.underlay420_chroma_lb_size_per_component =
2583 bw_int_to_fixed(164352);
2584 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2586 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2587 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2588 dceip.underlay_maximum_width_efficient_for_tiling =
2589 bw_int_to_fixed(1920);
2590 dceip.underlay_maximum_height_efficient_for_tiling =
2591 bw_int_to_fixed(1080);
2592 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2593 bw_frc_to_fixed(3, 10);
2594 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2595 bw_int_to_fixed(25);
2596 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2598 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2599 bw_int_to_fixed(128);
2600 dceip.limit_excessive_outstanding_dmif_requests = true;
2601 dceip.linear_mode_line_request_alternation_slice =
2602 bw_int_to_fixed(64);
2603 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2605 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2606 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2607 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2608 dceip.dispclk_per_request = bw_int_to_fixed(2);
2609 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2610 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2611 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2612 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2614 case BW_CALCS_VERSION_VEGA10:
2615 vbios.memory_type = bw_def_hbm;
2616 vbios.dram_channel_width_in_bits = 128;
2617 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2618 vbios.number_of_dram_banks = 16;
2619 vbios.high_yclk = bw_int_to_fixed(2400);
2620 vbios.mid_yclk = bw_int_to_fixed(1700);
2621 vbios.low_yclk = bw_int_to_fixed(1000);
2622 vbios.low_sclk = bw_int_to_fixed(300);
2623 vbios.mid1_sclk = bw_int_to_fixed(350);
2624 vbios.mid2_sclk = bw_int_to_fixed(400);
2625 vbios.mid3_sclk = bw_int_to_fixed(500);
2626 vbios.mid4_sclk = bw_int_to_fixed(600);
2627 vbios.mid5_sclk = bw_int_to_fixed(700);
2628 vbios.mid6_sclk = bw_int_to_fixed(760);
2629 vbios.high_sclk = bw_int_to_fixed(776);
2630 vbios.low_voltage_max_dispclk = bw_int_to_fixed(460);
2631 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(670);
2632 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1133);
2633 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2634 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2635 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2636 vbios.data_return_bus_width = bw_int_to_fixed(32);
2637 vbios.trc = bw_int_to_fixed(48);
2638 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2639 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(75, 10);
2640 vbios.stutter_self_refresh_entry_latency = bw_frc_to_fixed(19, 10);
2641 vbios.nbp_state_change_latency = bw_int_to_fixed(39);
2642 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2643 vbios.scatter_gather_enable = false;
2644 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2645 vbios.cursor_width = 32;
2646 vbios.average_compression_rate = 4;
2647 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 8;
2648 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2649 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2651 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2652 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2653 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2654 dceip.large_cursor = false;
2655 dceip.dmif_request_buffer_size = bw_int_to_fixed(2304);
2656 dceip.dmif_pipe_en_fbc_chunk_tracker = true;
2657 dceip.cursor_max_outstanding_group_num = 1;
2658 dceip.lines_interleaved_into_lb = 2;
2659 dceip.chunk_width = 256;
2660 dceip.number_of_graphics_pipes = 6;
2661 dceip.number_of_underlay_pipes = 0;
2662 dceip.low_power_tiling_mode = 0;
2663 dceip.display_write_back_supported = true;
2664 dceip.argb_compression_support = true;
2665 dceip.underlay_vscaler_efficiency6_bit_per_component =
2666 bw_frc_to_fixed(35556, 10000);
2667 dceip.underlay_vscaler_efficiency8_bit_per_component =
2668 bw_frc_to_fixed(34286, 10000);
2669 dceip.underlay_vscaler_efficiency10_bit_per_component =
2670 bw_frc_to_fixed(32, 10);
2671 dceip.underlay_vscaler_efficiency12_bit_per_component =
2673 dceip.graphics_vscaler_efficiency6_bit_per_component =
2674 bw_frc_to_fixed(35, 10);
2675 dceip.graphics_vscaler_efficiency8_bit_per_component =
2676 bw_frc_to_fixed(34286, 10000);
2677 dceip.graphics_vscaler_efficiency10_bit_per_component =
2678 bw_frc_to_fixed(32, 10);
2679 dceip.graphics_vscaler_efficiency12_bit_per_component =
2681 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2682 dceip.max_dmif_buffer_allocated = 4;
2683 dceip.graphics_dmif_size = 24576;
2684 dceip.underlay_luma_dmif_size = 19456;
2685 dceip.underlay_chroma_dmif_size = 23552;
2686 dceip.pre_downscaler_enabled = true;
2687 dceip.underlay_downscale_prefetch_enabled = false;
2688 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2689 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2690 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2691 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2693 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2695 dceip.underlay420_chroma_lb_size_per_component =
2696 bw_int_to_fixed(164352);
2697 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2699 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2700 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2701 dceip.underlay_maximum_width_efficient_for_tiling =
2702 bw_int_to_fixed(1920);
2703 dceip.underlay_maximum_height_efficient_for_tiling =
2704 bw_int_to_fixed(1080);
2705 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2706 bw_frc_to_fixed(3, 10);
2707 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2708 bw_int_to_fixed(25);
2709 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2711 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2712 bw_int_to_fixed(128);
2713 dceip.limit_excessive_outstanding_dmif_requests = true;
2714 dceip.linear_mode_line_request_alternation_slice =
2715 bw_int_to_fixed(64);
2716 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2718 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2719 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2720 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2721 dceip.dispclk_per_request = bw_int_to_fixed(2);
2722 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2723 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2724 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2725 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2736 * Compare calculated (required) clocks against the clocks available at
2737 * maximum voltage (max Performance Level).
2739 static bool is_display_configuration_supported(
2740 const struct bw_calcs_vbios *vbios,
2741 const struct dce_bw_output *calcs_output)
2743 uint32_t int_max_clk;
2745 int_max_clk = bw_fixed_to_int(vbios->high_voltage_max_dispclk);
2746 int_max_clk *= 1000; /* MHz to kHz */
2747 if (calcs_output->dispclk_khz > int_max_clk)
2750 int_max_clk = bw_fixed_to_int(vbios->high_sclk);
2751 int_max_clk *= 1000; /* MHz to kHz */
2752 if (calcs_output->sclk_khz > int_max_clk)
2758 static void populate_initial_data(
2759 const struct pipe_ctx pipe[], int pipe_count, struct bw_calcs_data *data)
2762 int num_displays = 0;
2764 data->underlay_surface_type = bw_def_420;
2765 data->panning_and_bezel_adjustment = bw_def_none;
2766 data->graphics_lb_bpc = 10;
2767 data->underlay_lb_bpc = 8;
2768 data->underlay_tiling_mode = bw_def_tiled;
2769 data->graphics_tiling_mode = bw_def_tiled;
2770 data->underlay_micro_tile_mode = bw_def_display_micro_tiling;
2771 data->graphics_micro_tile_mode = bw_def_display_micro_tiling;
2772 data->increase_voltage_to_support_mclk_switch = true;
2774 /* Pipes with underlay first */
2775 for (i = 0; i < pipe_count; i++) {
2776 if (!pipe[i].stream || !pipe[i].bottom_pipe)
2779 ASSERT(pipe[i].plane_state);
2781 if (num_displays == 0) {
2782 if (!pipe[i].plane_state->visible)
2783 data->d0_underlay_mode = bw_def_underlay_only;
2785 data->d0_underlay_mode = bw_def_blend;
2787 if (!pipe[i].plane_state->visible)
2788 data->d1_underlay_mode = bw_def_underlay_only;
2790 data->d1_underlay_mode = bw_def_blend;
2793 data->fbc_en[num_displays + 4] = false;
2794 data->lpt_en[num_displays + 4] = false;
2795 data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
2796 data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
2797 data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->timing.pix_clk_100hz, 10000);
2798 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
2799 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2800 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.height);
2801 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.h_taps);
2802 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.v_taps);
2803 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.horz.value);
2804 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.vert.value);
2805 switch (pipe[i].plane_state->rotation) {
2806 case ROTATION_ANGLE_0:
2807 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2809 case ROTATION_ANGLE_90:
2810 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(90);
2812 case ROTATION_ANGLE_180:
2813 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(180);
2815 case ROTATION_ANGLE_270:
2816 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(270);
2821 switch (pipe[i].plane_state->format) {
2822 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
2823 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
2824 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2825 data->bytes_per_pixel[num_displays + 4] = 2;
2827 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2828 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2829 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2830 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2831 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
2832 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
2833 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
2834 data->bytes_per_pixel[num_displays + 4] = 4;
2836 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2837 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2838 data->bytes_per_pixel[num_displays + 4] = 8;
2841 data->bytes_per_pixel[num_displays + 4] = 4;
2844 data->interlace_mode[num_displays + 4] = false;
2845 data->stereo_mode[num_displays + 4] = bw_def_mono;
2848 for (j = 0; j < 2; j++) {
2849 data->fbc_en[num_displays * 2 + j] = false;
2850 data->lpt_en[num_displays * 2 + j] = false;
2852 data->src_height[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.height);
2853 data->src_width[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.width);
2854 data->pitch_in_pixels[num_displays * 2 + j] = bw_int_to_fixed(
2855 pipe[i].bottom_pipe->plane_state->plane_size.grph.surface_pitch);
2856 data->h_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.h_taps);
2857 data->v_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.v_taps);
2858 data->h_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2859 pipe[i].bottom_pipe->plane_res.scl_data.ratios.horz.value);
2860 data->v_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2861 pipe[i].bottom_pipe->plane_res.scl_data.ratios.vert.value);
2862 switch (pipe[i].bottom_pipe->plane_state->rotation) {
2863 case ROTATION_ANGLE_0:
2864 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(0);
2866 case ROTATION_ANGLE_90:
2867 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(90);
2869 case ROTATION_ANGLE_180:
2870 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(180);
2872 case ROTATION_ANGLE_270:
2873 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(270);
2878 data->stereo_mode[num_displays * 2 + j] = bw_def_mono;
2884 /* Pipes without underlay after */
2885 for (i = 0; i < pipe_count; i++) {
2886 unsigned int pixel_clock_100hz;
2887 if (!pipe[i].stream || pipe[i].bottom_pipe)
2891 data->fbc_en[num_displays + 4] = false;
2892 data->lpt_en[num_displays + 4] = false;
2893 data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
2894 data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
2895 pixel_clock_100hz = pipe[i].stream->timing.pix_clk_100hz;
2896 if (pipe[i].stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
2897 pixel_clock_100hz *= 2;
2898 data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pixel_clock_100hz, 10000);
2899 if (pipe[i].plane_state) {
2900 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
2901 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2902 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.height);
2903 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.h_taps);
2904 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.v_taps);
2905 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.horz.value);
2906 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.vert.value);
2907 switch (pipe[i].plane_state->rotation) {
2908 case ROTATION_ANGLE_0:
2909 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2911 case ROTATION_ANGLE_90:
2912 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(90);
2914 case ROTATION_ANGLE_180:
2915 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(180);
2917 case ROTATION_ANGLE_270:
2918 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(270);
2923 switch (pipe[i].plane_state->format) {
2924 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
2925 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
2926 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
2927 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2928 data->bytes_per_pixel[num_displays + 4] = 2;
2930 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2931 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2932 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2933 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2934 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
2935 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
2936 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
2937 data->bytes_per_pixel[num_displays + 4] = 4;
2939 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2940 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2941 data->bytes_per_pixel[num_displays + 4] = 8;
2944 data->bytes_per_pixel[num_displays + 4] = 4;
2947 } else if (pipe[i].stream->dst.width != 0 &&
2948 pipe[i].stream->dst.height != 0 &&
2949 pipe[i].stream->src.width != 0 &&
2950 pipe[i].stream->src.height != 0) {
2951 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->src.width);
2952 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2953 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->src.height);
2954 data->h_taps[num_displays + 4] = pipe[i].stream->src.width == pipe[i].stream->dst.width ? bw_int_to_fixed(1) : bw_int_to_fixed(2);
2955 data->v_taps[num_displays + 4] = pipe[i].stream->src.height == pipe[i].stream->dst.height ? bw_int_to_fixed(1) : bw_int_to_fixed(2);
2956 data->h_scale_ratio[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->src.width, pipe[i].stream->dst.width);
2957 data->v_scale_ratio[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->src.height, pipe[i].stream->dst.height);
2958 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2959 data->bytes_per_pixel[num_displays + 4] = 4;
2961 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_addressable);
2962 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2963 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_addressable);
2964 data->h_taps[num_displays + 4] = bw_int_to_fixed(1);
2965 data->v_taps[num_displays + 4] = bw_int_to_fixed(1);
2966 data->h_scale_ratio[num_displays + 4] = bw_int_to_fixed(1);
2967 data->v_scale_ratio[num_displays + 4] = bw_int_to_fixed(1);
2968 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2969 data->bytes_per_pixel[num_displays + 4] = 4;
2972 data->interlace_mode[num_displays + 4] = false;
2973 data->stereo_mode[num_displays + 4] = bw_def_mono;
2977 data->number_of_displays = num_displays;
2982 * true - Display(s) configuration supported.
2983 * In this case 'calcs_output' contains data for HW programming
2984 * false - Display(s) configuration not supported (not enough bandwidth).
2987 bool bw_calcs(struct dc_context *ctx,
2988 const struct bw_calcs_dceip *dceip,
2989 const struct bw_calcs_vbios *vbios,
2990 const struct pipe_ctx pipe[],
2992 struct dce_bw_output *calcs_output)
2994 struct bw_calcs_data *data = kzalloc(sizeof(struct bw_calcs_data),
2999 populate_initial_data(pipe, pipe_count, data);
3001 /*TODO: this should be taken out calcs output and assigned during timing sync for pplib use*/
3002 calcs_output->all_displays_in_sync = false;
3004 if (data->number_of_displays != 0) {
3005 uint8_t yclk_lvl, sclk_lvl;
3006 struct bw_fixed high_sclk = vbios->high_sclk;
3007 struct bw_fixed mid1_sclk = vbios->mid1_sclk;
3008 struct bw_fixed mid2_sclk = vbios->mid2_sclk;
3009 struct bw_fixed mid3_sclk = vbios->mid3_sclk;
3010 struct bw_fixed mid4_sclk = vbios->mid4_sclk;
3011 struct bw_fixed mid5_sclk = vbios->mid5_sclk;
3012 struct bw_fixed mid6_sclk = vbios->mid6_sclk;
3013 struct bw_fixed low_sclk = vbios->low_sclk;
3014 struct bw_fixed high_yclk = vbios->high_yclk;
3015 struct bw_fixed mid_yclk = vbios->mid_yclk;
3016 struct bw_fixed low_yclk = vbios->low_yclk;
3018 if (ctx->dc->debug.bandwidth_calcs_trace) {
3019 print_bw_calcs_dceip(ctx, dceip);
3020 print_bw_calcs_vbios(ctx, vbios);
3021 print_bw_calcs_data(ctx, data);
3023 calculate_bandwidth(dceip, vbios, data);
3025 yclk_lvl = data->y_clk_level;
3026 sclk_lvl = data->sclk_level;
3028 calcs_output->nbp_state_change_enable =
3029 data->nbp_state_change_enable;
3030 calcs_output->cpuc_state_change_enable =
3031 data->cpuc_state_change_enable;
3032 calcs_output->cpup_state_change_enable =
3033 data->cpup_state_change_enable;
3034 calcs_output->stutter_mode_enable =
3035 data->stutter_mode_enable;
3036 calcs_output->dispclk_khz =
3037 bw_fixed_to_int(bw_mul(data->dispclk,
3038 bw_int_to_fixed(1000)));
3039 calcs_output->blackout_recovery_time_us =
3040 bw_fixed_to_int(data->blackout_recovery_time);
3041 calcs_output->sclk_khz =
3042 bw_fixed_to_int(bw_mul(data->required_sclk,
3043 bw_int_to_fixed(1000)));
3044 calcs_output->sclk_deep_sleep_khz =
3045 bw_fixed_to_int(bw_mul(data->sclk_deep_sleep,
3046 bw_int_to_fixed(1000)));
3048 calcs_output->yclk_khz = bw_fixed_to_int(
3049 bw_mul(low_yclk, bw_int_to_fixed(1000)));
3050 else if (yclk_lvl == 1)
3051 calcs_output->yclk_khz = bw_fixed_to_int(
3052 bw_mul(mid_yclk, bw_int_to_fixed(1000)));
3054 calcs_output->yclk_khz = bw_fixed_to_int(
3055 bw_mul(high_yclk, bw_int_to_fixed(1000)));
3057 /* units: nanosecond, 16bit storage. */
3059 calcs_output->nbp_state_change_wm_ns[0].a_mark =
3060 bw_fixed_to_int(bw_mul(data->
3061 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3062 calcs_output->nbp_state_change_wm_ns[1].a_mark =
3063 bw_fixed_to_int(bw_mul(data->
3064 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3065 calcs_output->nbp_state_change_wm_ns[2].a_mark =
3066 bw_fixed_to_int(bw_mul(data->
3067 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3069 if (ctx->dc->caps.max_slave_planes) {
3070 calcs_output->nbp_state_change_wm_ns[3].a_mark =
3071 bw_fixed_to_int(bw_mul(data->
3072 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3073 calcs_output->nbp_state_change_wm_ns[4].a_mark =
3074 bw_fixed_to_int(bw_mul(data->
3075 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3077 calcs_output->nbp_state_change_wm_ns[3].a_mark =
3078 bw_fixed_to_int(bw_mul(data->
3079 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3080 calcs_output->nbp_state_change_wm_ns[4].a_mark =
3081 bw_fixed_to_int(bw_mul(data->
3082 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3084 calcs_output->nbp_state_change_wm_ns[5].a_mark =
3085 bw_fixed_to_int(bw_mul(data->
3086 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3090 calcs_output->stutter_exit_wm_ns[0].a_mark =
3091 bw_fixed_to_int(bw_mul(data->
3092 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3093 calcs_output->stutter_exit_wm_ns[1].a_mark =
3094 bw_fixed_to_int(bw_mul(data->
3095 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3096 calcs_output->stutter_exit_wm_ns[2].a_mark =
3097 bw_fixed_to_int(bw_mul(data->
3098 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3099 if (ctx->dc->caps.max_slave_planes) {
3100 calcs_output->stutter_exit_wm_ns[3].a_mark =
3101 bw_fixed_to_int(bw_mul(data->
3102 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3103 calcs_output->stutter_exit_wm_ns[4].a_mark =
3104 bw_fixed_to_int(bw_mul(data->
3105 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3107 calcs_output->stutter_exit_wm_ns[3].a_mark =
3108 bw_fixed_to_int(bw_mul(data->
3109 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3110 calcs_output->stutter_exit_wm_ns[4].a_mark =
3111 bw_fixed_to_int(bw_mul(data->
3112 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3114 calcs_output->stutter_exit_wm_ns[5].a_mark =
3115 bw_fixed_to_int(bw_mul(data->
3116 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3118 calcs_output->stutter_entry_wm_ns[0].a_mark =
3119 bw_fixed_to_int(bw_mul(data->
3120 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3121 calcs_output->stutter_entry_wm_ns[1].a_mark =
3122 bw_fixed_to_int(bw_mul(data->
3123 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3124 calcs_output->stutter_entry_wm_ns[2].a_mark =
3125 bw_fixed_to_int(bw_mul(data->
3126 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3127 if (ctx->dc->caps.max_slave_planes) {
3128 calcs_output->stutter_entry_wm_ns[3].a_mark =
3129 bw_fixed_to_int(bw_mul(data->
3130 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3131 calcs_output->stutter_entry_wm_ns[4].a_mark =
3132 bw_fixed_to_int(bw_mul(data->
3133 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3135 calcs_output->stutter_entry_wm_ns[3].a_mark =
3136 bw_fixed_to_int(bw_mul(data->
3137 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3138 calcs_output->stutter_entry_wm_ns[4].a_mark =
3139 bw_fixed_to_int(bw_mul(data->
3140 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3142 calcs_output->stutter_entry_wm_ns[5].a_mark =
3143 bw_fixed_to_int(bw_mul(data->
3144 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3146 calcs_output->urgent_wm_ns[0].a_mark =
3147 bw_fixed_to_int(bw_mul(data->
3148 urgent_watermark[4], bw_int_to_fixed(1000)));
3149 calcs_output->urgent_wm_ns[1].a_mark =
3150 bw_fixed_to_int(bw_mul(data->
3151 urgent_watermark[5], bw_int_to_fixed(1000)));
3152 calcs_output->urgent_wm_ns[2].a_mark =
3153 bw_fixed_to_int(bw_mul(data->
3154 urgent_watermark[6], bw_int_to_fixed(1000)));
3155 if (ctx->dc->caps.max_slave_planes) {
3156 calcs_output->urgent_wm_ns[3].a_mark =
3157 bw_fixed_to_int(bw_mul(data->
3158 urgent_watermark[0], bw_int_to_fixed(1000)));
3159 calcs_output->urgent_wm_ns[4].a_mark =
3160 bw_fixed_to_int(bw_mul(data->
3161 urgent_watermark[1], bw_int_to_fixed(1000)));
3163 calcs_output->urgent_wm_ns[3].a_mark =
3164 bw_fixed_to_int(bw_mul(data->
3165 urgent_watermark[7], bw_int_to_fixed(1000)));
3166 calcs_output->urgent_wm_ns[4].a_mark =
3167 bw_fixed_to_int(bw_mul(data->
3168 urgent_watermark[8], bw_int_to_fixed(1000)));
3170 calcs_output->urgent_wm_ns[5].a_mark =
3171 bw_fixed_to_int(bw_mul(data->
3172 urgent_watermark[9], bw_int_to_fixed(1000)));
3174 if (dceip->version != BW_CALCS_VERSION_CARRIZO) {
3175 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
3176 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
3177 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
3178 calculate_bandwidth(dceip, vbios, data);
3180 calcs_output->nbp_state_change_wm_ns[0].b_mark =
3181 bw_fixed_to_int(bw_mul(data->
3182 nbp_state_change_watermark[4],bw_int_to_fixed(1000)));
3183 calcs_output->nbp_state_change_wm_ns[1].b_mark =
3184 bw_fixed_to_int(bw_mul(data->
3185 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3186 calcs_output->nbp_state_change_wm_ns[2].b_mark =
3187 bw_fixed_to_int(bw_mul(data->
3188 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3190 if (ctx->dc->caps.max_slave_planes) {
3191 calcs_output->nbp_state_change_wm_ns[3].b_mark =
3192 bw_fixed_to_int(bw_mul(data->
3193 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3194 calcs_output->nbp_state_change_wm_ns[4].b_mark =
3195 bw_fixed_to_int(bw_mul(data->
3196 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3198 calcs_output->nbp_state_change_wm_ns[3].b_mark =
3199 bw_fixed_to_int(bw_mul(data->
3200 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3201 calcs_output->nbp_state_change_wm_ns[4].b_mark =
3202 bw_fixed_to_int(bw_mul(data->
3203 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3205 calcs_output->nbp_state_change_wm_ns[5].b_mark =
3206 bw_fixed_to_int(bw_mul(data->
3207 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3211 calcs_output->stutter_exit_wm_ns[0].b_mark =
3212 bw_fixed_to_int(bw_mul(data->
3213 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3214 calcs_output->stutter_exit_wm_ns[1].b_mark =
3215 bw_fixed_to_int(bw_mul(data->
3216 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3217 calcs_output->stutter_exit_wm_ns[2].b_mark =
3218 bw_fixed_to_int(bw_mul(data->
3219 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3220 if (ctx->dc->caps.max_slave_planes) {
3221 calcs_output->stutter_exit_wm_ns[3].b_mark =
3222 bw_fixed_to_int(bw_mul(data->
3223 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3224 calcs_output->stutter_exit_wm_ns[4].b_mark =
3225 bw_fixed_to_int(bw_mul(data->
3226 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3228 calcs_output->stutter_exit_wm_ns[3].b_mark =
3229 bw_fixed_to_int(bw_mul(data->
3230 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3231 calcs_output->stutter_exit_wm_ns[4].b_mark =
3232 bw_fixed_to_int(bw_mul(data->
3233 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3235 calcs_output->stutter_exit_wm_ns[5].b_mark =
3236 bw_fixed_to_int(bw_mul(data->
3237 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3239 calcs_output->stutter_entry_wm_ns[0].b_mark =
3240 bw_fixed_to_int(bw_mul(data->
3241 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3242 calcs_output->stutter_entry_wm_ns[1].b_mark =
3243 bw_fixed_to_int(bw_mul(data->
3244 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3245 calcs_output->stutter_entry_wm_ns[2].b_mark =
3246 bw_fixed_to_int(bw_mul(data->
3247 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3248 if (ctx->dc->caps.max_slave_planes) {
3249 calcs_output->stutter_entry_wm_ns[3].b_mark =
3250 bw_fixed_to_int(bw_mul(data->
3251 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3252 calcs_output->stutter_entry_wm_ns[4].b_mark =
3253 bw_fixed_to_int(bw_mul(data->
3254 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3256 calcs_output->stutter_entry_wm_ns[3].b_mark =
3257 bw_fixed_to_int(bw_mul(data->
3258 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3259 calcs_output->stutter_entry_wm_ns[4].b_mark =
3260 bw_fixed_to_int(bw_mul(data->
3261 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3263 calcs_output->stutter_entry_wm_ns[5].b_mark =
3264 bw_fixed_to_int(bw_mul(data->
3265 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3267 calcs_output->urgent_wm_ns[0].b_mark =
3268 bw_fixed_to_int(bw_mul(data->
3269 urgent_watermark[4], bw_int_to_fixed(1000)));
3270 calcs_output->urgent_wm_ns[1].b_mark =
3271 bw_fixed_to_int(bw_mul(data->
3272 urgent_watermark[5], bw_int_to_fixed(1000)));
3273 calcs_output->urgent_wm_ns[2].b_mark =
3274 bw_fixed_to_int(bw_mul(data->
3275 urgent_watermark[6], bw_int_to_fixed(1000)));
3276 if (ctx->dc->caps.max_slave_planes) {
3277 calcs_output->urgent_wm_ns[3].b_mark =
3278 bw_fixed_to_int(bw_mul(data->
3279 urgent_watermark[0], bw_int_to_fixed(1000)));
3280 calcs_output->urgent_wm_ns[4].b_mark =
3281 bw_fixed_to_int(bw_mul(data->
3282 urgent_watermark[1], bw_int_to_fixed(1000)));
3284 calcs_output->urgent_wm_ns[3].b_mark =
3285 bw_fixed_to_int(bw_mul(data->
3286 urgent_watermark[7], bw_int_to_fixed(1000)));
3287 calcs_output->urgent_wm_ns[4].b_mark =
3288 bw_fixed_to_int(bw_mul(data->
3289 urgent_watermark[8], bw_int_to_fixed(1000)));
3291 calcs_output->urgent_wm_ns[5].b_mark =
3292 bw_fixed_to_int(bw_mul(data->
3293 urgent_watermark[9], bw_int_to_fixed(1000)));
3295 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3296 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3297 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3298 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3299 calculate_bandwidth(dceip, vbios, data);
3301 calcs_output->nbp_state_change_wm_ns[0].c_mark =
3302 bw_fixed_to_int(bw_mul(data->
3303 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3304 calcs_output->nbp_state_change_wm_ns[1].c_mark =
3305 bw_fixed_to_int(bw_mul(data->
3306 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3307 calcs_output->nbp_state_change_wm_ns[2].c_mark =
3308 bw_fixed_to_int(bw_mul(data->
3309 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3310 if (ctx->dc->caps.max_slave_planes) {
3311 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3312 bw_fixed_to_int(bw_mul(data->
3313 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3314 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3315 bw_fixed_to_int(bw_mul(data->
3316 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3318 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3319 bw_fixed_to_int(bw_mul(data->
3320 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3321 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3322 bw_fixed_to_int(bw_mul(data->
3323 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3325 calcs_output->nbp_state_change_wm_ns[5].c_mark =
3326 bw_fixed_to_int(bw_mul(data->
3327 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3330 calcs_output->stutter_exit_wm_ns[0].c_mark =
3331 bw_fixed_to_int(bw_mul(data->
3332 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3333 calcs_output->stutter_exit_wm_ns[1].c_mark =
3334 bw_fixed_to_int(bw_mul(data->
3335 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3336 calcs_output->stutter_exit_wm_ns[2].c_mark =
3337 bw_fixed_to_int(bw_mul(data->
3338 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3339 if (ctx->dc->caps.max_slave_planes) {
3340 calcs_output->stutter_exit_wm_ns[3].c_mark =
3341 bw_fixed_to_int(bw_mul(data->
3342 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3343 calcs_output->stutter_exit_wm_ns[4].c_mark =
3344 bw_fixed_to_int(bw_mul(data->
3345 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3347 calcs_output->stutter_exit_wm_ns[3].c_mark =
3348 bw_fixed_to_int(bw_mul(data->
3349 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3350 calcs_output->stutter_exit_wm_ns[4].c_mark =
3351 bw_fixed_to_int(bw_mul(data->
3352 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3354 calcs_output->stutter_exit_wm_ns[5].c_mark =
3355 bw_fixed_to_int(bw_mul(data->
3356 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3358 calcs_output->stutter_entry_wm_ns[0].c_mark =
3359 bw_fixed_to_int(bw_mul(data->
3360 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3361 calcs_output->stutter_entry_wm_ns[1].c_mark =
3362 bw_fixed_to_int(bw_mul(data->
3363 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3364 calcs_output->stutter_entry_wm_ns[2].c_mark =
3365 bw_fixed_to_int(bw_mul(data->
3366 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3367 if (ctx->dc->caps.max_slave_planes) {
3368 calcs_output->stutter_entry_wm_ns[3].c_mark =
3369 bw_fixed_to_int(bw_mul(data->
3370 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3371 calcs_output->stutter_entry_wm_ns[4].c_mark =
3372 bw_fixed_to_int(bw_mul(data->
3373 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3375 calcs_output->stutter_entry_wm_ns[3].c_mark =
3376 bw_fixed_to_int(bw_mul(data->
3377 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3378 calcs_output->stutter_entry_wm_ns[4].c_mark =
3379 bw_fixed_to_int(bw_mul(data->
3380 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3382 calcs_output->stutter_entry_wm_ns[5].c_mark =
3383 bw_fixed_to_int(bw_mul(data->
3384 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3386 calcs_output->urgent_wm_ns[0].c_mark =
3387 bw_fixed_to_int(bw_mul(data->
3388 urgent_watermark[4], bw_int_to_fixed(1000)));
3389 calcs_output->urgent_wm_ns[1].c_mark =
3390 bw_fixed_to_int(bw_mul(data->
3391 urgent_watermark[5], bw_int_to_fixed(1000)));
3392 calcs_output->urgent_wm_ns[2].c_mark =
3393 bw_fixed_to_int(bw_mul(data->
3394 urgent_watermark[6], bw_int_to_fixed(1000)));
3395 if (ctx->dc->caps.max_slave_planes) {
3396 calcs_output->urgent_wm_ns[3].c_mark =
3397 bw_fixed_to_int(bw_mul(data->
3398 urgent_watermark[0], bw_int_to_fixed(1000)));
3399 calcs_output->urgent_wm_ns[4].c_mark =
3400 bw_fixed_to_int(bw_mul(data->
3401 urgent_watermark[1], bw_int_to_fixed(1000)));
3403 calcs_output->urgent_wm_ns[3].c_mark =
3404 bw_fixed_to_int(bw_mul(data->
3405 urgent_watermark[7], bw_int_to_fixed(1000)));
3406 calcs_output->urgent_wm_ns[4].c_mark =
3407 bw_fixed_to_int(bw_mul(data->
3408 urgent_watermark[8], bw_int_to_fixed(1000)));
3410 calcs_output->urgent_wm_ns[5].c_mark =
3411 bw_fixed_to_int(bw_mul(data->
3412 urgent_watermark[9], bw_int_to_fixed(1000)));
3415 if (dceip->version == BW_CALCS_VERSION_CARRIZO) {
3416 ((struct bw_calcs_vbios *)vbios)->low_yclk = high_yclk;
3417 ((struct bw_calcs_vbios *)vbios)->mid_yclk = high_yclk;
3418 ((struct bw_calcs_vbios *)vbios)->low_sclk = high_sclk;
3419 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = high_sclk;
3420 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = high_sclk;
3421 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = high_sclk;
3422 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = high_sclk;
3423 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = high_sclk;
3424 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = high_sclk;
3426 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3427 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
3428 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
3429 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
3432 calculate_bandwidth(dceip, vbios, data);
3434 calcs_output->nbp_state_change_wm_ns[0].d_mark =
3435 bw_fixed_to_int(bw_mul(data->
3436 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3437 calcs_output->nbp_state_change_wm_ns[1].d_mark =
3438 bw_fixed_to_int(bw_mul(data->
3439 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3440 calcs_output->nbp_state_change_wm_ns[2].d_mark =
3441 bw_fixed_to_int(bw_mul(data->
3442 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3443 if (ctx->dc->caps.max_slave_planes) {
3444 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3445 bw_fixed_to_int(bw_mul(data->
3446 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3447 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3448 bw_fixed_to_int(bw_mul(data->
3449 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3451 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3452 bw_fixed_to_int(bw_mul(data->
3453 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3454 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3455 bw_fixed_to_int(bw_mul(data->
3456 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3458 calcs_output->nbp_state_change_wm_ns[5].d_mark =
3459 bw_fixed_to_int(bw_mul(data->
3460 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3462 calcs_output->stutter_exit_wm_ns[0].d_mark =
3463 bw_fixed_to_int(bw_mul(data->
3464 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3465 calcs_output->stutter_exit_wm_ns[1].d_mark =
3466 bw_fixed_to_int(bw_mul(data->
3467 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3468 calcs_output->stutter_exit_wm_ns[2].d_mark =
3469 bw_fixed_to_int(bw_mul(data->
3470 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3471 if (ctx->dc->caps.max_slave_planes) {
3472 calcs_output->stutter_exit_wm_ns[3].d_mark =
3473 bw_fixed_to_int(bw_mul(data->
3474 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3475 calcs_output->stutter_exit_wm_ns[4].d_mark =
3476 bw_fixed_to_int(bw_mul(data->
3477 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3479 calcs_output->stutter_exit_wm_ns[3].d_mark =
3480 bw_fixed_to_int(bw_mul(data->
3481 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3482 calcs_output->stutter_exit_wm_ns[4].d_mark =
3483 bw_fixed_to_int(bw_mul(data->
3484 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3486 calcs_output->stutter_exit_wm_ns[5].d_mark =
3487 bw_fixed_to_int(bw_mul(data->
3488 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3490 calcs_output->stutter_entry_wm_ns[0].d_mark =
3491 bw_fixed_to_int(bw_mul(data->
3492 stutter_entry_watermark[4], bw_int_to_fixed(1000)));
3493 calcs_output->stutter_entry_wm_ns[1].d_mark =
3494 bw_fixed_to_int(bw_mul(data->
3495 stutter_entry_watermark[5], bw_int_to_fixed(1000)));
3496 calcs_output->stutter_entry_wm_ns[2].d_mark =
3497 bw_fixed_to_int(bw_mul(data->
3498 stutter_entry_watermark[6], bw_int_to_fixed(1000)));
3499 if (ctx->dc->caps.max_slave_planes) {
3500 calcs_output->stutter_entry_wm_ns[3].d_mark =
3501 bw_fixed_to_int(bw_mul(data->
3502 stutter_entry_watermark[0], bw_int_to_fixed(1000)));
3503 calcs_output->stutter_entry_wm_ns[4].d_mark =
3504 bw_fixed_to_int(bw_mul(data->
3505 stutter_entry_watermark[1], bw_int_to_fixed(1000)));
3507 calcs_output->stutter_entry_wm_ns[3].d_mark =
3508 bw_fixed_to_int(bw_mul(data->
3509 stutter_entry_watermark[7], bw_int_to_fixed(1000)));
3510 calcs_output->stutter_entry_wm_ns[4].d_mark =
3511 bw_fixed_to_int(bw_mul(data->
3512 stutter_entry_watermark[8], bw_int_to_fixed(1000)));
3514 calcs_output->stutter_entry_wm_ns[5].d_mark =
3515 bw_fixed_to_int(bw_mul(data->
3516 stutter_entry_watermark[9], bw_int_to_fixed(1000)));
3518 calcs_output->urgent_wm_ns[0].d_mark =
3519 bw_fixed_to_int(bw_mul(data->
3520 urgent_watermark[4], bw_int_to_fixed(1000)));
3521 calcs_output->urgent_wm_ns[1].d_mark =
3522 bw_fixed_to_int(bw_mul(data->
3523 urgent_watermark[5], bw_int_to_fixed(1000)));
3524 calcs_output->urgent_wm_ns[2].d_mark =
3525 bw_fixed_to_int(bw_mul(data->
3526 urgent_watermark[6], bw_int_to_fixed(1000)));
3527 if (ctx->dc->caps.max_slave_planes) {
3528 calcs_output->urgent_wm_ns[3].d_mark =
3529 bw_fixed_to_int(bw_mul(data->
3530 urgent_watermark[0], bw_int_to_fixed(1000)));
3531 calcs_output->urgent_wm_ns[4].d_mark =
3532 bw_fixed_to_int(bw_mul(data->
3533 urgent_watermark[1], bw_int_to_fixed(1000)));
3535 calcs_output->urgent_wm_ns[3].d_mark =
3536 bw_fixed_to_int(bw_mul(data->
3537 urgent_watermark[7], bw_int_to_fixed(1000)));
3538 calcs_output->urgent_wm_ns[4].d_mark =
3539 bw_fixed_to_int(bw_mul(data->
3540 urgent_watermark[8], bw_int_to_fixed(1000)));
3542 calcs_output->urgent_wm_ns[5].d_mark =
3543 bw_fixed_to_int(bw_mul(data->
3544 urgent_watermark[9], bw_int_to_fixed(1000)));
3546 ((struct bw_calcs_vbios *)vbios)->low_yclk = low_yclk;
3547 ((struct bw_calcs_vbios *)vbios)->mid_yclk = mid_yclk;
3548 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3549 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3550 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3551 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = mid3_sclk;
3552 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = mid4_sclk;
3553 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = mid5_sclk;
3554 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = mid6_sclk;
3555 ((struct bw_calcs_vbios *)vbios)->high_sclk = high_sclk;
3557 calcs_output->nbp_state_change_enable = true;
3558 calcs_output->cpuc_state_change_enable = true;
3559 calcs_output->cpup_state_change_enable = true;
3560 calcs_output->stutter_mode_enable = true;
3561 calcs_output->dispclk_khz = 0;
3562 calcs_output->sclk_khz = 0;
3567 return is_display_configuration_supported(vbios, calcs_output);