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