]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
7f7cb8ff124dbfeb6e14592e6b98c466da8d16e7
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / calcs / dcn_calcs.c
1 /*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26 #include "dm_services.h"
27 #include "dcn_calcs.h"
28 #include "dcn_calc_auto.h"
29 #include "dc.h"
30 #include "core_dc.h"
31 #include "dal_asic_id.h"
32
33 #include "resource.h"
34 #include "dcn10/dcn10_resource.h"
35 #include "dcn_calc_math.h"
36
37 /* Defaults from spreadsheet rev#247 */
38 const struct dcn_soc_bounding_box dcn10_soc_defaults = {
39 /* latencies */
40 .sr_exit_time = 17, /*us*/
41 .sr_enter_plus_exit_time = 19, /*us*/
42 .urgent_latency = 4, /*us*/
43 .dram_clock_change_latency = 17, /*us*/
44 .write_back_latency = 12, /*us*/
45 .percent_of_ideal_drambw_received_after_urg_latency = 80, /*%*/
46
47 /* below default clocks derived from STA target base on
48 * slow-slow corner + 10% margin with voltages aligned to FCLK.
49 *
50 * Use these value if fused value doesn't make sense as earlier
51 * part don't have correct value fused */
52 /* default DCF CLK DPM on RV*/
53 .dcfclkv_max0p9 = 655, /* MHz, = 3600/5.5 */
54 .dcfclkv_nom0p8 = 626, /* MHz, = 3600/5.75 */
55 .dcfclkv_mid0p72 = 600, /* MHz, = 3600/6, bypass */
56 .dcfclkv_min0p65 = 300, /* MHz, = 3600/12, bypass */
57
58 /* default DISP CLK voltage state on RV */
59 .max_dispclk_vmax0p9 = 1108, /* MHz, = 3600/3.25 */
60 .max_dispclk_vnom0p8 = 1029, /* MHz, = 3600/3.5 */
61 .max_dispclk_vmid0p72 = 960, /* MHz, = 3600/3.75 */
62 .max_dispclk_vmin0p65 = 626, /* MHz, = 3600/5.75 */
63
64 /* default DPP CLK voltage state on RV */
65 .max_dppclk_vmax0p9 = 720, /* MHz, = 3600/5 */
66 .max_dppclk_vnom0p8 = 686, /* MHz, = 3600/5.25 */
67 .max_dppclk_vmid0p72 = 626, /* MHz, = 3600/5.75 */
68 .max_dppclk_vmin0p65 = 400, /* MHz, = 3600/9 */
69
70 /* default PHY CLK voltage state on RV */
71 .phyclkv_max0p9 = 900, /*MHz*/
72 .phyclkv_nom0p8 = 847, /*MHz*/
73 .phyclkv_mid0p72 = 800, /*MHz*/
74 .phyclkv_min0p65 = 600, /*MHz*/
75
76 /* BW depend on FCLK, MCLK, # of channels */
77 /* dual channel BW */
78 .fabric_and_dram_bandwidth_vmax0p9 = 38.4f, /*GB/s*/
79 .fabric_and_dram_bandwidth_vnom0p8 = 34.133f, /*GB/s*/
80 .fabric_and_dram_bandwidth_vmid0p72 = 29.866f, /*GB/s*/
81 .fabric_and_dram_bandwidth_vmin0p65 = 12.8f, /*GB/s*/
82 /* single channel BW
83 .fabric_and_dram_bandwidth_vmax0p9 = 19.2f,
84 .fabric_and_dram_bandwidth_vnom0p8 = 17.066f,
85 .fabric_and_dram_bandwidth_vmid0p72 = 14.933f,
86 .fabric_and_dram_bandwidth_vmin0p65 = 12.8f,
87 */
88
89 .number_of_channels = 2,
90
91 .socclk = 208, /*MHz*/
92 .downspreading = 0.5f, /*%*/
93 .round_trip_ping_latency_cycles = 128, /*DCFCLK Cycles*/
94 .urgent_out_of_order_return_per_channel = 256, /*bytes*/
95 .vmm_page_size = 4096, /*bytes*/
96 .return_bus_width = 64, /*bytes*/
97 .max_request_size = 256, /*bytes*/
98
99 /* Depends on user class (client vs embedded, workstation, etc) */
100 .percent_disp_bw_limit = 0.3f /*%*/
101 };
102
103 const struct dcn_ip_params dcn10_ip_defaults = {
104 .rob_buffer_size_in_kbyte = 64,
105 .det_buffer_size_in_kbyte = 164,
106 .dpp_output_buffer_pixels = 2560,
107 .opp_output_buffer_lines = 1,
108 .pixel_chunk_size_in_kbyte = 8,
109 .pte_enable = dcn_bw_yes,
110 .pte_chunk_size = 2, /*kbytes*/
111 .meta_chunk_size = 2, /*kbytes*/
112 .writeback_chunk_size = 2, /*kbytes*/
113 .odm_capability = dcn_bw_no,
114 .dsc_capability = dcn_bw_no,
115 .line_buffer_size = 589824, /*bit*/
116 .max_line_buffer_lines = 12,
117 .is_line_buffer_bpp_fixed = dcn_bw_no,
118 .line_buffer_fixed_bpp = dcn_bw_na,
119 .writeback_luma_buffer_size = 12, /*kbytes*/
120 .writeback_chroma_buffer_size = 8, /*kbytes*/
121 .max_num_dpp = 4,
122 .max_num_writeback = 2,
123 .max_dchub_topscl_throughput = 4, /*pixels/dppclk*/
124 .max_pscl_tolb_throughput = 2, /*pixels/dppclk*/
125 .max_lb_tovscl_throughput = 4, /*pixels/dppclk*/
126 .max_vscl_tohscl_throughput = 4, /*pixels/dppclk*/
127 .max_hscl_ratio = 4,
128 .max_vscl_ratio = 4,
129 .max_hscl_taps = 8,
130 .max_vscl_taps = 8,
131 .pte_buffer_size_in_requests = 42,
132 .dispclk_ramping_margin = 1, /*%*/
133 .under_scan_factor = 1.11f,
134 .max_inter_dcn_tile_repeaters = 8,
135 .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = dcn_bw_no,
136 .bug_forcing_luma_and_chroma_request_to_same_size_fixed = dcn_bw_no,
137 .dcfclk_cstate_latency = 10 /*TODO clone of something else? sr_enter_plus_exit_time?*/
138 };
139
140 static enum dcn_bw_defs tl_sw_mode_to_bw_defs(enum swizzle_mode_values sw_mode)
141 {
142 switch (sw_mode) {
143 case DC_SW_LINEAR:
144 return dcn_bw_sw_linear;
145 case DC_SW_4KB_S:
146 return dcn_bw_sw_4_kb_s;
147 case DC_SW_4KB_D:
148 return dcn_bw_sw_4_kb_d;
149 case DC_SW_64KB_S:
150 return dcn_bw_sw_64_kb_s;
151 case DC_SW_64KB_D:
152 return dcn_bw_sw_64_kb_d;
153 case DC_SW_VAR_S:
154 return dcn_bw_sw_var_s;
155 case DC_SW_VAR_D:
156 return dcn_bw_sw_var_d;
157 case DC_SW_64KB_S_T:
158 return dcn_bw_sw_64_kb_s_t;
159 case DC_SW_64KB_D_T:
160 return dcn_bw_sw_64_kb_d_t;
161 case DC_SW_4KB_S_X:
162 return dcn_bw_sw_4_kb_s_x;
163 case DC_SW_4KB_D_X:
164 return dcn_bw_sw_4_kb_d_x;
165 case DC_SW_64KB_S_X:
166 return dcn_bw_sw_64_kb_s_x;
167 case DC_SW_64KB_D_X:
168 return dcn_bw_sw_64_kb_d_x;
169 case DC_SW_VAR_S_X:
170 return dcn_bw_sw_var_s_x;
171 case DC_SW_VAR_D_X:
172 return dcn_bw_sw_var_d_x;
173 case DC_SW_256B_S:
174 case DC_SW_256_D:
175 case DC_SW_256_R:
176 case DC_SW_4KB_R:
177 case DC_SW_64KB_R:
178 case DC_SW_VAR_R:
179 case DC_SW_4KB_R_X:
180 case DC_SW_64KB_R_X:
181 case DC_SW_VAR_R_X:
182 default:
183 BREAK_TO_DEBUGGER(); /*not in formula*/
184 return dcn_bw_sw_4_kb_s;
185 }
186 }
187
188 static int tl_lb_bpp_to_int(enum lb_pixel_depth depth)
189 {
190 switch (depth) {
191 case LB_PIXEL_DEPTH_18BPP:
192 return 18;
193 case LB_PIXEL_DEPTH_24BPP:
194 return 24;
195 case LB_PIXEL_DEPTH_30BPP:
196 return 30;
197 case LB_PIXEL_DEPTH_36BPP:
198 return 36;
199 default:
200 return 30;
201 }
202 }
203
204 static enum dcn_bw_defs tl_pixel_format_to_bw_defs(enum surface_pixel_format format)
205 {
206 switch (format) {
207 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
208 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
209 return dcn_bw_rgb_sub_16;
210 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
211 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
212 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
213 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
214 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
215 return dcn_bw_rgb_sub_32;
216 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
217 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
218 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
219 return dcn_bw_rgb_sub_64;
220 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
221 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
222 return dcn_bw_yuv420_sub_8;
223 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
224 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
225 return dcn_bw_yuv420_sub_10;
226 default:
227 return dcn_bw_rgb_sub_32;
228 }
229 }
230
231 static void pipe_ctx_to_e2e_pipe_params (
232 const struct pipe_ctx *pipe,
233 struct _vcs_dpi_display_pipe_params_st *input)
234 {
235 input->src.is_hsplit = false;
236 if (pipe->top_pipe != NULL && pipe->top_pipe->surface == pipe->surface)
237 input->src.is_hsplit = true;
238 else if (pipe->bottom_pipe != NULL && pipe->bottom_pipe->surface == pipe->surface)
239 input->src.is_hsplit = true;
240
241 input->src.dcc = pipe->surface->dcc.enable;
242 input->src.dcc_rate = 1;
243 input->src.meta_pitch = pipe->surface->dcc.grph.meta_pitch;
244 input->src.source_scan = dm_horz;
245 input->src.sw_mode = pipe->surface->tiling_info.gfx9.swizzle;
246
247 input->src.viewport_width = pipe->scl_data.viewport.width;
248 input->src.viewport_height = pipe->scl_data.viewport.height;
249 input->src.data_pitch = pipe->scl_data.viewport.width;
250 input->src.data_pitch_c = pipe->scl_data.viewport.width;
251 input->src.cur0_src_width = 128; /* TODO: Cursor calcs, not curently stored */
252 input->src.cur0_bpp = 32;
253
254 switch (pipe->surface->tiling_info.gfx9.swizzle) {
255 /* for 4/8/16 high tiles */
256 case DC_SW_LINEAR:
257 input->src.is_display_sw = 1;
258 input->src.macro_tile_size = dm_4k_tile;
259 break;
260 case DC_SW_4KB_S:
261 case DC_SW_4KB_S_X:
262 input->src.is_display_sw = 0;
263 input->src.macro_tile_size = dm_4k_tile;
264 break;
265 case DC_SW_64KB_S:
266 case DC_SW_64KB_S_X:
267 case DC_SW_64KB_S_T:
268 input->src.is_display_sw = 0;
269 input->src.macro_tile_size = dm_64k_tile;
270 break;
271 case DC_SW_VAR_S:
272 case DC_SW_VAR_S_X:
273 input->src.is_display_sw = 0;
274 input->src.macro_tile_size = dm_256k_tile;
275 break;
276
277 /* For 64bpp 2 high tiles */
278 case DC_SW_4KB_D:
279 case DC_SW_4KB_D_X:
280 input->src.is_display_sw = 1;
281 input->src.macro_tile_size = dm_4k_tile;
282 break;
283 case DC_SW_64KB_D:
284 case DC_SW_64KB_D_X:
285 case DC_SW_64KB_D_T:
286 input->src.is_display_sw = 1;
287 input->src.macro_tile_size = dm_64k_tile;
288 break;
289 case DC_SW_VAR_D:
290 case DC_SW_VAR_D_X:
291 input->src.is_display_sw = 1;
292 input->src.macro_tile_size = dm_256k_tile;
293 break;
294
295 /* Unsupported swizzle modes for dcn */
296 case DC_SW_256B_S:
297 default:
298 ASSERT(0); /* Not supported */
299 break;
300 }
301
302 switch (pipe->surface->rotation) {
303 case ROTATION_ANGLE_0:
304 case ROTATION_ANGLE_180:
305 input->src.source_scan = dm_horz;
306 break;
307 case ROTATION_ANGLE_90:
308 case ROTATION_ANGLE_270:
309 input->src.source_scan = dm_vert;
310 break;
311 default:
312 ASSERT(0); /* Not supported */
313 break;
314 }
315
316 /* TODO: Fix pixel format mappings */
317 switch (pipe->surface->format) {
318 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
319 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
320 input->src.source_format = dm_420_8;
321 input->src.viewport_width_c = input->src.viewport_width / 2;
322 input->src.viewport_height_c = input->src.viewport_height / 2;
323 break;
324 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
325 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
326 input->src.source_format = dm_420_10;
327 input->src.viewport_width_c = input->src.viewport_width / 2;
328 input->src.viewport_height_c = input->src.viewport_height / 2;
329 break;
330 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
331 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
332 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
333 input->src.source_format = dm_444_64;
334 input->src.viewport_width_c = input->src.viewport_width;
335 input->src.viewport_height_c = input->src.viewport_height;
336 break;
337 default:
338 input->src.source_format = dm_444_32;
339 input->src.viewport_width_c = input->src.viewport_width;
340 input->src.viewport_height_c = input->src.viewport_height;
341 break;
342 }
343
344 input->scale_taps.htaps = pipe->scl_data.taps.h_taps;
345 input->scale_ratio_depth.hscl_ratio = pipe->scl_data.ratios.horz.value/4294967296.0;
346 input->scale_ratio_depth.vscl_ratio = pipe->scl_data.ratios.vert.value/4294967296.0;
347 input->scale_ratio_depth.vinit = pipe->scl_data.inits.v.value/4294967296.0;
348 if (input->scale_ratio_depth.vinit < 1.0)
349 input->scale_ratio_depth.vinit = 1;
350 input->scale_taps.vtaps = pipe->scl_data.taps.v_taps;
351 input->scale_taps.vtaps_c = pipe->scl_data.taps.v_taps_c;
352 input->scale_taps.htaps_c = pipe->scl_data.taps.h_taps_c;
353 input->scale_ratio_depth.hscl_ratio_c = pipe->scl_data.ratios.horz_c.value/4294967296.0;
354 input->scale_ratio_depth.vscl_ratio_c = pipe->scl_data.ratios.vert_c.value/4294967296.0;
355 input->scale_ratio_depth.vinit_c = pipe->scl_data.inits.v_c.value/4294967296.0;
356 if (input->scale_ratio_depth.vinit_c < 1.0)
357 input->scale_ratio_depth.vinit_c = 1;
358 switch (pipe->scl_data.lb_params.depth) {
359 case LB_PIXEL_DEPTH_30BPP:
360 input->scale_ratio_depth.lb_depth = 30; break;
361 case LB_PIXEL_DEPTH_36BPP:
362 input->scale_ratio_depth.lb_depth = 36; break;
363 default:
364 input->scale_ratio_depth.lb_depth = 24; break;
365 }
366
367
368 input->dest.vactive = pipe->stream->timing.v_addressable;
369
370 input->dest.recout_width = pipe->scl_data.recout.width;
371 input->dest.recout_height = pipe->scl_data.recout.height;
372
373 input->dest.full_recout_width = pipe->scl_data.recout.width;
374 input->dest.full_recout_height = pipe->scl_data.recout.height;
375
376 input->dest.htotal = pipe->stream->timing.h_total;
377 input->dest.hblank_start = input->dest.htotal - pipe->stream->timing.h_front_porch;
378 input->dest.hblank_end = input->dest.hblank_start
379 - pipe->stream->timing.h_addressable
380 - pipe->stream->timing.h_border_left
381 - pipe->stream->timing.h_border_right;
382
383 input->dest.vtotal = pipe->stream->timing.v_total;
384 input->dest.vblank_start = input->dest.vtotal - pipe->stream->timing.v_front_porch;
385 input->dest.vblank_end = input->dest.vblank_start
386 - pipe->stream->timing.v_addressable
387 - pipe->stream->timing.v_border_bottom
388 - pipe->stream->timing.v_border_top;
389
390 input->dest.vsync_plus_back_porch = pipe->stream->timing.v_total
391 - pipe->stream->timing.v_addressable
392 - pipe->stream->timing.v_front_porch;
393 input->dest.pixel_rate_mhz = pipe->stream->timing.pix_clk_khz/1000.0;
394 input->dest.vstartup_start = pipe->pipe_dlg_param.vstartup_start;
395 input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
396 input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset;
397 input->dest.vupdate_width = pipe->pipe_dlg_param.vupdate_width;
398
399 }
400
401 static void dcn_bw_calc_rq_dlg_ttu(
402 const struct core_dc *dc,
403 const struct dcn_bw_internal_vars *v,
404 struct pipe_ctx *pipe)
405 {
406 struct display_mode_lib *dml = (struct display_mode_lib *)(&dc->dml);
407 struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &pipe->dlg_regs;
408 struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &pipe->ttu_regs;
409 struct _vcs_dpi_display_rq_regs_st *rq_regs = &pipe->rq_regs;
410 struct _vcs_dpi_display_rq_params_st rq_param = {0};
411 struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0};
412 struct _vcs_dpi_display_e2e_pipe_params_st input = { { { 0 } } };
413 float total_active_bw = 0;
414 float total_prefetch_bw = 0;
415 int total_flip_bytes = 0;
416 int i;
417
418 for (i = 0; i < number_of_planes; i++) {
419 total_active_bw += v->read_bandwidth[i];
420 total_prefetch_bw += v->prefetch_bandwidth[i];
421 total_flip_bytes += v->total_immediate_flip_bytes[i];
422 }
423 dlg_sys_param.total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw);
424 if (dlg_sys_param.total_flip_bw < 0.0)
425 dlg_sys_param.total_flip_bw = 0;
426
427 dlg_sys_param.t_mclk_wm_us = v->dram_clock_change_watermark;
428 dlg_sys_param.t_sr_wm_us = v->stutter_enter_plus_exit_watermark;
429 dlg_sys_param.t_urg_wm_us = v->urgent_watermark;
430 dlg_sys_param.t_extra_us = v->urgent_extra_latency;
431 dlg_sys_param.deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep;
432 dlg_sys_param.total_flip_bytes = total_flip_bytes;
433
434 pipe_ctx_to_e2e_pipe_params(pipe, &input.pipe);
435 input.clks_cfg.dcfclk_mhz = v->dcfclk;
436 input.clks_cfg.dispclk_mhz = v->dispclk;
437 input.clks_cfg.dppclk_mhz = v->dppclk;
438 input.clks_cfg.refclk_mhz = dc->res_pool->ref_clock_inKhz/1000;
439 input.clks_cfg.socclk_mhz = v->socclk;
440 input.clks_cfg.voltage = v->voltage_level;
441 // dc->dml.logger = pool->base.logger;
442
443 /*todo: soc->sr_enter_plus_exit_time??*/
444 dlg_sys_param.t_srx_delay_us = dc->dcn_ip.dcfclk_cstate_latency / v->dcf_clk_deep_sleep;
445
446 dml_rq_dlg_get_rq_params(dml, &rq_param, input.pipe.src);
447 extract_rq_regs(dml, rq_regs, rq_param);
448 dml_rq_dlg_get_dlg_params(
449 dml,
450 dlg_regs,
451 ttu_regs,
452 rq_param.dlg,
453 dlg_sys_param,
454 input,
455 true,
456 true,
457 v->pte_enable == dcn_bw_yes,
458 pipe->surface->flip_immediate);
459 }
460
461 static void dcn_dml_wm_override(
462 const struct dcn_bw_internal_vars *v,
463 struct display_mode_lib *dml,
464 struct validate_context *context,
465 const struct resource_pool *pool)
466 {
467 int i, in_idx, active_count;
468
469 struct _vcs_dpi_display_e2e_pipe_params_st *input = dm_alloc(pool->pipe_count *
470 sizeof(struct _vcs_dpi_display_e2e_pipe_params_st));
471 struct wm {
472 double urgent;
473 struct _vcs_dpi_cstate_pstate_watermarks_st cpstate;
474 double pte_meta_urgent;
475 } a;
476
477
478 for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
479 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
480
481 if (!pipe->stream || !pipe->surface)
482 continue;
483
484 input[in_idx].clks_cfg.dcfclk_mhz = v->dcfclk;
485 input[in_idx].clks_cfg.dispclk_mhz = v->dispclk;
486 input[in_idx].clks_cfg.dppclk_mhz = v->dppclk;
487 input[in_idx].clks_cfg.refclk_mhz = pool->ref_clock_inKhz / 1000;
488 input[in_idx].clks_cfg.socclk_mhz = v->socclk;
489 input[in_idx].clks_cfg.voltage = v->voltage_level;
490 pipe_ctx_to_e2e_pipe_params(pipe, &input[in_idx].pipe);
491 dml_rq_dlg_get_rq_reg(
492 dml,
493 &pipe->rq_regs,
494 input[in_idx].pipe.src);
495 in_idx++;
496 }
497 active_count = in_idx;
498
499 a.urgent = dml_wm_urgent_e2e(dml, input, active_count);
500 a.cpstate = dml_wm_cstate_pstate_e2e(dml, input, active_count);
501 a.pte_meta_urgent = dml_wm_pte_meta_urgent(dml, a.urgent);
502
503 context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
504 a.cpstate.cstate_exit_us * 1000;
505 context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
506 a.cpstate.cstate_enter_plus_exit_us * 1000;
507 context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
508 a.cpstate.pstate_change_us * 1000;
509 context->bw.dcn.watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000;
510 context->bw.dcn.watermarks.a.urgent_ns = a.urgent * 1000;
511 context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
512 context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
513 context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
514
515
516 for (i = 0, in_idx = 0; i < pool->pipe_count; i++) {
517 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
518
519 if (!pipe->stream || !pipe->surface)
520 continue;
521
522 dml_rq_dlg_get_dlg_reg(dml,
523 &pipe->dlg_regs,
524 &pipe->ttu_regs,
525 input, active_count,
526 in_idx,
527 true,
528 true,
529 v->pte_enable == dcn_bw_yes,
530 pipe->surface->flip_immediate);
531 in_idx++;
532 }
533 dm_free(input);
534 }
535
536 static void split_stream_across_pipes(
537 struct resource_context *res_ctx,
538 const struct resource_pool *pool,
539 struct pipe_ctx *primary_pipe,
540 struct pipe_ctx *secondary_pipe)
541 {
542 int pipe_idx = secondary_pipe->pipe_idx;
543
544 if (!primary_pipe->surface)
545 return;
546
547 *secondary_pipe = *primary_pipe;
548
549 secondary_pipe->pipe_idx = pipe_idx;
550 secondary_pipe->mi = pool->mis[secondary_pipe->pipe_idx];
551 secondary_pipe->ipp = pool->ipps[secondary_pipe->pipe_idx];
552 secondary_pipe->xfm = pool->transforms[secondary_pipe->pipe_idx];
553 if (primary_pipe->bottom_pipe) {
554 secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe;
555 secondary_pipe->bottom_pipe->top_pipe = secondary_pipe;
556 }
557 primary_pipe->bottom_pipe = secondary_pipe;
558 secondary_pipe->top_pipe = primary_pipe;
559
560 resource_build_scaling_params(primary_pipe);
561 resource_build_scaling_params(secondary_pipe);
562 }
563
564 static void calc_wm_sets_and_perf_params(
565 struct validate_context *context,
566 struct dcn_bw_internal_vars *v)
567 {
568 /* Calculate set A last to keep internal var state consistent for required config */
569 if (v->voltage_level < 2) {
570 v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vnom0p8;
571 v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vnom0p8;
572 v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vnom0p8;
573 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v);
574
575 context->bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns =
576 v->stutter_exit_watermark * 1000;
577 context->bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns =
578 v->stutter_enter_plus_exit_watermark * 1000;
579 context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns =
580 v->dram_clock_change_watermark * 1000;
581 context->bw.dcn.watermarks.b.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000;
582 context->bw.dcn.watermarks.b.urgent_ns = v->urgent_watermark * 1000;
583
584 v->dcfclk_per_state[1] = v->dcfclkv_nom0p8;
585 v->dcfclk_per_state[0] = v->dcfclkv_nom0p8;
586 v->dcfclk = v->dcfclkv_nom0p8;
587 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v);
588
589 context->bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns =
590 v->stutter_exit_watermark * 1000;
591 context->bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns =
592 v->stutter_enter_plus_exit_watermark * 1000;
593 context->bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns =
594 v->dram_clock_change_watermark * 1000;
595 context->bw.dcn.watermarks.c.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000;
596 context->bw.dcn.watermarks.c.urgent_ns = v->urgent_watermark * 1000;
597 }
598
599 if (v->voltage_level < 3) {
600 v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vmax0p9;
601 v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmax0p9;
602 v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmax0p9;
603 v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vmax0p9;
604 v->dcfclk_per_state[2] = v->dcfclkv_max0p9;
605 v->dcfclk_per_state[1] = v->dcfclkv_max0p9;
606 v->dcfclk_per_state[0] = v->dcfclkv_max0p9;
607 v->dcfclk = v->dcfclkv_max0p9;
608 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v);
609
610 context->bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns =
611 v->stutter_exit_watermark * 1000;
612 context->bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns =
613 v->stutter_enter_plus_exit_watermark * 1000;
614 context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns =
615 v->dram_clock_change_watermark * 1000;
616 context->bw.dcn.watermarks.d.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000;
617 context->bw.dcn.watermarks.d.urgent_ns = v->urgent_watermark * 1000;
618 }
619
620 v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8;
621 v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72;
622 v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65;
623 v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_per_state[v->voltage_level];
624 v->dcfclk_per_state[2] = v->dcfclkv_nom0p8;
625 v->dcfclk_per_state[1] = v->dcfclkv_mid0p72;
626 v->dcfclk_per_state[0] = v->dcfclkv_min0p65;
627 v->dcfclk = v->dcfclk_per_state[v->voltage_level];
628 dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v);
629
630 context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns =
631 v->stutter_exit_watermark * 1000;
632 context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns =
633 v->stutter_enter_plus_exit_watermark * 1000;
634 context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns =
635 v->dram_clock_change_watermark * 1000;
636 context->bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000;
637 context->bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000;
638 if (v->voltage_level >= 2) {
639 context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a;
640 context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a;
641 }
642 if (v->voltage_level >= 3)
643 context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a;
644 }
645
646 static bool dcn_bw_apply_registry_override(struct core_dc *dc)
647 {
648 bool updated = false;
649
650 kernel_fpu_begin();
651 if ((int)(dc->dcn_soc.sr_exit_time * 1000) != dc->public.debug.sr_exit_time_ns
652 && dc->public.debug.sr_exit_time_ns) {
653 updated = true;
654 dc->dcn_soc.sr_exit_time = dc->public.debug.sr_exit_time_ns / 1000.0;
655 }
656
657 if ((int)(dc->dcn_soc.sr_enter_plus_exit_time * 1000)
658 != dc->public.debug.sr_enter_plus_exit_time_ns
659 && dc->public.debug.sr_enter_plus_exit_time_ns) {
660 updated = true;
661 dc->dcn_soc.sr_enter_plus_exit_time =
662 dc->public.debug.sr_enter_plus_exit_time_ns / 1000.0;
663 }
664
665 if ((int)(dc->dcn_soc.urgent_latency * 1000) != dc->public.debug.urgent_latency_ns
666 && dc->public.debug.urgent_latency_ns) {
667 updated = true;
668 dc->dcn_soc.urgent_latency = dc->public.debug.urgent_latency_ns / 1000.0;
669 }
670
671 if ((int)(dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency * 1000)
672 != dc->public.debug.percent_of_ideal_drambw
673 && dc->public.debug.percent_of_ideal_drambw) {
674 updated = true;
675 dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency =
676 dc->public.debug.percent_of_ideal_drambw;
677 }
678
679 if ((int)(dc->dcn_soc.dram_clock_change_latency * 1000)
680 != dc->public.debug.dram_clock_change_latency_ns
681 && dc->public.debug.dram_clock_change_latency_ns) {
682 updated = true;
683 dc->dcn_soc.dram_clock_change_latency =
684 dc->public.debug.dram_clock_change_latency_ns / 1000.0;
685 }
686 kernel_fpu_end();
687
688 return updated;
689 }
690
691 bool dcn_validate_bandwidth(
692 const struct core_dc *dc,
693 struct validate_context *context)
694 {
695 const struct resource_pool *pool = dc->res_pool;
696 struct dcn_bw_internal_vars *v = &context->dcn_bw_vars;
697 int i, input_idx;
698 int vesa_sync_start, asic_blank_end, asic_blank_start;
699 bool bw_limit_pass;
700 float bw_limit;
701
702 if (dcn_bw_apply_registry_override(DC_TO_CORE(&dc->public)))
703 dcn_bw_sync_calcs_and_dml(DC_TO_CORE(&dc->public));
704
705 memset(v, 0, sizeof(*v));
706 kernel_fpu_begin();
707 v->sr_exit_time = dc->dcn_soc.sr_exit_time;
708 v->sr_enter_plus_exit_time = dc->dcn_soc.sr_enter_plus_exit_time;
709 v->urgent_latency = dc->dcn_soc.urgent_latency;
710 v->write_back_latency = dc->dcn_soc.write_back_latency;
711 v->percent_of_ideal_drambw_received_after_urg_latency =
712 dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency;
713
714 v->dcfclkv_min0p65 = dc->dcn_soc.dcfclkv_min0p65;
715 v->dcfclkv_mid0p72 = dc->dcn_soc.dcfclkv_mid0p72;
716 v->dcfclkv_nom0p8 = dc->dcn_soc.dcfclkv_nom0p8;
717 v->dcfclkv_max0p9 = dc->dcn_soc.dcfclkv_max0p9;
718
719 v->max_dispclk_vmin0p65 = dc->dcn_soc.max_dispclk_vmin0p65;
720 v->max_dispclk_vmid0p72 = dc->dcn_soc.max_dispclk_vmid0p72;
721 v->max_dispclk_vnom0p8 = dc->dcn_soc.max_dispclk_vnom0p8;
722 v->max_dispclk_vmax0p9 = dc->dcn_soc.max_dispclk_vmax0p9;
723
724 v->max_dppclk_vmin0p65 = dc->dcn_soc.max_dppclk_vmin0p65;
725 v->max_dppclk_vmid0p72 = dc->dcn_soc.max_dppclk_vmid0p72;
726 v->max_dppclk_vnom0p8 = dc->dcn_soc.max_dppclk_vnom0p8;
727 v->max_dppclk_vmax0p9 = dc->dcn_soc.max_dppclk_vmax0p9;
728
729 v->socclk = dc->dcn_soc.socclk;
730
731 v->fabric_and_dram_bandwidth_vmin0p65 = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65;
732 v->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72;
733 v->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8;
734 v->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9;
735
736 v->phyclkv_min0p65 = dc->dcn_soc.phyclkv_min0p65;
737 v->phyclkv_mid0p72 = dc->dcn_soc.phyclkv_mid0p72;
738 v->phyclkv_nom0p8 = dc->dcn_soc.phyclkv_nom0p8;
739 v->phyclkv_max0p9 = dc->dcn_soc.phyclkv_max0p9;
740
741 v->downspreading = dc->dcn_soc.downspreading;
742 v->round_trip_ping_latency_cycles = dc->dcn_soc.round_trip_ping_latency_cycles;
743 v->urgent_out_of_order_return_per_channel = dc->dcn_soc.urgent_out_of_order_return_per_channel;
744 v->number_of_channels = dc->dcn_soc.number_of_channels;
745 v->vmm_page_size = dc->dcn_soc.vmm_page_size;
746 v->dram_clock_change_latency = dc->dcn_soc.dram_clock_change_latency;
747 v->return_bus_width = dc->dcn_soc.return_bus_width;
748
749 v->rob_buffer_size_in_kbyte = dc->dcn_ip.rob_buffer_size_in_kbyte;
750 v->det_buffer_size_in_kbyte = dc->dcn_ip.det_buffer_size_in_kbyte;
751 v->dpp_output_buffer_pixels = dc->dcn_ip.dpp_output_buffer_pixels;
752 v->opp_output_buffer_lines = dc->dcn_ip.opp_output_buffer_lines;
753 v->pixel_chunk_size_in_kbyte = dc->dcn_ip.pixel_chunk_size_in_kbyte;
754 v->pte_enable = dc->dcn_ip.pte_enable;
755 v->pte_chunk_size = dc->dcn_ip.pte_chunk_size;
756 v->meta_chunk_size = dc->dcn_ip.meta_chunk_size;
757 v->writeback_chunk_size = dc->dcn_ip.writeback_chunk_size;
758 v->odm_capability = dc->dcn_ip.odm_capability;
759 v->dsc_capability = dc->dcn_ip.dsc_capability;
760 v->line_buffer_size = dc->dcn_ip.line_buffer_size;
761 v->is_line_buffer_bpp_fixed = dc->dcn_ip.is_line_buffer_bpp_fixed;
762 v->line_buffer_fixed_bpp = dc->dcn_ip.line_buffer_fixed_bpp;
763 v->max_line_buffer_lines = dc->dcn_ip.max_line_buffer_lines;
764 v->writeback_luma_buffer_size = dc->dcn_ip.writeback_luma_buffer_size;
765 v->writeback_chroma_buffer_size = dc->dcn_ip.writeback_chroma_buffer_size;
766 v->max_num_dpp = dc->dcn_ip.max_num_dpp;
767 v->max_num_writeback = dc->dcn_ip.max_num_writeback;
768 v->max_dchub_topscl_throughput = dc->dcn_ip.max_dchub_topscl_throughput;
769 v->max_pscl_tolb_throughput = dc->dcn_ip.max_pscl_tolb_throughput;
770 v->max_lb_tovscl_throughput = dc->dcn_ip.max_lb_tovscl_throughput;
771 v->max_vscl_tohscl_throughput = dc->dcn_ip.max_vscl_tohscl_throughput;
772 v->max_hscl_ratio = dc->dcn_ip.max_hscl_ratio;
773 v->max_vscl_ratio = dc->dcn_ip.max_vscl_ratio;
774 v->max_hscl_taps = dc->dcn_ip.max_hscl_taps;
775 v->max_vscl_taps = dc->dcn_ip.max_vscl_taps;
776 v->under_scan_factor = dc->dcn_ip.under_scan_factor;
777 v->pte_buffer_size_in_requests = dc->dcn_ip.pte_buffer_size_in_requests;
778 v->dispclk_ramping_margin = dc->dcn_ip.dispclk_ramping_margin;
779 v->max_inter_dcn_tile_repeaters = dc->dcn_ip.max_inter_dcn_tile_repeaters;
780 v->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one =
781 dc->dcn_ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one;
782 v->bug_forcing_luma_and_chroma_request_to_same_size_fixed =
783 dc->dcn_ip.bug_forcing_luma_and_chroma_request_to_same_size_fixed;
784
785 v->voltage[5] = dcn_bw_no_support;
786 v->voltage[4] = dcn_bw_v_max0p9;
787 v->voltage[3] = dcn_bw_v_max0p9;
788 v->voltage[2] = dcn_bw_v_nom0p8;
789 v->voltage[1] = dcn_bw_v_mid0p72;
790 v->voltage[0] = dcn_bw_v_min0p65;
791 v->fabric_and_dram_bandwidth_per_state[5] = v->fabric_and_dram_bandwidth_vmax0p9;
792 v->fabric_and_dram_bandwidth_per_state[4] = v->fabric_and_dram_bandwidth_vmax0p9;
793 v->fabric_and_dram_bandwidth_per_state[3] = v->fabric_and_dram_bandwidth_vmax0p9;
794 v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8;
795 v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72;
796 v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65;
797 v->dcfclk_per_state[5] = v->dcfclkv_max0p9;
798 v->dcfclk_per_state[4] = v->dcfclkv_max0p9;
799 v->dcfclk_per_state[3] = v->dcfclkv_max0p9;
800 v->dcfclk_per_state[2] = v->dcfclkv_nom0p8;
801 v->dcfclk_per_state[1] = v->dcfclkv_mid0p72;
802 v->dcfclk_per_state[0] = v->dcfclkv_min0p65;
803 v->max_dispclk[5] = v->max_dispclk_vmax0p9;
804 v->max_dispclk[4] = v->max_dispclk_vmax0p9;
805 v->max_dispclk[3] = v->max_dispclk_vmax0p9;
806 v->max_dispclk[2] = v->max_dispclk_vnom0p8;
807 v->max_dispclk[1] = v->max_dispclk_vmid0p72;
808 v->max_dispclk[0] = v->max_dispclk_vmin0p65;
809 v->max_dppclk[5] = v->max_dppclk_vmax0p9;
810 v->max_dppclk[4] = v->max_dppclk_vmax0p9;
811 v->max_dppclk[3] = v->max_dppclk_vmax0p9;
812 v->max_dppclk[2] = v->max_dppclk_vnom0p8;
813 v->max_dppclk[1] = v->max_dppclk_vmid0p72;
814 v->max_dppclk[0] = v->max_dppclk_vmin0p65;
815 v->phyclk_per_state[5] = v->phyclkv_max0p9;
816 v->phyclk_per_state[4] = v->phyclkv_max0p9;
817 v->phyclk_per_state[3] = v->phyclkv_max0p9;
818 v->phyclk_per_state[2] = v->phyclkv_nom0p8;
819 v->phyclk_per_state[1] = v->phyclkv_mid0p72;
820 v->phyclk_per_state[0] = v->phyclkv_min0p65;
821
822 if (dc->public.debug.disable_pipe_split) {
823 v->max_dispclk[0] = v->max_dppclk_vmin0p65;
824 }
825
826 if (v->voltage_override == dcn_bw_v_max0p9) {
827 v->voltage_override_level = number_of_states - 1;
828 } else if (v->voltage_override == dcn_bw_v_nom0p8) {
829 v->voltage_override_level = number_of_states - 2;
830 } else if (v->voltage_override == dcn_bw_v_mid0p72) {
831 v->voltage_override_level = number_of_states - 3;
832 } else {
833 v->voltage_override_level = 0;
834 }
835 v->synchronized_vblank = dcn_bw_no;
836 v->ta_pscalculation = dcn_bw_override;
837 v->allow_different_hratio_vratio = dcn_bw_yes;
838
839
840 for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
841 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
842
843 if (!pipe->stream)
844 continue;
845 /* skip all but first of split pipes */
846 if (pipe->top_pipe && pipe->top_pipe->surface == pipe->surface)
847 continue;
848
849 v->underscan_output[input_idx] = false; /* taken care of in recout already*/
850 v->interlace_output[input_idx] = false;
851
852 v->htotal[input_idx] = pipe->stream->timing.h_total;
853 v->vtotal[input_idx] = pipe->stream->timing.v_total;
854 v->v_sync_plus_back_porch[input_idx] = pipe->stream->timing.v_total
855 - pipe->stream->timing.v_addressable
856 - pipe->stream->timing.v_front_porch;
857 v->vactive[input_idx] = pipe->stream->timing.v_addressable;
858 v->pixel_clock[input_idx] = pipe->stream->timing.pix_clk_khz / 1000.0f;
859 if (pipe->stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) {
860 switch (pipe->stream->timing.display_color_depth) {
861 case COLOR_DEPTH_101010:
862 v->pixel_clock[input_idx] = (v->pixel_clock[input_idx] * 30) / 24;
863 break;
864 case COLOR_DEPTH_121212:
865 v->pixel_clock[input_idx] = (v->pixel_clock[input_idx] * 36) / 24;
866 break;
867 default:
868 break;
869 }
870 }
871
872 if (!pipe->surface){
873 v->dcc_enable[input_idx] = dcn_bw_yes;
874 v->source_pixel_format[input_idx] = dcn_bw_rgb_sub_32;
875 v->source_surface_mode[input_idx] = dcn_bw_sw_4_kb_s;
876 v->lb_bit_per_pixel[input_idx] = 30;
877 v->viewport_width[input_idx] = pipe->stream->timing.h_addressable;
878 v->viewport_height[input_idx] = pipe->stream->timing.v_addressable;
879 v->scaler_rec_out_width[input_idx] = pipe->stream->timing.h_addressable;
880 v->scaler_recout_height[input_idx] = pipe->stream->timing.v_addressable;
881 v->override_hta_ps[input_idx] = 1;
882 v->override_vta_ps[input_idx] = 1;
883 v->override_hta_pschroma[input_idx] = 1;
884 v->override_vta_pschroma[input_idx] = 1;
885 v->source_scan[input_idx] = dcn_bw_hor;
886
887 } else {
888 v->viewport_height[input_idx] = pipe->scl_data.viewport.height;
889 v->viewport_width[input_idx] = pipe->scl_data.viewport.width;
890 v->scaler_rec_out_width[input_idx] = pipe->scl_data.recout.width;
891 v->scaler_recout_height[input_idx] = pipe->scl_data.recout.height;
892 if (pipe->bottom_pipe && pipe->bottom_pipe->surface == pipe->surface) {
893 if (pipe->surface->rotation % 2 == 0) {
894 int viewport_end = pipe->scl_data.viewport.width
895 + pipe->scl_data.viewport.x;
896 int viewport_b_end = pipe->bottom_pipe->scl_data.viewport.width
897 + pipe->bottom_pipe->scl_data.viewport.x;
898
899 if (viewport_end > viewport_b_end)
900 v->viewport_width[input_idx] = viewport_end
901 - pipe->bottom_pipe->scl_data.viewport.x;
902 else
903 v->viewport_width[input_idx] = viewport_b_end
904 - pipe->scl_data.viewport.x;
905 } else {
906 int viewport_end = pipe->scl_data.viewport.height
907 + pipe->scl_data.viewport.y;
908 int viewport_b_end = pipe->bottom_pipe->scl_data.viewport.height
909 + pipe->bottom_pipe->scl_data.viewport.y;
910
911 if (viewport_end > viewport_b_end)
912 v->viewport_height[input_idx] = viewport_end
913 - pipe->bottom_pipe->scl_data.viewport.y;
914 else
915 v->viewport_height[input_idx] = viewport_b_end
916 - pipe->scl_data.viewport.y;
917 }
918 v->scaler_rec_out_width[input_idx] = pipe->scl_data.recout.width
919 + pipe->bottom_pipe->scl_data.recout.width;
920 }
921
922 v->dcc_enable[input_idx] = pipe->surface->dcc.enable ? dcn_bw_yes : dcn_bw_no;
923 v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs(
924 pipe->surface->format);
925 v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs(
926 pipe->surface->tiling_info.gfx9.swizzle);
927 v->lb_bit_per_pixel[input_idx] = tl_lb_bpp_to_int(pipe->scl_data.lb_params.depth);
928 v->override_hta_ps[input_idx] = pipe->scl_data.taps.h_taps;
929 v->override_vta_ps[input_idx] = pipe->scl_data.taps.v_taps;
930 v->override_hta_pschroma[input_idx] = pipe->scl_data.taps.h_taps_c;
931 v->override_vta_pschroma[input_idx] = pipe->scl_data.taps.v_taps_c;
932 v->source_scan[input_idx] = (pipe->surface->rotation % 2) ? dcn_bw_vert : dcn_bw_hor;
933 }
934 if (v->is_line_buffer_bpp_fixed == dcn_bw_yes)
935 v->lb_bit_per_pixel[input_idx] = v->line_buffer_fixed_bpp;
936 v->dcc_rate[input_idx] = 1; /*TODO: Worst case? does this change?*/
937 v->output_format[input_idx] = pipe->stream->timing.pixel_encoding ==
938 PIXEL_ENCODING_YCBCR420 ? dcn_bw_420 : dcn_bw_444;
939 v->output[input_idx] = pipe->stream->sink->sink_signal ==
940 SIGNAL_TYPE_HDMI_TYPE_A ? dcn_bw_hdmi : dcn_bw_dp;
941
942 input_idx++;
943 }
944 v->number_of_active_planes = input_idx;
945
946 scaler_settings_calculation(v);
947 mode_support_and_system_configuration(v);
948
949 if (v->voltage_level == 0 &&
950 (dc->public.debug.sr_exit_time_dpm0_ns
951 || dc->public.debug.sr_enter_plus_exit_time_dpm0_ns)) {
952 struct core_dc *dc_core = DC_TO_CORE(&dc->public);
953
954 if (dc->public.debug.sr_enter_plus_exit_time_dpm0_ns)
955 v->sr_enter_plus_exit_time =
956 dc->public.debug.sr_enter_plus_exit_time_dpm0_ns / 1000.0f;
957 if (dc->public.debug.sr_exit_time_dpm0_ns)
958 v->sr_exit_time = dc->public.debug.sr_exit_time_dpm0_ns / 1000.0f;
959 dc_core->dml.soc.sr_enter_plus_exit_time_us = v->sr_enter_plus_exit_time;
960 dc_core->dml.soc.sr_exit_time_us = v->sr_exit_time;
961 mode_support_and_system_configuration(v);
962 }
963
964 if (v->voltage_level != 5) {
965 float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second;
966 if (bw_consumed < v->fabric_and_dram_bandwidth_vmin0p65)
967 bw_consumed = v->fabric_and_dram_bandwidth_vmin0p65;
968 else if (bw_consumed < v->fabric_and_dram_bandwidth_vmid0p72)
969 bw_consumed = v->fabric_and_dram_bandwidth_vmid0p72;
970 else if (bw_consumed < v->fabric_and_dram_bandwidth_vnom0p8)
971 bw_consumed = v->fabric_and_dram_bandwidth_vnom0p8;
972 else
973 bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9;
974
975 display_pipe_configuration(v);
976 calc_wm_sets_and_perf_params(context, v);
977 context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 /
978 (ddr4_dram_factor_single_Channel * v->number_of_channels));
979 if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) {
980 context->bw.dcn.calc_clk.fclk_khz = (int)(bw_consumed * 1000000 / 32);
981 }
982
983 context->bw.dcn.calc_clk.dram_ccm_us = (int)(v->dram_clock_change_margin);
984 context->bw.dcn.calc_clk.min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin);
985 context->bw.dcn.calc_clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000);
986 context->bw.dcn.calc_clk.dcfclk_khz = (int)(v->dcfclk * 1000);
987 context->bw.dcn.calc_clk.dispclk_khz = (int)(v->dispclk * 1000);
988 if (dc->public.debug.max_disp_clk == true)
989 context->bw.dcn.calc_clk.dispclk_khz = (int)(dc->dcn_soc.max_dispclk_vmax0p9 * 1000);
990 context->bw.dcn.calc_clk.dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2;
991
992 for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
993 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
994
995 /* skip inactive pipe */
996 if (!pipe->stream)
997 continue;
998 /* skip all but first of split pipes */
999 if (pipe->top_pipe && pipe->top_pipe->surface == pipe->surface)
1000 continue;
1001
1002 pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
1003 pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx];
1004 pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx];
1005 pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx];
1006
1007 pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total;
1008 pipe->pipe_dlg_param.vtotal = pipe->stream->timing.v_total;
1009 vesa_sync_start = pipe->stream->timing.v_addressable +
1010 pipe->stream->timing.v_border_bottom +
1011 pipe->stream->timing.v_front_porch;
1012
1013 asic_blank_end = (pipe->stream->timing.v_total -
1014 vesa_sync_start -
1015 pipe->stream->timing.v_border_top)
1016 * (pipe->stream->timing.flags.INTERLACE ? 1 : 0);
1017
1018 asic_blank_start = asic_blank_end +
1019 (pipe->stream->timing.v_border_top +
1020 pipe->stream->timing.v_addressable +
1021 pipe->stream->timing.v_border_bottom)
1022 * (pipe->stream->timing.flags.INTERLACE ? 1 : 0);
1023
1024 pipe->pipe_dlg_param.vblank_start = asic_blank_start;
1025 pipe->pipe_dlg_param.vblank_end = asic_blank_end;
1026
1027 if (pipe->surface) {
1028 struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe;
1029
1030 if (v->dpp_per_plane[input_idx] == 2 ||
1031 ((pipe->stream->view_format ==
1032 VIEW_3D_FORMAT_SIDE_BY_SIDE ||
1033 pipe->stream->view_format ==
1034 VIEW_3D_FORMAT_TOP_AND_BOTTOM) &&
1035 (pipe->stream->timing.timing_3d_format ==
1036 TIMING_3D_FORMAT_TOP_AND_BOTTOM ||
1037 pipe->stream->timing.timing_3d_format ==
1038 TIMING_3D_FORMAT_SIDE_BY_SIDE))) {
1039 if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) {
1040 /* update previously split pipe */
1041 hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx];
1042 hsplit_pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx];
1043 hsplit_pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx];
1044 hsplit_pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx];
1045
1046 hsplit_pipe->pipe_dlg_param.htotal = pipe->stream->timing.h_total;
1047 hsplit_pipe->pipe_dlg_param.vtotal = pipe->stream->timing.v_total;
1048 hsplit_pipe->pipe_dlg_param.vblank_start = pipe->pipe_dlg_param.vblank_start;
1049 hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end;
1050 } else {
1051 /* pipe not split previously needs split */
1052 hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool);
1053 ASSERT(hsplit_pipe);
1054 split_stream_across_pipes(
1055 &context->res_ctx, pool,
1056 pipe, hsplit_pipe);
1057 }
1058
1059 dcn_bw_calc_rq_dlg_ttu(dc, v, hsplit_pipe);
1060 } else if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) {
1061 /* merge previously split pipe */
1062 pipe->bottom_pipe = hsplit_pipe->bottom_pipe;
1063 if (hsplit_pipe->bottom_pipe)
1064 hsplit_pipe->bottom_pipe->top_pipe = pipe;
1065 hsplit_pipe->surface = NULL;
1066 hsplit_pipe->stream = NULL;
1067 hsplit_pipe->top_pipe = NULL;
1068 hsplit_pipe->bottom_pipe = NULL;
1069 resource_build_scaling_params(pipe);
1070 }
1071 /* for now important to do this after pipe split for building e2e params */
1072 dcn_bw_calc_rq_dlg_ttu(dc, v, pipe);
1073 }
1074
1075 input_idx++;
1076 }
1077 if (dc->public.debug.use_dml_wm)
1078 dcn_dml_wm_override(v, (struct display_mode_lib *)
1079 &dc->dml, context, pool);
1080 }
1081
1082 if (v->voltage_level == 0) {
1083 struct core_dc *dc_core = DC_TO_CORE(&dc->public);
1084
1085 dc_core->dml.soc.sr_enter_plus_exit_time_us =
1086 dc_core->dcn_soc.sr_enter_plus_exit_time;
1087 dc_core->dml.soc.sr_exit_time_us = dc_core->dcn_soc.sr_exit_time;
1088 }
1089
1090 /*
1091 * BW limit is set to prevent display from impacting other system functions
1092 */
1093
1094 bw_limit = dc->dcn_soc.percent_disp_bw_limit * v->fabric_and_dram_bandwidth_vmax0p9;
1095 bw_limit_pass = (v->total_data_read_bandwidth / 1000.0) < bw_limit;
1096
1097 kernel_fpu_end();
1098
1099 if (bw_limit_pass && v->voltage_level != 5)
1100 return true;
1101 else
1102 return false;
1103 }
1104
1105 unsigned int dcn_find_normalized_clock_vdd_Level(
1106 const struct core_dc *dc,
1107 enum dm_pp_clock_type clocks_type,
1108 int clocks_in_khz)
1109 {
1110 int vdd_level = dcn_bw_v_min0p65;
1111
1112 if (clocks_in_khz == 0)/*todo some clock not in the considerations*/
1113 return vdd_level;
1114
1115 switch (clocks_type) {
1116 case DM_PP_CLOCK_TYPE_DISPLAY_CLK:
1117 if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmax0p9*1000) {
1118 vdd_level = dcn_bw_v_max0p91;
1119 BREAK_TO_DEBUGGER();
1120 } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vnom0p8*1000) {
1121 vdd_level = dcn_bw_v_max0p9;
1122 } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmid0p72*1000) {
1123 vdd_level = dcn_bw_v_nom0p8;
1124 } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmin0p65*1000) {
1125 vdd_level = dcn_bw_v_mid0p72;
1126 } else
1127 vdd_level = dcn_bw_v_min0p65;
1128 break;
1129 case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK:
1130 if (clocks_in_khz > dc->dcn_soc.phyclkv_max0p9*1000) {
1131 vdd_level = dcn_bw_v_max0p91;
1132 BREAK_TO_DEBUGGER();
1133 } else if (clocks_in_khz > dc->dcn_soc.phyclkv_nom0p8*1000) {
1134 vdd_level = dcn_bw_v_max0p9;
1135 } else if (clocks_in_khz > dc->dcn_soc.phyclkv_mid0p72*1000) {
1136 vdd_level = dcn_bw_v_nom0p8;
1137 } else if (clocks_in_khz > dc->dcn_soc.phyclkv_min0p65*1000) {
1138 vdd_level = dcn_bw_v_mid0p72;
1139 } else
1140 vdd_level = dcn_bw_v_min0p65;
1141 break;
1142
1143 case DM_PP_CLOCK_TYPE_DPPCLK:
1144 if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmax0p9*1000) {
1145 vdd_level = dcn_bw_v_max0p91;
1146 BREAK_TO_DEBUGGER();
1147 } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vnom0p8*1000) {
1148 vdd_level = dcn_bw_v_max0p9;
1149 } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmid0p72*1000) {
1150 vdd_level = dcn_bw_v_nom0p8;
1151 } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmin0p65*1000) {
1152 vdd_level = dcn_bw_v_mid0p72;
1153 } else
1154 vdd_level = dcn_bw_v_min0p65;
1155 break;
1156
1157 case DM_PP_CLOCK_TYPE_MEMORY_CLK:
1158 {
1159 unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc.number_of_channels);
1160 if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9*1000000/factor) {
1161 vdd_level = dcn_bw_v_max0p91;
1162 BREAK_TO_DEBUGGER();
1163 } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8*1000000/factor) {
1164 vdd_level = dcn_bw_v_max0p9;
1165 } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72*1000000/factor) {
1166 vdd_level = dcn_bw_v_nom0p8;
1167 } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65*1000000/factor) {
1168 vdd_level = dcn_bw_v_mid0p72;
1169 } else
1170 vdd_level = dcn_bw_v_min0p65;
1171 }
1172 break;
1173
1174 case DM_PP_CLOCK_TYPE_DCFCLK:
1175 if (clocks_in_khz > dc->dcn_soc.dcfclkv_max0p9*1000) {
1176 vdd_level = dcn_bw_v_max0p91;
1177 BREAK_TO_DEBUGGER();
1178 } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_nom0p8*1000) {
1179 vdd_level = dcn_bw_v_max0p9;
1180 } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_mid0p72*1000) {
1181 vdd_level = dcn_bw_v_nom0p8;
1182 } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_min0p65*1000) {
1183 vdd_level = dcn_bw_v_mid0p72;
1184 } else
1185 vdd_level = dcn_bw_v_min0p65;
1186 break;
1187
1188 default:
1189 break;
1190 }
1191 return vdd_level;
1192 }
1193
1194 unsigned int dcn_find_dcfclk_suits_all(
1195 const struct core_dc *dc,
1196 struct clocks_value *clocks)
1197 {
1198 unsigned vdd_level, vdd_level_temp;
1199 unsigned dcf_clk;
1200
1201 /*find a common supported voltage level*/
1202 vdd_level = dcn_find_normalized_clock_vdd_Level(
1203 dc, DM_PP_CLOCK_TYPE_DISPLAY_CLK, clocks->dispclk_in_khz);
1204 vdd_level_temp = dcn_find_normalized_clock_vdd_Level(
1205 dc, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, clocks->phyclk_in_khz);
1206
1207 vdd_level = dcn_bw_max(vdd_level, vdd_level_temp);
1208 vdd_level_temp = dcn_find_normalized_clock_vdd_Level(
1209 dc, DM_PP_CLOCK_TYPE_DPPCLK, clocks->dppclk_in_khz);
1210 vdd_level = dcn_bw_max(vdd_level, vdd_level_temp);
1211
1212 vdd_level_temp = dcn_find_normalized_clock_vdd_Level(
1213 dc, DM_PP_CLOCK_TYPE_MEMORY_CLK, clocks->dcfclock_in_khz);
1214 vdd_level = dcn_bw_max(vdd_level, vdd_level_temp);
1215 vdd_level_temp = dcn_find_normalized_clock_vdd_Level(
1216 dc, DM_PP_CLOCK_TYPE_DCFCLK, clocks->dcfclock_in_khz);
1217
1218 /*find that level conresponding dcfclk*/
1219 vdd_level = dcn_bw_max(vdd_level, vdd_level_temp);
1220 if (vdd_level == dcn_bw_v_max0p91) {
1221 BREAK_TO_DEBUGGER();
1222 dcf_clk = dc->dcn_soc.dcfclkv_max0p9*1000;
1223 } else if (vdd_level == dcn_bw_v_max0p9)
1224 dcf_clk = dc->dcn_soc.dcfclkv_max0p9*1000;
1225 else if (vdd_level == dcn_bw_v_nom0p8)
1226 dcf_clk = dc->dcn_soc.dcfclkv_nom0p8*1000;
1227 else if (vdd_level == dcn_bw_v_mid0p72)
1228 dcf_clk = dc->dcn_soc.dcfclkv_mid0p72*1000;
1229 else
1230 dcf_clk = dc->dcn_soc.dcfclkv_min0p65*1000;
1231
1232 dm_logger_write(dc->ctx->logger, LOG_HW_MARKS,
1233 "\tdcf_clk for voltage = %d\n", dcf_clk);
1234 return dcf_clk;
1235 }
1236
1237 void dcn_bw_update_from_pplib(struct core_dc *dc)
1238 {
1239 struct dc_context *ctx = dc->ctx;
1240 struct dm_pp_clock_levels_with_voltage clks = {0};
1241
1242 kernel_fpu_begin();
1243
1244 /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
1245
1246 if (dm_pp_get_clock_levels_by_type_with_voltage(
1247 ctx, DM_PP_CLOCK_TYPE_FCLK, &clks) &&
1248 clks.num_levels != 0) {
1249 ASSERT(clks.num_levels >= 3);
1250 dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65 = 32 * (clks.data[0].clocks_in_khz / 1000.0) / 1000.0;
1251 if (clks.num_levels > 2) {
1252 dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.number_of_channels *
1253 (clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
1254 } else {
1255 dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.number_of_channels *
1256 (clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
1257 }
1258 dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc.number_of_channels *
1259 (clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
1260 dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc.number_of_channels *
1261 (clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0;
1262 } else
1263 BREAK_TO_DEBUGGER();
1264 if (dm_pp_get_clock_levels_by_type_with_voltage(
1265 ctx, DM_PP_CLOCK_TYPE_DCFCLK, &clks) &&
1266 clks.num_levels >= 3) {
1267 dc->dcn_soc.dcfclkv_min0p65 = clks.data[0].clocks_in_khz / 1000.0;
1268 dc->dcn_soc.dcfclkv_mid0p72 = clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0;
1269 dc->dcn_soc.dcfclkv_nom0p8 = clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0;
1270 dc->dcn_soc.dcfclkv_max0p9 = clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0;
1271 } else
1272 BREAK_TO_DEBUGGER();
1273
1274 kernel_fpu_end();
1275 }
1276
1277 void dcn_bw_notify_pplib_of_wm_ranges(struct core_dc *dc)
1278 {
1279 struct dm_pp_wm_sets_with_clock_ranges_soc15 clk_ranges = {0};
1280 int max_fclk_khz, nom_fclk_khz, min_fclk_khz, max_dcfclk_khz,
1281 nom_dcfclk_khz, mid_fclk_khz, min_dcfclk_khz, socclk_khz;
1282 const int overdrive = 5000000; /* 5 GHz to cover Overdrive */
1283 unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc.number_of_channels);
1284
1285 kernel_fpu_begin();
1286 max_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9 * 1000000 / factor;
1287 nom_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8 * 1000000 / factor;
1288 mid_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 * 1000000 / factor;
1289 min_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65 * 1000000 / 32;
1290 max_dcfclk_khz = dc->dcn_soc.dcfclkv_max0p9 * 1000;
1291 nom_dcfclk_khz = dc->dcn_soc.dcfclkv_nom0p8 * 1000;
1292 min_dcfclk_khz = dc->dcn_soc.dcfclkv_min0p65 * 1000;
1293 socclk_khz = dc->dcn_soc.socclk * 1000;
1294 kernel_fpu_end();
1295
1296 /* Now notify PPLib/SMU about which Watermarks sets they should select
1297 * depending on DPM state they are in. And update BW MGR GFX Engine and
1298 * Memory clock member variables for Watermarks calculations for each
1299 * Watermark Set
1300 */
1301 /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont
1302 * care what the value is, hence min to overdrive level
1303 */
1304 clk_ranges.num_wm_dmif_sets = 4;
1305 clk_ranges.num_wm_mcif_sets = 4;
1306 clk_ranges.wm_dmif_clocks_ranges[0].wm_set_id = WM_SET_A;
1307 clk_ranges.wm_dmif_clocks_ranges[0].wm_min_dcfclk_clk_in_khz = min_dcfclk_khz;
1308 clk_ranges.wm_dmif_clocks_ranges[0].wm_max_dcfclk_clk_in_khz = max_dcfclk_khz;
1309 clk_ranges.wm_dmif_clocks_ranges[0].wm_min_memg_clk_in_khz = min_fclk_khz;
1310 clk_ranges.wm_dmif_clocks_ranges[0].wm_max_mem_clk_in_khz = min_fclk_khz;
1311 clk_ranges.wm_mcif_clocks_ranges[0].wm_set_id = WM_SET_A;
1312 clk_ranges.wm_mcif_clocks_ranges[0].wm_min_socclk_clk_in_khz = socclk_khz;
1313 clk_ranges.wm_mcif_clocks_ranges[0].wm_max_socclk_clk_in_khz = overdrive;
1314 clk_ranges.wm_mcif_clocks_ranges[0].wm_min_memg_clk_in_khz = min_fclk_khz;
1315 clk_ranges.wm_mcif_clocks_ranges[0].wm_max_mem_clk_in_khz = min_fclk_khz;
1316
1317 clk_ranges.wm_dmif_clocks_ranges[1].wm_set_id = WM_SET_B;
1318 clk_ranges.wm_dmif_clocks_ranges[1].wm_min_dcfclk_clk_in_khz = min_fclk_khz;
1319 clk_ranges.wm_dmif_clocks_ranges[1].wm_max_dcfclk_clk_in_khz = max_dcfclk_khz;
1320 clk_ranges.wm_dmif_clocks_ranges[1].wm_min_memg_clk_in_khz = mid_fclk_khz;
1321 clk_ranges.wm_dmif_clocks_ranges[1].wm_max_mem_clk_in_khz = mid_fclk_khz;
1322 clk_ranges.wm_mcif_clocks_ranges[1].wm_set_id = WM_SET_B;
1323 clk_ranges.wm_mcif_clocks_ranges[1].wm_min_socclk_clk_in_khz = socclk_khz;
1324 clk_ranges.wm_mcif_clocks_ranges[1].wm_max_socclk_clk_in_khz = overdrive;
1325 clk_ranges.wm_mcif_clocks_ranges[1].wm_min_memg_clk_in_khz = mid_fclk_khz;
1326 clk_ranges.wm_mcif_clocks_ranges[1].wm_max_mem_clk_in_khz = mid_fclk_khz;
1327
1328
1329 clk_ranges.wm_dmif_clocks_ranges[2].wm_set_id = WM_SET_C;
1330 clk_ranges.wm_dmif_clocks_ranges[2].wm_min_dcfclk_clk_in_khz = min_fclk_khz;
1331 clk_ranges.wm_dmif_clocks_ranges[2].wm_max_dcfclk_clk_in_khz = max_dcfclk_khz;
1332 clk_ranges.wm_dmif_clocks_ranges[2].wm_min_memg_clk_in_khz = nom_fclk_khz;
1333 clk_ranges.wm_dmif_clocks_ranges[2].wm_max_mem_clk_in_khz = nom_fclk_khz;
1334 clk_ranges.wm_mcif_clocks_ranges[2].wm_set_id = WM_SET_C;
1335 clk_ranges.wm_mcif_clocks_ranges[2].wm_min_socclk_clk_in_khz = socclk_khz;
1336 clk_ranges.wm_mcif_clocks_ranges[2].wm_max_socclk_clk_in_khz = overdrive;
1337 clk_ranges.wm_mcif_clocks_ranges[2].wm_min_memg_clk_in_khz = nom_fclk_khz;
1338 clk_ranges.wm_mcif_clocks_ranges[2].wm_max_mem_clk_in_khz = nom_fclk_khz;
1339
1340 clk_ranges.wm_dmif_clocks_ranges[3].wm_set_id = WM_SET_D;
1341 clk_ranges.wm_dmif_clocks_ranges[3].wm_min_dcfclk_clk_in_khz = min_fclk_khz;
1342 clk_ranges.wm_dmif_clocks_ranges[3].wm_max_dcfclk_clk_in_khz = max_dcfclk_khz;
1343 clk_ranges.wm_dmif_clocks_ranges[3].wm_min_memg_clk_in_khz = max_fclk_khz;
1344 clk_ranges.wm_dmif_clocks_ranges[3].wm_max_mem_clk_in_khz = max_fclk_khz;
1345 clk_ranges.wm_mcif_clocks_ranges[3].wm_set_id = WM_SET_D;
1346 clk_ranges.wm_mcif_clocks_ranges[3].wm_min_socclk_clk_in_khz = socclk_khz;
1347 clk_ranges.wm_mcif_clocks_ranges[3].wm_max_socclk_clk_in_khz = overdrive;
1348 clk_ranges.wm_mcif_clocks_ranges[3].wm_min_memg_clk_in_khz = max_fclk_khz;
1349 clk_ranges.wm_mcif_clocks_ranges[3].wm_max_mem_clk_in_khz = max_fclk_khz;
1350
1351 /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
1352 dm_pp_notify_wm_clock_changes_soc15(dc->ctx, &clk_ranges);
1353 }
1354
1355 void dcn_bw_sync_calcs_and_dml(struct core_dc *dc)
1356 {
1357 kernel_fpu_begin();
1358 dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
1359 "sr_exit_time: %d ns\n"
1360 "sr_enter_plus_exit_time: %d ns\n"
1361 "urgent_latency: %d ns\n"
1362 "write_back_latency: %d ns\n"
1363 "percent_of_ideal_drambw_received_after_urg_latency: %d %\n"
1364 "max_request_size: %d bytes\n"
1365 "dcfclkv_max0p9: %d kHz\n"
1366 "dcfclkv_nom0p8: %d kHz\n"
1367 "dcfclkv_mid0p72: %d kHz\n"
1368 "dcfclkv_min0p65: %d kHz\n"
1369 "max_dispclk_vmax0p9: %d kHz\n"
1370 "max_dispclk_vnom0p8: %d kHz\n"
1371 "max_dispclk_vmid0p72: %d kHz\n"
1372 "max_dispclk_vmin0p65: %d kHz\n"
1373 "max_dppclk_vmax0p9: %d kHz\n"
1374 "max_dppclk_vnom0p8: %d kHz\n"
1375 "max_dppclk_vmid0p72: %d kHz\n"
1376 "max_dppclk_vmin0p65: %d kHz\n"
1377 "socclk: %d kHz\n"
1378 "fabric_and_dram_bandwidth_vmax0p9: %d MB/s\n"
1379 "fabric_and_dram_bandwidth_vnom0p8: %d MB/s\n"
1380 "fabric_and_dram_bandwidth_vmid0p72: %d MB/s\n"
1381 "fabric_and_dram_bandwidth_vmin0p65: %d MB/s\n"
1382 "phyclkv_max0p9: %d kHz\n"
1383 "phyclkv_nom0p8: %d kHz\n"
1384 "phyclkv_mid0p72: %d kHz\n"
1385 "phyclkv_min0p65: %d kHz\n"
1386 "downspreading: %d %\n"
1387 "round_trip_ping_latency_cycles: %d DCFCLK Cycles\n"
1388 "urgent_out_of_order_return_per_channel: %d Bytes\n"
1389 "number_of_channels: %d\n"
1390 "vmm_page_size: %d Bytes\n"
1391 "dram_clock_change_latency: %d ns\n"
1392 "return_bus_width: %d Bytes\n",
1393 dc->dcn_soc.sr_exit_time * 1000,
1394 dc->dcn_soc.sr_enter_plus_exit_time * 1000,
1395 dc->dcn_soc.urgent_latency * 1000,
1396 dc->dcn_soc.write_back_latency * 1000,
1397 dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency,
1398 dc->dcn_soc.max_request_size,
1399 dc->dcn_soc.dcfclkv_max0p9 * 1000,
1400 dc->dcn_soc.dcfclkv_nom0p8 * 1000,
1401 dc->dcn_soc.dcfclkv_mid0p72 * 1000,
1402 dc->dcn_soc.dcfclkv_min0p65 * 1000,
1403 dc->dcn_soc.max_dispclk_vmax0p9 * 1000,
1404 dc->dcn_soc.max_dispclk_vnom0p8 * 1000,
1405 dc->dcn_soc.max_dispclk_vmid0p72 * 1000,
1406 dc->dcn_soc.max_dispclk_vmin0p65 * 1000,
1407 dc->dcn_soc.max_dppclk_vmax0p9 * 1000,
1408 dc->dcn_soc.max_dppclk_vnom0p8 * 1000,
1409 dc->dcn_soc.max_dppclk_vmid0p72 * 1000,
1410 dc->dcn_soc.max_dppclk_vmin0p65 * 1000,
1411 dc->dcn_soc.socclk * 1000,
1412 dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9 * 1000,
1413 dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8 * 1000,
1414 dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 * 1000,
1415 dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65 * 1000,
1416 dc->dcn_soc.phyclkv_max0p9 * 1000,
1417 dc->dcn_soc.phyclkv_nom0p8 * 1000,
1418 dc->dcn_soc.phyclkv_mid0p72 * 1000,
1419 dc->dcn_soc.phyclkv_min0p65 * 1000,
1420 dc->dcn_soc.downspreading * 100,
1421 dc->dcn_soc.round_trip_ping_latency_cycles,
1422 dc->dcn_soc.urgent_out_of_order_return_per_channel,
1423 dc->dcn_soc.number_of_channels,
1424 dc->dcn_soc.vmm_page_size,
1425 dc->dcn_soc.dram_clock_change_latency * 1000,
1426 dc->dcn_soc.return_bus_width);
1427 dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_CALCS,
1428 "rob_buffer_size_in_kbyte: %d\n"
1429 "det_buffer_size_in_kbyte: %d\n"
1430 "dpp_output_buffer_pixels: %d\n"
1431 "opp_output_buffer_lines: %d\n"
1432 "pixel_chunk_size_in_kbyte: %d\n"
1433 "pte_enable: %d\n"
1434 "pte_chunk_size: %d kbytes\n"
1435 "meta_chunk_size: %d kbytes\n"
1436 "writeback_chunk_size: %d kbytes\n"
1437 "odm_capability: %d\n"
1438 "dsc_capability: %d\n"
1439 "line_buffer_size: %d bits\n"
1440 "max_line_buffer_lines: %d\n"
1441 "is_line_buffer_bpp_fixed: %d\n"
1442 "line_buffer_fixed_bpp: %d\n"
1443 "writeback_luma_buffer_size: %d kbytes\n"
1444 "writeback_chroma_buffer_size: %d kbytes\n"
1445 "max_num_dpp: %d\n"
1446 "max_num_writeback: %d\n"
1447 "max_dchub_topscl_throughput: %d pixels/dppclk\n"
1448 "max_pscl_tolb_throughput: %d pixels/dppclk\n"
1449 "max_lb_tovscl_throughput: %d pixels/dppclk\n"
1450 "max_vscl_tohscl_throughput: %d pixels/dppclk\n"
1451 "max_hscl_ratio: %d\n"
1452 "max_vscl_ratio: %d\n"
1453 "max_hscl_taps: %d\n"
1454 "max_vscl_taps: %d\n"
1455 "pte_buffer_size_in_requests: %d\n"
1456 "dispclk_ramping_margin: %d %\n"
1457 "under_scan_factor: %d %\n"
1458 "max_inter_dcn_tile_repeaters: %d\n"
1459 "can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one: %d\n"
1460 "bug_forcing_luma_and_chroma_request_to_same_size_fixed: %d\n"
1461 "dcfclk_cstate_latency: %d\n",
1462 dc->dcn_ip.rob_buffer_size_in_kbyte,
1463 dc->dcn_ip.det_buffer_size_in_kbyte,
1464 dc->dcn_ip.dpp_output_buffer_pixels,
1465 dc->dcn_ip.opp_output_buffer_lines,
1466 dc->dcn_ip.pixel_chunk_size_in_kbyte,
1467 dc->dcn_ip.pte_enable,
1468 dc->dcn_ip.pte_chunk_size,
1469 dc->dcn_ip.meta_chunk_size,
1470 dc->dcn_ip.writeback_chunk_size,
1471 dc->dcn_ip.odm_capability,
1472 dc->dcn_ip.dsc_capability,
1473 dc->dcn_ip.line_buffer_size,
1474 dc->dcn_ip.max_line_buffer_lines,
1475 dc->dcn_ip.is_line_buffer_bpp_fixed,
1476 dc->dcn_ip.line_buffer_fixed_bpp,
1477 dc->dcn_ip.writeback_luma_buffer_size,
1478 dc->dcn_ip.writeback_chroma_buffer_size,
1479 dc->dcn_ip.max_num_dpp,
1480 dc->dcn_ip.max_num_writeback,
1481 dc->dcn_ip.max_dchub_topscl_throughput,
1482 dc->dcn_ip.max_pscl_tolb_throughput,
1483 dc->dcn_ip.max_lb_tovscl_throughput,
1484 dc->dcn_ip.max_vscl_tohscl_throughput,
1485 dc->dcn_ip.max_hscl_ratio,
1486 dc->dcn_ip.max_vscl_ratio,
1487 dc->dcn_ip.max_hscl_taps,
1488 dc->dcn_ip.max_vscl_taps,
1489 dc->dcn_ip.pte_buffer_size_in_requests,
1490 dc->dcn_ip.dispclk_ramping_margin,
1491 dc->dcn_ip.under_scan_factor * 100,
1492 dc->dcn_ip.max_inter_dcn_tile_repeaters,
1493 dc->dcn_ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one,
1494 dc->dcn_ip.bug_forcing_luma_and_chroma_request_to_same_size_fixed,
1495 dc->dcn_ip.dcfclk_cstate_latency);
1496 dc->dml.soc.vmin.socclk_mhz = dc->dcn_soc.socclk;
1497 dc->dml.soc.vmid.socclk_mhz = dc->dcn_soc.socclk;
1498 dc->dml.soc.vnom.socclk_mhz = dc->dcn_soc.socclk;
1499 dc->dml.soc.vmax.socclk_mhz = dc->dcn_soc.socclk;
1500
1501 dc->dml.soc.vmin.dcfclk_mhz = dc->dcn_soc.dcfclkv_min0p65;
1502 dc->dml.soc.vmid.dcfclk_mhz = dc->dcn_soc.dcfclkv_mid0p72;
1503 dc->dml.soc.vnom.dcfclk_mhz = dc->dcn_soc.dcfclkv_nom0p8;
1504 dc->dml.soc.vmax.dcfclk_mhz = dc->dcn_soc.dcfclkv_max0p9;
1505
1506 dc->dml.soc.vmin.dispclk_mhz = dc->dcn_soc.max_dispclk_vmin0p65;
1507 dc->dml.soc.vmid.dispclk_mhz = dc->dcn_soc.max_dispclk_vmid0p72;
1508 dc->dml.soc.vnom.dispclk_mhz = dc->dcn_soc.max_dispclk_vnom0p8;
1509 dc->dml.soc.vmax.dispclk_mhz = dc->dcn_soc.max_dispclk_vmax0p9;
1510
1511 dc->dml.soc.vmin.dppclk_mhz = dc->dcn_soc.max_dppclk_vmin0p65;
1512 dc->dml.soc.vmid.dppclk_mhz = dc->dcn_soc.max_dppclk_vmid0p72;
1513 dc->dml.soc.vnom.dppclk_mhz = dc->dcn_soc.max_dppclk_vnom0p8;
1514 dc->dml.soc.vmax.dppclk_mhz = dc->dcn_soc.max_dppclk_vmax0p9;
1515
1516 dc->dml.soc.vmin.phyclk_mhz = dc->dcn_soc.phyclkv_min0p65;
1517 dc->dml.soc.vmid.phyclk_mhz = dc->dcn_soc.phyclkv_mid0p72;
1518 dc->dml.soc.vnom.phyclk_mhz = dc->dcn_soc.phyclkv_nom0p8;
1519 dc->dml.soc.vmax.phyclk_mhz = dc->dcn_soc.phyclkv_max0p9;
1520
1521 dc->dml.soc.vmin.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65;
1522 dc->dml.soc.vmid.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72;
1523 dc->dml.soc.vnom.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8;
1524 dc->dml.soc.vmax.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9;
1525
1526 dc->dml.soc.sr_exit_time_us = dc->dcn_soc.sr_exit_time;
1527 dc->dml.soc.sr_enter_plus_exit_time_us = dc->dcn_soc.sr_enter_plus_exit_time;
1528 dc->dml.soc.urgent_latency_us = dc->dcn_soc.urgent_latency;
1529 dc->dml.soc.writeback_latency_us = dc->dcn_soc.write_back_latency;
1530 dc->dml.soc.ideal_dram_bw_after_urgent_percent =
1531 dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency;
1532 dc->dml.soc.max_request_size_bytes = dc->dcn_soc.max_request_size;
1533 dc->dml.soc.downspread_percent = dc->dcn_soc.downspreading;
1534 dc->dml.soc.round_trip_ping_latency_dcfclk_cycles =
1535 dc->dcn_soc.round_trip_ping_latency_cycles;
1536 dc->dml.soc.urgent_out_of_order_return_per_channel_bytes =
1537 dc->dcn_soc.urgent_out_of_order_return_per_channel;
1538 dc->dml.soc.num_chans = dc->dcn_soc.number_of_channels;
1539 dc->dml.soc.vmm_page_size_bytes = dc->dcn_soc.vmm_page_size;
1540 dc->dml.soc.dram_clock_change_latency_us = dc->dcn_soc.dram_clock_change_latency;
1541 dc->dml.soc.return_bus_width_bytes = dc->dcn_soc.return_bus_width;
1542
1543 dc->dml.ip.rob_buffer_size_kbytes = dc->dcn_ip.rob_buffer_size_in_kbyte;
1544 dc->dml.ip.det_buffer_size_kbytes = dc->dcn_ip.det_buffer_size_in_kbyte;
1545 dc->dml.ip.dpp_output_buffer_pixels = dc->dcn_ip.dpp_output_buffer_pixels;
1546 dc->dml.ip.opp_output_buffer_lines = dc->dcn_ip.opp_output_buffer_lines;
1547 dc->dml.ip.pixel_chunk_size_kbytes = dc->dcn_ip.pixel_chunk_size_in_kbyte;
1548 dc->dml.ip.pte_enable = dc->dcn_ip.pte_enable == dcn_bw_yes;
1549 dc->dml.ip.pte_chunk_size_kbytes = dc->dcn_ip.pte_chunk_size;
1550 dc->dml.ip.meta_chunk_size_kbytes = dc->dcn_ip.meta_chunk_size;
1551 dc->dml.ip.writeback_chunk_size_kbytes = dc->dcn_ip.writeback_chunk_size;
1552 dc->dml.ip.line_buffer_size_bits = dc->dcn_ip.line_buffer_size;
1553 dc->dml.ip.max_line_buffer_lines = dc->dcn_ip.max_line_buffer_lines;
1554 dc->dml.ip.IsLineBufferBppFixed = dc->dcn_ip.is_line_buffer_bpp_fixed == dcn_bw_yes;
1555 dc->dml.ip.LineBufferFixedBpp = dc->dcn_ip.line_buffer_fixed_bpp;
1556 dc->dml.ip.writeback_luma_buffer_size_kbytes = dc->dcn_ip.writeback_luma_buffer_size;
1557 dc->dml.ip.writeback_chroma_buffer_size_kbytes = dc->dcn_ip.writeback_chroma_buffer_size;
1558 dc->dml.ip.max_num_dpp = dc->dcn_ip.max_num_dpp;
1559 dc->dml.ip.max_num_wb = dc->dcn_ip.max_num_writeback;
1560 dc->dml.ip.max_dchub_pscl_bw_pix_per_clk = dc->dcn_ip.max_dchub_topscl_throughput;
1561 dc->dml.ip.max_pscl_lb_bw_pix_per_clk = dc->dcn_ip.max_pscl_tolb_throughput;
1562 dc->dml.ip.max_lb_vscl_bw_pix_per_clk = dc->dcn_ip.max_lb_tovscl_throughput;
1563 dc->dml.ip.max_vscl_hscl_bw_pix_per_clk = dc->dcn_ip.max_vscl_tohscl_throughput;
1564 dc->dml.ip.max_hscl_ratio = dc->dcn_ip.max_hscl_ratio;
1565 dc->dml.ip.max_vscl_ratio = dc->dcn_ip.max_vscl_ratio;
1566 dc->dml.ip.max_hscl_taps = dc->dcn_ip.max_hscl_taps;
1567 dc->dml.ip.max_vscl_taps = dc->dcn_ip.max_vscl_taps;
1568 /*pte_buffer_size_in_requests missing in dml*/
1569 dc->dml.ip.dispclk_ramp_margin_percent = dc->dcn_ip.dispclk_ramping_margin;
1570 dc->dml.ip.underscan_factor = dc->dcn_ip.under_scan_factor;
1571 dc->dml.ip.max_inter_dcn_tile_repeaters = dc->dcn_ip.max_inter_dcn_tile_repeaters;
1572 dc->dml.ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one =
1573 dc->dcn_ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one == dcn_bw_yes;
1574 dc->dml.ip.bug_forcing_LC_req_same_size_fixed =
1575 dc->dcn_ip.bug_forcing_luma_and_chroma_request_to_same_size_fixed == dcn_bw_yes;
1576 dc->dml.ip.dcfclk_cstate_latency = dc->dcn_ip.dcfclk_cstate_latency;
1577 kernel_fpu_end();
1578 }