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