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