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