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