Loading...
Note: File does not exist in v6.9.4.
1/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "dm_services.h"
27#include "dce_calcs.h"
28#include "dc.h"
29#include "core_types.h"
30#include "dal_asic_id.h"
31
32/*
33 * NOTE:
34 * This file is gcc-parseable HW gospel, coming straight from HW engineers.
35 *
36 * It doesn't adhere to Linux kernel style and sometimes will do things in odd
37 * ways. Unless there is something clearly wrong with it the code should
38 * remain as-is as it provides us with a guarantee from HW that it is correct.
39 */
40
41/*******************************************************************************
42 * Private Functions
43 ******************************************************************************/
44
45static enum bw_calcs_version bw_calcs_version_from_asic_id(struct hw_asic_id asic_id)
46{
47 switch (asic_id.chip_family) {
48
49 case FAMILY_CZ:
50 if (ASIC_REV_IS_STONEY(asic_id.hw_internal_rev))
51 return BW_CALCS_VERSION_STONEY;
52 return BW_CALCS_VERSION_CARRIZO;
53
54 case FAMILY_VI:
55 if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev))
56 return BW_CALCS_VERSION_POLARIS10;
57 if (ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev) ||
58 ASIC_REV_IS_POLARIS12_V(asic_id.hw_internal_rev))
59 return BW_CALCS_VERSION_POLARIS11;
60 return BW_CALCS_VERSION_INVALID;
61
62 case FAMILY_AI:
63 return BW_CALCS_VERSION_VEGA10;
64
65 default:
66 return BW_CALCS_VERSION_INVALID;
67 }
68}
69
70static void calculate_bandwidth(
71 const struct bw_calcs_dceip *dceip,
72 const struct bw_calcs_vbios *vbios,
73 struct bw_calcs_data *data)
74
75{
76 const int32_t pixels_per_chunk = 512;
77 const int32_t high = 2;
78 const int32_t mid = 1;
79 const int32_t low = 0;
80 const uint32_t s_low = 0;
81 const uint32_t s_mid1 = 1;
82 const uint32_t s_mid2 = 2;
83 const uint32_t s_mid3 = 3;
84 const uint32_t s_mid4 = 4;
85 const uint32_t s_mid5 = 5;
86 const uint32_t s_mid6 = 6;
87 const uint32_t s_high = 7;
88 const uint32_t dmif_chunk_buff_margin = 1;
89
90 uint32_t max_chunks_fbc_mode;
91 int32_t num_cursor_lines;
92
93 int32_t i, j, k;
94 struct bw_fixed yclk[3];
95 struct bw_fixed sclk[8];
96 bool d0_underlay_enable;
97 bool d1_underlay_enable;
98 bool fbc_enabled;
99 bool lpt_enabled;
100 enum bw_defines sclk_message;
101 enum bw_defines yclk_message;
102 enum bw_defines v_filter_init_mode[maximum_number_of_surfaces];
103 enum bw_defines tiling_mode[maximum_number_of_surfaces];
104 enum bw_defines surface_type[maximum_number_of_surfaces];
105 enum bw_defines voltage;
106 enum bw_defines pipe_check;
107 enum bw_defines hsr_check;
108 enum bw_defines vsr_check;
109 enum bw_defines lb_size_check;
110 enum bw_defines fbc_check;
111 enum bw_defines rotation_check;
112 enum bw_defines mode_check;
113 enum bw_defines nbp_state_change_enable_blank;
114 /*initialize variables*/
115 int32_t number_of_displays_enabled = 0;
116 int32_t number_of_displays_enabled_with_margin = 0;
117 int32_t number_of_aligned_displays_with_no_margin = 0;
118
119 yclk[low] = vbios->low_yclk;
120 yclk[mid] = vbios->mid_yclk;
121 yclk[high] = vbios->high_yclk;
122 sclk[s_low] = vbios->low_sclk;
123 sclk[s_mid1] = vbios->mid1_sclk;
124 sclk[s_mid2] = vbios->mid2_sclk;
125 sclk[s_mid3] = vbios->mid3_sclk;
126 sclk[s_mid4] = vbios->mid4_sclk;
127 sclk[s_mid5] = vbios->mid5_sclk;
128 sclk[s_mid6] = vbios->mid6_sclk;
129 sclk[s_high] = vbios->high_sclk;
130 /*''''''''''''''''''*/
131 /* surface assignment:*/
132 /* 0: d0 underlay or underlay luma*/
133 /* 1: d0 underlay chroma*/
134 /* 2: d1 underlay or underlay luma*/
135 /* 3: d1 underlay chroma*/
136 /* 4: d0 graphics*/
137 /* 5: d1 graphics*/
138 /* 6: d2 graphics*/
139 /* 7: d3 graphics, same mode as d2*/
140 /* 8: d4 graphics, same mode as d2*/
141 /* 9: d5 graphics, same mode as d2*/
142 /* ...*/
143 /* maximum_number_of_surfaces-2: d1 display_write_back420 luma*/
144 /* maximum_number_of_surfaces-1: d1 display_write_back420 chroma*/
145 /* underlay luma and chroma surface parameters from spreadsheet*/
146
147
148
149
150 if (data->d0_underlay_mode == bw_def_none) { d0_underlay_enable = 0; }
151 else {
152 d0_underlay_enable = 1;
153 }
154 if (data->d1_underlay_mode == bw_def_none) { d1_underlay_enable = 0; }
155 else {
156 d1_underlay_enable = 1;
157 }
158 data->number_of_underlay_surfaces = d0_underlay_enable + d1_underlay_enable;
159 switch (data->underlay_surface_type) {
160 case bw_def_420:
161 surface_type[0] = bw_def_underlay420_luma;
162 surface_type[2] = bw_def_underlay420_luma;
163 data->bytes_per_pixel[0] = 1;
164 data->bytes_per_pixel[2] = 1;
165 surface_type[1] = bw_def_underlay420_chroma;
166 surface_type[3] = bw_def_underlay420_chroma;
167 data->bytes_per_pixel[1] = 2;
168 data->bytes_per_pixel[3] = 2;
169 data->lb_size_per_component[0] = dceip->underlay420_luma_lb_size_per_component;
170 data->lb_size_per_component[1] = dceip->underlay420_chroma_lb_size_per_component;
171 data->lb_size_per_component[2] = dceip->underlay420_luma_lb_size_per_component;
172 data->lb_size_per_component[3] = dceip->underlay420_chroma_lb_size_per_component;
173 break;
174 case bw_def_422:
175 surface_type[0] = bw_def_underlay422;
176 surface_type[2] = bw_def_underlay422;
177 data->bytes_per_pixel[0] = 2;
178 data->bytes_per_pixel[2] = 2;
179 data->lb_size_per_component[0] = dceip->underlay422_lb_size_per_component;
180 data->lb_size_per_component[2] = dceip->underlay422_lb_size_per_component;
181 break;
182 default:
183 surface_type[0] = bw_def_underlay444;
184 surface_type[2] = bw_def_underlay444;
185 data->bytes_per_pixel[0] = 4;
186 data->bytes_per_pixel[2] = 4;
187 data->lb_size_per_component[0] = dceip->lb_size_per_component444;
188 data->lb_size_per_component[2] = dceip->lb_size_per_component444;
189 break;
190 }
191 if (d0_underlay_enable) {
192 switch (data->underlay_surface_type) {
193 case bw_def_420:
194 data->enable[0] = 1;
195 data->enable[1] = 1;
196 break;
197 default:
198 data->enable[0] = 1;
199 data->enable[1] = 0;
200 break;
201 }
202 }
203 else {
204 data->enable[0] = 0;
205 data->enable[1] = 0;
206 }
207 if (d1_underlay_enable) {
208 switch (data->underlay_surface_type) {
209 case bw_def_420:
210 data->enable[2] = 1;
211 data->enable[3] = 1;
212 break;
213 default:
214 data->enable[2] = 1;
215 data->enable[3] = 0;
216 break;
217 }
218 }
219 else {
220 data->enable[2] = 0;
221 data->enable[3] = 0;
222 }
223 data->use_alpha[0] = 0;
224 data->use_alpha[1] = 0;
225 data->use_alpha[2] = 0;
226 data->use_alpha[3] = 0;
227 data->scatter_gather_enable_for_pipe[0] = vbios->scatter_gather_enable;
228 data->scatter_gather_enable_for_pipe[1] = vbios->scatter_gather_enable;
229 data->scatter_gather_enable_for_pipe[2] = vbios->scatter_gather_enable;
230 data->scatter_gather_enable_for_pipe[3] = vbios->scatter_gather_enable;
231 /*underlay0 same and graphics display pipe0*/
232 data->interlace_mode[0] = data->interlace_mode[4];
233 data->interlace_mode[1] = data->interlace_mode[4];
234 /*underlay1 same and graphics display pipe1*/
235 data->interlace_mode[2] = data->interlace_mode[5];
236 data->interlace_mode[3] = data->interlace_mode[5];
237 /*underlay0 same and graphics display pipe0*/
238 data->h_total[0] = data->h_total[4];
239 data->v_total[0] = data->v_total[4];
240 data->h_total[1] = data->h_total[4];
241 data->v_total[1] = data->v_total[4];
242 /*underlay1 same and graphics display pipe1*/
243 data->h_total[2] = data->h_total[5];
244 data->v_total[2] = data->v_total[5];
245 data->h_total[3] = data->h_total[5];
246 data->v_total[3] = data->v_total[5];
247 /*underlay0 same and graphics display pipe0*/
248 data->pixel_rate[0] = data->pixel_rate[4];
249 data->pixel_rate[1] = data->pixel_rate[4];
250 /*underlay1 same and graphics display pipe1*/
251 data->pixel_rate[2] = data->pixel_rate[5];
252 data->pixel_rate[3] = data->pixel_rate[5];
253 if ((data->underlay_tiling_mode == bw_def_array_linear_general || data->underlay_tiling_mode == bw_def_array_linear_aligned)) {
254 tiling_mode[0] = bw_def_linear;
255 tiling_mode[1] = bw_def_linear;
256 tiling_mode[2] = bw_def_linear;
257 tiling_mode[3] = bw_def_linear;
258 }
259 else {
260 tiling_mode[0] = bw_def_landscape;
261 tiling_mode[1] = bw_def_landscape;
262 tiling_mode[2] = bw_def_landscape;
263 tiling_mode[3] = bw_def_landscape;
264 }
265 data->lb_bpc[0] = data->underlay_lb_bpc;
266 data->lb_bpc[1] = data->underlay_lb_bpc;
267 data->lb_bpc[2] = data->underlay_lb_bpc;
268 data->lb_bpc[3] = data->underlay_lb_bpc;
269 data->compression_rate[0] = bw_int_to_fixed(1);
270 data->compression_rate[1] = bw_int_to_fixed(1);
271 data->compression_rate[2] = bw_int_to_fixed(1);
272 data->compression_rate[3] = bw_int_to_fixed(1);
273 data->access_one_channel_only[0] = 0;
274 data->access_one_channel_only[1] = 0;
275 data->access_one_channel_only[2] = 0;
276 data->access_one_channel_only[3] = 0;
277 data->cursor_width_pixels[0] = bw_int_to_fixed(0);
278 data->cursor_width_pixels[1] = bw_int_to_fixed(0);
279 data->cursor_width_pixels[2] = bw_int_to_fixed(0);
280 data->cursor_width_pixels[3] = bw_int_to_fixed(0);
281 /* graphics surface parameters from spreadsheet*/
282 fbc_enabled = 0;
283 lpt_enabled = 0;
284 for (i = 4; i <= maximum_number_of_surfaces - 3; i++) {
285 if (i < data->number_of_displays + 4) {
286 if (i == 4 && data->d0_underlay_mode == bw_def_underlay_only) {
287 data->enable[i] = 0;
288 data->use_alpha[i] = 0;
289 }
290 else if (i == 4 && data->d0_underlay_mode == bw_def_blend) {
291 data->enable[i] = 1;
292 data->use_alpha[i] = 1;
293 }
294 else if (i == 4) {
295 data->enable[i] = 1;
296 data->use_alpha[i] = 0;
297 }
298 else if (i == 5 && data->d1_underlay_mode == bw_def_underlay_only) {
299 data->enable[i] = 0;
300 data->use_alpha[i] = 0;
301 }
302 else if (i == 5 && data->d1_underlay_mode == bw_def_blend) {
303 data->enable[i] = 1;
304 data->use_alpha[i] = 1;
305 }
306 else {
307 data->enable[i] = 1;
308 data->use_alpha[i] = 0;
309 }
310 }
311 else {
312 data->enable[i] = 0;
313 data->use_alpha[i] = 0;
314 }
315 data->scatter_gather_enable_for_pipe[i] = vbios->scatter_gather_enable;
316 surface_type[i] = bw_def_graphics;
317 data->lb_size_per_component[i] = dceip->lb_size_per_component444;
318 if (data->graphics_tiling_mode == bw_def_array_linear_general || data->graphics_tiling_mode == bw_def_array_linear_aligned) {
319 tiling_mode[i] = bw_def_linear;
320 }
321 else {
322 tiling_mode[i] = bw_def_tiled;
323 }
324 data->lb_bpc[i] = data->graphics_lb_bpc;
325 if ((data->fbc_en[i] == 1 && (dceip->argb_compression_support || data->d0_underlay_mode != bw_def_blended))) {
326 data->compression_rate[i] = bw_int_to_fixed(vbios->average_compression_rate);
327 data->access_one_channel_only[i] = data->lpt_en[i];
328 }
329 else {
330 data->compression_rate[i] = bw_int_to_fixed(1);
331 data->access_one_channel_only[i] = 0;
332 }
333 if (data->fbc_en[i] == 1) {
334 fbc_enabled = 1;
335 if (data->lpt_en[i] == 1) {
336 lpt_enabled = 1;
337 }
338 }
339 data->cursor_width_pixels[i] = bw_int_to_fixed(vbios->cursor_width);
340 }
341 /* display_write_back420*/
342 data->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 2] = 0;
343 data->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 1] = 0;
344 if (data->d1_display_write_back_dwb_enable == 1) {
345 data->enable[maximum_number_of_surfaces - 2] = 1;
346 data->enable[maximum_number_of_surfaces - 1] = 1;
347 }
348 else {
349 data->enable[maximum_number_of_surfaces - 2] = 0;
350 data->enable[maximum_number_of_surfaces - 1] = 0;
351 }
352 surface_type[maximum_number_of_surfaces - 2] = bw_def_display_write_back420_luma;
353 surface_type[maximum_number_of_surfaces - 1] = bw_def_display_write_back420_chroma;
354 data->lb_size_per_component[maximum_number_of_surfaces - 2] = dceip->underlay420_luma_lb_size_per_component;
355 data->lb_size_per_component[maximum_number_of_surfaces - 1] = dceip->underlay420_chroma_lb_size_per_component;
356 data->bytes_per_pixel[maximum_number_of_surfaces - 2] = 1;
357 data->bytes_per_pixel[maximum_number_of_surfaces - 1] = 2;
358 data->interlace_mode[maximum_number_of_surfaces - 2] = data->interlace_mode[5];
359 data->interlace_mode[maximum_number_of_surfaces - 1] = data->interlace_mode[5];
360 data->h_taps[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
361 data->h_taps[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
362 data->v_taps[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
363 data->v_taps[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
364 data->rotation_angle[maximum_number_of_surfaces - 2] = bw_int_to_fixed(0);
365 data->rotation_angle[maximum_number_of_surfaces - 1] = bw_int_to_fixed(0);
366 tiling_mode[maximum_number_of_surfaces - 2] = bw_def_linear;
367 tiling_mode[maximum_number_of_surfaces - 1] = bw_def_linear;
368 data->lb_bpc[maximum_number_of_surfaces - 2] = 8;
369 data->lb_bpc[maximum_number_of_surfaces - 1] = 8;
370 data->compression_rate[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
371 data->compression_rate[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
372 data->access_one_channel_only[maximum_number_of_surfaces - 2] = 0;
373 data->access_one_channel_only[maximum_number_of_surfaces - 1] = 0;
374 /*assume display pipe1 has dwb enabled*/
375 data->h_total[maximum_number_of_surfaces - 2] = data->h_total[5];
376 data->h_total[maximum_number_of_surfaces - 1] = data->h_total[5];
377 data->v_total[maximum_number_of_surfaces - 2] = data->v_total[5];
378 data->v_total[maximum_number_of_surfaces - 1] = data->v_total[5];
379 data->pixel_rate[maximum_number_of_surfaces - 2] = data->pixel_rate[5];
380 data->pixel_rate[maximum_number_of_surfaces - 1] = data->pixel_rate[5];
381 data->src_width[maximum_number_of_surfaces - 2] = data->src_width[5];
382 data->src_width[maximum_number_of_surfaces - 1] = data->src_width[5];
383 data->src_height[maximum_number_of_surfaces - 2] = data->src_height[5];
384 data->src_height[maximum_number_of_surfaces - 1] = data->src_height[5];
385 data->pitch_in_pixels[maximum_number_of_surfaces - 2] = data->src_width[5];
386 data->pitch_in_pixels[maximum_number_of_surfaces - 1] = data->src_width[5];
387 data->h_scale_ratio[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
388 data->h_scale_ratio[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
389 data->v_scale_ratio[maximum_number_of_surfaces - 2] = bw_int_to_fixed(1);
390 data->v_scale_ratio[maximum_number_of_surfaces - 1] = bw_int_to_fixed(1);
391 data->stereo_mode[maximum_number_of_surfaces - 2] = bw_def_mono;
392 data->stereo_mode[maximum_number_of_surfaces - 1] = bw_def_mono;
393 data->cursor_width_pixels[maximum_number_of_surfaces - 2] = bw_int_to_fixed(0);
394 data->cursor_width_pixels[maximum_number_of_surfaces - 1] = bw_int_to_fixed(0);
395 data->use_alpha[maximum_number_of_surfaces - 2] = 0;
396 data->use_alpha[maximum_number_of_surfaces - 1] = 0;
397 /*mode check calculations:*/
398 /* mode within dce ip capabilities*/
399 /* fbc*/
400 /* hsr*/
401 /* vsr*/
402 /* lb size*/
403 /*effective scaling source and ratios:*/
404 /*for graphics, non-stereo, non-interlace surfaces when the size of the source and destination are the same, only one tap is used*/
405 /*420 chroma has half the width, height, horizontal and vertical scaling ratios than luma*/
406 /*rotating a graphic or underlay surface swaps the width, height, horizontal and vertical scaling ratios*/
407 /*in top-bottom stereo mode there is 2:1 vertical downscaling for each eye*/
408 /*in side-by-side stereo mode there is 2:1 horizontal downscaling for each eye*/
409 /*in interlace mode there is 2:1 vertical downscaling for each field*/
410 /*in panning or bezel adjustment mode the source width has an extra 128 pixels*/
411 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
412 if (data->enable[i]) {
413 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) {
414 data->h_taps[i] = bw_int_to_fixed(1);
415 data->v_taps[i] = bw_int_to_fixed(1);
416 }
417 if (surface_type[i] == bw_def_display_write_back420_chroma || surface_type[i] == bw_def_underlay420_chroma) {
418 data->pitch_in_pixels_after_surface_type[i] = bw_div(data->pitch_in_pixels[i], bw_int_to_fixed(2));
419 data->src_width_after_surface_type = bw_div(data->src_width[i], bw_int_to_fixed(2));
420 data->src_height_after_surface_type = bw_div(data->src_height[i], bw_int_to_fixed(2));
421 data->hsr_after_surface_type = bw_div(data->h_scale_ratio[i], bw_int_to_fixed(2));
422 data->vsr_after_surface_type = bw_div(data->v_scale_ratio[i], bw_int_to_fixed(2));
423 }
424 else {
425 data->pitch_in_pixels_after_surface_type[i] = data->pitch_in_pixels[i];
426 data->src_width_after_surface_type = data->src_width[i];
427 data->src_height_after_surface_type = data->src_height[i];
428 data->hsr_after_surface_type = data->h_scale_ratio[i];
429 data->vsr_after_surface_type = data->v_scale_ratio[i];
430 }
431 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) {
432 data->src_width_after_rotation = data->src_height_after_surface_type;
433 data->src_height_after_rotation = data->src_width_after_surface_type;
434 data->hsr_after_rotation = data->vsr_after_surface_type;
435 data->vsr_after_rotation = data->hsr_after_surface_type;
436 }
437 else {
438 data->src_width_after_rotation = data->src_width_after_surface_type;
439 data->src_height_after_rotation = data->src_height_after_surface_type;
440 data->hsr_after_rotation = data->hsr_after_surface_type;
441 data->vsr_after_rotation = data->vsr_after_surface_type;
442 }
443 switch (data->stereo_mode[i]) {
444 case bw_def_top_bottom:
445 data->source_width_pixels[i] = data->src_width_after_rotation;
446 data->source_height_pixels = bw_mul(bw_int_to_fixed(2), data->src_height_after_rotation);
447 data->hsr_after_stereo = data->hsr_after_rotation;
448 data->vsr_after_stereo = bw_mul(bw_int_to_fixed(1), data->vsr_after_rotation);
449 break;
450 case bw_def_side_by_side:
451 data->source_width_pixels[i] = bw_mul(bw_int_to_fixed(2), data->src_width_after_rotation);
452 data->source_height_pixels = data->src_height_after_rotation;
453 data->hsr_after_stereo = bw_mul(bw_int_to_fixed(1), data->hsr_after_rotation);
454 data->vsr_after_stereo = data->vsr_after_rotation;
455 break;
456 default:
457 data->source_width_pixels[i] = data->src_width_after_rotation;
458 data->source_height_pixels = data->src_height_after_rotation;
459 data->hsr_after_stereo = data->hsr_after_rotation;
460 data->vsr_after_stereo = data->vsr_after_rotation;
461 break;
462 }
463 data->hsr[i] = data->hsr_after_stereo;
464 if (data->interlace_mode[i]) {
465 data->vsr[i] = bw_mul(data->vsr_after_stereo, bw_int_to_fixed(2));
466 }
467 else {
468 data->vsr[i] = data->vsr_after_stereo;
469 }
470 if (data->panning_and_bezel_adjustment != bw_def_none) {
471 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));
472 }
473 else {
474 data->source_width_rounded_up_to_chunks[i] = bw_ceil2(data->source_width_pixels[i], bw_int_to_fixed(128));
475 }
476 data->source_height_rounded_up_to_chunks[i] = data->source_height_pixels;
477 }
478 }
479 /*mode support checks:*/
480 /*the number of graphics and underlay pipes is limited by the ip support*/
481 /*maximum horizontal and vertical scale ratio is 4, and should not exceed the number of taps*/
482 /*for downscaling with the pre-downscaler, the horizontal scale ratio must be more than the ceiling of one quarter of the number of taps*/
483 /*the pre-downscaler reduces the line buffer source by the horizontal scale ratio*/
484 /*the number of lines in the line buffer has to exceed the number of vertical taps*/
485 /*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*/
486 /*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*/
487 /*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*/
488 /*frame buffer compression is not supported with stereo mode, rotation, or non- 888 formats*/
489 /*rotation is not supported with linear of stereo modes*/
490 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)) {
491 pipe_check = bw_def_ok;
492 }
493 else {
494 pipe_check = bw_def_notok;
495 }
496 hsr_check = bw_def_ok;
497 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
498 if (data->enable[i]) {
499 if (bw_neq(data->hsr[i], bw_int_to_fixed(1))) {
500 if (bw_mtn(data->hsr[i], bw_int_to_fixed(4))) {
501 hsr_check = bw_def_hsr_mtn_4;
502 }
503 else {
504 if (bw_mtn(data->hsr[i], data->h_taps[i])) {
505 hsr_check = bw_def_hsr_mtn_h_taps;
506 }
507 else {
508 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)))) {
509 hsr_check = bw_def_ceiling__h_taps_div_4___meq_hsr;
510 }
511 }
512 }
513 }
514 }
515 }
516 vsr_check = bw_def_ok;
517 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
518 if (data->enable[i]) {
519 if (bw_neq(data->vsr[i], bw_int_to_fixed(1))) {
520 if (bw_mtn(data->vsr[i], bw_int_to_fixed(4))) {
521 vsr_check = bw_def_vsr_mtn_4;
522 }
523 else {
524 if (bw_mtn(data->vsr[i], data->v_taps[i])) {
525 vsr_check = bw_def_vsr_mtn_v_taps;
526 }
527 }
528 }
529 }
530 }
531 lb_size_check = bw_def_ok;
532 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
533 if (data->enable[i]) {
534 if ((dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1)))) {
535 data->source_width_in_lb = bw_div(data->source_width_pixels[i], data->hsr[i]);
536 }
537 else {
538 data->source_width_in_lb = data->source_width_pixels[i];
539 }
540 switch (data->lb_bpc[i]) {
541 case 8:
542 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));
543 break;
544 case 10:
545 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));
546 break;
547 default:
548 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));
549 break;
550 }
551 data->lb_partitions[i] = bw_floor2(bw_div(data->lb_size_per_component[i], data->lb_line_pitch), bw_int_to_fixed(1));
552 /*clamp the partitions to the maxium number supported by the lb*/
553 if ((surface_type[i] != bw_def_graphics || dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1)) {
554 data->lb_partitions_max[i] = bw_int_to_fixed(10);
555 }
556 else {
557 data->lb_partitions_max[i] = bw_int_to_fixed(7);
558 }
559 data->lb_partitions[i] = bw_min2(data->lb_partitions_max[i], data->lb_partitions[i]);
560 if (bw_mtn(bw_add(data->v_taps[i], bw_int_to_fixed(1)), data->lb_partitions[i])) {
561 lb_size_check = bw_def_notok;
562 }
563 }
564 }
565 fbc_check = bw_def_ok;
566 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
567 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)) {
568 fbc_check = bw_def_invalid_rotation_or_bpp_or_stereo;
569 }
570 }
571 rotation_check = bw_def_ok;
572 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
573 if (data->enable[i]) {
574 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)) {
575 rotation_check = bw_def_invalid_linear_or_stereo_mode;
576 }
577 }
578 }
579 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) {
580 mode_check = bw_def_ok;
581 }
582 else {
583 mode_check = bw_def_notok;
584 }
585 /*number of memory channels for write-back client*/
586 data->number_of_dram_wrchannels = vbios->number_of_dram_channels;
587 data->number_of_dram_channels = vbios->number_of_dram_channels;
588 /*modify number of memory channels if lpt mode is enabled*/
589 /* low power tiling mode register*/
590 /* 0 = use channel 0*/
591 /* 1 = use channel 0 and 1*/
592 /* 2 = use channel 0,1,2,3*/
593 if ((fbc_enabled == 1 && lpt_enabled == 1)) {
594 if (vbios->memory_type == bw_def_hbm)
595 data->dram_efficiency = bw_frc_to_fixed(5, 10);
596 else
597 data->dram_efficiency = bw_int_to_fixed(1);
598
599
600 if (dceip->low_power_tiling_mode == 0) {
601 data->number_of_dram_channels = 1;
602 }
603 else if (dceip->low_power_tiling_mode == 1) {
604 data->number_of_dram_channels = 2;
605 }
606 else if (dceip->low_power_tiling_mode == 2) {
607 data->number_of_dram_channels = 4;
608 }
609 else {
610 data->number_of_dram_channels = 1;
611 }
612 }
613 else {
614 if (vbios->memory_type == bw_def_hbm)
615 data->dram_efficiency = bw_frc_to_fixed(5, 10);
616 else
617 data->dram_efficiency = bw_frc_to_fixed(8, 10);
618 }
619 /*memory request size and latency hiding:*/
620 /*request size is normally 64 byte, 2-line interleaved, with full latency hiding*/
621 /*the display write-back requests are single line*/
622 /*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.*/
623 /*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.*/
624 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
625 if (data->enable[i]) {
626 if ((bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270)))) {
627 if ((i < 4)) {
628 /*underlay portrait tiling mode is not supported*/
629 data->orthogonal_rotation[i] = 1;
630 }
631 else {
632 /*graphics portrait tiling mode*/
633 if (data->graphics_micro_tile_mode == bw_def_rotated_micro_tiling) {
634 data->orthogonal_rotation[i] = 0;
635 }
636 else {
637 data->orthogonal_rotation[i] = 1;
638 }
639 }
640 }
641 else {
642 if ((i < 4)) {
643 /*underlay landscape tiling mode is only supported*/
644 if (data->underlay_micro_tile_mode == bw_def_display_micro_tiling) {
645 data->orthogonal_rotation[i] = 0;
646 }
647 else {
648 data->orthogonal_rotation[i] = 1;
649 }
650 }
651 else {
652 /*graphics landscape tiling mode*/
653 if (data->graphics_micro_tile_mode == bw_def_display_micro_tiling) {
654 data->orthogonal_rotation[i] = 0;
655 }
656 else {
657 data->orthogonal_rotation[i] = 1;
658 }
659 }
660 }
661 if (bw_equ(data->rotation_angle[i], bw_int_to_fixed(90)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(270))) {
662 data->underlay_maximum_source_efficient_for_tiling = dceip->underlay_maximum_height_efficient_for_tiling;
663 }
664 else {
665 data->underlay_maximum_source_efficient_for_tiling = dceip->underlay_maximum_width_efficient_for_tiling;
666 }
667 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
668 data->bytes_per_request[i] = bw_int_to_fixed(64);
669 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
670 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(1);
671 data->latency_hiding_lines[i] = bw_int_to_fixed(1);
672 }
673 else if (tiling_mode[i] == bw_def_linear) {
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(2);
677 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
678 }
679 else {
680 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))))) {
681 switch (data->bytes_per_pixel[i]) {
682 case 8:
683 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
684 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
685 if (data->orthogonal_rotation[i]) {
686 data->bytes_per_request[i] = bw_int_to_fixed(32);
687 data->useful_bytes_per_request[i] = bw_int_to_fixed(32);
688 }
689 else {
690 data->bytes_per_request[i] = bw_int_to_fixed(64);
691 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
692 }
693 break;
694 case 4:
695 if (data->orthogonal_rotation[i]) {
696 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
697 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
698 data->bytes_per_request[i] = bw_int_to_fixed(32);
699 data->useful_bytes_per_request[i] = bw_int_to_fixed(16);
700 }
701 else {
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(64);
705 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
706 }
707 break;
708 case 2:
709 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
710 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
711 data->bytes_per_request[i] = bw_int_to_fixed(32);
712 data->useful_bytes_per_request[i] = bw_int_to_fixed(32);
713 break;
714 default:
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(16);
719 break;
720 }
721 }
722 else {
723 data->bytes_per_request[i] = bw_int_to_fixed(64);
724 data->useful_bytes_per_request[i] = bw_int_to_fixed(64);
725 if (data->orthogonal_rotation[i]) {
726 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(8);
727 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
728 }
729 else {
730 switch (data->bytes_per_pixel[i]) {
731 case 4:
732 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(2);
733 data->latency_hiding_lines[i] = bw_int_to_fixed(2);
734 break;
735 case 2:
736 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(4);
737 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
738 break;
739 default:
740 data->lines_interleaved_in_mem_access[i] = bw_int_to_fixed(8);
741 data->latency_hiding_lines[i] = bw_int_to_fixed(4);
742 break;
743 }
744 }
745 }
746 }
747 }
748 }
749 /*requested peak bandwidth:*/
750 /*the peak request-per-second bandwidth is the product of the maximum source lines in per line out in the beginning*/
751 /*and in the middle of the frame, the ratio of the source width to the line time, the ratio of line interleaving*/
752 /*in memory to lines of latency hiding, and the ratio of bytes per pixel to useful bytes per request.*/
753 /**/
754 /*if the dmif data buffer size holds more than vta_ps worth of source lines, then only vsr is used.*/
755 /*the peak bandwidth is the peak request-per-second bandwidth times the request size.*/
756 /**/
757 /*the line buffer lines in per line out in the beginning of the frame is the vertical filter initialization value*/
758 /*rounded up to even and divided by the line times for initialization, which is normally three.*/
759 /*the line buffer lines in per line out in the middle of the frame is at least one, or the vertical scale ratio,*/
760 /*rounded up to line pairs if not doing line buffer prefetching.*/
761 /**/
762 /*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),*/
763 /*6/4 (for a 0,2,2,2 pattern), or 3 (for a 2,4 pattern).*/
764 /**/
765 /*the scaler vertical filter initialization value is calculated by the hardware as the floor of the average of the*/
766 /*vertical scale ratio and the number of vertical taps increased by one. add one more for possible odd line*/
767 /*panning/bezel adjustment mode.*/
768 /**/
769 /*for the bottom interlace field an extra 50% of the vertical scale ratio is considered for this calculation.*/
770 /*in top-bottom stereo mode software has to set the filter initialization value manually and explicitly limit it to 4.*/
771 /*furthermore, there is only one line time for initialization.*/
772 /**/
773 /*line buffer prefetching is done when the number of lines in the line buffer exceeds the number of taps plus*/
774 /*the ceiling of the vertical scale ratio.*/
775 /**/
776 /*multi-line buffer prefetching is only done in the graphics pipe when the scaler is disabled or when upscaling and the vsr <= 0.8.'*/
777 /**/
778 /*the horizontal blank and chunk granularity factor is indirectly used indicate the interval of time required to transfer the source pixels.*/
779 /*the denominator of this term represents the total number of destination output pixels required for the input source pixels.*/
780 /*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.*/
781 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
782 if (data->enable[i]) {
783 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));
784 if (data->panning_and_bezel_adjustment == bw_def_any_lines) {
785 data->v_filter_init[i] = bw_add(data->v_filter_init[i], bw_int_to_fixed(1));
786 }
787 if (data->stereo_mode[i] == bw_def_top_bottom) {
788 v_filter_init_mode[i] = bw_def_manual;
789 data->v_filter_init[i] = bw_min2(data->v_filter_init[i], bw_int_to_fixed(4));
790 }
791 else {
792 v_filter_init_mode[i] = bw_def_auto;
793 }
794 if (data->stereo_mode[i] == bw_def_top_bottom) {
795 data->num_lines_at_frame_start = bw_int_to_fixed(1);
796 }
797 else {
798 data->num_lines_at_frame_start = bw_int_to_fixed(3);
799 }
800 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) {
801 data->line_buffer_prefetch[i] = 0;
802 }
803 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))))))) {
804 data->line_buffer_prefetch[i] = 1;
805 }
806 else {
807 data->line_buffer_prefetch[i] = 0;
808 }
809 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);
810 if (data->line_buffer_prefetch[i] == 1) {
811 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_max2(bw_int_to_fixed(1), data->vsr[i]);
812 }
813 else if (bw_leq(data->vsr[i], bw_int_to_fixed(1))) {
814 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(1);
815 } else if (bw_leq(data->vsr[i],
816 bw_frc_to_fixed(4, 3))) {
817 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_div(bw_int_to_fixed(4), bw_int_to_fixed(3));
818 } else if (bw_leq(data->vsr[i],
819 bw_frc_to_fixed(6, 4))) {
820 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_div(bw_int_to_fixed(6), bw_int_to_fixed(4));
821 }
822 else if (bw_leq(data->vsr[i], bw_int_to_fixed(2))) {
823 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(2);
824 }
825 else if (bw_leq(data->vsr[i], bw_int_to_fixed(3))) {
826 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(3);
827 }
828 else {
829 data->lb_lines_in_per_line_out_in_middle_of_frame[i] = bw_int_to_fixed(4);
830 }
831 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))) {
832 data->horizontal_blank_and_chunk_granularity_factor[i] = bw_int_to_fixed(1);
833 }
834 else {
835 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))));
836 }
837 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]);
838 data->display_bandwidth[i] = bw_mul(data->request_bandwidth[i], data->bytes_per_request[i]);
839 }
840 }
841 /*outstanding chunk request limit*/
842 /*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.*/
843 /*underlay buffer sharing mode is only permitted in orthogonal rotation modes.*/
844 /**/
845 /*if there is only one display enabled, the dmif data buffer size for the graphics surface is increased by concatenating the adjacent buffers.*/
846 /**/
847 /*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*/
848 /*and underlay.*/
849 /**/
850 /*the pipe chunk size uses 2 for line interleaving, except for the write back, in which case it is 1.*/
851 /*graphics and underlay data buffer size is adjusted (limited) using the outstanding chunk request limit if there is more than one*/
852 /*display enabled or if the dmif request buffer is not large enough for the total data buffer size.*/
853 /*the outstanding chunk request limit is the ceiling of the adjusted data buffer size divided by the chunk size in bytes*/
854 /*the adjusted data buffer size is the product of the display bandwidth and the minimum effective data buffer size in terms of time,*/
855 /*rounded up to the chunk size in bytes, but should not exceed the original data buffer size*/
856 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
857 if (data->enable[i]) {
858 if ((dceip->dmif_pipe_en_fbc_chunk_tracker + 3 == i && fbc_enabled == 0 && tiling_mode[i] != bw_def_linear)) {
859 data->max_chunks_non_fbc_mode[i] = 128 - dmif_chunk_buff_margin;
860 }
861 else {
862 data->max_chunks_non_fbc_mode[i] = 16 - dmif_chunk_buff_margin;
863 }
864 }
865 if (data->fbc_en[i] == 1) {
866 max_chunks_fbc_mode = 128 - dmif_chunk_buff_margin;
867 }
868 }
869 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
870 if (data->enable[i]) {
871 switch (surface_type[i]) {
872 case bw_def_display_write_back420_luma:
873 data->data_buffer_size[i] = bw_int_to_fixed(dceip->display_write_back420_luma_mcifwr_buffer_size);
874 break;
875 case bw_def_display_write_back420_chroma:
876 data->data_buffer_size[i] = bw_int_to_fixed(dceip->display_write_back420_chroma_mcifwr_buffer_size);
877 break;
878 case bw_def_underlay420_luma:
879 data->data_buffer_size[i] = bw_int_to_fixed(dceip->underlay_luma_dmif_size);
880 break;
881 case bw_def_underlay420_chroma:
882 data->data_buffer_size[i] = bw_div(bw_int_to_fixed(dceip->underlay_chroma_dmif_size), bw_int_to_fixed(2));
883 break;
884 case bw_def_underlay422:case bw_def_underlay444:
885 if (data->orthogonal_rotation[i] == 0) {
886 data->data_buffer_size[i] = bw_int_to_fixed(dceip->underlay_luma_dmif_size);
887 }
888 else {
889 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));
890 }
891 break;
892 default:
893 if (data->fbc_en[i] == 1) {
894 /*data_buffer_size(i) = max_dmif_buffer_allocated * graphics_dmif_size*/
895 if (data->number_of_displays == 1) {
896 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)));
897 }
898 else {
899 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));
900 }
901 }
902 else {
903 /*the effective dmif buffer size in non-fbc mode is limited by the 16 entry chunk tracker*/
904 if (data->number_of_displays == 1) {
905 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)));
906 }
907 else {
908 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));
909 }
910 }
911 break;
912 }
913 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
914 data->memory_chunk_size_in_bytes[i] = bw_int_to_fixed(1024);
915 data->pipe_chunk_size_in_bytes[i] = bw_int_to_fixed(1024);
916 }
917 else {
918 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]));
919 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]));
920 }
921 }
922 }
923 data->min_dmif_size_in_time = bw_int_to_fixed(9999);
924 data->min_mcifwr_size_in_time = bw_int_to_fixed(9999);
925 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
926 if (data->enable[i]) {
927 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
928 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)) {
929 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]);
930 }
931 }
932 else {
933 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)) {
934 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]);
935 }
936 }
937 }
938 }
939 data->total_requests_for_dmif_size = bw_int_to_fixed(0);
940 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
941 if (data->enable[i] && surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
942 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]));
943 }
944 }
945 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
946 if (data->enable[i]) {
947 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))) {
948 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]));
949 }
950 else {
951 data->adjusted_data_buffer_size[i] = data->data_buffer_size[i];
952 }
953 }
954 }
955 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
956 if (data->enable[i]) {
957 if (data->number_of_displays == 1 && data->number_of_underlay_surfaces == 0) {
958 /*set maximum chunk limit if only one graphic pipe is enabled*/
959 data->outstanding_chunk_request_limit[i] = bw_int_to_fixed(127);
960 }
961 else {
962 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));
963 /*clamp maximum chunk limit in the graphic display pipe*/
964 if (i >= 4) {
965 data->outstanding_chunk_request_limit[i] = bw_max2(bw_int_to_fixed(127), data->outstanding_chunk_request_limit[i]);
966 }
967 }
968 }
969 }
970 /*outstanding pte request limit*/
971 /*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*/
972 /*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*/
973 /*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*/
974 /*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*/
975 /*if not using peak pte request to eviction limiting, the outstanding pte request limit is the pte requests in the vblank*/
976 /*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*/
977 /*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*/
978 /*the pte requests per chunk is 256 divided by the scatter-gather page width and the useful pt_es per pte request*/
979 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)))) {
980 data->peak_pte_request_to_eviction_ratio_limiting = dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display;
981 }
982 else {
983 data->peak_pte_request_to_eviction_ratio_limiting = dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation;
984 }
985 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
986 if (data->enable[i] && data->scatter_gather_enable_for_pipe[i] == 1) {
987 if (tiling_mode[i] == bw_def_linear) {
988 data->useful_pte_per_pte_request = bw_int_to_fixed(8);
989 data->scatter_gather_page_width[i] = bw_div(bw_int_to_fixed(4096), bw_int_to_fixed(data->bytes_per_pixel[i]));
990 data->scatter_gather_page_height[i] = bw_int_to_fixed(1);
991 data->scatter_gather_pte_request_rows = bw_int_to_fixed(1);
992 data->scatter_gather_row_height = bw_int_to_fixed(dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode);
993 }
994 else if (bw_equ(data->rotation_angle[i], bw_int_to_fixed(0)) || bw_equ(data->rotation_angle[i], bw_int_to_fixed(180))) {
995 data->useful_pte_per_pte_request = bw_int_to_fixed(8);
996 switch (data->bytes_per_pixel[i]) {
997 case 4:
998 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
999 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1000 break;
1001 case 2:
1002 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1003 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1004 break;
1005 default:
1006 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1007 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1008 break;
1009 }
1010 data->scatter_gather_pte_request_rows = bw_int_to_fixed(dceip->scatter_gather_pte_request_rows_in_tiling_mode);
1011 data->scatter_gather_row_height = data->scatter_gather_page_height[i];
1012 }
1013 else {
1014 data->useful_pte_per_pte_request = bw_int_to_fixed(1);
1015 switch (data->bytes_per_pixel[i]) {
1016 case 4:
1017 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
1018 data->scatter_gather_page_height[i] = bw_int_to_fixed(32);
1019 break;
1020 case 2:
1021 data->scatter_gather_page_width[i] = bw_int_to_fixed(32);
1022 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1023 break;
1024 default:
1025 data->scatter_gather_page_width[i] = bw_int_to_fixed(64);
1026 data->scatter_gather_page_height[i] = bw_int_to_fixed(64);
1027 break;
1028 }
1029 data->scatter_gather_pte_request_rows = bw_int_to_fixed(dceip->scatter_gather_pte_request_rows_in_tiling_mode);
1030 data->scatter_gather_row_height = data->scatter_gather_page_height[i];
1031 }
1032 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);
1033 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]);
1034 data->scatter_gather_pte_requests_in_vblank = bw_mul(data->scatter_gather_pte_request_rows, data->scatter_gather_pte_requests_in_row[i]);
1035 if (bw_equ(data->peak_pte_request_to_eviction_ratio_limiting, bw_int_to_fixed(0))) {
1036 data->scatter_gather_pte_request_limit[i] = data->scatter_gather_pte_requests_in_vblank;
1037 }
1038 else {
1039 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))));
1040 }
1041 }
1042 }
1043 /*pitch padding recommended for efficiency in linear mode*/
1044 /*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*/
1045 /*if that is the case it is recommended to pad the pitch by at least 256 pixels*/
1046 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));
1047
1048 /*pixel transfer time*/
1049 /*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*/
1050 /*for dmif, pte and cursor requests have to be included.*/
1051 /*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)*/
1052 /*the dram data requirement is also multiplied by the number of channels in the case of low power tiling*/
1053 /*the page close-open time is determined by trc and the number of page close-opens*/
1054 /*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.*/
1055 /*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.*/
1056 /*otherwise, the bytes page close-open is the chunk size because that is the arbitration slice.*/
1057 /*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*/
1058 /*cursor requests outstanding are limited to a group of two source lines. each group costs a page close-open time for dmif reads*/
1059 /*the display reads and writes time for data transfer is the minimum data or cursor buffer size in time minus the mc urgent latency*/
1060 /*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*/
1061 /*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.*/
1062 /*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.*/
1063 /*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.*/
1064 /*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.*/
1065 /*the source pixels for the last output pixel is the source width times the scaler vertical filter initialization value rounded up to even*/
1066 /*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.*/
1067 data->cursor_total_data = bw_int_to_fixed(0);
1068 data->cursor_total_request_groups = bw_int_to_fixed(0);
1069 data->scatter_gather_total_pte_requests = bw_int_to_fixed(0);
1070 data->scatter_gather_total_pte_request_groups = bw_int_to_fixed(0);
1071 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1072 if (data->enable[i]) {
1073 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)));
1074 if (dceip->large_cursor == 1) {
1075 data->cursor_total_request_groups = bw_add(data->cursor_total_request_groups, bw_int_to_fixed((dceip->cursor_max_outstanding_group_num + 1)));
1076 }
1077 else {
1078 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)));
1079 }
1080 if (data->scatter_gather_enable_for_pipe[i]) {
1081 data->scatter_gather_total_pte_requests = bw_add(data->scatter_gather_total_pte_requests, data->scatter_gather_pte_request_limit[i]);
1082 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)));
1083 }
1084 }
1085 }
1086 data->tile_width_in_pixels = bw_int_to_fixed(8);
1087 data->dmif_total_number_of_data_request_page_close_open = bw_int_to_fixed(0);
1088 data->mcifwr_total_number_of_data_request_page_close_open = bw_int_to_fixed(0);
1089 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1090 if (data->enable[i]) {
1091 if (data->scatter_gather_enable_for_pipe[i] == 1 && tiling_mode[i] != bw_def_linear) {
1092 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])));
1093 }
1094 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))) {
1095 data->bytes_per_page_close_open = dceip->linear_mode_line_request_alternation_slice;
1096 }
1097 else {
1098 data->bytes_per_page_close_open = data->memory_chunk_size_in_bytes[i];
1099 }
1100 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1101 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));
1102 }
1103 else {
1104 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));
1105 }
1106 }
1107 }
1108 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));
1109 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));
1110 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1111 if (data->enable[i]) {
1112 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]);
1113 }
1114 }
1115 data->total_requests_for_adjusted_dmif_size = bw_int_to_fixed(0);
1116 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1117 if (data->enable[i]) {
1118 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1119 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]));
1120 }
1121 }
1122 }
1123 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));
1124 data->total_dmifmc_urgent_latency = bw_mul(vbios->dmifmc_urgent_latency, data->total_dmifmc_urgent_trips);
1125 data->total_display_reads_required_data = bw_int_to_fixed(0);
1126 data->total_display_reads_required_dram_access_data = bw_int_to_fixed(0);
1127 data->total_display_writes_required_data = bw_int_to_fixed(0);
1128 data->total_display_writes_required_dram_access_data = bw_int_to_fixed(0);
1129 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1130 if (data->enable[i]) {
1131 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1132 data->display_reads_required_data = data->adjusted_data_buffer_size_in_memory[i];
1133 /*for hbm memories, each channel is split into 2 pseudo-channels that are each 64 bits in width. each*/
1134 /*pseudo-channel may be read independently of one another.*/
1135 /*the read burst length (bl) for hbm memories is 4, so each read command will access 32 bytes of data.*/
1136 /*the 64 or 32 byte sized data is stored in one pseudo-channel.*/
1137 /*it will take 4 memclk cycles or 8 yclk cycles to fetch 64 bytes of data from the hbm memory (2 read commands).*/
1138 /*it will take 2 memclk cycles or 4 yclk cycles to fetch 32 bytes of data from the hbm memory (1 read command).*/
1139 /*for gddr5/ddr4 memories, there is additional overhead if the size of the request is smaller than 64 bytes.*/
1140 /*the read burst length (bl) for gddr5/ddr4 memories is 8, regardless of the size of the data request.*/
1141 /*therefore it will require 8 cycles to fetch 64 or 32 bytes of data from the memory.*/
1142 /*the memory efficiency will be 50% for the 32 byte sized data.*/
1143 if (vbios->memory_type == bw_def_hbm) {
1144 data->display_reads_required_dram_access_data = data->adjusted_data_buffer_size_in_memory[i];
1145 }
1146 else {
1147 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)));
1148 }
1149 data->total_display_reads_required_data = bw_add(data->total_display_reads_required_data, data->display_reads_required_data);
1150 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);
1151 }
1152 else {
1153 data->total_display_writes_required_data = bw_add(data->total_display_writes_required_data, data->adjusted_data_buffer_size_in_memory[i]);
1154 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))));
1155 }
1156 }
1157 }
1158 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)));
1159 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)));
1160 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1161 if (data->enable[i]) {
1162 if (bw_mtn(data->v_filter_init[i], bw_int_to_fixed(4))) {
1163 data->src_pixels_for_first_output_pixel[i] = bw_mul(bw_int_to_fixed(4), data->source_width_rounded_up_to_chunks[i]);
1164 }
1165 else {
1166 if (bw_mtn(data->v_filter_init[i], bw_int_to_fixed(2))) {
1167 data->src_pixels_for_first_output_pixel[i] = bw_int_to_fixed(512);
1168 }
1169 else {
1170 data->src_pixels_for_first_output_pixel[i] = bw_int_to_fixed(0);
1171 }
1172 }
1173 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]);
1174 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])));
1175 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]);
1176 data->active_time[i] = bw_div(bw_div(data->source_width_rounded_up_to_chunks[i], data->hsr[i]), data->pixel_rate[i]);
1177 }
1178 }
1179 for (i = 0; i <= 2; i++) {
1180 for (j = 0; j <= 7; j++) {
1181 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)))));
1182 if (data->d1_display_write_back_dwb_enable == 1) {
1183 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))));
1184 }
1185 }
1186 }
1187 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1188 for (j = 0; j <= 2; j++) {
1189 for (k = 0; k <= 7; k++) {
1190 if (data->enable[i]) {
1191 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1192 /*time to transfer data from the dmif buffer to the lb. since the mc to dmif transfer time overlaps*/
1193 /*with the dmif to lb transfer time, only time to transfer the last chunk is considered.*/
1194 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)))));
1195 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]));
1196 /*during an mclk switch the requests from the dce ip are stored in the gmc/arb. these requests should be serviced immediately*/
1197 /*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*/
1198 /*per memory channel. if the dce ip is urgent after the mclk switch sequence, all pending requests and subsequent requests should be*/
1199 /*immediately serviced without a gap in the urgent requests.*/
1200 /*the latency incurred would be the time to issue the requests and return the data for the first or last output pixel.*/
1201 if (surface_type[i] == bw_def_graphics) {
1202 switch (data->lb_bpc[i]) {
1203 case 6:
1204 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency6_bit_per_component;
1205 break;
1206 case 8:
1207 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency8_bit_per_component;
1208 break;
1209 case 10:
1210 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency10_bit_per_component;
1211 break;
1212 default:
1213 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency12_bit_per_component;
1214 break;
1215 }
1216 if (data->use_alpha[i] == 1) {
1217 data->v_scaler_efficiency = bw_min2(data->v_scaler_efficiency, dceip->alpha_vscaler_efficiency);
1218 }
1219 }
1220 else {
1221 switch (data->lb_bpc[i]) {
1222 case 6:
1223 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency6_bit_per_component;
1224 break;
1225 case 8:
1226 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency8_bit_per_component;
1227 break;
1228 case 10:
1229 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency10_bit_per_component;
1230 break;
1231 default:
1232 data->v_scaler_efficiency = bw_int_to_fixed(3);
1233 break;
1234 }
1235 }
1236 if (dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1))) {
1237 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]));
1238 }
1239 else {
1240 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))));
1241 }
1242 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]))))));
1243 }
1244 else {
1245 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]));
1246 /*during an mclk switch the requests from the dce ip are stored in the gmc/arb. these requests should be serviced immediately*/
1247 /*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*/
1248 /*per memory channel. if the dce ip is urgent after the mclk switch sequence, all pending requests and subsequent requests should be*/
1249 /*immediately serviced without a gap in the urgent requests.*/
1250 /*the latency incurred would be the time to issue the requests and return the data for the first or last output pixel.*/
1251 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])))));
1252 }
1253 }
1254 }
1255 }
1256 }
1257 /*cpu c-state and p-state change enable*/
1258 /*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*/
1259 /*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*/
1260 /*condition for the blackout duration:*/
1261 /* minimum latency hiding > blackout duration + dmif burst time + line source transfer time*/
1262 /*condition for the blackout recovery:*/
1263 /* recovery time > dmif burst time + 2 * urgent latency*/
1264 /* recovery time > (display bw * blackout duration + (2 * urgent latency + dmif burst time)*dispclk - dmif size )*/
1265 /* / (dispclk - display bw)*/
1266 /*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.*/
1267 /*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*/
1268
1269 /*initialize variables*/
1270 number_of_displays_enabled = 0;
1271 number_of_displays_enabled_with_margin = 0;
1272 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1273 if (data->enable[k]) {
1274 number_of_displays_enabled = number_of_displays_enabled + 1;
1275 }
1276 data->display_pstate_change_enable[k] = 0;
1277 }
1278 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1279 if (data->enable[i]) {
1280 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)))) {
1281 if (bw_ltn(data->vsr[i], bw_int_to_fixed(2))) {
1282 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]);
1283 }
1284 else {
1285 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]);
1286 }
1287 }
1288 else {
1289 data->cursor_latency_hiding[i] = bw_int_to_fixed(9999);
1290 }
1291 }
1292 }
1293 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1294 if (data->enable[i]) {
1295 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) {
1296 if (number_of_displays_enabled > 2)
1297 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);
1298 else
1299 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);
1300 }
1301 else {
1302 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);
1303 }
1304 data->minimum_latency_hiding_with_cursor[i] = bw_min2(data->minimum_latency_hiding[i], data->cursor_latency_hiding[i]);
1305 }
1306 }
1307 for (i = 0; i <= 2; i++) {
1308 for (j = 0; j <= 7; j++) {
1309 data->blackout_duration_margin[i][j] = bw_int_to_fixed(9999);
1310 data->dispclk_required_for_blackout_duration[i][j] = bw_int_to_fixed(0);
1311 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(0);
1312 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1313 if (data->enable[k] && bw_mtn(vbios->blackout_duration, bw_int_to_fixed(0))) {
1314 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1315 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]));
1316 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]))));
1317 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]))) {
1318 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(9999);
1319 }
1320 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])))))) {
1321 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]));
1322 }
1323 }
1324 else {
1325 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]));
1326 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]))));
1327 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]))) {
1328 data->dispclk_required_for_blackout_recovery[i][j] = bw_int_to_fixed(9999);
1329 }
1330 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])))))) {
1331 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]));
1332 }
1333 }
1334 }
1335 }
1336 }
1337 }
1338 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)) {
1339 data->cpup_state_change_enable = bw_def_yes;
1340 if (bw_ltn(data->dispclk_required_for_blackout_recovery[high][s_high], vbios->high_voltage_max_dispclk)) {
1341 data->cpuc_state_change_enable = bw_def_yes;
1342 }
1343 else {
1344 data->cpuc_state_change_enable = bw_def_no;
1345 }
1346 }
1347 else {
1348 data->cpup_state_change_enable = bw_def_no;
1349 data->cpuc_state_change_enable = bw_def_no;
1350 }
1351 /*nb p-state change enable*/
1352 /*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*/
1353 /*below the maximum.*/
1354 /*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,*/
1355 /*minus the dmif burst time, minus the source line transfer time*/
1356 /*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*/
1357 /*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*/
1358 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1359 if (data->enable[i]) {
1360 if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1) {
1361 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));
1362 }
1363 else {
1364 /*maximum_latency_hiding(i) = minimum_latency_hiding(i) + 1 / vsr(i) * h_total(i) / pixel_rate(i) + 0.5 * total_dmifmc_urgent_latency*/
1365 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));
1366 }
1367 data->maximum_latency_hiding_with_cursor[i] = bw_min2(data->maximum_latency_hiding[i], data->cursor_latency_hiding[i]);
1368 }
1369 }
1370 for (i = 0; i <= 2; i++) {
1371 for (j = 0; j <= 7; j++) {
1372 data->min_dram_speed_change_margin[i][j] = bw_int_to_fixed(9999);
1373 data->dram_speed_change_margin = bw_int_to_fixed(9999);
1374 data->dispclk_required_for_dram_speed_change[i][j] = bw_int_to_fixed(0);
1375 data->num_displays_with_margin[i][j] = 0;
1376 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1377 if (data->enable[k]) {
1378 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1379 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]);
1380 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)))) {
1381 /*determine the minimum dram clock change margin for each set of clock frequencies*/
1382 data->min_dram_speed_change_margin[i][j] = bw_min2(data->min_dram_speed_change_margin[i][j], data->dram_speed_change_margin);
1383 /*compute the maximum clock frequuency required for the dram clock change at each set of clock frequencies*/
1384 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]))));
1385 if ((bw_ltn(data->dispclk_required_for_dram_speed_change_pipe[i][j], vbios->high_voltage_max_dispclk))) {
1386 data->display_pstate_change_enable[k] = 1;
1387 data->num_displays_with_margin[i][j] = data->num_displays_with_margin[i][j] + 1;
1388 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]);
1389 }
1390 }
1391 }
1392 else {
1393 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]);
1394 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)))) {
1395 /*determine the minimum dram clock change margin for each display pipe*/
1396 data->min_dram_speed_change_margin[i][j] = bw_min2(data->min_dram_speed_change_margin[i][j], data->dram_speed_change_margin);
1397 /*compute the maximum clock frequuency required for the dram clock change at each set of clock frequencies*/
1398 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]))));
1399 if ((bw_ltn(data->dispclk_required_for_dram_speed_change_pipe[i][j], vbios->high_voltage_max_dispclk))) {
1400 data->display_pstate_change_enable[k] = 1;
1401 data->num_displays_with_margin[i][j] = data->num_displays_with_margin[i][j] + 1;
1402 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]);
1403 }
1404 }
1405 }
1406 }
1407 }
1408 }
1409 }
1410 /*determine the number of displays with margin to switch in the v_active region*/
1411 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1412 if (data->enable[k] == 1 && data->display_pstate_change_enable[k] == 1) {
1413 number_of_displays_enabled_with_margin = number_of_displays_enabled_with_margin + 1;
1414 }
1415 }
1416 /*determine the number of displays that don't have any dram clock change margin, but*/
1417 /*have the same resolution. these displays can switch in a common vblank region if*/
1418 /*their frames are aligned.*/
1419 data->min_vblank_dram_speed_change_margin = bw_int_to_fixed(9999);
1420 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1421 if (data->enable[k]) {
1422 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1423 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]);
1424 data->min_vblank_dram_speed_change_margin = bw_min2(data->min_vblank_dram_speed_change_margin, data->v_blank_dram_speed_change_margin[k]);
1425 }
1426 else {
1427 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]);
1428 data->min_vblank_dram_speed_change_margin = bw_min2(data->min_vblank_dram_speed_change_margin, data->v_blank_dram_speed_change_margin[k]);
1429 }
1430 }
1431 }
1432 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1433 data->displays_with_same_mode[i] = bw_int_to_fixed(0);
1434 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))) {
1435 for (j = 0; j <= maximum_number_of_surfaces - 1; j++) {
1436 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]))) {
1437 data->displays_with_same_mode[i] = bw_add(data->displays_with_same_mode[i], bw_int_to_fixed(1));
1438 }
1439 }
1440 }
1441 }
1442 /*compute the maximum number of aligned displays with no margin*/
1443 number_of_aligned_displays_with_no_margin = 0;
1444 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1445 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]));
1446 }
1447 /*dram clock change is possible, if all displays have positive margin except for one display or a group of*/
1448 /*aligned displays with the same timing.*/
1449 /*the display(s) with the negative margin can be switched in the v_blank region while the other*/
1450 /*displays are in v_blank or v_active.*/
1451 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)) {
1452 data->nbp_state_change_enable = bw_def_yes;
1453 }
1454 else {
1455 data->nbp_state_change_enable = bw_def_no;
1456 }
1457 /*dram clock change is possible only in vblank if all displays are aligned and have no margin*/
1458 if (number_of_aligned_displays_with_no_margin == number_of_displays_enabled) {
1459 nbp_state_change_enable_blank = bw_def_yes;
1460 }
1461 else {
1462 nbp_state_change_enable_blank = bw_def_no;
1463 }
1464
1465 /*average bandwidth*/
1466 /*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.*/
1467 /*the average bandwidth with compression is the same, divided by the compression ratio*/
1468 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1469 if (data->enable[i]) {
1470 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]);
1471 data->average_bandwidth[i] = bw_div(data->average_bandwidth_no_compression[i], data->compression_rate[i]);
1472 }
1473 }
1474 data->total_average_bandwidth_no_compression = bw_int_to_fixed(0);
1475 data->total_average_bandwidth = bw_int_to_fixed(0);
1476 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1477 if (data->enable[i]) {
1478 data->total_average_bandwidth_no_compression = bw_add(data->total_average_bandwidth_no_compression, data->average_bandwidth_no_compression[i]);
1479 data->total_average_bandwidth = bw_add(data->total_average_bandwidth, data->average_bandwidth[i]);
1480 }
1481 }
1482
1483 /*required yclk(pclk)*/
1484 /*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*/
1485 /*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*/
1486 /*high yclk(pclk) has to be selected when dram speed/p-state change is not possible.*/
1487 data->min_cursor_memory_interface_buffer_size_in_time = bw_int_to_fixed(9999);
1488 /* number of cursor lines stored in the cursor data return buffer*/
1489 num_cursor_lines = 0;
1490 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1491 if (data->enable[i]) {
1492 if (bw_mtn(data->cursor_width_pixels[i], bw_int_to_fixed(0))) {
1493 /*compute number of cursor lines stored in data return buffer*/
1494 if (bw_leq(data->cursor_width_pixels[i], bw_int_to_fixed(64)) && dceip->large_cursor == 1) {
1495 num_cursor_lines = 4;
1496 }
1497 else {
1498 num_cursor_lines = 2;
1499 }
1500 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]));
1501 }
1502 }
1503 }
1504 /*compute minimum time to read one chunk from the dmif buffer*/
1505 if (number_of_displays_enabled > 2) {
1506 data->chunk_request_delay = 0;
1507 }
1508 else {
1509 data->chunk_request_delay = bw_fixed_to_int(bw_div(bw_int_to_fixed(512), vbios->high_voltage_max_dispclk));
1510 }
1511 data->min_read_buffer_size_in_time = bw_min2(data->min_cursor_memory_interface_buffer_size_in_time, data->min_dmif_size_in_time);
1512 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));
1513 data->display_writes_time_for_data_transfer = bw_sub(data->min_mcifwr_size_in_time, vbios->mcifwrmc_urgent_latency);
1514 data->dmif_required_dram_bandwidth = bw_div(data->total_display_reads_required_dram_access_data, data->display_reads_time_for_data_transfer);
1515 data->mcifwr_required_dram_bandwidth = bw_div(data->total_display_writes_required_dram_access_data, data->display_writes_time_for_data_transfer);
1516 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);
1517 data->required_mcifmcwr_urgent_latency = bw_sub(data->min_mcifwr_size_in_time, data->mcifwr_total_page_close_open_time);
1518 if (bw_mtn(data->scatter_gather_total_pte_requests, dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
1519 data->required_dram_bandwidth_gbyte_per_second = bw_int_to_fixed(9999);
1520 yclk_message = bw_def_exceeded_allowed_outstanding_pte_req_queue_size;
1521 data->y_clk_level = high;
1522 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));
1523 }
1524 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)) {
1525 data->required_dram_bandwidth_gbyte_per_second = bw_int_to_fixed(9999);
1526 yclk_message = bw_def_exceeded_allowed_page_close_open;
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));
1529 }
1530 else {
1531 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));
1532 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)))
1533 && 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))) {
1534 yclk_message = bw_fixed_to_int(vbios->low_yclk);
1535 data->y_clk_level = low;
1536 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));
1537 }
1538 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)))
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[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))) {
1540 yclk_message = bw_fixed_to_int(vbios->mid_yclk);
1541 data->y_clk_level = mid;
1542 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));
1543 }
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[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)))
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[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)))) {
1546 yclk_message = bw_fixed_to_int(vbios->high_yclk);
1547 data->y_clk_level = high;
1548 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));
1549 }
1550 else {
1551 yclk_message = bw_def_exceeded_allowed_maximum_bw;
1552 data->y_clk_level = high;
1553 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));
1554 }
1555 }
1556 /*required sclk*/
1557 /*sclk requirement only makes sense if the total pte requests fit in the scatter-gather saw queque size*/
1558 /*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.*/
1559 /*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*/
1560 /*for dmif, pte and cursor requests have to be included.*/
1561 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))));
1562 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);
1563 if (bw_mtn(data->scatter_gather_total_pte_requests, dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
1564 data->required_sclk = bw_int_to_fixed(9999);
1565 sclk_message = bw_def_exceeded_allowed_outstanding_pte_req_queue_size;
1566 data->sclk_level = s_high;
1567 }
1568 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)) {
1569 data->required_sclk = bw_int_to_fixed(9999);
1570 sclk_message = bw_def_exceeded_allowed_page_close_open;
1571 data->sclk_level = s_high;
1572 }
1573 else {
1574 data->required_sclk = bw_max2(data->dmif_required_sclk, data->mcifwr_required_sclk);
1575 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))
1576 && 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))) {
1577 sclk_message = bw_def_low;
1578 data->sclk_level = s_low;
1579 data->required_sclk = vbios->low_sclk;
1580 }
1581 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))
1582 && 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))) {
1583 sclk_message = bw_def_mid;
1584 data->sclk_level = s_mid1;
1585 data->required_sclk = vbios->mid1_sclk;
1586 }
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[s_mid2]),vbios->data_return_bus_width))
1588 && 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))) {
1589 sclk_message = bw_def_mid;
1590 data->sclk_level = s_mid2;
1591 data->required_sclk = vbios->mid2_sclk;
1592 }
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_mid3]),vbios->data_return_bus_width))
1594 && 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))) {
1595 sclk_message = bw_def_mid;
1596 data->sclk_level = s_mid3;
1597 data->required_sclk = vbios->mid3_sclk;
1598 }
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_mid4]),vbios->data_return_bus_width))
1600 && 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))) {
1601 sclk_message = bw_def_mid;
1602 data->sclk_level = s_mid4;
1603 data->required_sclk = vbios->mid4_sclk;
1604 }
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_mid5]),vbios->data_return_bus_width))
1606 && 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))) {
1607 sclk_message = bw_def_mid;
1608 data->sclk_level = s_mid5;
1609 data->required_sclk = vbios->mid5_sclk;
1610 }
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_mid6]),vbios->data_return_bus_width))
1612 && 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))) {
1613 sclk_message = bw_def_mid;
1614 data->sclk_level = s_mid6;
1615 data->required_sclk = vbios->mid6_sclk;
1616 }
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_high]),vbios->data_return_bus_width))
1618 && bw_ltn(data->required_sclk, sclk[s_high])) {
1619 sclk_message = bw_def_high;
1620 data->sclk_level = s_high;
1621 data->required_sclk = vbios->high_sclk;
1622 }
1623 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))
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;
1628 }
1629 else {
1630 sclk_message = bw_def_exceeded_allowed_maximum_sclk;
1631 data->sclk_level = s_high;
1632 /*required_sclk = high_sclk*/
1633 }
1634 }
1635 /*dispclk*/
1636 /*if dispclk is set to the maximum, ramping is not required. dispclk required without ramping is less than the dispclk required with ramping.*/
1637 /*if dispclk required without ramping is more than the maximum dispclk, that is the dispclk required, and the mode is not supported*/
1638 /*if that does not happen, but dispclk required with ramping is more than the maximum dispclk, dispclk required is just the maximum dispclk*/
1639 /*if that does not happen either, dispclk required is the dispclk required with ramping.*/
1640 /*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.*/
1641 /*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.*/
1642 /*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.*/
1643 /*the dispclk required for scaler throughput is the product of the pixel rate and the scaling limits factor.*/
1644 /*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.*/
1645 /*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.*/
1646 /*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.*/
1647 /*the scaling limits factor itself it also clamped to at least 1*/
1648 /*if doing downscaling with the pre-downscaler enabled, the horizontal scale ratio should not be considered above (use "1")*/
1649 data->downspread_factor = bw_add(bw_int_to_fixed(1), bw_div(vbios->down_spread_percentage, bw_int_to_fixed(100)));
1650 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1651 if (data->enable[i]) {
1652 if (surface_type[i] == bw_def_graphics) {
1653 switch (data->lb_bpc[i]) {
1654 case 6:
1655 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency6_bit_per_component;
1656 break;
1657 case 8:
1658 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency8_bit_per_component;
1659 break;
1660 case 10:
1661 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency10_bit_per_component;
1662 break;
1663 default:
1664 data->v_scaler_efficiency = dceip->graphics_vscaler_efficiency12_bit_per_component;
1665 break;
1666 }
1667 if (data->use_alpha[i] == 1) {
1668 data->v_scaler_efficiency = bw_min2(data->v_scaler_efficiency, dceip->alpha_vscaler_efficiency);
1669 }
1670 }
1671 else {
1672 switch (data->lb_bpc[i]) {
1673 case 6:
1674 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency6_bit_per_component;
1675 break;
1676 case 8:
1677 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency8_bit_per_component;
1678 break;
1679 case 10:
1680 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency10_bit_per_component;
1681 break;
1682 default:
1683 data->v_scaler_efficiency = dceip->underlay_vscaler_efficiency12_bit_per_component;
1684 break;
1685 }
1686 }
1687 if (dceip->pre_downscaler_enabled && bw_mtn(data->hsr[i], bw_int_to_fixed(1))) {
1688 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]));
1689 }
1690 else {
1691 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))));
1692 }
1693 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);
1694 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)));
1695 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));
1696 }
1697 }
1698 data->total_dispclk_required_with_ramping = bw_int_to_fixed(0);
1699 data->total_dispclk_required_without_ramping = bw_int_to_fixed(0);
1700 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1701 if (data->enable[i]) {
1702 if (bw_ltn(data->total_dispclk_required_with_ramping, data->dispclk_required_with_ramping[i])) {
1703 data->total_dispclk_required_with_ramping = data->dispclk_required_with_ramping[i];
1704 }
1705 if (bw_ltn(data->total_dispclk_required_without_ramping, data->dispclk_required_without_ramping[i])) {
1706 data->total_dispclk_required_without_ramping = data->dispclk_required_without_ramping[i];
1707 }
1708 }
1709 }
1710 data->total_read_request_bandwidth = bw_int_to_fixed(0);
1711 data->total_write_request_bandwidth = bw_int_to_fixed(0);
1712 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1713 if (data->enable[i]) {
1714 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1715 data->total_read_request_bandwidth = bw_add(data->total_read_request_bandwidth, data->request_bandwidth[i]);
1716 }
1717 else {
1718 data->total_write_request_bandwidth = bw_add(data->total_write_request_bandwidth, data->request_bandwidth[i]);
1719 }
1720 }
1721 }
1722 data->dispclk_required_for_total_read_request_bandwidth = bw_div(bw_mul(data->total_read_request_bandwidth, dceip->dispclk_per_request), dceip->request_efficiency);
1723 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);
1724 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);
1725 if (data->cpuc_state_change_enable == bw_def_yes) {
1726 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]);
1727 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]);
1728 }
1729 if (data->cpup_state_change_enable == bw_def_yes) {
1730 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]);
1731 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]);
1732 }
1733 if (data->nbp_state_change_enable == bw_def_yes && data->increase_voltage_to_support_mclk_switch) {
1734 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]);
1735 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]);
1736 }
1737 if (bw_ltn(data->total_dispclk_required_with_ramping_with_request_bandwidth, vbios->high_voltage_max_dispclk)) {
1738 data->dispclk = data->total_dispclk_required_with_ramping_with_request_bandwidth;
1739 }
1740 else if (bw_ltn(data->total_dispclk_required_without_ramping_with_request_bandwidth, vbios->high_voltage_max_dispclk)) {
1741 data->dispclk = vbios->high_voltage_max_dispclk;
1742 }
1743 else {
1744 data->dispclk = data->total_dispclk_required_without_ramping_with_request_bandwidth;
1745 }
1746 /* required core voltage*/
1747 /* the core voltage required is low if sclk, yclk(pclk)and dispclk are within the low limits*/
1748 /* otherwise, the core voltage required is medium if yclk (pclk) is within the low limit and sclk and dispclk are within the medium limit*/
1749 /* otherwise, the core voltage required is high if the three clocks are within the high limits*/
1750 /* otherwise, or if the mode is not supported, core voltage requirement is not applicable*/
1751 if (pipe_check == bw_def_notok) {
1752 voltage = bw_def_na;
1753 }
1754 else if (mode_check == bw_def_notok) {
1755 voltage = bw_def_notok;
1756 }
1757 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)) {
1758 voltage = bw_def_0_72;
1759 }
1760 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)) {
1761 voltage = bw_def_0_8;
1762 }
1763 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)) {
1764 if ((data->nbp_state_change_enable == bw_def_no && nbp_state_change_enable_blank == bw_def_no)) {
1765 voltage = bw_def_high_no_nbp_state_change;
1766 }
1767 else {
1768 voltage = bw_def_0_9;
1769 }
1770 }
1771 else {
1772 voltage = bw_def_notok;
1773 }
1774 if (voltage == bw_def_0_72) {
1775 data->max_phyclk = vbios->low_voltage_max_phyclk;
1776 }
1777 else if (voltage == bw_def_0_8) {
1778 data->max_phyclk = vbios->mid_voltage_max_phyclk;
1779 }
1780 else {
1781 data->max_phyclk = vbios->high_voltage_max_phyclk;
1782 }
1783 /*required blackout recovery time*/
1784 data->blackout_recovery_time = bw_int_to_fixed(0);
1785 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
1786 if (data->enable[k] && bw_mtn(vbios->blackout_duration, bw_int_to_fixed(0)) && data->cpup_state_change_enable == bw_def_yes) {
1787 if (surface_type[k] != bw_def_display_write_back420_luma && surface_type[k] != bw_def_display_write_back420_chroma) {
1788 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]));
1789 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])))))) {
1790 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])))));
1791 }
1792 }
1793 else {
1794 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]));
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), vbios->mcifwrmc_urgent_latency), data->mcifwr_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_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])))));
1797 }
1798 }
1799 }
1800 }
1801 /*sclk deep sleep*/
1802 /*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.*/
1803 /*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,*/
1804 /*and 16 bytes/bytes_per_pixel for the orthogonal rotation underlay.*/
1805 /*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)*/
1806 /*in orthogonal mode (underlay pipe), the data read from the dmifv buffer is fixed at 16 bytes.*/
1807 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1808 if (data->enable[i]) {
1809 if (surface_type[i] == bw_def_display_write_back420_luma || surface_type[i] == bw_def_display_write_back420_chroma) {
1810 data->pixels_per_data_fifo_entry[i] = bw_int_to_fixed(16);
1811 }
1812 else if (surface_type[i] == bw_def_graphics) {
1813 data->pixels_per_data_fifo_entry[i] = bw_div(bw_int_to_fixed(64), bw_int_to_fixed(data->bytes_per_pixel[i]));
1814 }
1815 else if (data->orthogonal_rotation[i] == 0) {
1816 data->pixels_per_data_fifo_entry[i] = bw_int_to_fixed(16);
1817 }
1818 else {
1819 data->pixels_per_data_fifo_entry[i] = bw_div(bw_int_to_fixed(16), bw_int_to_fixed(data->bytes_per_pixel[i]));
1820 }
1821 }
1822 }
1823 data->min_pixels_per_data_fifo_entry = bw_int_to_fixed(9999);
1824 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1825 if (data->enable[i]) {
1826 if (bw_mtn(data->min_pixels_per_data_fifo_entry, data->pixels_per_data_fifo_entry[i])) {
1827 data->min_pixels_per_data_fifo_entry = data->pixels_per_data_fifo_entry[i];
1828 }
1829 }
1830 }
1831 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);
1832 /*urgent, stutter and nb-p_state watermark*/
1833 /*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.*/
1834 /*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.*/
1835 /*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.*/
1836 /*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.*/
1837 /*blackout_duration is added to the urgent watermark*/
1838 data->chunk_request_time = bw_int_to_fixed(0);
1839 data->cursor_request_time = bw_int_to_fixed(0);
1840 /*compute total time to request one chunk from each active display pipe*/
1841 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1842 if (data->enable[i]) {
1843 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))))));
1844 }
1845 }
1846 /*compute total time to request cursor data*/
1847 data->cursor_request_time = (bw_div(data->cursor_total_data, (bw_mul(bw_int_to_fixed(32), sclk[data->sclk_level]))));
1848 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1849 if (data->enable[i]) {
1850 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]));
1851 if (surface_type[i] != bw_def_display_write_back420_luma && surface_type[i] != bw_def_display_write_back420_chroma) {
1852 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);
1853 data->stutter_exit_watermark[i] = bw_add(bw_sub(vbios->stutter_self_refresh_exit_latency, data->total_dmifmc_urgent_latency), data->urgent_watermark[i]);
1854 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]);
1855 /*unconditionally remove black out time from the nb p_state watermark*/
1856 if (data->display_pstate_change_enable[i] == 1) {
1857 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]));
1858 }
1859 else {
1860 /*maximize the watermark to force the switch in the vb_lank region of the frame*/
1861 data->nbp_state_change_watermark[i] = bw_int_to_fixed(131000);
1862 }
1863 }
1864 else {
1865 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);
1866 data->stutter_exit_watermark[i] = bw_int_to_fixed(0);
1867 data->stutter_entry_watermark[i] = bw_int_to_fixed(0);
1868 if (data->display_pstate_change_enable[i] == 1) {
1869 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]));
1870 }
1871 else {
1872 /*maximize the watermark to force the switch in the vb_lank region of the frame*/
1873 data->nbp_state_change_watermark[i] = bw_int_to_fixed(131000);
1874 }
1875 }
1876 }
1877 }
1878 /*stutter mode enable*/
1879 /*in the multi-display case the stutter exit or entry watermark cannot exceed the minimum latency hiding capabilities of the*/
1880 /*display pipe.*/
1881 data->stutter_mode_enable = data->cpuc_state_change_enable;
1882 if (data->number_of_displays > 1) {
1883 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1884 if (data->enable[i]) {
1885 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]))) {
1886 data->stutter_mode_enable = bw_def_no;
1887 }
1888 }
1889 }
1890 }
1891 /*performance metrics*/
1892 /* display read access efficiency (%)*/
1893 /* display write back access efficiency (%)*/
1894 /* stutter efficiency (%)*/
1895 /* extra underlay pitch recommended for efficiency (pixels)*/
1896 /* immediate flip time (us)*/
1897 /* latency for other clients due to urgent display read (us)*/
1898 /* latency for other clients due to urgent display write (us)*/
1899 /* average bandwidth consumed by display (no compression) (gb/s)*/
1900 /* required dram bandwidth (gb/s)*/
1901 /* required sclk (m_hz)*/
1902 /* required rd urgent latency (us)*/
1903 /* nb p-state change margin (us)*/
1904 /*dmif and mcifwr dram access efficiency*/
1905 /*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*/
1906 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));
1907 if (bw_mtn(data->total_display_writes_required_dram_access_data, bw_int_to_fixed(0))) {
1908 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));
1909 }
1910 else {
1911 data->mcifwrdram_access_efficiency = bw_int_to_fixed(0);
1912 }
1913 /*stutter efficiency*/
1914 /*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.*/
1915 /*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*/
1916 /*the frame-average time in self-refresh is the stutter cycle minus the self refresh exit latency and the burst time*/
1917 /*the stutter cycle is the dmif buffer size reduced by the excess of the stutter exit watermark over the lb size in time.*/
1918 /*the burst time is the data needed during the stutter cycle divided by the available bandwidth*/
1919 /*compute the time read all the data from the dmif buffer to the lb (dram refresh period)*/
1920 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1921 if (data->enable[i]) {
1922 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]))));
1923 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]);
1924 }
1925 }
1926 data->min_stutter_refresh_duration = bw_int_to_fixed(9999);
1927 data->total_stutter_dmif_buffer_size = 0;
1928 data->total_bytes_requested = 0;
1929 data->min_stutter_dmif_buffer_size = 9999;
1930 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1931 if (data->enable[i]) {
1932 if (bw_mtn(data->min_stutter_refresh_duration, data->stutter_refresh_duration[i])) {
1933 data->min_stutter_refresh_duration = data->stutter_refresh_duration[i];
1934 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])))));
1935 data->min_stutter_dmif_buffer_size = bw_fixed_to_int(data->stutter_dmif_buffer_size[i]);
1936 }
1937 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)));
1938 }
1939 }
1940 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));
1941 data->num_stutter_bursts = data->total_bytes_requested / data->min_stutter_dmif_buffer_size;
1942 data->total_stutter_cycle_duration = bw_add(bw_add(data->min_stutter_refresh_duration, vbios->stutter_self_refresh_exit_latency), data->stutter_burst_time);
1943 data->time_in_self_refresh = data->min_stutter_refresh_duration;
1944 if (data->d1_display_write_back_dwb_enable == 1) {
1945 data->stutter_efficiency = bw_int_to_fixed(0);
1946 }
1947 else if (bw_ltn(data->time_in_self_refresh, bw_int_to_fixed(0))) {
1948 data->stutter_efficiency = bw_int_to_fixed(0);
1949 }
1950 else {
1951 /*compute stutter efficiency assuming 60 hz refresh rate*/
1952 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)));
1953 }
1954 /*immediate flip time*/
1955 /*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.*/
1956 /*otherwise, it may take just one urgenr memory trip*/
1957 data->worst_number_of_trips_to_memory = bw_int_to_fixed(1);
1958 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1959 if (data->enable[i] && data->scatter_gather_enable_for_pipe[i] == 1) {
1960 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));
1961 if (bw_ltn(data->worst_number_of_trips_to_memory, data->number_of_trips_to_memory_for_getting_apte_row[i])) {
1962 data->worst_number_of_trips_to_memory = data->number_of_trips_to_memory_for_getting_apte_row[i];
1963 }
1964 }
1965 }
1966 data->immediate_flip_time = bw_mul(data->worst_number_of_trips_to_memory, data->total_dmifmc_urgent_latency);
1967 /*worst latency for other clients*/
1968 /*it is the urgent latency plus the urgent burst time*/
1969 data->latency_for_non_dmif_clients = bw_add(data->total_dmifmc_urgent_latency, data->dmif_burst_time[data->y_clk_level][data->sclk_level]);
1970 if (data->d1_display_write_back_dwb_enable == 1) {
1971 data->latency_for_non_mcifwr_clients = bw_add(vbios->mcifwrmc_urgent_latency, dceip->mcifwr_all_surfaces_burst_time);
1972 }
1973 else {
1974 data->latency_for_non_mcifwr_clients = bw_int_to_fixed(0);
1975 }
1976 /*dmif mc urgent latency suppported in high sclk and yclk*/
1977 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);
1978 /*dram speed/p-state change margin*/
1979 /*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*/
1980 data->v_blank_nbp_state_dram_speed_change_latency_supported = bw_int_to_fixed(99999);
1981 data->nbp_state_dram_speed_change_latency_supported = bw_int_to_fixed(99999);
1982 for (i = 0; i <= maximum_number_of_surfaces - 1; i++) {
1983 if (data->enable[i]) {
1984 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));
1985 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));
1986 }
1987 }
1988 /*sclk required vs urgent latency*/
1989 for (i = 1; i <= 5; i++) {
1990 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)));
1991 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))) {
1992 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))));
1993 }
1994 else {
1995 data->dmif_required_sclk_for_urgent_latency[i] = bw_int_to_fixed(bw_def_na);
1996 }
1997 }
1998 /*output link bit per pixel supported*/
1999 for (k = 0; k <= maximum_number_of_surfaces - 1; k++) {
2000 data->output_bpphdmi[k] = bw_def_na;
2001 data->output_bppdp4_lane_hbr[k] = bw_def_na;
2002 data->output_bppdp4_lane_hbr2[k] = bw_def_na;
2003 data->output_bppdp4_lane_hbr3[k] = bw_def_na;
2004 if (data->enable[k]) {
2005 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)));
2006 if (bw_meq(data->max_phyclk, bw_int_to_fixed(270))) {
2007 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)));
2008 }
2009 if (bw_meq(data->max_phyclk, bw_int_to_fixed(540))) {
2010 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)));
2011 }
2012 if (bw_meq(data->max_phyclk, bw_int_to_fixed(810))) {
2013 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)));
2014 }
2015 }
2016 }
2017}
2018
2019/*******************************************************************************
2020 * Public functions
2021 ******************************************************************************/
2022void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
2023 struct bw_calcs_vbios *bw_vbios,
2024 struct hw_asic_id asic_id)
2025{
2026 struct bw_calcs_dceip dceip = { 0 };
2027 struct bw_calcs_vbios vbios = { 0 };
2028
2029 enum bw_calcs_version version = bw_calcs_version_from_asic_id(asic_id);
2030
2031 dceip.version = version;
2032
2033 switch (version) {
2034 case BW_CALCS_VERSION_CARRIZO:
2035 vbios.memory_type = bw_def_gddr5;
2036 vbios.dram_channel_width_in_bits = 64;
2037 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2038 vbios.number_of_dram_banks = 8;
2039 vbios.high_yclk = bw_int_to_fixed(1600);
2040 vbios.mid_yclk = bw_int_to_fixed(1600);
2041 vbios.low_yclk = bw_frc_to_fixed(66666, 100);
2042 vbios.low_sclk = bw_int_to_fixed(200);
2043 vbios.mid1_sclk = bw_int_to_fixed(300);
2044 vbios.mid2_sclk = bw_int_to_fixed(300);
2045 vbios.mid3_sclk = bw_int_to_fixed(300);
2046 vbios.mid4_sclk = bw_int_to_fixed(300);
2047 vbios.mid5_sclk = bw_int_to_fixed(300);
2048 vbios.mid6_sclk = bw_int_to_fixed(300);
2049 vbios.high_sclk = bw_frc_to_fixed(62609, 100);
2050 vbios.low_voltage_max_dispclk = bw_int_to_fixed(352);
2051 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467);
2052 vbios.high_voltage_max_dispclk = bw_int_to_fixed(643);
2053 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2054 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2055 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2056 vbios.data_return_bus_width = bw_int_to_fixed(32);
2057 vbios.trc = bw_int_to_fixed(50);
2058 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2059 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(153, 10);
2060 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2061 vbios.nbp_state_change_latency = bw_frc_to_fixed(19649, 1000);
2062 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2063 vbios.scatter_gather_enable = true;
2064 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2065 vbios.cursor_width = 32;
2066 vbios.average_compression_rate = 4;
2067 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2068 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2069 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2070
2071 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2072 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2073 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2074 dceip.large_cursor = false;
2075 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2076 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2077 dceip.cursor_max_outstanding_group_num = 1;
2078 dceip.lines_interleaved_into_lb = 2;
2079 dceip.chunk_width = 256;
2080 dceip.number_of_graphics_pipes = 3;
2081 dceip.number_of_underlay_pipes = 1;
2082 dceip.low_power_tiling_mode = 0;
2083 dceip.display_write_back_supported = false;
2084 dceip.argb_compression_support = false;
2085 dceip.underlay_vscaler_efficiency6_bit_per_component =
2086 bw_frc_to_fixed(35556, 10000);
2087 dceip.underlay_vscaler_efficiency8_bit_per_component =
2088 bw_frc_to_fixed(34286, 10000);
2089 dceip.underlay_vscaler_efficiency10_bit_per_component =
2090 bw_frc_to_fixed(32, 10);
2091 dceip.underlay_vscaler_efficiency12_bit_per_component =
2092 bw_int_to_fixed(3);
2093 dceip.graphics_vscaler_efficiency6_bit_per_component =
2094 bw_frc_to_fixed(35, 10);
2095 dceip.graphics_vscaler_efficiency8_bit_per_component =
2096 bw_frc_to_fixed(34286, 10000);
2097 dceip.graphics_vscaler_efficiency10_bit_per_component =
2098 bw_frc_to_fixed(32, 10);
2099 dceip.graphics_vscaler_efficiency12_bit_per_component =
2100 bw_int_to_fixed(3);
2101 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2102 dceip.max_dmif_buffer_allocated = 2;
2103 dceip.graphics_dmif_size = 12288;
2104 dceip.underlay_luma_dmif_size = 19456;
2105 dceip.underlay_chroma_dmif_size = 23552;
2106 dceip.pre_downscaler_enabled = true;
2107 dceip.underlay_downscale_prefetch_enabled = true;
2108 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2109 dceip.lb_size_per_component444 = bw_int_to_fixed(82176);
2110 dceip.graphics_lb_nodownscaling_multi_line_prefetching = false;
2111 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2112 bw_int_to_fixed(0);
2113 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2114 82176);
2115 dceip.underlay420_chroma_lb_size_per_component =
2116 bw_int_to_fixed(164352);
2117 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2118 82176);
2119 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2120 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2121 dceip.underlay_maximum_width_efficient_for_tiling =
2122 bw_int_to_fixed(1920);
2123 dceip.underlay_maximum_height_efficient_for_tiling =
2124 bw_int_to_fixed(1080);
2125 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2126 bw_frc_to_fixed(3, 10);
2127 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2128 bw_int_to_fixed(25);
2129 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2130 2);
2131 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2132 bw_int_to_fixed(128);
2133 dceip.limit_excessive_outstanding_dmif_requests = true;
2134 dceip.linear_mode_line_request_alternation_slice =
2135 bw_int_to_fixed(64);
2136 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2137 32;
2138 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2139 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2140 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2141 dceip.dispclk_per_request = bw_int_to_fixed(2);
2142 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2143 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2144 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2145 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/
2146 break;
2147 case BW_CALCS_VERSION_POLARIS10:
2148 vbios.memory_type = bw_def_gddr5;
2149 vbios.dram_channel_width_in_bits = 32;
2150 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2151 vbios.number_of_dram_banks = 8;
2152 vbios.high_yclk = bw_int_to_fixed(6000);
2153 vbios.mid_yclk = bw_int_to_fixed(3200);
2154 vbios.low_yclk = bw_int_to_fixed(1000);
2155 vbios.low_sclk = bw_int_to_fixed(300);
2156 vbios.mid1_sclk = bw_int_to_fixed(400);
2157 vbios.mid2_sclk = bw_int_to_fixed(500);
2158 vbios.mid3_sclk = bw_int_to_fixed(600);
2159 vbios.mid4_sclk = bw_int_to_fixed(700);
2160 vbios.mid5_sclk = bw_int_to_fixed(800);
2161 vbios.mid6_sclk = bw_int_to_fixed(974);
2162 vbios.high_sclk = bw_int_to_fixed(1154);
2163 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2164 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2165 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2166 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2167 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2168 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2169 vbios.data_return_bus_width = bw_int_to_fixed(32);
2170 vbios.trc = bw_int_to_fixed(48);
2171 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2172 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2173 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2174 vbios.nbp_state_change_latency = bw_int_to_fixed(45);
2175 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2176 vbios.scatter_gather_enable = true;
2177 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2178 vbios.cursor_width = 32;
2179 vbios.average_compression_rate = 4;
2180 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2181 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2182 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2183
2184 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2185 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2186 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2187 dceip.large_cursor = false;
2188 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2189 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2190 dceip.cursor_max_outstanding_group_num = 1;
2191 dceip.lines_interleaved_into_lb = 2;
2192 dceip.chunk_width = 256;
2193 dceip.number_of_graphics_pipes = 6;
2194 dceip.number_of_underlay_pipes = 0;
2195 dceip.low_power_tiling_mode = 0;
2196 dceip.display_write_back_supported = false;
2197 dceip.argb_compression_support = true;
2198 dceip.underlay_vscaler_efficiency6_bit_per_component =
2199 bw_frc_to_fixed(35556, 10000);
2200 dceip.underlay_vscaler_efficiency8_bit_per_component =
2201 bw_frc_to_fixed(34286, 10000);
2202 dceip.underlay_vscaler_efficiency10_bit_per_component =
2203 bw_frc_to_fixed(32, 10);
2204 dceip.underlay_vscaler_efficiency12_bit_per_component =
2205 bw_int_to_fixed(3);
2206 dceip.graphics_vscaler_efficiency6_bit_per_component =
2207 bw_frc_to_fixed(35, 10);
2208 dceip.graphics_vscaler_efficiency8_bit_per_component =
2209 bw_frc_to_fixed(34286, 10000);
2210 dceip.graphics_vscaler_efficiency10_bit_per_component =
2211 bw_frc_to_fixed(32, 10);
2212 dceip.graphics_vscaler_efficiency12_bit_per_component =
2213 bw_int_to_fixed(3);
2214 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2215 dceip.max_dmif_buffer_allocated = 4;
2216 dceip.graphics_dmif_size = 12288;
2217 dceip.underlay_luma_dmif_size = 19456;
2218 dceip.underlay_chroma_dmif_size = 23552;
2219 dceip.pre_downscaler_enabled = true;
2220 dceip.underlay_downscale_prefetch_enabled = true;
2221 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2222 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2223 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2224 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2225 bw_int_to_fixed(1);
2226 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2227 82176);
2228 dceip.underlay420_chroma_lb_size_per_component =
2229 bw_int_to_fixed(164352);
2230 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2231 82176);
2232 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2233 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2234 dceip.underlay_maximum_width_efficient_for_tiling =
2235 bw_int_to_fixed(1920);
2236 dceip.underlay_maximum_height_efficient_for_tiling =
2237 bw_int_to_fixed(1080);
2238 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2239 bw_frc_to_fixed(3, 10);
2240 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2241 bw_int_to_fixed(25);
2242 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2243 2);
2244 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2245 bw_int_to_fixed(128);
2246 dceip.limit_excessive_outstanding_dmif_requests = true;
2247 dceip.linear_mode_line_request_alternation_slice =
2248 bw_int_to_fixed(64);
2249 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2250 32;
2251 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2252 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2253 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2254 dceip.dispclk_per_request = bw_int_to_fixed(2);
2255 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2256 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2257 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2258 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2259 break;
2260 case BW_CALCS_VERSION_POLARIS11:
2261 vbios.memory_type = bw_def_gddr5;
2262 vbios.dram_channel_width_in_bits = 32;
2263 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2264 vbios.number_of_dram_banks = 8;
2265 vbios.high_yclk = bw_int_to_fixed(6000);
2266 vbios.mid_yclk = bw_int_to_fixed(3200);
2267 vbios.low_yclk = bw_int_to_fixed(1000);
2268 vbios.low_sclk = bw_int_to_fixed(300);
2269 vbios.mid1_sclk = bw_int_to_fixed(400);
2270 vbios.mid2_sclk = bw_int_to_fixed(500);
2271 vbios.mid3_sclk = bw_int_to_fixed(600);
2272 vbios.mid4_sclk = bw_int_to_fixed(700);
2273 vbios.mid5_sclk = bw_int_to_fixed(800);
2274 vbios.mid6_sclk = bw_int_to_fixed(974);
2275 vbios.high_sclk = bw_int_to_fixed(1154);
2276 vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
2277 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
2278 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1108);
2279 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2280 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2281 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2282 vbios.data_return_bus_width = bw_int_to_fixed(32);
2283 vbios.trc = bw_int_to_fixed(48);
2284 if (vbios.number_of_dram_channels == 2) // 64-bit
2285 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2286 else
2287 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2288 vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
2289 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2290 vbios.nbp_state_change_latency = bw_int_to_fixed(45);
2291 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2292 vbios.scatter_gather_enable = true;
2293 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2294 vbios.cursor_width = 32;
2295 vbios.average_compression_rate = 4;
2296 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2297 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2298 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2299
2300 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2301 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2302 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2303 dceip.large_cursor = false;
2304 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2305 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2306 dceip.cursor_max_outstanding_group_num = 1;
2307 dceip.lines_interleaved_into_lb = 2;
2308 dceip.chunk_width = 256;
2309 dceip.number_of_graphics_pipes = 5;
2310 dceip.number_of_underlay_pipes = 0;
2311 dceip.low_power_tiling_mode = 0;
2312 dceip.display_write_back_supported = false;
2313 dceip.argb_compression_support = true;
2314 dceip.underlay_vscaler_efficiency6_bit_per_component =
2315 bw_frc_to_fixed(35556, 10000);
2316 dceip.underlay_vscaler_efficiency8_bit_per_component =
2317 bw_frc_to_fixed(34286, 10000);
2318 dceip.underlay_vscaler_efficiency10_bit_per_component =
2319 bw_frc_to_fixed(32, 10);
2320 dceip.underlay_vscaler_efficiency12_bit_per_component =
2321 bw_int_to_fixed(3);
2322 dceip.graphics_vscaler_efficiency6_bit_per_component =
2323 bw_frc_to_fixed(35, 10);
2324 dceip.graphics_vscaler_efficiency8_bit_per_component =
2325 bw_frc_to_fixed(34286, 10000);
2326 dceip.graphics_vscaler_efficiency10_bit_per_component =
2327 bw_frc_to_fixed(32, 10);
2328 dceip.graphics_vscaler_efficiency12_bit_per_component =
2329 bw_int_to_fixed(3);
2330 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2331 dceip.max_dmif_buffer_allocated = 4;
2332 dceip.graphics_dmif_size = 12288;
2333 dceip.underlay_luma_dmif_size = 19456;
2334 dceip.underlay_chroma_dmif_size = 23552;
2335 dceip.pre_downscaler_enabled = true;
2336 dceip.underlay_downscale_prefetch_enabled = true;
2337 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2338 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2339 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2340 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2341 bw_int_to_fixed(1);
2342 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2343 82176);
2344 dceip.underlay420_chroma_lb_size_per_component =
2345 bw_int_to_fixed(164352);
2346 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2347 82176);
2348 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2349 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2350 dceip.underlay_maximum_width_efficient_for_tiling =
2351 bw_int_to_fixed(1920);
2352 dceip.underlay_maximum_height_efficient_for_tiling =
2353 bw_int_to_fixed(1080);
2354 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2355 bw_frc_to_fixed(3, 10);
2356 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2357 bw_int_to_fixed(25);
2358 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2359 2);
2360 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2361 bw_int_to_fixed(128);
2362 dceip.limit_excessive_outstanding_dmif_requests = true;
2363 dceip.linear_mode_line_request_alternation_slice =
2364 bw_int_to_fixed(64);
2365 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2366 32;
2367 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2368 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2369 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2370 dceip.dispclk_per_request = bw_int_to_fixed(2);
2371 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2372 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2373 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2374 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2375 break;
2376 case BW_CALCS_VERSION_STONEY:
2377 vbios.memory_type = bw_def_gddr5;
2378 vbios.dram_channel_width_in_bits = 64;
2379 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2380 vbios.number_of_dram_banks = 8;
2381 vbios.high_yclk = bw_int_to_fixed(1866);
2382 vbios.mid_yclk = bw_int_to_fixed(1866);
2383 vbios.low_yclk = bw_int_to_fixed(1333);
2384 vbios.low_sclk = bw_int_to_fixed(200);
2385 vbios.mid1_sclk = bw_int_to_fixed(600);
2386 vbios.mid2_sclk = bw_int_to_fixed(600);
2387 vbios.mid3_sclk = bw_int_to_fixed(600);
2388 vbios.mid4_sclk = bw_int_to_fixed(600);
2389 vbios.mid5_sclk = bw_int_to_fixed(600);
2390 vbios.mid6_sclk = bw_int_to_fixed(600);
2391 vbios.high_sclk = bw_int_to_fixed(800);
2392 vbios.low_voltage_max_dispclk = bw_int_to_fixed(352);
2393 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(467);
2394 vbios.high_voltage_max_dispclk = bw_int_to_fixed(643);
2395 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2396 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2397 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2398 vbios.data_return_bus_width = bw_int_to_fixed(32);
2399 vbios.trc = bw_int_to_fixed(50);
2400 vbios.dmifmc_urgent_latency = bw_int_to_fixed(4);
2401 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(158, 10);
2402 vbios.stutter_self_refresh_entry_latency = bw_int_to_fixed(0);
2403 vbios.nbp_state_change_latency = bw_frc_to_fixed(2008, 100);
2404 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2405 vbios.scatter_gather_enable = true;
2406 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2407 vbios.cursor_width = 32;
2408 vbios.average_compression_rate = 4;
2409 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 256;
2410 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2411 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2412
2413 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2414 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2415 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2416 dceip.large_cursor = false;
2417 dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
2418 dceip.dmif_pipe_en_fbc_chunk_tracker = false;
2419 dceip.cursor_max_outstanding_group_num = 1;
2420 dceip.lines_interleaved_into_lb = 2;
2421 dceip.chunk_width = 256;
2422 dceip.number_of_graphics_pipes = 2;
2423 dceip.number_of_underlay_pipes = 1;
2424 dceip.low_power_tiling_mode = 0;
2425 dceip.display_write_back_supported = false;
2426 dceip.argb_compression_support = true;
2427 dceip.underlay_vscaler_efficiency6_bit_per_component =
2428 bw_frc_to_fixed(35556, 10000);
2429 dceip.underlay_vscaler_efficiency8_bit_per_component =
2430 bw_frc_to_fixed(34286, 10000);
2431 dceip.underlay_vscaler_efficiency10_bit_per_component =
2432 bw_frc_to_fixed(32, 10);
2433 dceip.underlay_vscaler_efficiency12_bit_per_component =
2434 bw_int_to_fixed(3);
2435 dceip.graphics_vscaler_efficiency6_bit_per_component =
2436 bw_frc_to_fixed(35, 10);
2437 dceip.graphics_vscaler_efficiency8_bit_per_component =
2438 bw_frc_to_fixed(34286, 10000);
2439 dceip.graphics_vscaler_efficiency10_bit_per_component =
2440 bw_frc_to_fixed(32, 10);
2441 dceip.graphics_vscaler_efficiency12_bit_per_component =
2442 bw_int_to_fixed(3);
2443 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2444 dceip.max_dmif_buffer_allocated = 2;
2445 dceip.graphics_dmif_size = 12288;
2446 dceip.underlay_luma_dmif_size = 19456;
2447 dceip.underlay_chroma_dmif_size = 23552;
2448 dceip.pre_downscaler_enabled = true;
2449 dceip.underlay_downscale_prefetch_enabled = true;
2450 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2451 dceip.lb_size_per_component444 = bw_int_to_fixed(82176);
2452 dceip.graphics_lb_nodownscaling_multi_line_prefetching = false;
2453 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2454 bw_int_to_fixed(0);
2455 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2456 82176);
2457 dceip.underlay420_chroma_lb_size_per_component =
2458 bw_int_to_fixed(164352);
2459 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2460 82176);
2461 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2462 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2463 dceip.underlay_maximum_width_efficient_for_tiling =
2464 bw_int_to_fixed(1920);
2465 dceip.underlay_maximum_height_efficient_for_tiling =
2466 bw_int_to_fixed(1080);
2467 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2468 bw_frc_to_fixed(3, 10);
2469 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2470 bw_int_to_fixed(25);
2471 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2472 2);
2473 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2474 bw_int_to_fixed(128);
2475 dceip.limit_excessive_outstanding_dmif_requests = true;
2476 dceip.linear_mode_line_request_alternation_slice =
2477 bw_int_to_fixed(64);
2478 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2479 32;
2480 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2481 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2482 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2483 dceip.dispclk_per_request = bw_int_to_fixed(2);
2484 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2485 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2486 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2487 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2488 break;
2489 case BW_CALCS_VERSION_VEGA10:
2490 vbios.memory_type = bw_def_hbm;
2491 vbios.dram_channel_width_in_bits = 128;
2492 vbios.number_of_dram_channels = asic_id.vram_width / vbios.dram_channel_width_in_bits;
2493 vbios.number_of_dram_banks = 16;
2494 vbios.high_yclk = bw_int_to_fixed(2400);
2495 vbios.mid_yclk = bw_int_to_fixed(1700);
2496 vbios.low_yclk = bw_int_to_fixed(1000);
2497 vbios.low_sclk = bw_int_to_fixed(300);
2498 vbios.mid1_sclk = bw_int_to_fixed(350);
2499 vbios.mid2_sclk = bw_int_to_fixed(400);
2500 vbios.mid3_sclk = bw_int_to_fixed(500);
2501 vbios.mid4_sclk = bw_int_to_fixed(600);
2502 vbios.mid5_sclk = bw_int_to_fixed(700);
2503 vbios.mid6_sclk = bw_int_to_fixed(760);
2504 vbios.high_sclk = bw_int_to_fixed(776);
2505 vbios.low_voltage_max_dispclk = bw_int_to_fixed(460);
2506 vbios.mid_voltage_max_dispclk = bw_int_to_fixed(670);
2507 vbios.high_voltage_max_dispclk = bw_int_to_fixed(1133);
2508 vbios.low_voltage_max_phyclk = bw_int_to_fixed(540);
2509 vbios.mid_voltage_max_phyclk = bw_int_to_fixed(810);
2510 vbios.high_voltage_max_phyclk = bw_int_to_fixed(810);
2511 vbios.data_return_bus_width = bw_int_to_fixed(32);
2512 vbios.trc = bw_int_to_fixed(48);
2513 vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
2514 vbios.stutter_self_refresh_exit_latency = bw_frc_to_fixed(75, 10);
2515 vbios.stutter_self_refresh_entry_latency = bw_frc_to_fixed(19, 10);
2516 vbios.nbp_state_change_latency = bw_int_to_fixed(39);
2517 vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
2518 vbios.scatter_gather_enable = false;
2519 vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
2520 vbios.cursor_width = 32;
2521 vbios.average_compression_rate = 4;
2522 vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel = 8;
2523 vbios.blackout_duration = bw_int_to_fixed(0); /* us */
2524 vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
2525
2526 dceip.max_average_percent_of_ideal_port_bw_display_can_use_in_normal_system_operation = 100;
2527 dceip.max_average_percent_of_ideal_drambw_display_can_use_in_normal_system_operation = 100;
2528 dceip.percent_of_ideal_port_bw_received_after_urgent_latency = 100;
2529 dceip.large_cursor = false;
2530 dceip.dmif_request_buffer_size = bw_int_to_fixed(2304);
2531 dceip.dmif_pipe_en_fbc_chunk_tracker = true;
2532 dceip.cursor_max_outstanding_group_num = 1;
2533 dceip.lines_interleaved_into_lb = 2;
2534 dceip.chunk_width = 256;
2535 dceip.number_of_graphics_pipes = 6;
2536 dceip.number_of_underlay_pipes = 0;
2537 dceip.low_power_tiling_mode = 0;
2538 dceip.display_write_back_supported = true;
2539 dceip.argb_compression_support = true;
2540 dceip.underlay_vscaler_efficiency6_bit_per_component =
2541 bw_frc_to_fixed(35556, 10000);
2542 dceip.underlay_vscaler_efficiency8_bit_per_component =
2543 bw_frc_to_fixed(34286, 10000);
2544 dceip.underlay_vscaler_efficiency10_bit_per_component =
2545 bw_frc_to_fixed(32, 10);
2546 dceip.underlay_vscaler_efficiency12_bit_per_component =
2547 bw_int_to_fixed(3);
2548 dceip.graphics_vscaler_efficiency6_bit_per_component =
2549 bw_frc_to_fixed(35, 10);
2550 dceip.graphics_vscaler_efficiency8_bit_per_component =
2551 bw_frc_to_fixed(34286, 10000);
2552 dceip.graphics_vscaler_efficiency10_bit_per_component =
2553 bw_frc_to_fixed(32, 10);
2554 dceip.graphics_vscaler_efficiency12_bit_per_component =
2555 bw_int_to_fixed(3);
2556 dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
2557 dceip.max_dmif_buffer_allocated = 4;
2558 dceip.graphics_dmif_size = 24576;
2559 dceip.underlay_luma_dmif_size = 19456;
2560 dceip.underlay_chroma_dmif_size = 23552;
2561 dceip.pre_downscaler_enabled = true;
2562 dceip.underlay_downscale_prefetch_enabled = false;
2563 dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
2564 dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
2565 dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
2566 dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
2567 bw_int_to_fixed(1);
2568 dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
2569 82176);
2570 dceip.underlay420_chroma_lb_size_per_component =
2571 bw_int_to_fixed(164352);
2572 dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
2573 82176);
2574 dceip.cursor_chunk_width = bw_int_to_fixed(64);
2575 dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
2576 dceip.underlay_maximum_width_efficient_for_tiling =
2577 bw_int_to_fixed(1920);
2578 dceip.underlay_maximum_height_efficient_for_tiling =
2579 bw_int_to_fixed(1080);
2580 dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
2581 bw_frc_to_fixed(3, 10);
2582 dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
2583 bw_int_to_fixed(25);
2584 dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
2585 2);
2586 dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
2587 bw_int_to_fixed(128);
2588 dceip.limit_excessive_outstanding_dmif_requests = true;
2589 dceip.linear_mode_line_request_alternation_slice =
2590 bw_int_to_fixed(64);
2591 dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
2592 32;
2593 dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
2594 dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
2595 dceip.request_efficiency = bw_frc_to_fixed(8, 10);
2596 dceip.dispclk_per_request = bw_int_to_fixed(2);
2597 dceip.dispclk_ramping_factor = bw_frc_to_fixed(105, 100);
2598 dceip.display_pipe_throughput_factor = bw_frc_to_fixed(105, 100);
2599 dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
2600 dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
2601 break;
2602 default:
2603 break;
2604 }
2605 *bw_dceip = dceip;
2606 *bw_vbios = vbios;
2607
2608}
2609
2610/**
2611 * Compare calculated (required) clocks against the clocks available at
2612 * maximum voltage (max Performance Level).
2613 */
2614static bool is_display_configuration_supported(
2615 const struct bw_calcs_vbios *vbios,
2616 const struct dce_bw_output *calcs_output)
2617{
2618 uint32_t int_max_clk;
2619
2620 int_max_clk = bw_fixed_to_int(vbios->high_voltage_max_dispclk);
2621 int_max_clk *= 1000; /* MHz to kHz */
2622 if (calcs_output->dispclk_khz > int_max_clk)
2623 return false;
2624
2625 int_max_clk = bw_fixed_to_int(vbios->high_sclk);
2626 int_max_clk *= 1000; /* MHz to kHz */
2627 if (calcs_output->sclk_khz > int_max_clk)
2628 return false;
2629
2630 return true;
2631}
2632
2633static void populate_initial_data(
2634 const struct pipe_ctx pipe[], int pipe_count, struct bw_calcs_data *data)
2635{
2636 int i, j;
2637 int num_displays = 0;
2638
2639 data->underlay_surface_type = bw_def_420;
2640 data->panning_and_bezel_adjustment = bw_def_none;
2641 data->graphics_lb_bpc = 10;
2642 data->underlay_lb_bpc = 8;
2643 data->underlay_tiling_mode = bw_def_tiled;
2644 data->graphics_tiling_mode = bw_def_tiled;
2645 data->underlay_micro_tile_mode = bw_def_display_micro_tiling;
2646 data->graphics_micro_tile_mode = bw_def_display_micro_tiling;
2647 data->increase_voltage_to_support_mclk_switch = true;
2648
2649 /* Pipes with underlay first */
2650 for (i = 0; i < pipe_count; i++) {
2651 if (!pipe[i].stream || !pipe[i].bottom_pipe)
2652 continue;
2653
2654 ASSERT(pipe[i].plane_state);
2655
2656 if (num_displays == 0) {
2657 if (!pipe[i].plane_state->visible)
2658 data->d0_underlay_mode = bw_def_underlay_only;
2659 else
2660 data->d0_underlay_mode = bw_def_blend;
2661 } else {
2662 if (!pipe[i].plane_state->visible)
2663 data->d1_underlay_mode = bw_def_underlay_only;
2664 else
2665 data->d1_underlay_mode = bw_def_blend;
2666 }
2667
2668 data->fbc_en[num_displays + 4] = false;
2669 data->lpt_en[num_displays + 4] = false;
2670 data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
2671 data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
2672 data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->timing.pix_clk_khz, 1000);
2673 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
2674 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2675 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.height);
2676 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.h_taps);
2677 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.v_taps);
2678 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.horz.value);
2679 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.vert.value);
2680 switch (pipe[i].plane_state->rotation) {
2681 case ROTATION_ANGLE_0:
2682 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2683 break;
2684 case ROTATION_ANGLE_90:
2685 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(90);
2686 break;
2687 case ROTATION_ANGLE_180:
2688 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(180);
2689 break;
2690 case ROTATION_ANGLE_270:
2691 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(270);
2692 break;
2693 default:
2694 break;
2695 }
2696 switch (pipe[i].plane_state->format) {
2697 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
2698 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
2699 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2700 data->bytes_per_pixel[num_displays + 4] = 2;
2701 break;
2702 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2703 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2704 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2705 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2706 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
2707 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
2708 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
2709 data->bytes_per_pixel[num_displays + 4] = 4;
2710 break;
2711 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2712 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2713 data->bytes_per_pixel[num_displays + 4] = 8;
2714 break;
2715 default:
2716 data->bytes_per_pixel[num_displays + 4] = 4;
2717 break;
2718 }
2719 data->interlace_mode[num_displays + 4] = false;
2720 data->stereo_mode[num_displays + 4] = bw_def_mono;
2721
2722
2723 for (j = 0; j < 2; j++) {
2724 data->fbc_en[num_displays * 2 + j] = false;
2725 data->lpt_en[num_displays * 2 + j] = false;
2726
2727 data->src_height[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.height);
2728 data->src_width[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.viewport.width);
2729 data->pitch_in_pixels[num_displays * 2 + j] = bw_int_to_fixed(
2730 pipe[i].bottom_pipe->plane_state->plane_size.grph.surface_pitch);
2731 data->h_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.h_taps);
2732 data->v_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->plane_res.scl_data.taps.v_taps);
2733 data->h_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2734 pipe[i].bottom_pipe->plane_res.scl_data.ratios.horz.value);
2735 data->v_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2736 pipe[i].bottom_pipe->plane_res.scl_data.ratios.vert.value);
2737 switch (pipe[i].bottom_pipe->plane_state->rotation) {
2738 case ROTATION_ANGLE_0:
2739 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(0);
2740 break;
2741 case ROTATION_ANGLE_90:
2742 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(90);
2743 break;
2744 case ROTATION_ANGLE_180:
2745 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(180);
2746 break;
2747 case ROTATION_ANGLE_270:
2748 data->rotation_angle[num_displays * 2 + j] = bw_int_to_fixed(270);
2749 break;
2750 default:
2751 break;
2752 }
2753 data->stereo_mode[num_displays * 2 + j] = bw_def_mono;
2754 }
2755
2756 num_displays++;
2757 }
2758
2759 /* Pipes without underlay after */
2760 for (i = 0; i < pipe_count; i++) {
2761 if (!pipe[i].stream || pipe[i].bottom_pipe)
2762 continue;
2763
2764
2765 data->fbc_en[num_displays + 4] = false;
2766 data->lpt_en[num_displays + 4] = false;
2767 data->h_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_total);
2768 data->v_total[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_total);
2769 data->pixel_rate[num_displays + 4] = bw_frc_to_fixed(pipe[i].stream->timing.pix_clk_khz, 1000);
2770 if (pipe[i].plane_state) {
2771 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.width);
2772 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2773 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.viewport.height);
2774 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.h_taps);
2775 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].plane_res.scl_data.taps.v_taps);
2776 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.horz.value);
2777 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].plane_res.scl_data.ratios.vert.value);
2778 switch (pipe[i].plane_state->rotation) {
2779 case ROTATION_ANGLE_0:
2780 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2781 break;
2782 case ROTATION_ANGLE_90:
2783 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(90);
2784 break;
2785 case ROTATION_ANGLE_180:
2786 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(180);
2787 break;
2788 case ROTATION_ANGLE_270:
2789 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(270);
2790 break;
2791 default:
2792 break;
2793 }
2794 switch (pipe[i].plane_state->format) {
2795 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
2796 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
2797 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
2798 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
2799 data->bytes_per_pixel[num_displays + 4] = 2;
2800 break;
2801 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
2802 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
2803 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
2804 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
2805 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
2806 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
2807 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
2808 data->bytes_per_pixel[num_displays + 4] = 4;
2809 break;
2810 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
2811 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
2812 data->bytes_per_pixel[num_displays + 4] = 8;
2813 break;
2814 default:
2815 data->bytes_per_pixel[num_displays + 4] = 4;
2816 break;
2817 }
2818 } else {
2819 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.h_addressable);
2820 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
2821 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].stream->timing.v_addressable);
2822 data->h_taps[num_displays + 4] = bw_int_to_fixed(1);
2823 data->v_taps[num_displays + 4] = bw_int_to_fixed(1);
2824 data->h_scale_ratio[num_displays + 4] = bw_int_to_fixed(1);
2825 data->v_scale_ratio[num_displays + 4] = bw_int_to_fixed(1);
2826 data->rotation_angle[num_displays + 4] = bw_int_to_fixed(0);
2827 data->bytes_per_pixel[num_displays + 4] = 4;
2828 }
2829
2830 data->interlace_mode[num_displays + 4] = false;
2831 data->stereo_mode[num_displays + 4] = bw_def_mono;
2832 num_displays++;
2833 }
2834
2835 data->number_of_displays = num_displays;
2836}
2837
2838/**
2839 * Return:
2840 * true - Display(s) configuration supported.
2841 * In this case 'calcs_output' contains data for HW programming
2842 * false - Display(s) configuration not supported (not enough bandwidth).
2843 */
2844
2845bool bw_calcs(struct dc_context *ctx,
2846 const struct bw_calcs_dceip *dceip,
2847 const struct bw_calcs_vbios *vbios,
2848 const struct pipe_ctx pipe[],
2849 int pipe_count,
2850 struct dce_bw_output *calcs_output)
2851{
2852 struct bw_calcs_data *data = kzalloc(sizeof(struct bw_calcs_data),
2853 GFP_KERNEL);
2854 if (!data)
2855 return false;
2856
2857 populate_initial_data(pipe, pipe_count, data);
2858
2859 /*TODO: this should be taken out calcs output and assigned during timing sync for pplib use*/
2860 calcs_output->all_displays_in_sync = false;
2861
2862 if (data->number_of_displays != 0) {
2863 uint8_t yclk_lvl, sclk_lvl;
2864 struct bw_fixed high_sclk = vbios->high_sclk;
2865 struct bw_fixed mid1_sclk = vbios->mid1_sclk;
2866 struct bw_fixed mid2_sclk = vbios->mid2_sclk;
2867 struct bw_fixed mid3_sclk = vbios->mid3_sclk;
2868 struct bw_fixed mid4_sclk = vbios->mid4_sclk;
2869 struct bw_fixed mid5_sclk = vbios->mid5_sclk;
2870 struct bw_fixed mid6_sclk = vbios->mid6_sclk;
2871 struct bw_fixed low_sclk = vbios->low_sclk;
2872 struct bw_fixed high_yclk = vbios->high_yclk;
2873 struct bw_fixed mid_yclk = vbios->mid_yclk;
2874 struct bw_fixed low_yclk = vbios->low_yclk;
2875
2876 calculate_bandwidth(dceip, vbios, data);
2877
2878 yclk_lvl = data->y_clk_level;
2879 sclk_lvl = data->sclk_level;
2880
2881 calcs_output->nbp_state_change_enable =
2882 data->nbp_state_change_enable;
2883 calcs_output->cpuc_state_change_enable =
2884 data->cpuc_state_change_enable;
2885 calcs_output->cpup_state_change_enable =
2886 data->cpup_state_change_enable;
2887 calcs_output->stutter_mode_enable =
2888 data->stutter_mode_enable;
2889 calcs_output->dispclk_khz =
2890 bw_fixed_to_int(bw_mul(data->dispclk,
2891 bw_int_to_fixed(1000)));
2892 calcs_output->blackout_recovery_time_us =
2893 bw_fixed_to_int(data->blackout_recovery_time);
2894 calcs_output->sclk_khz =
2895 bw_fixed_to_int(bw_mul(data->required_sclk,
2896 bw_int_to_fixed(1000)));
2897 calcs_output->sclk_deep_sleep_khz =
2898 bw_fixed_to_int(bw_mul(data->sclk_deep_sleep,
2899 bw_int_to_fixed(1000)));
2900 if (yclk_lvl == 0)
2901 calcs_output->yclk_khz = bw_fixed_to_int(
2902 bw_mul(low_yclk, bw_int_to_fixed(1000)));
2903 else if (yclk_lvl == 1)
2904 calcs_output->yclk_khz = bw_fixed_to_int(
2905 bw_mul(mid_yclk, bw_int_to_fixed(1000)));
2906 else
2907 calcs_output->yclk_khz = bw_fixed_to_int(
2908 bw_mul(high_yclk, bw_int_to_fixed(1000)));
2909
2910 /* units: nanosecond, 16bit storage. */
2911
2912 calcs_output->nbp_state_change_wm_ns[0].a_mark =
2913 bw_fixed_to_int(bw_mul(data->
2914 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
2915 calcs_output->nbp_state_change_wm_ns[1].a_mark =
2916 bw_fixed_to_int(bw_mul(data->
2917 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
2918 calcs_output->nbp_state_change_wm_ns[2].a_mark =
2919 bw_fixed_to_int(bw_mul(data->
2920 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
2921
2922 if (ctx->dc->caps.max_slave_planes) {
2923 calcs_output->nbp_state_change_wm_ns[3].a_mark =
2924 bw_fixed_to_int(bw_mul(data->
2925 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
2926 calcs_output->nbp_state_change_wm_ns[4].a_mark =
2927 bw_fixed_to_int(bw_mul(data->
2928 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
2929 } else {
2930 calcs_output->nbp_state_change_wm_ns[3].a_mark =
2931 bw_fixed_to_int(bw_mul(data->
2932 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
2933 calcs_output->nbp_state_change_wm_ns[4].a_mark =
2934 bw_fixed_to_int(bw_mul(data->
2935 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
2936 }
2937 calcs_output->nbp_state_change_wm_ns[5].a_mark =
2938 bw_fixed_to_int(bw_mul(data->
2939 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
2940
2941
2942
2943 calcs_output->stutter_exit_wm_ns[0].a_mark =
2944 bw_fixed_to_int(bw_mul(data->
2945 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
2946 calcs_output->stutter_exit_wm_ns[1].a_mark =
2947 bw_fixed_to_int(bw_mul(data->
2948 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
2949 calcs_output->stutter_exit_wm_ns[2].a_mark =
2950 bw_fixed_to_int(bw_mul(data->
2951 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
2952 if (ctx->dc->caps.max_slave_planes) {
2953 calcs_output->stutter_exit_wm_ns[3].a_mark =
2954 bw_fixed_to_int(bw_mul(data->
2955 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
2956 calcs_output->stutter_exit_wm_ns[4].a_mark =
2957 bw_fixed_to_int(bw_mul(data->
2958 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
2959 } else {
2960 calcs_output->stutter_exit_wm_ns[3].a_mark =
2961 bw_fixed_to_int(bw_mul(data->
2962 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
2963 calcs_output->stutter_exit_wm_ns[4].a_mark =
2964 bw_fixed_to_int(bw_mul(data->
2965 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
2966 }
2967 calcs_output->stutter_exit_wm_ns[5].a_mark =
2968 bw_fixed_to_int(bw_mul(data->
2969 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
2970
2971
2972
2973 calcs_output->urgent_wm_ns[0].a_mark =
2974 bw_fixed_to_int(bw_mul(data->
2975 urgent_watermark[4], bw_int_to_fixed(1000)));
2976 calcs_output->urgent_wm_ns[1].a_mark =
2977 bw_fixed_to_int(bw_mul(data->
2978 urgent_watermark[5], bw_int_to_fixed(1000)));
2979 calcs_output->urgent_wm_ns[2].a_mark =
2980 bw_fixed_to_int(bw_mul(data->
2981 urgent_watermark[6], bw_int_to_fixed(1000)));
2982 if (ctx->dc->caps.max_slave_planes) {
2983 calcs_output->urgent_wm_ns[3].a_mark =
2984 bw_fixed_to_int(bw_mul(data->
2985 urgent_watermark[0], bw_int_to_fixed(1000)));
2986 calcs_output->urgent_wm_ns[4].a_mark =
2987 bw_fixed_to_int(bw_mul(data->
2988 urgent_watermark[1], bw_int_to_fixed(1000)));
2989 } else {
2990 calcs_output->urgent_wm_ns[3].a_mark =
2991 bw_fixed_to_int(bw_mul(data->
2992 urgent_watermark[7], bw_int_to_fixed(1000)));
2993 calcs_output->urgent_wm_ns[4].a_mark =
2994 bw_fixed_to_int(bw_mul(data->
2995 urgent_watermark[8], bw_int_to_fixed(1000)));
2996 }
2997 calcs_output->urgent_wm_ns[5].a_mark =
2998 bw_fixed_to_int(bw_mul(data->
2999 urgent_watermark[9], bw_int_to_fixed(1000)));
3000
3001 if (dceip->version != BW_CALCS_VERSION_CARRIZO) {
3002 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
3003 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
3004 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
3005 calculate_bandwidth(dceip, vbios, data);
3006
3007 calcs_output->nbp_state_change_wm_ns[0].b_mark =
3008 bw_fixed_to_int(bw_mul(data->
3009 nbp_state_change_watermark[4],bw_int_to_fixed(1000)));
3010 calcs_output->nbp_state_change_wm_ns[1].b_mark =
3011 bw_fixed_to_int(bw_mul(data->
3012 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3013 calcs_output->nbp_state_change_wm_ns[2].b_mark =
3014 bw_fixed_to_int(bw_mul(data->
3015 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3016
3017 if (ctx->dc->caps.max_slave_planes) {
3018 calcs_output->nbp_state_change_wm_ns[3].b_mark =
3019 bw_fixed_to_int(bw_mul(data->
3020 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3021 calcs_output->nbp_state_change_wm_ns[4].b_mark =
3022 bw_fixed_to_int(bw_mul(data->
3023 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3024 } else {
3025 calcs_output->nbp_state_change_wm_ns[3].b_mark =
3026 bw_fixed_to_int(bw_mul(data->
3027 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3028 calcs_output->nbp_state_change_wm_ns[4].b_mark =
3029 bw_fixed_to_int(bw_mul(data->
3030 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3031 }
3032 calcs_output->nbp_state_change_wm_ns[5].b_mark =
3033 bw_fixed_to_int(bw_mul(data->
3034 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3035
3036
3037
3038 calcs_output->stutter_exit_wm_ns[0].b_mark =
3039 bw_fixed_to_int(bw_mul(data->
3040 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3041 calcs_output->stutter_exit_wm_ns[1].b_mark =
3042 bw_fixed_to_int(bw_mul(data->
3043 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3044 calcs_output->stutter_exit_wm_ns[2].b_mark =
3045 bw_fixed_to_int(bw_mul(data->
3046 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3047 if (ctx->dc->caps.max_slave_planes) {
3048 calcs_output->stutter_exit_wm_ns[3].b_mark =
3049 bw_fixed_to_int(bw_mul(data->
3050 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3051 calcs_output->stutter_exit_wm_ns[4].b_mark =
3052 bw_fixed_to_int(bw_mul(data->
3053 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3054 } else {
3055 calcs_output->stutter_exit_wm_ns[3].b_mark =
3056 bw_fixed_to_int(bw_mul(data->
3057 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3058 calcs_output->stutter_exit_wm_ns[4].b_mark =
3059 bw_fixed_to_int(bw_mul(data->
3060 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3061 }
3062 calcs_output->stutter_exit_wm_ns[5].b_mark =
3063 bw_fixed_to_int(bw_mul(data->
3064 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3065
3066
3067
3068 calcs_output->urgent_wm_ns[0].b_mark =
3069 bw_fixed_to_int(bw_mul(data->
3070 urgent_watermark[4], bw_int_to_fixed(1000)));
3071 calcs_output->urgent_wm_ns[1].b_mark =
3072 bw_fixed_to_int(bw_mul(data->
3073 urgent_watermark[5], bw_int_to_fixed(1000)));
3074 calcs_output->urgent_wm_ns[2].b_mark =
3075 bw_fixed_to_int(bw_mul(data->
3076 urgent_watermark[6], bw_int_to_fixed(1000)));
3077 if (ctx->dc->caps.max_slave_planes) {
3078 calcs_output->urgent_wm_ns[3].b_mark =
3079 bw_fixed_to_int(bw_mul(data->
3080 urgent_watermark[0], bw_int_to_fixed(1000)));
3081 calcs_output->urgent_wm_ns[4].b_mark =
3082 bw_fixed_to_int(bw_mul(data->
3083 urgent_watermark[1], bw_int_to_fixed(1000)));
3084 } else {
3085 calcs_output->urgent_wm_ns[3].b_mark =
3086 bw_fixed_to_int(bw_mul(data->
3087 urgent_watermark[7], bw_int_to_fixed(1000)));
3088 calcs_output->urgent_wm_ns[4].b_mark =
3089 bw_fixed_to_int(bw_mul(data->
3090 urgent_watermark[8], bw_int_to_fixed(1000)));
3091 }
3092 calcs_output->urgent_wm_ns[5].b_mark =
3093 bw_fixed_to_int(bw_mul(data->
3094 urgent_watermark[9], bw_int_to_fixed(1000)));
3095
3096 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3097 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3098 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3099 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3100 calculate_bandwidth(dceip, vbios, data);
3101
3102 calcs_output->nbp_state_change_wm_ns[0].c_mark =
3103 bw_fixed_to_int(bw_mul(data->
3104 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3105 calcs_output->nbp_state_change_wm_ns[1].c_mark =
3106 bw_fixed_to_int(bw_mul(data->
3107 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3108 calcs_output->nbp_state_change_wm_ns[2].c_mark =
3109 bw_fixed_to_int(bw_mul(data->
3110 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3111 if (ctx->dc->caps.max_slave_planes) {
3112 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3113 bw_fixed_to_int(bw_mul(data->
3114 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3115 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3116 bw_fixed_to_int(bw_mul(data->
3117 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3118 } else {
3119 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3120 bw_fixed_to_int(bw_mul(data->
3121 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3122 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3123 bw_fixed_to_int(bw_mul(data->
3124 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3125 }
3126 calcs_output->nbp_state_change_wm_ns[5].c_mark =
3127 bw_fixed_to_int(bw_mul(data->
3128 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3129
3130
3131 calcs_output->stutter_exit_wm_ns[0].c_mark =
3132 bw_fixed_to_int(bw_mul(data->
3133 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3134 calcs_output->stutter_exit_wm_ns[1].c_mark =
3135 bw_fixed_to_int(bw_mul(data->
3136 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3137 calcs_output->stutter_exit_wm_ns[2].c_mark =
3138 bw_fixed_to_int(bw_mul(data->
3139 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3140 if (ctx->dc->caps.max_slave_planes) {
3141 calcs_output->stutter_exit_wm_ns[3].c_mark =
3142 bw_fixed_to_int(bw_mul(data->
3143 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3144 calcs_output->stutter_exit_wm_ns[4].c_mark =
3145 bw_fixed_to_int(bw_mul(data->
3146 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3147 } else {
3148 calcs_output->stutter_exit_wm_ns[3].c_mark =
3149 bw_fixed_to_int(bw_mul(data->
3150 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3151 calcs_output->stutter_exit_wm_ns[4].c_mark =
3152 bw_fixed_to_int(bw_mul(data->
3153 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3154 }
3155 calcs_output->stutter_exit_wm_ns[5].c_mark =
3156 bw_fixed_to_int(bw_mul(data->
3157 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3158
3159 calcs_output->urgent_wm_ns[0].c_mark =
3160 bw_fixed_to_int(bw_mul(data->
3161 urgent_watermark[4], bw_int_to_fixed(1000)));
3162 calcs_output->urgent_wm_ns[1].c_mark =
3163 bw_fixed_to_int(bw_mul(data->
3164 urgent_watermark[5], bw_int_to_fixed(1000)));
3165 calcs_output->urgent_wm_ns[2].c_mark =
3166 bw_fixed_to_int(bw_mul(data->
3167 urgent_watermark[6], bw_int_to_fixed(1000)));
3168 if (ctx->dc->caps.max_slave_planes) {
3169 calcs_output->urgent_wm_ns[3].c_mark =
3170 bw_fixed_to_int(bw_mul(data->
3171 urgent_watermark[0], bw_int_to_fixed(1000)));
3172 calcs_output->urgent_wm_ns[4].c_mark =
3173 bw_fixed_to_int(bw_mul(data->
3174 urgent_watermark[1], bw_int_to_fixed(1000)));
3175 } else {
3176 calcs_output->urgent_wm_ns[3].c_mark =
3177 bw_fixed_to_int(bw_mul(data->
3178 urgent_watermark[7], bw_int_to_fixed(1000)));
3179 calcs_output->urgent_wm_ns[4].c_mark =
3180 bw_fixed_to_int(bw_mul(data->
3181 urgent_watermark[8], bw_int_to_fixed(1000)));
3182 }
3183 calcs_output->urgent_wm_ns[5].c_mark =
3184 bw_fixed_to_int(bw_mul(data->
3185 urgent_watermark[9], bw_int_to_fixed(1000)));
3186 }
3187
3188 if (dceip->version == BW_CALCS_VERSION_CARRIZO) {
3189 ((struct bw_calcs_vbios *)vbios)->low_yclk = high_yclk;
3190 ((struct bw_calcs_vbios *)vbios)->mid_yclk = high_yclk;
3191 ((struct bw_calcs_vbios *)vbios)->low_sclk = high_sclk;
3192 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = high_sclk;
3193 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = high_sclk;
3194 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = high_sclk;
3195 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = high_sclk;
3196 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = high_sclk;
3197 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = high_sclk;
3198 } else {
3199 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3200 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
3201 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
3202 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
3203 }
3204
3205 calculate_bandwidth(dceip, vbios, data);
3206
3207 calcs_output->nbp_state_change_wm_ns[0].d_mark =
3208 bw_fixed_to_int(bw_mul(data->
3209 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3210 calcs_output->nbp_state_change_wm_ns[1].d_mark =
3211 bw_fixed_to_int(bw_mul(data->
3212 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3213 calcs_output->nbp_state_change_wm_ns[2].d_mark =
3214 bw_fixed_to_int(bw_mul(data->
3215 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3216 if (ctx->dc->caps.max_slave_planes) {
3217 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3218 bw_fixed_to_int(bw_mul(data->
3219 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3220 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3221 bw_fixed_to_int(bw_mul(data->
3222 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3223 } else {
3224 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3225 bw_fixed_to_int(bw_mul(data->
3226 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3227 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3228 bw_fixed_to_int(bw_mul(data->
3229 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3230 }
3231 calcs_output->nbp_state_change_wm_ns[5].d_mark =
3232 bw_fixed_to_int(bw_mul(data->
3233 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3234
3235 calcs_output->stutter_exit_wm_ns[0].d_mark =
3236 bw_fixed_to_int(bw_mul(data->
3237 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3238 calcs_output->stutter_exit_wm_ns[1].d_mark =
3239 bw_fixed_to_int(bw_mul(data->
3240 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3241 calcs_output->stutter_exit_wm_ns[2].d_mark =
3242 bw_fixed_to_int(bw_mul(data->
3243 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3244 if (ctx->dc->caps.max_slave_planes) {
3245 calcs_output->stutter_exit_wm_ns[3].d_mark =
3246 bw_fixed_to_int(bw_mul(data->
3247 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3248 calcs_output->stutter_exit_wm_ns[4].d_mark =
3249 bw_fixed_to_int(bw_mul(data->
3250 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3251 } else {
3252 calcs_output->stutter_exit_wm_ns[3].d_mark =
3253 bw_fixed_to_int(bw_mul(data->
3254 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3255 calcs_output->stutter_exit_wm_ns[4].d_mark =
3256 bw_fixed_to_int(bw_mul(data->
3257 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3258 }
3259 calcs_output->stutter_exit_wm_ns[5].d_mark =
3260 bw_fixed_to_int(bw_mul(data->
3261 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3262
3263
3264 calcs_output->urgent_wm_ns[0].d_mark =
3265 bw_fixed_to_int(bw_mul(data->
3266 urgent_watermark[4], bw_int_to_fixed(1000)));
3267 calcs_output->urgent_wm_ns[1].d_mark =
3268 bw_fixed_to_int(bw_mul(data->
3269 urgent_watermark[5], bw_int_to_fixed(1000)));
3270 calcs_output->urgent_wm_ns[2].d_mark =
3271 bw_fixed_to_int(bw_mul(data->
3272 urgent_watermark[6], bw_int_to_fixed(1000)));
3273 if (ctx->dc->caps.max_slave_planes) {
3274 calcs_output->urgent_wm_ns[3].d_mark =
3275 bw_fixed_to_int(bw_mul(data->
3276 urgent_watermark[0], bw_int_to_fixed(1000)));
3277 calcs_output->urgent_wm_ns[4].d_mark =
3278 bw_fixed_to_int(bw_mul(data->
3279 urgent_watermark[1], bw_int_to_fixed(1000)));
3280 } else {
3281 calcs_output->urgent_wm_ns[3].d_mark =
3282 bw_fixed_to_int(bw_mul(data->
3283 urgent_watermark[7], bw_int_to_fixed(1000)));
3284 calcs_output->urgent_wm_ns[4].d_mark =
3285 bw_fixed_to_int(bw_mul(data->
3286 urgent_watermark[8], bw_int_to_fixed(1000)));
3287 }
3288 calcs_output->urgent_wm_ns[5].d_mark =
3289 bw_fixed_to_int(bw_mul(data->
3290 urgent_watermark[9], bw_int_to_fixed(1000)));
3291
3292 ((struct bw_calcs_vbios *)vbios)->low_yclk = low_yclk;
3293 ((struct bw_calcs_vbios *)vbios)->mid_yclk = mid_yclk;
3294 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3295 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3296 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3297 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = mid3_sclk;
3298 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = mid4_sclk;
3299 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = mid5_sclk;
3300 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = mid6_sclk;
3301 ((struct bw_calcs_vbios *)vbios)->high_sclk = high_sclk;
3302 } else {
3303 calcs_output->nbp_state_change_enable = true;
3304 calcs_output->cpuc_state_change_enable = true;
3305 calcs_output->cpup_state_change_enable = true;
3306 calcs_output->stutter_mode_enable = true;
3307 calcs_output->dispclk_khz = 0;
3308 calcs_output->sclk_khz = 0;
3309 }
3310
3311 kfree(data);
3312
3313 return is_display_configuration_supported(vbios, calcs_output);
3314}