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