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