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