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