]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c
drm/amd/display: Rename more dc_surface stuff to plane_state
[mirror_ubuntu-bionic-kernel.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:
534 data->lb_line_pitch = bw_ceil2(bw_mul(bw_div(bw_frc_to_fixed(2401171875, 100000000), bw_int_to_fixed(3)), bw_ceil2(data->source_width_in_lb, bw_int_to_fixed(8))), bw_int_to_fixed(48));
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);
4562236b 2616 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.viewport.width);
dff06ddd 2617 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
4562236b
HW
2618 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.viewport.height);
2619 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.taps.h_taps);
2620 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.taps.v_taps);
2621 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].scl_data.ratios.horz.value);
2622 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].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
2670 data->src_height[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->scl_data.viewport.height);
2671 data->src_width[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->scl_data.viewport.width);
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);
4562236b
HW
2674 data->h_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->scl_data.taps.h_taps);
2675 data->v_taps[num_displays * 2 + j] = bw_int_to_fixed(pipe[i].bottom_pipe->scl_data.taps.v_taps);
2676 data->h_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2677 pipe[i].bottom_pipe->scl_data.ratios.horz.value);
2678 data->v_scale_ratio[num_displays * 2 + j] = fixed31_32_to_bw_fixed(
2679 pipe[i].bottom_pipe->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) {
4562236b 2714 data->src_width[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.viewport.width);
dff06ddd 2715 data->pitch_in_pixels[num_displays + 4] = data->src_width[num_displays + 4];
4562236b
HW
2716 data->src_height[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.viewport.height);
2717 data->h_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.taps.h_taps);
2718 data->v_taps[num_displays + 4] = bw_int_to_fixed(pipe[i].scl_data.taps.v_taps);
2719 data->h_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].scl_data.ratios.horz.value);
2720 data->v_scale_ratio[num_displays + 4] = fixed31_32_to_bw_fixed(pipe[i].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
HW
2794{
2795 struct bw_calcs_data *data = dm_alloc(sizeof(struct bw_calcs_data));
2796
2797 populate_initial_data(pipe, pipe_count, data);
2798
2799 /*TODO: this should be taken out calcs output and assigned during timing sync for pplib use*/
2800 calcs_output->all_displays_in_sync = false;
2801
2802 if (data->number_of_displays != 0) {
2803 uint8_t yclk_lvl, sclk_lvl;
2804 struct bw_fixed high_sclk = vbios->high_sclk;
2805 struct bw_fixed mid1_sclk = vbios->mid1_sclk;
2806 struct bw_fixed mid2_sclk = vbios->mid2_sclk;
2807 struct bw_fixed mid3_sclk = vbios->mid3_sclk;
2808 struct bw_fixed mid4_sclk = vbios->mid4_sclk;
2809 struct bw_fixed mid5_sclk = vbios->mid5_sclk;
2810 struct bw_fixed mid6_sclk = vbios->mid6_sclk;
2811 struct bw_fixed low_sclk = vbios->low_sclk;
2812 struct bw_fixed high_yclk = vbios->high_yclk;
2813 struct bw_fixed mid_yclk = vbios->mid_yclk;
2814 struct bw_fixed low_yclk = vbios->low_yclk;
2815
2816 calculate_bandwidth(dceip, vbios, data);
2817
2818 yclk_lvl = data->y_clk_level;
2819 sclk_lvl = data->sclk_level;
2820
2821 calcs_output->nbp_state_change_enable =
2822 data->nbp_state_change_enable;
2823 calcs_output->cpuc_state_change_enable =
2824 data->cpuc_state_change_enable;
2825 calcs_output->cpup_state_change_enable =
2826 data->cpup_state_change_enable;
2827 calcs_output->stutter_mode_enable =
2828 data->stutter_mode_enable;
2829 calcs_output->dispclk_khz =
2830 bw_fixed_to_int(bw_mul(data->dispclk,
2831 bw_int_to_fixed(1000)));
2832 calcs_output->blackout_recovery_time_us =
2833 bw_fixed_to_int(data->blackout_recovery_time);
9037d802 2834 calcs_output->sclk_khz =
4562236b
HW
2835 bw_fixed_to_int(bw_mul(data->required_sclk,
2836 bw_int_to_fixed(1000)));
9037d802 2837 calcs_output->sclk_deep_sleep_khz =
4562236b
HW
2838 bw_fixed_to_int(bw_mul(data->sclk_deep_sleep,
2839 bw_int_to_fixed(1000)));
2840 if (yclk_lvl == 0)
9037d802 2841 calcs_output->yclk_khz = bw_fixed_to_int(
4562236b
HW
2842 bw_mul(low_yclk, bw_int_to_fixed(1000)));
2843 else if (yclk_lvl == 1)
9037d802 2844 calcs_output->yclk_khz = bw_fixed_to_int(
4562236b
HW
2845 bw_mul(mid_yclk, bw_int_to_fixed(1000)));
2846 else
9037d802 2847 calcs_output->yclk_khz = bw_fixed_to_int(
4562236b
HW
2848 bw_mul(high_yclk, bw_int_to_fixed(1000)));
2849
2850 /* units: nanosecond, 16bit storage. */
2851
2852 calcs_output->nbp_state_change_wm_ns[0].a_mark =
2853 bw_fixed_to_int(bw_mul(data->
2854 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
2855 calcs_output->nbp_state_change_wm_ns[1].a_mark =
2856 bw_fixed_to_int(bw_mul(data->
2857 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
2858 calcs_output->nbp_state_change_wm_ns[2].a_mark =
2859 bw_fixed_to_int(bw_mul(data->
2860 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
2861
2862 if (ctx->dc->caps.max_slave_planes) {
2863 calcs_output->nbp_state_change_wm_ns[3].a_mark =
2864 bw_fixed_to_int(bw_mul(data->
2865 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
2866 calcs_output->nbp_state_change_wm_ns[4].a_mark =
2867 bw_fixed_to_int(bw_mul(data->
2868 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
2869 } else {
2870 calcs_output->nbp_state_change_wm_ns[3].a_mark =
2871 bw_fixed_to_int(bw_mul(data->
2872 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
2873 calcs_output->nbp_state_change_wm_ns[4].a_mark =
2874 bw_fixed_to_int(bw_mul(data->
2875 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
2876 }
2877 calcs_output->nbp_state_change_wm_ns[5].a_mark =
2878 bw_fixed_to_int(bw_mul(data->
2879 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
2880
2881
2882
2883 calcs_output->stutter_exit_wm_ns[0].a_mark =
2884 bw_fixed_to_int(bw_mul(data->
2885 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
2886 calcs_output->stutter_exit_wm_ns[1].a_mark =
2887 bw_fixed_to_int(bw_mul(data->
2888 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
2889 calcs_output->stutter_exit_wm_ns[2].a_mark =
2890 bw_fixed_to_int(bw_mul(data->
2891 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
2892 if (ctx->dc->caps.max_slave_planes) {
2893 calcs_output->stutter_exit_wm_ns[3].a_mark =
2894 bw_fixed_to_int(bw_mul(data->
2895 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
2896 calcs_output->stutter_exit_wm_ns[4].a_mark =
2897 bw_fixed_to_int(bw_mul(data->
2898 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
2899 } else {
2900 calcs_output->stutter_exit_wm_ns[3].a_mark =
2901 bw_fixed_to_int(bw_mul(data->
2902 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
2903 calcs_output->stutter_exit_wm_ns[4].a_mark =
2904 bw_fixed_to_int(bw_mul(data->
2905 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
2906 }
2907 calcs_output->stutter_exit_wm_ns[5].a_mark =
2908 bw_fixed_to_int(bw_mul(data->
2909 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
2910
2911
2912
2913 calcs_output->urgent_wm_ns[0].a_mark =
2914 bw_fixed_to_int(bw_mul(data->
2915 urgent_watermark[4], bw_int_to_fixed(1000)));
2916 calcs_output->urgent_wm_ns[1].a_mark =
2917 bw_fixed_to_int(bw_mul(data->
2918 urgent_watermark[5], bw_int_to_fixed(1000)));
2919 calcs_output->urgent_wm_ns[2].a_mark =
2920 bw_fixed_to_int(bw_mul(data->
2921 urgent_watermark[6], bw_int_to_fixed(1000)));
2922 if (ctx->dc->caps.max_slave_planes) {
2923 calcs_output->urgent_wm_ns[3].a_mark =
2924 bw_fixed_to_int(bw_mul(data->
2925 urgent_watermark[0], bw_int_to_fixed(1000)));
2926 calcs_output->urgent_wm_ns[4].a_mark =
2927 bw_fixed_to_int(bw_mul(data->
2928 urgent_watermark[1], bw_int_to_fixed(1000)));
2929 } else {
2930 calcs_output->urgent_wm_ns[3].a_mark =
2931 bw_fixed_to_int(bw_mul(data->
2932 urgent_watermark[7], bw_int_to_fixed(1000)));
2933 calcs_output->urgent_wm_ns[4].a_mark =
2934 bw_fixed_to_int(bw_mul(data->
2935 urgent_watermark[8], bw_int_to_fixed(1000)));
2936 }
2937 calcs_output->urgent_wm_ns[5].a_mark =
2938 bw_fixed_to_int(bw_mul(data->
2939 urgent_watermark[9], bw_int_to_fixed(1000)));
2940
2941 if (dceip->version != BW_CALCS_VERSION_CARRIZO) {
2942 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
2943 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
2944 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
2945 calculate_bandwidth(dceip, vbios, data);
2946
2947 calcs_output->nbp_state_change_wm_ns[0].b_mark =
2948 bw_fixed_to_int(bw_mul(data->
2949 nbp_state_change_watermark[4],bw_int_to_fixed(1000)));
2950 calcs_output->nbp_state_change_wm_ns[1].b_mark =
2951 bw_fixed_to_int(bw_mul(data->
2952 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
2953 calcs_output->nbp_state_change_wm_ns[2].b_mark =
2954 bw_fixed_to_int(bw_mul(data->
2955 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
2956
2957 if (ctx->dc->caps.max_slave_planes) {
2958 calcs_output->nbp_state_change_wm_ns[3].b_mark =
2959 bw_fixed_to_int(bw_mul(data->
2960 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
2961 calcs_output->nbp_state_change_wm_ns[4].b_mark =
2962 bw_fixed_to_int(bw_mul(data->
2963 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
2964 } else {
2965 calcs_output->nbp_state_change_wm_ns[3].b_mark =
2966 bw_fixed_to_int(bw_mul(data->
2967 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
2968 calcs_output->nbp_state_change_wm_ns[4].b_mark =
2969 bw_fixed_to_int(bw_mul(data->
2970 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
2971 }
2972 calcs_output->nbp_state_change_wm_ns[5].b_mark =
2973 bw_fixed_to_int(bw_mul(data->
2974 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
2975
2976
2977
2978 calcs_output->stutter_exit_wm_ns[0].b_mark =
2979 bw_fixed_to_int(bw_mul(data->
2980 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
2981 calcs_output->stutter_exit_wm_ns[1].b_mark =
2982 bw_fixed_to_int(bw_mul(data->
2983 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
2984 calcs_output->stutter_exit_wm_ns[2].b_mark =
2985 bw_fixed_to_int(bw_mul(data->
2986 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
2987 if (ctx->dc->caps.max_slave_planes) {
2988 calcs_output->stutter_exit_wm_ns[3].b_mark =
2989 bw_fixed_to_int(bw_mul(data->
2990 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
2991 calcs_output->stutter_exit_wm_ns[4].b_mark =
2992 bw_fixed_to_int(bw_mul(data->
2993 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
2994 } else {
2995 calcs_output->stutter_exit_wm_ns[3].b_mark =
2996 bw_fixed_to_int(bw_mul(data->
2997 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
2998 calcs_output->stutter_exit_wm_ns[4].b_mark =
2999 bw_fixed_to_int(bw_mul(data->
3000 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3001 }
3002 calcs_output->stutter_exit_wm_ns[5].b_mark =
3003 bw_fixed_to_int(bw_mul(data->
3004 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3005
3006
3007
3008 calcs_output->urgent_wm_ns[0].b_mark =
3009 bw_fixed_to_int(bw_mul(data->
3010 urgent_watermark[4], bw_int_to_fixed(1000)));
3011 calcs_output->urgent_wm_ns[1].b_mark =
3012 bw_fixed_to_int(bw_mul(data->
3013 urgent_watermark[5], bw_int_to_fixed(1000)));
3014 calcs_output->urgent_wm_ns[2].b_mark =
3015 bw_fixed_to_int(bw_mul(data->
3016 urgent_watermark[6], bw_int_to_fixed(1000)));
3017 if (ctx->dc->caps.max_slave_planes) {
3018 calcs_output->urgent_wm_ns[3].b_mark =
3019 bw_fixed_to_int(bw_mul(data->
3020 urgent_watermark[0], bw_int_to_fixed(1000)));
3021 calcs_output->urgent_wm_ns[4].b_mark =
3022 bw_fixed_to_int(bw_mul(data->
3023 urgent_watermark[1], bw_int_to_fixed(1000)));
3024 } else {
3025 calcs_output->urgent_wm_ns[3].b_mark =
3026 bw_fixed_to_int(bw_mul(data->
3027 urgent_watermark[7], bw_int_to_fixed(1000)));
3028 calcs_output->urgent_wm_ns[4].b_mark =
3029 bw_fixed_to_int(bw_mul(data->
3030 urgent_watermark[8], bw_int_to_fixed(1000)));
3031 }
3032 calcs_output->urgent_wm_ns[5].b_mark =
3033 bw_fixed_to_int(bw_mul(data->
3034 urgent_watermark[9], bw_int_to_fixed(1000)));
3035
3036 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3037 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3038 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3039 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3040 calculate_bandwidth(dceip, vbios, data);
3041
3042 calcs_output->nbp_state_change_wm_ns[0].c_mark =
3043 bw_fixed_to_int(bw_mul(data->
3044 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3045 calcs_output->nbp_state_change_wm_ns[1].c_mark =
3046 bw_fixed_to_int(bw_mul(data->
3047 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3048 calcs_output->nbp_state_change_wm_ns[2].c_mark =
3049 bw_fixed_to_int(bw_mul(data->
3050 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3051 if (ctx->dc->caps.max_slave_planes) {
3052 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3053 bw_fixed_to_int(bw_mul(data->
3054 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3055 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3056 bw_fixed_to_int(bw_mul(data->
3057 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3058 } else {
3059 calcs_output->nbp_state_change_wm_ns[3].c_mark =
3060 bw_fixed_to_int(bw_mul(data->
3061 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3062 calcs_output->nbp_state_change_wm_ns[4].c_mark =
3063 bw_fixed_to_int(bw_mul(data->
3064 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3065 }
3066 calcs_output->nbp_state_change_wm_ns[5].c_mark =
3067 bw_fixed_to_int(bw_mul(data->
3068 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3069
3070
3071 calcs_output->stutter_exit_wm_ns[0].c_mark =
3072 bw_fixed_to_int(bw_mul(data->
3073 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3074 calcs_output->stutter_exit_wm_ns[1].c_mark =
3075 bw_fixed_to_int(bw_mul(data->
3076 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3077 calcs_output->stutter_exit_wm_ns[2].c_mark =
3078 bw_fixed_to_int(bw_mul(data->
3079 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3080 if (ctx->dc->caps.max_slave_planes) {
3081 calcs_output->stutter_exit_wm_ns[3].c_mark =
3082 bw_fixed_to_int(bw_mul(data->
3083 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3084 calcs_output->stutter_exit_wm_ns[4].c_mark =
3085 bw_fixed_to_int(bw_mul(data->
3086 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3087 } else {
3088 calcs_output->stutter_exit_wm_ns[3].c_mark =
3089 bw_fixed_to_int(bw_mul(data->
3090 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3091 calcs_output->stutter_exit_wm_ns[4].c_mark =
3092 bw_fixed_to_int(bw_mul(data->
3093 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3094 }
3095 calcs_output->stutter_exit_wm_ns[5].c_mark =
3096 bw_fixed_to_int(bw_mul(data->
3097 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3098
3099 calcs_output->urgent_wm_ns[0].c_mark =
3100 bw_fixed_to_int(bw_mul(data->
3101 urgent_watermark[4], bw_int_to_fixed(1000)));
3102 calcs_output->urgent_wm_ns[1].c_mark =
3103 bw_fixed_to_int(bw_mul(data->
3104 urgent_watermark[5], bw_int_to_fixed(1000)));
3105 calcs_output->urgent_wm_ns[2].c_mark =
3106 bw_fixed_to_int(bw_mul(data->
3107 urgent_watermark[6], bw_int_to_fixed(1000)));
3108 if (ctx->dc->caps.max_slave_planes) {
3109 calcs_output->urgent_wm_ns[3].c_mark =
3110 bw_fixed_to_int(bw_mul(data->
3111 urgent_watermark[0], bw_int_to_fixed(1000)));
3112 calcs_output->urgent_wm_ns[4].c_mark =
3113 bw_fixed_to_int(bw_mul(data->
3114 urgent_watermark[1], bw_int_to_fixed(1000)));
3115 } else {
3116 calcs_output->urgent_wm_ns[3].c_mark =
3117 bw_fixed_to_int(bw_mul(data->
3118 urgent_watermark[7], bw_int_to_fixed(1000)));
3119 calcs_output->urgent_wm_ns[4].c_mark =
3120 bw_fixed_to_int(bw_mul(data->
3121 urgent_watermark[8], bw_int_to_fixed(1000)));
3122 }
3123 calcs_output->urgent_wm_ns[5].c_mark =
3124 bw_fixed_to_int(bw_mul(data->
3125 urgent_watermark[9], bw_int_to_fixed(1000)));
3126 }
3127
3128 if (dceip->version == BW_CALCS_VERSION_CARRIZO) {
3129 ((struct bw_calcs_vbios *)vbios)->low_yclk = high_yclk;
3130 ((struct bw_calcs_vbios *)vbios)->mid_yclk = high_yclk;
3131 ((struct bw_calcs_vbios *)vbios)->low_sclk = high_sclk;
3132 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = high_sclk;
3133 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = high_sclk;
3134 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = high_sclk;
3135 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = high_sclk;
3136 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = high_sclk;
3137 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = high_sclk;
3138 } else {
3139 ((struct bw_calcs_vbios *)vbios)->low_yclk = mid_yclk;
3140 ((struct bw_calcs_vbios *)vbios)->low_sclk = mid3_sclk;
3141 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid3_sclk;
3142 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid3_sclk;
3143 }
3144
3145 calculate_bandwidth(dceip, vbios, data);
3146
3147 calcs_output->nbp_state_change_wm_ns[0].d_mark =
3148 bw_fixed_to_int(bw_mul(data->
3149 nbp_state_change_watermark[4], bw_int_to_fixed(1000)));
3150 calcs_output->nbp_state_change_wm_ns[1].d_mark =
3151 bw_fixed_to_int(bw_mul(data->
3152 nbp_state_change_watermark[5], bw_int_to_fixed(1000)));
3153 calcs_output->nbp_state_change_wm_ns[2].d_mark =
3154 bw_fixed_to_int(bw_mul(data->
3155 nbp_state_change_watermark[6], bw_int_to_fixed(1000)));
3156 if (ctx->dc->caps.max_slave_planes) {
3157 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3158 bw_fixed_to_int(bw_mul(data->
3159 nbp_state_change_watermark[0], bw_int_to_fixed(1000)));
3160 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3161 bw_fixed_to_int(bw_mul(data->
3162 nbp_state_change_watermark[1], bw_int_to_fixed(1000)));
3163 } else {
3164 calcs_output->nbp_state_change_wm_ns[3].d_mark =
3165 bw_fixed_to_int(bw_mul(data->
3166 nbp_state_change_watermark[7], bw_int_to_fixed(1000)));
3167 calcs_output->nbp_state_change_wm_ns[4].d_mark =
3168 bw_fixed_to_int(bw_mul(data->
3169 nbp_state_change_watermark[8], bw_int_to_fixed(1000)));
3170 }
3171 calcs_output->nbp_state_change_wm_ns[5].d_mark =
3172 bw_fixed_to_int(bw_mul(data->
3173 nbp_state_change_watermark[9], bw_int_to_fixed(1000)));
3174
3175 calcs_output->stutter_exit_wm_ns[0].d_mark =
3176 bw_fixed_to_int(bw_mul(data->
3177 stutter_exit_watermark[4], bw_int_to_fixed(1000)));
3178 calcs_output->stutter_exit_wm_ns[1].d_mark =
3179 bw_fixed_to_int(bw_mul(data->
3180 stutter_exit_watermark[5], bw_int_to_fixed(1000)));
3181 calcs_output->stutter_exit_wm_ns[2].d_mark =
3182 bw_fixed_to_int(bw_mul(data->
3183 stutter_exit_watermark[6], bw_int_to_fixed(1000)));
3184 if (ctx->dc->caps.max_slave_planes) {
3185 calcs_output->stutter_exit_wm_ns[3].d_mark =
3186 bw_fixed_to_int(bw_mul(data->
3187 stutter_exit_watermark[0], bw_int_to_fixed(1000)));
3188 calcs_output->stutter_exit_wm_ns[4].d_mark =
3189 bw_fixed_to_int(bw_mul(data->
3190 stutter_exit_watermark[1], bw_int_to_fixed(1000)));
3191 } else {
3192 calcs_output->stutter_exit_wm_ns[3].d_mark =
3193 bw_fixed_to_int(bw_mul(data->
3194 stutter_exit_watermark[7], bw_int_to_fixed(1000)));
3195 calcs_output->stutter_exit_wm_ns[4].d_mark =
3196 bw_fixed_to_int(bw_mul(data->
3197 stutter_exit_watermark[8], bw_int_to_fixed(1000)));
3198 }
3199 calcs_output->stutter_exit_wm_ns[5].d_mark =
3200 bw_fixed_to_int(bw_mul(data->
3201 stutter_exit_watermark[9], bw_int_to_fixed(1000)));
3202
3203
3204 calcs_output->urgent_wm_ns[0].d_mark =
3205 bw_fixed_to_int(bw_mul(data->
3206 urgent_watermark[4], bw_int_to_fixed(1000)));
3207 calcs_output->urgent_wm_ns[1].d_mark =
3208 bw_fixed_to_int(bw_mul(data->
3209 urgent_watermark[5], bw_int_to_fixed(1000)));
3210 calcs_output->urgent_wm_ns[2].d_mark =
3211 bw_fixed_to_int(bw_mul(data->
3212 urgent_watermark[6], bw_int_to_fixed(1000)));
3213 if (ctx->dc->caps.max_slave_planes) {
3214 calcs_output->urgent_wm_ns[3].d_mark =
3215 bw_fixed_to_int(bw_mul(data->
3216 urgent_watermark[0], bw_int_to_fixed(1000)));
3217 calcs_output->urgent_wm_ns[4].d_mark =
3218 bw_fixed_to_int(bw_mul(data->
3219 urgent_watermark[1], bw_int_to_fixed(1000)));
3220 } else {
3221 calcs_output->urgent_wm_ns[3].d_mark =
3222 bw_fixed_to_int(bw_mul(data->
3223 urgent_watermark[7], bw_int_to_fixed(1000)));
3224 calcs_output->urgent_wm_ns[4].d_mark =
3225 bw_fixed_to_int(bw_mul(data->
3226 urgent_watermark[8], bw_int_to_fixed(1000)));
3227 }
3228 calcs_output->urgent_wm_ns[5].d_mark =
3229 bw_fixed_to_int(bw_mul(data->
3230 urgent_watermark[9], bw_int_to_fixed(1000)));
3231
3232 ((struct bw_calcs_vbios *)vbios)->low_yclk = low_yclk;
3233 ((struct bw_calcs_vbios *)vbios)->mid_yclk = mid_yclk;
3234 ((struct bw_calcs_vbios *)vbios)->low_sclk = low_sclk;
3235 ((struct bw_calcs_vbios *)vbios)->mid1_sclk = mid1_sclk;
3236 ((struct bw_calcs_vbios *)vbios)->mid2_sclk = mid2_sclk;
3237 ((struct bw_calcs_vbios *)vbios)->mid3_sclk = mid3_sclk;
3238 ((struct bw_calcs_vbios *)vbios)->mid4_sclk = mid4_sclk;
3239 ((struct bw_calcs_vbios *)vbios)->mid5_sclk = mid5_sclk;
3240 ((struct bw_calcs_vbios *)vbios)->mid6_sclk = mid6_sclk;
3241 ((struct bw_calcs_vbios *)vbios)->high_sclk = high_sclk;
3242 } else {
3243 calcs_output->nbp_state_change_enable = true;
3244 calcs_output->cpuc_state_change_enable = true;
3245 calcs_output->cpup_state_change_enable = true;
3246 calcs_output->stutter_mode_enable = true;
3247 calcs_output->dispclk_khz = 0;
9037d802 3248 calcs_output->sclk_khz = 0;
4562236b
HW
3249 }
3250
3251 dm_free(data);
3252
3253 return is_display_configuration_supported(vbios, calcs_output);
3254}