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