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