1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024-2025 Advanced Micro Devices, Inc.
4
5 #include "dml2_core_dcn5_funcs_mode_programming.h"
6 #include "dml2_core_dcn5_calcs_dchub.h"
7 #include "dml2_core_dcn5_calcs_display_pipe.h"
8 #include "dml2_core_utils.h"
9 #include "dml2_debug.h"
10
dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex * in_out_params)11 static bool dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex *in_out_params)
12 {
13 const struct dml2_display_cfg *display_cfg = in_out_params->in_display_cfg;
14 const struct dml2_utm_soc_bb *utm_soc_bb = in_out_params->utm_soc_bb;
15 const struct dml2_sop_table *sop_table = &in_out_params->utm_soc_bb->sop_table;
16 const struct core_display_cfg_support_info *cfg_support_info = in_out_params->cfg_support_info;
17 struct dml2_core_internal_display_mode_lib *mode_lib = in_out_params->mode_lib;
18 const struct dml2_display_cfg_programming *programming = in_out_params->programming;
19 struct dml2_core_calcs_mode_programming_locals *s = &mode_lib->scratch.dml_core_mode_programming_locals;
20 struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params *CalculateWatermarks_params = &mode_lib->scratch.CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_params;
21 struct dml2_core_calcs_CalculateVMRowAndSwath_params *CalculateVMRowAndSwath_params = &mode_lib->scratch.CalculateVMRowAndSwath_params;
22 struct dml2_core_calcs_CalculateSwathAndDETConfiguration_params *CalculateSwathAndDETConfiguration_params = &mode_lib->scratch.CalculateSwathAndDETConfiguration_params;
23 struct dml2_core_calcs_CalculateStutterEfficiency_params *CalculateStutterEfficiency_params = &mode_lib->scratch.CalculateStutterEfficiency_params;
24 struct dml2_core_calcs_CalculatePrefetchSchedule_params *CalculatePrefetchSchedule_params = &mode_lib->scratch.CalculatePrefetchSchedule_params;
25 struct dml2_core_calcs_calculate_mcache_setting_params *calculate_mcache_setting_params = &mode_lib->scratch.calculate_mcache_setting_params;
26 struct dml2_core_calcs_calculate_tdlut_setting_params *calculate_tdlut_setting_params = &mode_lib->scratch.calculate_tdlut_setting_params;
27 struct dml2_core_shared_CalculateMetaAndPTETimes_params *CalculateMetaAndPTETimes_params = &mode_lib->scratch.CalculateMetaAndPTETimes_params;
28 struct dml2_core_calcs_calculate_peak_bandwidth_required_params *calculate_peak_bandwidth_params = &mode_lib->scratch.calculate_peak_bandwidth_params;
29 struct dml2_core_calcs_calculate_bytes_to_fetch_required_to_hide_latency_params *calculate_bytes_to_fetch_required_to_hide_latency_params = &mode_lib->scratch.calculate_bytes_to_fetch_required_to_hide_latency_params;
30
31 unsigned int k, j;
32 bool must_support_iflip;
33 const long min_return_uclk_cycles = 83;
34 const long min_return_fclk_cycles = 75;
35 struct dml2_soc_operating_point max_sop;
36 struct dml2_soc_operating_point min_sop;
37 double min_return_latency_in_DCFCLK_cycles = 0;
38
39 DML_LOG_VERBOSE("DML::%s: --- START --- \n", __func__);
40
41 s->num_active_planes = display_cfg->num_planes;
42 dml2_core_utils_get_stream_output_bpp(s->OutputBpp, display_cfg);
43
44 mode_lib->mp.num_active_pipes = dml2_core_util_get_num_active_pipes(display_cfg->num_planes, cfg_support_info);
45 dml2_core_utils_pipe_plane_mapping(cfg_support_info, mode_lib->mp.pipe_plane);
46
47 mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0;
48 sop_table->get_max_sop(sop_table, &max_sop);
49 sop_table->get_min_sop(sop_table, &min_sop);
50 s->SOCCLK = min_sop.socclk_khz / 1000.0;
51
52 for (k = 0; k < s->num_active_planes; ++k) {
53 unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
54 DML_ASSERT(cfg_support_info->stream_support_info[stream_index].odms_used <= 4);
55 DML_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4 ||
56 cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2 ||
57 cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1);
58
59 if (cfg_support_info->stream_support_info[stream_index].odms_used > 1)
60 DML_ASSERT(cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 1);
61
62 switch (cfg_support_info->stream_support_info[stream_index].odms_used) {
63 case (4):
64 mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_4to1;
65 break;
66 case (3):
67 mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_3to1;
68 break;
69 case (2):
70 mode_lib->mp.ODMMode[k] = dml2_odm_mode_combine_2to1;
71 break;
72 default:
73 if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 4)
74 mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to4;
75 else if (cfg_support_info->stream_support_info[stream_index].num_odm_output_segments == 2)
76 mode_lib->mp.ODMMode[k] = dml2_odm_mode_mso_1to2;
77 else
78 mode_lib->mp.ODMMode[k] = dml2_odm_mode_bypass;
79 break;
80 }
81 }
82
83 for (k = 0; k < s->num_active_planes; ++k) {
84 mode_lib->mp.NoOfDPP[k] = cfg_support_info->plane_support_info[k].dpps_used;
85 mode_lib->mp.Dppclk[k] = programming->plane_programming[k].min_clocks.dcn4x.dppclk_khz / 1000.0;
86 DML_ASSERT(mode_lib->mp.Dppclk[k] > 0);
87 }
88
89 for (k = 0; k < s->num_active_planes; ++k) {
90 unsigned int stream_index = display_cfg->plane_descriptors[k].stream_index;
91 mode_lib->mp.DSCCLK[k] = programming->stream_programming[stream_index].min_clocks.dcn4x.dscclk_khz / 1000.0;
92 DML_LOG_VERBOSE("DML::%s: k=%d stream_index=%d, mode_lib->mp.DSCCLK = %f\n", __func__, k, stream_index, mode_lib->mp.DSCCLK[k]);
93 }
94
95 mode_lib->mp.Dispclk = programming->min_clocks.dcn4x.dispclk_khz / 1000.0;
96 mode_lib->mp.DCFCLKDeepSleep = programming->min_clocks.dcn4x.deepsleep_dcfclk_khz / 1000.0;
97
98 memcpy(mode_lib->mp.uclk_pstate_switch_modes,
99 in_out_params->uclk_params->pstate_switch_modes,
100 sizeof(in_out_params->uclk_params->pstate_switch_modes));
101
102 DML_ASSERT(mode_lib->mp.Dcfclk > 0);
103 DML_ASSERT(mode_lib->mp.FabricClock > 0);
104 DML_ASSERT(mode_lib->mp.uclk_freq_mhz > 0);
105 DML_ASSERT(mode_lib->mp.GlobalDPPCLK > 0);
106 DML_ASSERT(mode_lib->mp.Dispclk > 0);
107 DML_ASSERT(mode_lib->mp.DCFCLKDeepSleep > 0);
108 DML_ASSERT(s->SOCCLK > 0);
109
110 DML_LOG_VERBOSE("DML::%s: num_active_planes = %u\n", __func__, s->num_active_planes);
111 DML_LOG_VERBOSE("DML::%s: num_active_pipes = %u\n", __func__, mode_lib->mp.num_active_pipes);
112 DML_LOG_VERBOSE("DML::%s: Dcfclk = %f\n", __func__, mode_lib->mp.Dcfclk);
113 DML_LOG_VERBOSE("DML::%s: FabricClock = %f\n", __func__, mode_lib->mp.FabricClock);
114 DML_LOG_VERBOSE("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->mp.uclk_freq_mhz);
115 DML_LOG_VERBOSE("DML::%s: Dispclk = %f\n", __func__, mode_lib->mp.Dispclk);
116 for (k = 0; k < s->num_active_planes; ++k) {
117 DML_LOG_VERBOSE("DML::%s: Dppclk[%0d] = %f\n", __func__, k, mode_lib->mp.Dppclk[k]);
118 }
119 DML_LOG_VERBOSE("DML::%s: GlobalDPPCLK = %f\n", __func__, mode_lib->mp.GlobalDPPCLK);
120 DML_LOG_VERBOSE("DML::%s: DCFCLKDeepSleep = %f\n", __func__, mode_lib->mp.DCFCLKDeepSleep);
121 DML_LOG_VERBOSE("DML::%s: SOCCLK = %f\n", __func__, s->SOCCLK);
122 for (k = 0; k < mode_lib->mp.num_active_pipes; ++k) {
123 DML_LOG_VERBOSE("DML::%s: pipe=%d is in plane=%d\n", __func__, k, mode_lib->mp.pipe_plane[k]);
124 DML_LOG_VERBOSE("DML::%s: Per-plane DPPPerSurface[%0d] = %d\n", __func__, k, mode_lib->mp.NoOfDPP[k]);
125 }
126
127 for (k = 0; k < s->num_active_planes; k++)
128 DML_LOG_VERBOSE("DML::%s: plane_%d: reserved_vblank_time_ns = %lu\n", __func__, k, display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns);
129
130 dcn5_calculate_max_det_and_min_compressed_buffer_size(
131 mode_lib->ip.config_return_buffer_size_in_kbytes,
132 mode_lib->ip.config_return_buffer_segment_size_in_kbytes,
133 mode_lib->ip.rob_buffer_size_kbytes,
134 mode_lib->ip.max_num_dpp,
135 display_cfg->overrides.hw.force_nom_det_size_kbytes.enable,
136 display_cfg->overrides.hw.force_nom_det_size_kbytes.value,
137 mode_lib->ip.dcn_mrq_present,
138
139 /* Output */
140 &s->MaxTotalDETInKByte,
141 &s->NomDETInKByte,
142 &s->MinCompressedBufferSizeInKByte);
143
144
145 dcn5_adjust_pixel_clock_for_progressive_to_interlace_unit(display_cfg, mode_lib->ip.ptoi_supported, s->PixelClockBackEnd);
146
147 for (k = 0; k < s->num_active_planes; ++k) {
148 dcn5_calculate_single_pipe_dppclk_and_scl_throughput(
149 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio,
150 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_ratio,
151 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
152 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
153 mode_lib->ip.max_dchub_pscl_bw_pix_per_clk,
154 mode_lib->ip.max_pscl_lb_bw_pix_per_clk,
155 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
156 display_cfg->plane_descriptors[k].pixel_format,
157 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_taps,
158 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps,
159 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps,
160 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.h_taps,
161
162 /* Output */
163 &mode_lib->mp.PSCL_THROUGHPUT[k],
164 &mode_lib->mp.PSCL_THROUGHPUT_CHROMA[k],
165 &mode_lib->mp.DPPCLKUsingSingleDPP[k]);
166 }
167
168 for (k = 0; k < s->num_active_planes; ++k) {
169 dcn5_calculate_byte_per_pixel_and_block_sizes(
170 display_cfg->plane_descriptors[k].pixel_format,
171 display_cfg->plane_descriptors[k].surface.tiling,
172 display_cfg->plane_descriptors[k].surface.plane0.pitch,
173 display_cfg->plane_descriptors[k].surface.plane1.pitch,
174
175 // Output
176 &mode_lib->mp.BytePerPixelY[k],
177 &mode_lib->mp.BytePerPixelC[k],
178 &mode_lib->mp.BytePerPixelInDETY[k],
179 &mode_lib->mp.BytePerPixelInDETC[k],
180 &mode_lib->mp.Read256BlockHeightY[k],
181 &mode_lib->mp.Read256BlockHeightC[k],
182 &mode_lib->mp.Read256BlockWidthY[k],
183 &mode_lib->mp.Read256BlockWidthC[k],
184 &mode_lib->mp.MacroTileHeightY[k],
185 &mode_lib->mp.MacroTileHeightC[k],
186 &mode_lib->mp.MacroTileWidthY[k],
187 &mode_lib->mp.MacroTileWidthC[k],
188 &mode_lib->mp.surf_linear128_l[k],
189 &mode_lib->mp.surf_linear128_c[k]);
190 }
191
192 dcn5_calculate_swath_width(
193 display_cfg,
194 false, // ForceSingleDPP
195 s->num_active_planes,
196 mode_lib->mp.ODMMode,
197 mode_lib->mp.BytePerPixelY,
198 mode_lib->mp.BytePerPixelC,
199 mode_lib->mp.Read256BlockHeightY,
200 mode_lib->mp.Read256BlockHeightC,
201 mode_lib->mp.Read256BlockWidthY,
202 mode_lib->mp.Read256BlockWidthC,
203 mode_lib->mp.surf_linear128_l,
204 mode_lib->mp.surf_linear128_c,
205 mode_lib->mp.NoOfDPP,
206
207 /* Output */
208 mode_lib->mp.req_per_swath_ub_l,
209 mode_lib->mp.req_per_swath_ub_c,
210 mode_lib->mp.SwathWidthSingleDPPY,
211 mode_lib->mp.SwathWidthSingleDPPC,
212 mode_lib->mp.SwathWidthY,
213 mode_lib->mp.SwathWidthC,
214 s->dummy_integer_array[0], // unsigned int MaximumSwathHeightY[]
215 s->dummy_integer_array[1], // unsigned int MaximumSwathHeightC[]
216 mode_lib->mp.swath_width_luma_ub,
217 mode_lib->mp.swath_width_chroma_ub,
218 s->dummy_integer_array[2],
219 s->dummy_integer_array[3]);
220
221 for (k = 0; k < s->num_active_planes; ++k) {
222 mode_lib->mp.cursor_bw[k] = display_cfg->plane_descriptors[k].cursor.num_cursors * display_cfg->plane_descriptors[k].cursor.cursor_width * display_cfg->plane_descriptors[k].cursor.cursor_bpp / 8.0 /
223 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000));
224 mode_lib->mp.vactive_sw_bw_l[k] = mode_lib->mp.SwathWidthSingleDPPY[k] * mode_lib->mp.BytePerPixelY[k] / (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
225 mode_lib->mp.vactive_sw_bw_c[k] = mode_lib->mp.SwathWidthSingleDPPC[k] * mode_lib->mp.BytePerPixelC[k] / (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)) * display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
226 DML_LOG_VERBOSE("DML::%s: vactive_sw_bw_l[%i] = %fBps\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
227 DML_LOG_VERBOSE("DML::%s: vactive_sw_bw_c[%i] = %fBps\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
228 }
229
230 CalculateSwathAndDETConfiguration_params->display_cfg = display_cfg;
231 CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSizeInKByte = mode_lib->ip.config_return_buffer_size_in_kbytes;
232 CalculateSwathAndDETConfiguration_params->MaxTotalDETInKByte = s->MaxTotalDETInKByte;
233 CalculateSwathAndDETConfiguration_params->MinCompressedBufferSizeInKByte = s->MinCompressedBufferSizeInKByte;
234 CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes;
235 CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes;
236 CalculateSwathAndDETConfiguration_params->rob_buffer_size_kbytes = mode_lib->ip.rob_buffer_size_kbytes;
237 CalculateSwathAndDETConfiguration_params->pixel_chunk_size_kbytes = mode_lib->ip.pixel_chunk_size_kbytes;
238 CalculateSwathAndDETConfiguration_params->ForceSingleDPP = false;
239 CalculateSwathAndDETConfiguration_params->NumberOfActiveSurfaces = s->num_active_planes;
240 CalculateSwathAndDETConfiguration_params->nomDETInKByte = s->NomDETInKByte;
241 CalculateSwathAndDETConfiguration_params->ConfigReturnBufferSegmentSizeInkByte = mode_lib->ip.config_return_buffer_segment_size_in_kbytes;
242 CalculateSwathAndDETConfiguration_params->CompressedBufferSegmentSizeInkByte = mode_lib->ip.compressed_buffer_segment_size_in_kbytes;
243 CalculateSwathAndDETConfiguration_params->ReadBandwidthLuma = mode_lib->mp.vactive_sw_bw_l;
244 CalculateSwathAndDETConfiguration_params->ReadBandwidthChroma = mode_lib->mp.vactive_sw_bw_c;
245 CalculateSwathAndDETConfiguration_params->MaximumSwathWidthLuma = s->dummy_single_array[0];
246 CalculateSwathAndDETConfiguration_params->MaximumSwathWidthChroma = s->dummy_single_array[1];
247 CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightY = mode_lib->mp.Read256BlockHeightY;
248 CalculateSwathAndDETConfiguration_params->Read256BytesBlockHeightC = mode_lib->mp.Read256BlockHeightC;
249 CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthY = mode_lib->mp.Read256BlockWidthY;
250 CalculateSwathAndDETConfiguration_params->Read256BytesBlockWidthC = mode_lib->mp.Read256BlockWidthC;
251 CalculateSwathAndDETConfiguration_params->surf_linear128_l = mode_lib->mp.surf_linear128_l;
252 CalculateSwathAndDETConfiguration_params->surf_linear128_c = mode_lib->mp.surf_linear128_c;
253 CalculateSwathAndDETConfiguration_params->ODMMode = mode_lib->mp.ODMMode;
254 CalculateSwathAndDETConfiguration_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
255 CalculateSwathAndDETConfiguration_params->BytePerPixY = mode_lib->mp.BytePerPixelY;
256 CalculateSwathAndDETConfiguration_params->BytePerPixC = mode_lib->mp.BytePerPixelC;
257 CalculateSwathAndDETConfiguration_params->BytePerPixDETY = mode_lib->mp.BytePerPixelInDETY;
258 CalculateSwathAndDETConfiguration_params->BytePerPixDETC = mode_lib->mp.BytePerPixelInDETC;
259 CalculateSwathAndDETConfiguration_params->mrq_present = mode_lib->ip.dcn_mrq_present;
260
261 // output
262 CalculateSwathAndDETConfiguration_params->req_per_swath_ub_l = mode_lib->mp.req_per_swath_ub_l;
263 CalculateSwathAndDETConfiguration_params->req_per_swath_ub_c = mode_lib->mp.req_per_swath_ub_c;
264 CalculateSwathAndDETConfiguration_params->swath_width_luma_ub = s->dummy_long_array[0];
265 CalculateSwathAndDETConfiguration_params->swath_width_chroma_ub = s->dummy_long_array[1];
266 CalculateSwathAndDETConfiguration_params->SwathWidth = s->dummy_long_array[2];
267 CalculateSwathAndDETConfiguration_params->SwathWidthChroma = s->dummy_long_array[3];
268 CalculateSwathAndDETConfiguration_params->SwathHeightY = mode_lib->mp.SwathHeightY;
269 CalculateSwathAndDETConfiguration_params->SwathHeightC = mode_lib->mp.SwathHeightC;
270 CalculateSwathAndDETConfiguration_params->request_size_bytes_luma = mode_lib->mp.request_size_bytes_luma;
271 CalculateSwathAndDETConfiguration_params->request_size_bytes_chroma = mode_lib->mp.request_size_bytes_chroma;
272 CalculateSwathAndDETConfiguration_params->DETBufferSizeInKByte = mode_lib->mp.DETBufferSizeInKByte;
273 CalculateSwathAndDETConfiguration_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
274 CalculateSwathAndDETConfiguration_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC;
275 CalculateSwathAndDETConfiguration_params->full_swath_bytes_l = s->full_swath_bytes_l;
276 CalculateSwathAndDETConfiguration_params->full_swath_bytes_c = s->full_swath_bytes_c;
277 CalculateSwathAndDETConfiguration_params->full_swath_bytes_single_dpp_l = s->dummy_long_array[4];
278 CalculateSwathAndDETConfiguration_params->full_swath_bytes_single_dpp_c = s->dummy_long_array[5];
279 CalculateSwathAndDETConfiguration_params->UnboundedRequestEnabled = &mode_lib->mp.UnboundedRequestEnabled;
280 CalculateSwathAndDETConfiguration_params->compbuf_reserved_space_64b = &mode_lib->mp.compbuf_reserved_space_64b;
281 CalculateSwathAndDETConfiguration_params->hw_debug5 = &mode_lib->mp.hw_debug5;
282 CalculateSwathAndDETConfiguration_params->CompressedBufferSizeInkByte = &mode_lib->mp.CompressedBufferSizeInkByte;
283 CalculateSwathAndDETConfiguration_params->ViewportSizeSupportPerSurface = &s->dummy_boolean_array[0][0];
284 CalculateSwathAndDETConfiguration_params->ViewportSizeSupport = &s->dummy_boolean[0];
285
286 // Calculate DET size, swath height here.
287 dcn5_calculate_swath_and_det_configuration(&mode_lib->scratch, CalculateSwathAndDETConfiguration_params);
288
289 // DSC Delay
290 mode_lib->mp.use_legacy_dsc_delay_formula = mode_lib->ip.use_legacy_dsc_delay_formula;
291 for (k = 0; k < s->num_active_planes; ++k) {
292 mode_lib->mp.DSCDelay[k] = dcn5_calculate_dsc_delay_requirement(cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].dsc_enable,
293 mode_lib->mp.ODMMode[k],
294 mode_lib->ip.maximum_dsc_bits_per_component,
295 s->OutputBpp[k],
296 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active,
297 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total,
298 cfg_support_info->stream_support_info[display_cfg->plane_descriptors[k].stream_index].num_dsc_slices,
299 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format,
300 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_encoder,
301 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
302 s->PixelClockBackEnd[k],
303 mode_lib->mp.use_legacy_dsc_delay_formula);
304 }
305
306 for (k = 0; k < s->num_active_planes; ++k) {
307 s->SurfaceParameters[k].PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
308 s->SurfaceParameters[k].DPPPerSurface = mode_lib->mp.NoOfDPP[k];
309 s->SurfaceParameters[k].RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle;
310 s->SurfaceParameters[k].ViewportHeight = display_cfg->plane_descriptors[k].composition.viewport.plane0.height;
311 s->SurfaceParameters[k].ViewportHeightC = display_cfg->plane_descriptors[k].composition.viewport.plane1.height;
312 s->SurfaceParameters[k].BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k];
313 s->SurfaceParameters[k].BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k];
314 s->SurfaceParameters[k].BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k];
315 s->SurfaceParameters[k].BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k];
316 s->SurfaceParameters[k].BlockWidthY = mode_lib->mp.MacroTileWidthY[k];
317 s->SurfaceParameters[k].BlockHeightY = mode_lib->mp.MacroTileHeightY[k];
318 s->SurfaceParameters[k].BlockWidthC = mode_lib->mp.MacroTileWidthC[k];
319 s->SurfaceParameters[k].BlockHeightC = mode_lib->mp.MacroTileHeightC[k];
320 s->SurfaceParameters[k].InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced;
321 s->SurfaceParameters[k].HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total;
322 s->SurfaceParameters[k].DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable;
323 s->SurfaceParameters[k].SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format;
324 s->SurfaceParameters[k].SurfaceTiling = display_cfg->plane_descriptors[k].surface.tiling;
325 s->SurfaceParameters[k].BytePerPixelY = mode_lib->mp.BytePerPixelY[k];
326 s->SurfaceParameters[k].BytePerPixelC = mode_lib->mp.BytePerPixelC[k];
327 s->SurfaceParameters[k].ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
328 s->SurfaceParameters[k].VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
329 s->SurfaceParameters[k].VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
330 s->SurfaceParameters[k].VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps;
331 s->SurfaceParameters[k].VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps;
332 s->SurfaceParameters[k].PitchY = display_cfg->plane_descriptors[k].surface.plane0.pitch;
333 s->SurfaceParameters[k].PitchC = display_cfg->plane_descriptors[k].surface.plane1.pitch;
334 s->SurfaceParameters[k].ViewportStationary = display_cfg->plane_descriptors[k].composition.viewport.stationary;
335 s->SurfaceParameters[k].ViewportXStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.x_start;
336 s->SurfaceParameters[k].ViewportYStart = display_cfg->plane_descriptors[k].composition.viewport.plane0.y_start;
337 s->SurfaceParameters[k].ViewportXStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start;
338 s->SurfaceParameters[k].ViewportYStartC = display_cfg->plane_descriptors[k].composition.viewport.plane1.y_start;
339 s->SurfaceParameters[k].FORCE_ONE_ROW_FOR_FRAME = display_cfg->plane_descriptors[k].overrides.hw.force_one_row_for_frame;
340 s->SurfaceParameters[k].SwathHeightY = mode_lib->mp.SwathHeightY[k];
341 s->SurfaceParameters[k].SwathHeightC = mode_lib->mp.SwathHeightC[k];
342 s->SurfaceParameters[k].DCCMetaPitchY = display_cfg->plane_descriptors[k].surface.dcc.plane0.pitch;
343 s->SurfaceParameters[k].DCCMetaPitchC = display_cfg->plane_descriptors[k].surface.dcc.plane1.pitch;
344 s->SurfaceParameters[k].UPSPEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.upsp_enabled;
345 }
346
347 CalculateVMRowAndSwath_params->display_cfg = display_cfg;
348 CalculateVMRowAndSwath_params->uclk_pstate_switch_modes = mode_lib->ms.uclk_pstate_switch_modes;
349 CalculateVMRowAndSwath_params->NumberOfActiveSurfaces = s->num_active_planes;
350 CalculateVMRowAndSwath_params->myPipe = s->SurfaceParameters;
351 CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsLuma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_luma;
352 CalculateVMRowAndSwath_params->PTEBufferSizeInRequestsChroma = mode_lib->ip.dpte_buffer_size_in_pte_reqs_chroma;
353 CalculateVMRowAndSwath_params->SwathWidthY = mode_lib->mp.SwathWidthY;
354 CalculateVMRowAndSwath_params->SwathWidthC = mode_lib->mp.SwathWidthC;
355 CalculateVMRowAndSwath_params->DCCMetaBufferSizeBytes = mode_lib->ip.dcc_meta_buffer_size_bytes;
356 CalculateVMRowAndSwath_params->mrq_present = mode_lib->ip.dcn_mrq_present;
357
358 // output
359 CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0];
360 CalculateVMRowAndSwath_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub;
361 CalculateVMRowAndSwath_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub;
362 CalculateVMRowAndSwath_params->dpte_row_height_luma = mode_lib->mp.dpte_row_height;
363 CalculateVMRowAndSwath_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma;
364 CalculateVMRowAndSwath_params->dpte_row_height_linear_luma = mode_lib->mp.dpte_row_height_linear;
365 CalculateVMRowAndSwath_params->dpte_row_height_linear_chroma = mode_lib->mp.dpte_row_height_linear_chroma;
366 CalculateVMRowAndSwath_params->vm_group_bytes = mode_lib->mp.vm_group_bytes;
367 CalculateVMRowAndSwath_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
368 CalculateVMRowAndSwath_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY;
369 CalculateVMRowAndSwath_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY;
370 CalculateVMRowAndSwath_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY;
371 CalculateVMRowAndSwath_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC;
372 CalculateVMRowAndSwath_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC;
373 CalculateVMRowAndSwath_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC;
374 CalculateVMRowAndSwath_params->vmpg_width_y = s->vmpg_width_y;
375 CalculateVMRowAndSwath_params->vmpg_height_y = s->vmpg_height_y;
376 CalculateVMRowAndSwath_params->vmpg_width_c = s->vmpg_width_c;
377 CalculateVMRowAndSwath_params->vmpg_height_c = s->vmpg_height_c;
378 CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_l = mode_lib->mp.dpde0_bytes_per_frame_ub_l;
379 CalculateVMRowAndSwath_params->dpde0_bytes_per_frame_ub_c = mode_lib->mp.dpde0_bytes_per_frame_ub_c;
380 CalculateVMRowAndSwath_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY;
381 CalculateVMRowAndSwath_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC;
382 CalculateVMRowAndSwath_params->VInitPreFillY = mode_lib->mp.VInitPreFillY;
383 CalculateVMRowAndSwath_params->VInitPreFillC = mode_lib->mp.VInitPreFillC;
384 CalculateVMRowAndSwath_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY;
385 CalculateVMRowAndSwath_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC;
386 CalculateVMRowAndSwath_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
387 CalculateVMRowAndSwath_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow;
388 CalculateVMRowAndSwath_params->dpte_row_bytes_per_row_l = s->dpte_row_bytes_per_row_l;
389 CalculateVMRowAndSwath_params->dpte_row_bytes_per_row_c = s->dpte_row_bytes_per_row_c;
390 CalculateVMRowAndSwath_params->vm_bytes = mode_lib->mp.vm_bytes;
391 CalculateVMRowAndSwath_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame;
392 CalculateVMRowAndSwath_params->use_one_row_for_frame_flip = mode_lib->mp.use_one_row_for_frame_flip;
393 CalculateVMRowAndSwath_params->PTE_BUFFER_MODE = mode_lib->mp.PTE_BUFFER_MODE;
394 CalculateVMRowAndSwath_params->BIGK_FRAGMENT_SIZE = mode_lib->mp.BIGK_FRAGMENT_SIZE;
395 CalculateVMRowAndSwath_params->DCCMetaBufferSizeNotExceeded = s->dummy_boolean_array[1];
396 CalculateVMRowAndSwath_params->meta_row_bw = mode_lib->mp.meta_row_bw;
397 CalculateVMRowAndSwath_params->meta_row_bytes = mode_lib->mp.meta_row_bytes;
398 CalculateVMRowAndSwath_params->meta_row_bytes_per_row_ub_l = s->meta_row_bytes_per_row_ub_l;
399 CalculateVMRowAndSwath_params->meta_row_bytes_per_row_ub_c = s->meta_row_bytes_per_row_ub_c;
400 CalculateVMRowAndSwath_params->meta_req_width_luma = mode_lib->mp.meta_req_width;
401 CalculateVMRowAndSwath_params->meta_req_height_luma = mode_lib->mp.meta_req_height;
402 CalculateVMRowAndSwath_params->meta_row_width_luma = mode_lib->mp.meta_row_width;
403 CalculateVMRowAndSwath_params->meta_row_height_luma = mode_lib->mp.meta_row_height;
404 CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_l = mode_lib->mp.meta_pte_bytes_per_frame_ub_l;
405 CalculateVMRowAndSwath_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma;
406 CalculateVMRowAndSwath_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma;
407 CalculateVMRowAndSwath_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma;
408 CalculateVMRowAndSwath_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma;
409 CalculateVMRowAndSwath_params->meta_pte_bytes_per_frame_ub_c = mode_lib->mp.meta_pte_bytes_per_frame_ub_c;
410
411 dcn5_calculate_vm_row_and_swath(&mode_lib->scratch, CalculateVMRowAndSwath_params);
412
413 memset(calculate_mcache_setting_params, 0, sizeof(struct dml2_core_calcs_calculate_mcache_setting_params));
414 for (k = 0; k < s->num_active_planes; k++) {
415 mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0[k] = 1.0;
416 mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0[k] = 1.0;
417 mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1[k] = 1.0;
418 mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1[k] = 1.0;
419 }
420
421 dcn5_calculate_hostvm_inefficiency_factor(
422 &s->HostVMInefficiencyFactor,
423 &s->HostVMInefficiencyFactorPrefetch,
424
425 display_cfg->gpuvm_enable,
426 display_cfg->hostvm_enable,
427 mode_lib->ip.remote_iommu_outstanding_translations,
428 utm_soc_bb->max_outstanding_reqs,
429 1.0,
430 0.5);
431
432 s->TotalDCCActiveDPP = 0;
433 s->TotalActiveDPP = 0;
434 for (k = 0; k < s->num_active_planes; ++k) {
435 s->TotalActiveDPP = s->TotalActiveDPP + mode_lib->mp.NoOfDPP[k];
436 if (display_cfg->plane_descriptors[k].surface.dcc.enable)
437 s->TotalDCCActiveDPP = s->TotalDCCActiveDPP + mode_lib->mp.NoOfDPP[k];
438 }
439 // Calculate tdlut schedule related terms
440 for (k = 0; k <= s->num_active_planes - 1; k++) {
441 calculate_tdlut_setting_params->dispclk_mhz = mode_lib->mp.Dispclk;
442 calculate_tdlut_setting_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut;
443 calculate_tdlut_setting_params->tdlut_width_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_width_mode;
444 calculate_tdlut_setting_params->tdlut_addressing_mode = display_cfg->plane_descriptors[k].tdlut.tdlut_addressing_mode;
445 calculate_tdlut_setting_params->cursor_buffer_size = mode_lib->ip.cursor_buffer_size;
446 calculate_tdlut_setting_params->gpuvm_enable = display_cfg->gpuvm_enable;
447 calculate_tdlut_setting_params->gpuvm_page_size_kbytes = display_cfg->plane_descriptors[k].overrides.gpuvm_min_page_size_kbytes;
448
449 // output
450 calculate_tdlut_setting_params->tdlut_pte_bytes_per_frame = &s->tdlut_pte_bytes_per_frame[k];
451 calculate_tdlut_setting_params->tdlut_bytes_per_frame = &s->tdlut_bytes_per_frame[k];
452 calculate_tdlut_setting_params->tdlut_groups_per_2row_ub = &s->tdlut_groups_per_2row_ub[k];
453 calculate_tdlut_setting_params->tdlut_opt_time = &s->tdlut_opt_time[k];
454 calculate_tdlut_setting_params->tdlut_drain_time = &s->tdlut_drain_time[k];
455 calculate_tdlut_setting_params->tdlut_bytes_per_group = &s->tdlut_bytes_per_group[k];
456
457 dcn5_calculate_tdlut_setting(&mode_lib->scratch, calculate_tdlut_setting_params);
458 }
459
460 dcn5_calculate_extra_latency(
461 display_cfg,
462 mode_lib->ip.rob_buffer_size_kbytes,
463 0,
464 s->ReorderingBytes,
465 mode_lib->mp.Dcfclk,
466 mode_lib->mp.FabricClock,
467 mode_lib->ip.pixel_chunk_size_kbytes,
468 mode_lib->mp.dram_bw_mbps,
469 s->num_active_planes,
470 mode_lib->mp.NoOfDPP,
471 mode_lib->mp.dpte_group_bytes,
472 s->tdlut_bytes_per_group,
473 s->HostVMInefficiencyFactor,
474 s->HostVMInefficiencyFactorPrefetch,
475 dml2_qos_param_type_dcn4x,
476 !(display_cfg->overrides.max_outstanding_when_urgent_expected_disable),
477 utm_soc_bb->max_outstanding_reqs,
478 mode_lib->mp.request_size_bytes_luma,
479 mode_lib->mp.request_size_bytes_chroma,
480 mode_lib->ip.meta_chunk_size_kbytes,
481 mode_lib->ip.dchub_arb_to_ret_delay,
482 mode_lib->mp.TripToMemory,
483 mode_lib->ip.hostvm_mode,
484
485 // output
486 &mode_lib->mp.ExtraLatency,
487 &mode_lib->mp.ExtraLatency_sr,
488 &mode_lib->mp.ExtraLatencyPrefetch);
489
490 mode_lib->mp.TCalc = 24.0 / mode_lib->mp.DCFCLKDeepSleep;
491
492 for (k = 0; k < s->num_active_planes; ++k) {
493 mode_lib->mp.WritebackDelay[k] = 0.0;
494 for (j = 0; j < display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream; ++j) {
495 mode_lib->mp.WritebackDelay[k] = math_max2(mode_lib->mp.WritebackDelay[k],
496 utm_soc_bb->writeback_base_latency_us
497 + dcn5_calculate_write_back_delay(
498 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].pixel_format,
499 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].h_ratio,
500 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_ratio,
501 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_taps,
502 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].v_taps_chroma,
503 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].output_width,
504 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].output_height,
505 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].input_width,
506 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.writeback_stream[j].input_height,
507 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total)
508 / mode_lib->mp.Dispclk);
509 }
510 }
511
512 /* VActive bytes to fetch for UCLK P-State */
513 calculate_bytes_to_fetch_required_to_hide_latency_params->display_cfg = display_cfg;
514 calculate_bytes_to_fetch_required_to_hide_latency_params->mrq_present = mode_lib->ip.dcn_mrq_present;
515
516 calculate_bytes_to_fetch_required_to_hide_latency_params->num_active_planes = s->num_active_planes;
517 calculate_bytes_to_fetch_required_to_hide_latency_params->num_of_dpp = mode_lib->mp.NoOfDPP;
518 calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_height_l = mode_lib->mp.meta_row_height;
519 calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_height_c = mode_lib->mp.meta_row_height_chroma;
520 calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_bytes_per_row_ub_l = s->meta_row_bytes_per_row_ub_l;
521 calculate_bytes_to_fetch_required_to_hide_latency_params->meta_row_bytes_per_row_ub_c = s->meta_row_bytes_per_row_ub_c;
522 calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_row_height_l = mode_lib->mp.dpte_row_height;
523 calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_row_height_c = mode_lib->mp.dpte_row_height_chroma;
524 calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_bytes_per_row_l = s->dpte_row_bytes_per_row_l;
525 calculate_bytes_to_fetch_required_to_hide_latency_params->dpte_bytes_per_row_c = s->dpte_row_bytes_per_row_c;
526 calculate_bytes_to_fetch_required_to_hide_latency_params->byte_per_pix_l = mode_lib->mp.BytePerPixelY;
527 calculate_bytes_to_fetch_required_to_hide_latency_params->byte_per_pix_c = mode_lib->mp.BytePerPixelC;
528 calculate_bytes_to_fetch_required_to_hide_latency_params->swath_width_l = mode_lib->mp.SwathWidthY;
529 calculate_bytes_to_fetch_required_to_hide_latency_params->swath_width_c = mode_lib->mp.SwathWidthC;
530 calculate_bytes_to_fetch_required_to_hide_latency_params->swath_height_l = mode_lib->mp.SwathHeightY;
531 calculate_bytes_to_fetch_required_to_hide_latency_params->swath_height_c = mode_lib->mp.SwathHeightC;
532 for (k = 0; k < s->num_active_planes; ++k) {
533 calculate_bytes_to_fetch_required_to_hide_latency_params->latency_to_hide_us[k] = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
534 }
535
536 /* outputs */
537 calculate_bytes_to_fetch_required_to_hide_latency_params->bytes_required_l = s->pstate_bytes_required_l[dml2_pstate_type_uclk];
538 calculate_bytes_to_fetch_required_to_hide_latency_params->bytes_required_c = s->pstate_bytes_required_c[dml2_pstate_type_uclk];
539
540 dcn5_calculate_bytes_to_fetch_required_to_hide_latency(calculate_bytes_to_fetch_required_to_hide_latency_params);
541
542 /* Excess VActive bandwidth required to fill DET */
543 dcn5_calculate_excess_vactive_bandwidth_required(
544 display_cfg,
545 s->num_active_planes,
546 s->pstate_bytes_required_l[dml2_pstate_type_uclk],
547 s->pstate_bytes_required_c[dml2_pstate_type_uclk],
548 /* outputs */
549 mode_lib->mp.excess_vactive_fill_bw_l,
550 mode_lib->mp.excess_vactive_fill_bw_c);
551
552 mode_lib->mp.TripToMemory = math_max2(mode_lib->mp.UrgentLatency, mode_lib->mp.TripToMemory);
553
554 for (k = 0; k < s->num_active_planes; ++k) {
555 bool cursor_not_enough_urgent_latency_hiding = 0;
556 double line_time_us;
557
558 dcn5_calculate_cursor_req_attributes(
559 display_cfg->plane_descriptors[k].cursor.cursor_width,
560 display_cfg->plane_descriptors[k].cursor.cursor_bpp,
561
562 // output
563 &s->cursor_lines_per_chunk[k],
564 &s->cursor_bytes_per_line[k],
565 &s->cursor_bytes_per_chunk[k],
566 &s->cursor_bytes[k]);
567
568 line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
569
570 dcn5_calculate_cursor_urgent_burst_factor(
571 mode_lib->ip.cursor_buffer_size,
572 display_cfg->plane_descriptors[k].cursor.cursor_width,
573 s->cursor_bytes_per_chunk[k],
574 s->cursor_lines_per_chunk[k],
575 line_time_us,
576 mode_lib->mp.UrgentLatency,
577
578 // output
579 &mode_lib->mp.UrgentBurstFactorCursor[k],
580 &cursor_not_enough_urgent_latency_hiding);
581 mode_lib->mp.UrgentBurstFactorCursorPre[k] = mode_lib->mp.UrgentBurstFactorCursor[k];
582
583 dcn5_calculate_urgent_burst_factor(
584 &display_cfg->plane_descriptors[k],
585 mode_lib->mp.swath_width_luma_ub[k],
586 mode_lib->mp.swath_width_chroma_ub[k],
587 mode_lib->mp.SwathHeightY[k],
588 mode_lib->mp.SwathHeightC[k],
589 line_time_us,
590 mode_lib->mp.UrgentLatency,
591 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
592 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
593 mode_lib->mp.BytePerPixelInDETY[k],
594 mode_lib->mp.BytePerPixelInDETC[k],
595 mode_lib->mp.DETBufferSizeY[k],
596 mode_lib->mp.DETBufferSizeC[k],
597
598 /* output */
599 &mode_lib->mp.UrgentBurstFactorLuma[k],
600 &mode_lib->mp.UrgentBurstFactorChroma[k],
601 &mode_lib->mp.NotEnoughUrgentLatencyHiding[k]);
602
603 mode_lib->mp.NotEnoughUrgentLatencyHiding[k] = mode_lib->mp.NotEnoughUrgentLatencyHiding[k] || cursor_not_enough_urgent_latency_hiding;
604 }
605
606 for (k = 0; k < s->num_active_planes; ++k) {
607 s->MaxVStartupLines[k] = dcn5_calculate_max_vstartup(
608 mode_lib->ip.ptoi_supported,
609 mode_lib->ip.vblank_nom_default_us,
610 &display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing,
611 mode_lib->mp.WritebackDelay[k]);
612 DML_LOG_VERBOSE("DML::%s: k=%u MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
613 DML_LOG_VERBOSE("DML::%s: k=%u WritebackDelay = %f\n", __func__, k, mode_lib->mp.WritebackDelay[k]);
614 }
615
616 s->immediate_flip_required = false;
617 for (k = 0; k < s->num_active_planes; ++k) {
618 s->immediate_flip_required = s->immediate_flip_required || display_cfg->plane_descriptors[k].immediate_flip;
619 }
620 DML_LOG_VERBOSE("DML::%s: immediate_flip_required = %u\n", __func__, s->immediate_flip_required);
621
622 {
623 s->DestinationLineTimesForPrefetchLessThan2 = false;
624 s->VRatioPrefetchMoreThanMax = false;
625
626 DML_LOG_VERBOSE("DML::%s: Start one iteration of prefetch schedule evaluation\n", __func__);
627
628 for (k = 0; k < s->num_active_planes; ++k) {
629 struct dml2_core_internal_DmlPipe *myPipe = &s->myPipe;
630
631 DML_LOG_VERBOSE("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
632 mode_lib->mp.TWait[k] = dcn5_calculate_t_wait(
633 display_cfg->plane_descriptors[k].overrides.reserved_vblank_time_ns,
634 mode_lib->mp.UrgentLatency,
635 mode_lib->mp.TripToMemory,
636 utm_soc_bb->power_management_parameters.g7_ppt_blackout_us,
637 display_cfg->stream_descriptors->timing.drr_config.enabled);
638
639 myPipe->Dppclk = mode_lib->mp.Dppclk[k];
640 myPipe->Dispclk = mode_lib->mp.Dispclk;
641 myPipe->PixelClock = ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
642 myPipe->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep;
643 myPipe->DPPPerSurface = mode_lib->mp.NoOfDPP[k];
644 myPipe->ScalerEnabled = display_cfg->plane_descriptors[k].composition.scaler_info.enabled;
645 myPipe->VRatio = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio;
646 myPipe->VRatioChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio;
647 myPipe->VTaps = display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_taps;
648 myPipe->VTapsChroma = display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_taps;
649 myPipe->RotationAngle = display_cfg->plane_descriptors[k].composition.rotation_angle;
650 myPipe->mirrored = display_cfg->plane_descriptors[k].composition.mirrored;
651 myPipe->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY[k];
652 myPipe->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY[k];
653 myPipe->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC[k];
654 myPipe->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC[k];
655 myPipe->InterlaceEnable = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced;
656 myPipe->NumberOfCursors = display_cfg->plane_descriptors[k].cursor.num_cursors;
657 myPipe->VBlank = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active;
658 myPipe->HTotal = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total;
659 myPipe->HActive = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_active;
660 myPipe->DCCEnable = display_cfg->plane_descriptors[k].surface.dcc.enable;
661 myPipe->ODMMode = mode_lib->mp.ODMMode[k];
662 myPipe->SourcePixelFormat = display_cfg->plane_descriptors[k].pixel_format;
663 myPipe->BytePerPixelY = mode_lib->mp.BytePerPixelY[k];
664 myPipe->BytePerPixelC = mode_lib->mp.BytePerPixelC[k];
665 myPipe->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
666 DML_LOG_VERBOSE("DML::%s: Calling CalculatePrefetchSchedule for k=%u\n", __func__, k);
667
668 CalculatePrefetchSchedule_params->display_cfg = display_cfg;
669 CalculatePrefetchSchedule_params->HostVMInefficiencyFactor = s->HostVMInefficiencyFactorPrefetch;
670 CalculatePrefetchSchedule_params->myPipe = myPipe;
671 CalculatePrefetchSchedule_params->DSCDelay = mode_lib->mp.DSCDelay[k];
672 CalculatePrefetchSchedule_params->DPPCLKDelaySubtotalPlusCNVCFormater = mode_lib->ip.dppclk_delay_subtotal + mode_lib->ip.dppclk_delay_cnvc_formatter;
673 CalculatePrefetchSchedule_params->DPPCLKDelaySCL = mode_lib->ip.dppclk_delay_scl;
674 CalculatePrefetchSchedule_params->DPPCLKDelaySCLLBOnly = mode_lib->ip.dppclk_delay_scl_lb_only;
675 CalculatePrefetchSchedule_params->DPPCLKDelayCNVCCursor = mode_lib->ip.dppclk_delay_cnvc_cursor;
676 CalculatePrefetchSchedule_params->DISPCLKDelaySubtotal = mode_lib->ip.dispclk_delay_subtotal;
677 CalculatePrefetchSchedule_params->DPP_RECOUT_WIDTH = (unsigned int)(mode_lib->mp.SwathWidthY[k] / display_cfg->plane_descriptors[k].composition.scaler_info.plane0.h_ratio);
678 CalculatePrefetchSchedule_params->OutputFormat = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].output.output_format;
679 CalculatePrefetchSchedule_params->MaxInterDCNTileRepeaters = mode_lib->ip.max_inter_dcn_tile_repeaters;
680 CalculatePrefetchSchedule_params->VStartup = s->MaxVStartupLines[k];
681 CalculatePrefetchSchedule_params->HostVMMinPageSize = display_cfg->plane_descriptors[k].overrides.hostvm_min_page_size_kbytes;
682 CalculatePrefetchSchedule_params->DynamicMetadataEnable = display_cfg->plane_descriptors[k].dynamic_meta_data.enable;
683 CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ip.dynamic_metadata_vm_enabled;
684 CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = display_cfg->plane_descriptors[k].dynamic_meta_data.lines_before_active_required;
685 CalculatePrefetchSchedule_params->DynamicMetadataTransmittedBytes = display_cfg->plane_descriptors[k].dynamic_meta_data.transmitted_bytes;
686 CalculatePrefetchSchedule_params->ExtraLatencyPrefetch = mode_lib->mp.ExtraLatencyPrefetch;
687 CalculatePrefetchSchedule_params->TCalc = mode_lib->mp.TCalc;
688 CalculatePrefetchSchedule_params->vm_bytes = mode_lib->mp.vm_bytes[k];
689 CalculatePrefetchSchedule_params->PixelPTEBytesPerRow = mode_lib->mp.PixelPTEBytesPerRow[k];
690 CalculatePrefetchSchedule_params->PrefetchSourceLinesY = mode_lib->mp.PrefetchSourceLinesY[k];
691 CalculatePrefetchSchedule_params->VInitPreFillY = mode_lib->mp.VInitPreFillY[k];
692 CalculatePrefetchSchedule_params->MaxNumSwathY = mode_lib->mp.MaxNumSwathY[k];
693 CalculatePrefetchSchedule_params->PrefetchSourceLinesC = mode_lib->mp.PrefetchSourceLinesC[k];
694 CalculatePrefetchSchedule_params->VInitPreFillC = mode_lib->mp.VInitPreFillC[k];
695 CalculatePrefetchSchedule_params->MaxNumSwathC = mode_lib->mp.MaxNumSwathC[k];
696 CalculatePrefetchSchedule_params->swath_width_luma_ub = mode_lib->mp.swath_width_luma_ub[k];
697 CalculatePrefetchSchedule_params->swath_width_chroma_ub = mode_lib->mp.swath_width_chroma_ub[k];
698 CalculatePrefetchSchedule_params->SwathHeightY = mode_lib->mp.SwathHeightY[k];
699 CalculatePrefetchSchedule_params->SwathHeightC = mode_lib->mp.SwathHeightC[k];
700 CalculatePrefetchSchedule_params->TWait = mode_lib->mp.TWait[k];
701 CalculatePrefetchSchedule_params->Ttrip = mode_lib->mp.TripToMemory;
702 CalculatePrefetchSchedule_params->Turg = mode_lib->mp.UrgentLatency;
703 CalculatePrefetchSchedule_params->setup_for_tdlut = display_cfg->plane_descriptors[k].tdlut.setup_for_tdlut;
704 CalculatePrefetchSchedule_params->tdlut_pte_bytes_per_frame = s->tdlut_pte_bytes_per_frame[k];
705 CalculatePrefetchSchedule_params->tdlut_bytes_per_frame = s->tdlut_bytes_per_frame[k];
706 CalculatePrefetchSchedule_params->tdlut_opt_time = s->tdlut_opt_time[k];
707 CalculatePrefetchSchedule_params->tdlut_drain_time = s->tdlut_drain_time[k];
708 CalculatePrefetchSchedule_params->num_cursors = (display_cfg->plane_descriptors[k].cursor.cursor_width > 0);
709 CalculatePrefetchSchedule_params->cursor_bytes_per_chunk = s->cursor_bytes_per_chunk[k];
710 CalculatePrefetchSchedule_params->cursor_bytes_per_line = s->cursor_bytes_per_line[k];
711 CalculatePrefetchSchedule_params->dcc_enable = display_cfg->plane_descriptors[k].surface.dcc.enable;
712 CalculatePrefetchSchedule_params->mrq_present = mode_lib->ip.dcn_mrq_present;
713 CalculatePrefetchSchedule_params->meta_row_bytes = mode_lib->mp.meta_row_bytes[k];
714
715 // output
716 CalculatePrefetchSchedule_params->DSTXAfterScaler = &mode_lib->mp.DSTXAfterScaler[k];
717 CalculatePrefetchSchedule_params->DSTYAfterScaler = &mode_lib->mp.DSTYAfterScaler[k];
718 CalculatePrefetchSchedule_params->dst_y_prefetch = &mode_lib->mp.dst_y_prefetch[k];
719 CalculatePrefetchSchedule_params->dst_y_per_vm_vblank = &mode_lib->mp.dst_y_per_vm_vblank[k];
720 CalculatePrefetchSchedule_params->dst_y_per_row_vblank = &mode_lib->mp.dst_y_per_row_vblank[k];
721 CalculatePrefetchSchedule_params->VRatioPrefetchY = &mode_lib->mp.VRatioPrefetchY[k];
722 CalculatePrefetchSchedule_params->VRatioPrefetchC = &mode_lib->mp.VRatioPrefetchC[k];
723 CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWLuma = &mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k];
724 CalculatePrefetchSchedule_params->RequiredPrefetchPixelDataBWChroma = &mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k];
725 CalculatePrefetchSchedule_params->NotEnoughTimeForDynamicMetadata = &mode_lib->mp.NotEnoughTimeForDynamicMetadata[k];
726 CalculatePrefetchSchedule_params->Tno_bw = &mode_lib->mp.Tno_bw[k];
727 CalculatePrefetchSchedule_params->Tno_bw_flip = &mode_lib->mp.Tno_bw_flip[k];
728 CalculatePrefetchSchedule_params->prefetch_vmrow_bw = &mode_lib->mp.prefetch_vmrow_bw[k];
729 CalculatePrefetchSchedule_params->Tdmdl_vm = &mode_lib->mp.Tdmdl_vm[k];
730 CalculatePrefetchSchedule_params->Tdmdl = &mode_lib->mp.Tdmdl[k];
731 CalculatePrefetchSchedule_params->TSetup = &mode_lib->mp.TSetup[k];
732 CalculatePrefetchSchedule_params->Tvm_trips = &s->Tvm_trips[k];
733 CalculatePrefetchSchedule_params->Tr0_trips = &s->Tr0_trips[k];
734 CalculatePrefetchSchedule_params->Tvm_trips_flip = &s->Tvm_trips_flip[k];
735 CalculatePrefetchSchedule_params->Tr0_trips_flip = &s->Tr0_trips_flip[k];
736 CalculatePrefetchSchedule_params->Tvm_trips_flip_rounded = &s->Tvm_trips_flip_rounded[k];
737 CalculatePrefetchSchedule_params->Tr0_trips_flip_rounded = &s->Tr0_trips_flip_rounded[k];
738 CalculatePrefetchSchedule_params->VUpdateOffsetPix = &mode_lib->mp.VUpdateOffsetPix[k];
739 CalculatePrefetchSchedule_params->VUpdateWidthPix = &mode_lib->mp.VUpdateWidthPix[k];
740 CalculatePrefetchSchedule_params->VReadyOffsetPix = &mode_lib->mp.VReadyOffsetPix[k];
741 CalculatePrefetchSchedule_params->prefetch_cursor_bw = &mode_lib->mp.prefetch_cursor_bw[k];
742 CalculatePrefetchSchedule_params->prefetch_sw_bytes = &s->prefetch_sw_bytes[k];
743 CalculatePrefetchSchedule_params->Tpre_rounded = &s->Tpre_rounded[k];
744 CalculatePrefetchSchedule_params->Tpre_oto = &s->Tpre_oto[k];
745
746 mode_lib->mp.NoTimeToPrefetch[k] = dcn5_calculate_prefetch_schedule(&mode_lib->scratch, CalculatePrefetchSchedule_params);
747 DML_LOG_VERBOSE("DML::%s: k=%0u NoTimeToPrefetch=%0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]);
748 mode_lib->mp.VStartupMin[k] = s->MaxVStartupLines[k];
749 } // for k
750
751 mode_lib->mp.PrefetchModeSupported = true;
752 for (k = 0; k < s->num_active_planes; ++k) {
753 if (mode_lib->mp.NoTimeToPrefetch[k] == true ||
754 mode_lib->mp.NotEnoughTimeForDynamicMetadata[k] ||
755 mode_lib->mp.DSTYAfterScaler[k] > 8) {
756 DML_LOG_VERBOSE("DML::%s: k=%u, NoTimeToPrefetch = %0d\n", __func__, k, mode_lib->mp.NoTimeToPrefetch[k]);
757 DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughTimeForDynamicMetadata=%u\n", __func__, k, mode_lib->mp.NotEnoughTimeForDynamicMetadata[k]);
758 DML_LOG_VERBOSE("DML::%s: k=%u, DSTYAfterScaler=%u (should be <= 0)\n", __func__, k, mode_lib->mp.DSTYAfterScaler[k]);
759 mode_lib->mp.PrefetchModeSupported = false;
760 }
761 if (mode_lib->mp.dst_y_prefetch[k] < 2)
762 s->DestinationLineTimesForPrefetchLessThan2 = true;
763
764 if (mode_lib->mp.VRatioPrefetchY[k] > __DML2_CALCS_MAX_VRATIO_PRE__ ||
765 mode_lib->mp.VRatioPrefetchC[k] > __DML2_CALCS_MAX_VRATIO_PRE__) {
766 s->VRatioPrefetchMoreThanMax = true;
767 DML_LOG_VERBOSE("DML::%s: k=%d, VRatioPrefetchY=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k], __DML2_CALCS_MAX_VRATIO_PRE__);
768 DML_LOG_VERBOSE("DML::%s: k=%d, VRatioPrefetchC=%f (should not be < %f)\n", __func__, k, mode_lib->mp.VRatioPrefetchC[k], __DML2_CALCS_MAX_VRATIO_PRE__);
769 DML_LOG_VERBOSE("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
770 }
771
772 if (mode_lib->mp.NotEnoughUrgentLatencyHiding[k]) {
773 DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughUrgentLatencyHiding = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHiding[k]);
774 mode_lib->mp.PrefetchModeSupported = false;
775 }
776 }
777
778 if (s->VRatioPrefetchMoreThanMax == true || s->DestinationLineTimesForPrefetchLessThan2 == true) {
779 DML_LOG_VERBOSE("DML::%s: VRatioPrefetchMoreThanMax = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
780 DML_LOG_VERBOSE("DML::%s: DestinationLineTimesForPrefetchLessThan2 = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2);
781 mode_lib->mp.PrefetchModeSupported = false;
782 }
783
784 DML_LOG_VERBOSE("DML::%s: Prefetch schedule is %sOK at vstartup = %u\n", __func__,
785 mode_lib->mp.PrefetchModeSupported ? "" : "NOT ", CalculatePrefetchSchedule_params->VStartup);
786
787 // Prefetch schedule OK, now check prefetch bw
788 if (mode_lib->mp.PrefetchModeSupported == true) {
789 for (k = 0; k < s->num_active_planes; ++k) {
790 double line_time_us = display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
791 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
792 dcn5_calculate_urgent_burst_factor(
793 &display_cfg->plane_descriptors[k],
794 mode_lib->mp.swath_width_luma_ub[k],
795 mode_lib->mp.swath_width_chroma_ub[k],
796 mode_lib->mp.SwathHeightY[k],
797 mode_lib->mp.SwathHeightC[k],
798 line_time_us,
799 mode_lib->mp.UrgentLatency,
800 mode_lib->mp.VRatioPrefetchY[k],
801 mode_lib->mp.VRatioPrefetchC[k],
802 mode_lib->mp.BytePerPixelInDETY[k],
803 mode_lib->mp.BytePerPixelInDETC[k],
804 mode_lib->mp.DETBufferSizeY[k],
805 mode_lib->mp.DETBufferSizeC[k],
806 /* Output */
807 &mode_lib->mp.UrgentBurstFactorLumaPre[k],
808 &mode_lib->mp.UrgentBurstFactorChromaPre[k],
809 &mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]);
810
811 DML_LOG_VERBOSE("DML::%s: k=%0u DPPPerSurface=%u\n", __func__, k, mode_lib->mp.NoOfDPP[k]);
812 DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorLuma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLuma[k]);
813 DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorChroma=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChroma[k]);
814 DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorLumaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorLumaPre[k]);
815 DML_LOG_VERBOSE("DML::%s: k=%0u UrgentBurstFactorChromaPre=%f\n", __func__, k, mode_lib->mp.UrgentBurstFactorChromaPre[k]);
816
817 DML_LOG_VERBOSE("DML::%s: k=%0u VRatioPrefetchY=%f\n", __func__, k, mode_lib->mp.VRatioPrefetchY[k]);
818 DML_LOG_VERBOSE("DML::%s: k=%0u VRatioY=%f\n", __func__, k, display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio);
819
820 DML_LOG_VERBOSE("DML::%s: k=%0u prefetch_vmrow_bw=%f\n", __func__, k, mode_lib->mp.prefetch_vmrow_bw[k]);
821 DML_LOG_VERBOSE("DML::%s: k=%0u vactive_sw_bw_l=%f\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
822 DML_LOG_VERBOSE("DML::%s: k=%0u vactive_sw_bw_c=%f\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
823 DML_LOG_VERBOSE("DML::%s: k=%0u cursor_bw=%f\n", __func__, k, mode_lib->mp.cursor_bw[k]);
824 DML_LOG_VERBOSE("DML::%s: k=%0u dpte_row_bw=%f\n", __func__, k, mode_lib->mp.dpte_row_bw[k]);
825 DML_LOG_VERBOSE("DML::%s: k=%0u meta_row_bw=%f\n", __func__, k, mode_lib->mp.meta_row_bw[k]);
826 DML_LOG_VERBOSE("DML::%s: k=%0u RequiredPrefetchPixelDataBWLuma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWLuma[k]);
827 DML_LOG_VERBOSE("DML::%s: k=%0u RequiredPrefetchPixelDataBWChroma=%f\n", __func__, k, mode_lib->mp.RequiredPrefetchPixelDataBWChroma[k]);
828 DML_LOG_VERBOSE("DML::%s: k=%0u prefetch_cursor_bw=%f\n", __func__, k, mode_lib->mp.prefetch_cursor_bw[k]);
829 }
830
831 for (k = 0; k <= s->num_active_planes - 1; k++)
832 mode_lib->mp.final_flip_bw[k] = 0;
833
834 calculate_peak_bandwidth_params->urg_vactive_bandwidth_required = mode_lib->mp.urg_vactive_bandwidth_required;
835 calculate_peak_bandwidth_params->urg_bandwidth_required = mode_lib->mp.urg_bandwidth_required;
836 calculate_peak_bandwidth_params->urg_bandwidth_required_qual = mode_lib->mp.urg_bandwidth_required_qual;
837 calculate_peak_bandwidth_params->non_urg_bandwidth_required = mode_lib->mp.non_urg_bandwidth_required;
838 calculate_peak_bandwidth_params->surface_avg_vactive_required_bw = s->surface_dummy_bw;
839 calculate_peak_bandwidth_params->surface_peak_required_bw = s->surface_dummy_bw0;
840
841 calculate_peak_bandwidth_params->display_cfg = display_cfg;
842 calculate_peak_bandwidth_params->inc_flip_bw = 0;
843 calculate_peak_bandwidth_params->num_active_planes = s->num_active_planes;
844 calculate_peak_bandwidth_params->num_of_dpp = mode_lib->mp.NoOfDPP;
845 calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0;
846 calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1;
847 calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0;
848 calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1;
849
850 calculate_peak_bandwidth_params->surface_read_bandwidth_l = mode_lib->mp.vactive_sw_bw_l;
851 calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c;
852 calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma;
853 calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma;
854 calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l;
855 calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c;
856 calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw;
857 calculate_peak_bandwidth_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
858 calculate_peak_bandwidth_params->meta_row_bw = mode_lib->mp.meta_row_bw;
859 calculate_peak_bandwidth_params->prefetch_cursor_bw = mode_lib->mp.prefetch_cursor_bw;
860 calculate_peak_bandwidth_params->prefetch_vmrow_bw = mode_lib->mp.prefetch_vmrow_bw;
861 calculate_peak_bandwidth_params->flip_bw = mode_lib->mp.final_flip_bw;
862 calculate_peak_bandwidth_params->urgent_burst_factor_l = mode_lib->mp.UrgentBurstFactorLuma;
863 calculate_peak_bandwidth_params->urgent_burst_factor_c = mode_lib->mp.UrgentBurstFactorChroma;
864 calculate_peak_bandwidth_params->urgent_burst_factor_cursor = mode_lib->mp.UrgentBurstFactorCursor;
865 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_l = mode_lib->mp.UrgentBurstFactorLumaPre;
866 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_c = mode_lib->mp.UrgentBurstFactorChromaPre;
867 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_cursor = mode_lib->mp.UrgentBurstFactorCursorPre;
868
869 dcn5_calculate_peak_bandwidth_required(
870 &mode_lib->scratch,
871 calculate_peak_bandwidth_params);
872
873 // Check urg peak bandwidth against available urg bw
874 // check at SDP and DRAM, for all soc states (Sys Active)
875 dcn5_check_urgent_bandwidth_support(
876 &mode_lib->mp.FractionOfUrgentBandwidth, // double* frac_urg_bandwidth
877 &mode_lib->mp.PrefetchModeSupported, // prefetch bw ok
878
879 **mode_lib->mp.non_urg_bandwidth_required,
880 **mode_lib->mp.urg_bandwidth_required,
881 mode_lib->mp.dram_bw_mbps);
882
883 if (!mode_lib->mp.PrefetchModeSupported)
884 DML_LOG_VERBOSE("DML::%s: Bandwidth not sufficient for prefetch!\n", __func__);
885
886 for (k = 0; k < s->num_active_planes; ++k) {
887 if (mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]) {
888 DML_LOG_VERBOSE("DML::%s: k=%u, NotEnoughUrgentLatencyHidingPre = %u\n", __func__, k, mode_lib->mp.NotEnoughUrgentLatencyHidingPre[k]);
889 mode_lib->mp.PrefetchModeSupported = false;
890 }
891 }
892 } // prefetch schedule ok
893
894 // Prefetch schedule and prefetch bw ok, now check flip bw
895 if (mode_lib->mp.PrefetchModeSupported == true) { // prefetch schedule and prefetch bw ok, now check flip bw
896
897 mode_lib->mp.BandwidthAvailableForImmediateFlip =
898 dcn5_get_bandwidth_available_for_immediate_flip(
899 **mode_lib->mp.urg_bandwidth_required_qual, // no flip
900 mode_lib->mp.dram_bw_mbps);
901
902 mode_lib->mp.TotImmediateFlipBytes = 0;
903
904 for (k = 0; k < s->num_active_planes; ++k) {
905 if (display_cfg->plane_descriptors[k].immediate_flip) {
906 s->per_pipe_flip_bytes[k] = dcn5_get_pipe_flip_bytes(s->HostVMInefficiencyFactor,
907 mode_lib->mp.vm_bytes[k],
908 mode_lib->mp.PixelPTEBytesPerRow[k],
909 mode_lib->mp.meta_row_bytes[k]);
910 } else {
911 s->per_pipe_flip_bytes[k] = 0;
912 }
913 mode_lib->mp.TotImmediateFlipBytes += s->per_pipe_flip_bytes[k] * mode_lib->mp.NoOfDPP[k];
914 DML_LOG_VERBOSE("DML::%s: k = %u\n", __func__, k);
915 DML_LOG_VERBOSE("DML::%s: DPPPerSurface = %u\n", __func__, mode_lib->mp.NoOfDPP[k]);
916 DML_LOG_VERBOSE("DML::%s: vm_bytes = %u\n", __func__, mode_lib->mp.vm_bytes[k]);
917 DML_LOG_VERBOSE("DML::%s: PixelPTEBytesPerRow = %u\n", __func__, mode_lib->mp.PixelPTEBytesPerRow[k]);
918 DML_LOG_VERBOSE("DML::%s: meta_row_bytes = %u\n", __func__, mode_lib->mp.meta_row_bytes[k]);
919 DML_LOG_VERBOSE("DML::%s: TotImmediateFlipBytes = %u\n", __func__, mode_lib->mp.TotImmediateFlipBytes);
920 }
921 for (k = 0; k < s->num_active_planes; ++k) {
922 dcn5_calculate_flip_schedule(
923 &mode_lib->scratch,
924 display_cfg->plane_descriptors[k].immediate_flip,
925 0, // use_lb_flip_bw
926 s->HostVMInefficiencyFactor,
927 s->Tvm_trips_flip[k],
928 s->Tr0_trips_flip[k],
929 s->Tvm_trips_flip_rounded[k],
930 s->Tr0_trips_flip_rounded[k],
931 display_cfg->gpuvm_enable,
932 mode_lib->mp.vm_bytes[k],
933 mode_lib->mp.PixelPTEBytesPerRow[k],
934 mode_lib->mp.BandwidthAvailableForImmediateFlip,
935 mode_lib->mp.TotImmediateFlipBytes,
936 display_cfg->plane_descriptors[k].pixel_format,
937 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000),
938 display_cfg->plane_descriptors[k].composition.scaler_info.plane0.v_ratio,
939 display_cfg->plane_descriptors[k].composition.scaler_info.plane1.v_ratio,
940 mode_lib->mp.Tno_bw[k],
941 mode_lib->mp.dpte_row_height[k],
942 mode_lib->mp.dpte_row_height_chroma[k],
943 mode_lib->mp.use_one_row_for_frame_flip[k],
944 mode_lib->ip.max_flip_time_us,
945 mode_lib->ip.max_flip_time_lines,
946 s->per_pipe_flip_bytes[k],
947 mode_lib->mp.meta_row_bytes[k],
948 mode_lib->mp.meta_row_height[k],
949 mode_lib->mp.meta_row_height_chroma[k],
950 mode_lib->ip.dcn_mrq_present && display_cfg->plane_descriptors[k].surface.dcc.enable,
951
952 // Output
953 &mode_lib->mp.dst_y_per_vm_flip[k],
954 &mode_lib->mp.dst_y_per_row_flip[k],
955 &mode_lib->mp.final_flip_bw[k],
956 &mode_lib->mp.ImmediateFlipSupportedForPipe[k]);
957 }
958
959 calculate_peak_bandwidth_params->urg_vactive_bandwidth_required = s->dummy_bw;
960 calculate_peak_bandwidth_params->urg_bandwidth_required = mode_lib->mp.urg_bandwidth_required_flip;
961 calculate_peak_bandwidth_params->urg_bandwidth_required_qual = s->dummy_bw;
962 calculate_peak_bandwidth_params->non_urg_bandwidth_required = mode_lib->mp.non_urg_bandwidth_required_flip;
963 calculate_peak_bandwidth_params->surface_avg_vactive_required_bw = s->surface_dummy_bw;
964 calculate_peak_bandwidth_params->surface_peak_required_bw = s->surface_dummy_bw0;
965
966 calculate_peak_bandwidth_params->display_cfg = display_cfg;
967 calculate_peak_bandwidth_params->inc_flip_bw = 1;
968 calculate_peak_bandwidth_params->num_active_planes = s->num_active_planes;
969 calculate_peak_bandwidth_params->num_of_dpp = mode_lib->mp.NoOfDPP;
970 calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p0;
971 calculate_peak_bandwidth_params->dcc_dram_bw_nom_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_nom_overhead_factor_p1;
972 calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p0 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p0;
973 calculate_peak_bandwidth_params->dcc_dram_bw_pref_overhead_factor_p1 = mode_lib->mp.dcc_dram_bw_pref_overhead_factor_p1;
974
975 calculate_peak_bandwidth_params->surface_read_bandwidth_l = mode_lib->mp.vactive_sw_bw_l;
976 calculate_peak_bandwidth_params->surface_read_bandwidth_c = mode_lib->mp.vactive_sw_bw_c;
977 calculate_peak_bandwidth_params->prefetch_bandwidth_l = mode_lib->mp.RequiredPrefetchPixelDataBWLuma;
978 calculate_peak_bandwidth_params->prefetch_bandwidth_c = mode_lib->mp.RequiredPrefetchPixelDataBWChroma;
979 calculate_peak_bandwidth_params->excess_vactive_fill_bw_l = mode_lib->mp.excess_vactive_fill_bw_l;
980 calculate_peak_bandwidth_params->excess_vactive_fill_bw_c = mode_lib->mp.excess_vactive_fill_bw_c;
981 calculate_peak_bandwidth_params->cursor_bw = mode_lib->mp.cursor_bw;
982 calculate_peak_bandwidth_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
983 calculate_peak_bandwidth_params->meta_row_bw = mode_lib->mp.meta_row_bw;
984 calculate_peak_bandwidth_params->prefetch_cursor_bw = mode_lib->mp.prefetch_cursor_bw;
985 calculate_peak_bandwidth_params->prefetch_vmrow_bw = mode_lib->mp.prefetch_vmrow_bw;
986 calculate_peak_bandwidth_params->flip_bw = mode_lib->mp.final_flip_bw;
987 calculate_peak_bandwidth_params->urgent_burst_factor_l = mode_lib->mp.UrgentBurstFactorLuma;
988 calculate_peak_bandwidth_params->urgent_burst_factor_c = mode_lib->mp.UrgentBurstFactorChroma;
989 calculate_peak_bandwidth_params->urgent_burst_factor_cursor = mode_lib->mp.UrgentBurstFactorCursor;
990 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_l = mode_lib->mp.UrgentBurstFactorLumaPre;
991 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_c = mode_lib->mp.UrgentBurstFactorChromaPre;
992 calculate_peak_bandwidth_params->urgent_burst_factor_prefetch_cursor = mode_lib->mp.UrgentBurstFactorCursorPre;
993
994 dcn5_calculate_peak_bandwidth_required(
995 &mode_lib->scratch,
996 calculate_peak_bandwidth_params);
997
998 dcn5_check_immediate_flip_bandwidth_support(
999 &mode_lib->mp.FractionOfUrgentBandwidthImmediateFlip, // double* frac_urg_bandwidth_flip
1000 &mode_lib->mp.ImmediateFlipSupported, // bool* flip_bandwidth_support_ok
1001 **mode_lib->mp.urg_bandwidth_required_flip,
1002 **mode_lib->mp.non_urg_bandwidth_required_flip,
1003 mode_lib->mp.dram_bw_mbps);
1004
1005 if (!mode_lib->mp.ImmediateFlipSupported)
1006 DML_LOG_VERBOSE("DML::%s: Bandwidth not sufficient for flip!", __func__);
1007
1008 for (k = 0; k < s->num_active_planes; ++k) {
1009 if (display_cfg->plane_descriptors[k].immediate_flip && mode_lib->mp.ImmediateFlipSupportedForPipe[k] == false) {
1010 mode_lib->mp.ImmediateFlipSupported = false;
1011 DML_LOG_VERBOSE("DML::%s: Pipe %0d not supporting iflip!\n", __func__, k);
1012 }
1013 }
1014 } else { // flip or prefetch not support
1015 mode_lib->mp.ImmediateFlipSupported = false;
1016 }
1017
1018 // consider flip support is okay if the flip bw is ok or (when user does't require a iflip and there is no host vm)
1019 must_support_iflip = display_cfg->hostvm_enable || s->immediate_flip_required;
1020 mode_lib->mp.PrefetchAndImmediateFlipSupported = (mode_lib->mp.PrefetchModeSupported == true && (!must_support_iflip || mode_lib->mp.ImmediateFlipSupported));
1021
1022 DML_LOG_VERBOSE("DML::%s: PrefetchModeSupported = %u\n", __func__, mode_lib->mp.PrefetchModeSupported);
1023 for (k = 0; k < s->num_active_planes; ++k)
1024 DML_LOG_VERBOSE("DML::%s: immediate_flip_required[%u] = %u\n", __func__, k, display_cfg->plane_descriptors[k].immediate_flip);
1025 DML_LOG_VERBOSE("DML::%s: HostVMEnable = %u\n", __func__, display_cfg->hostvm_enable);
1026 DML_LOG_VERBOSE("DML::%s: ImmediateFlipSupported = %u\n", __func__, mode_lib->mp.ImmediateFlipSupported);
1027 DML_LOG_VERBOSE("DML::%s: PrefetchAndImmediateFlipSupported = %u\n", __func__, mode_lib->mp.PrefetchAndImmediateFlipSupported);
1028 DML_LOG_VERBOSE("DML::%s: Done one iteration: k=%d, MaxVStartupLines=%u\n", __func__, k, s->MaxVStartupLines[k]);
1029 }
1030
1031 for (k = 0; k < s->num_active_planes; ++k)
1032 DML_LOG_VERBOSE("DML::%s: k=%d MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
1033
1034 if (!mode_lib->mp.PrefetchAndImmediateFlipSupported) {
1035 DML_LOG_VERBOSE("DML::%s: Bad, Prefetch and flip scheduling solution NOT found!\n", __func__);
1036 } else {
1037 DML_LOG_VERBOSE("DML::%s: Good, Prefetch and flip scheduling solution found\n", __func__);
1038
1039 // DCC Configuration
1040 for (k = 0; k < s->num_active_planes; ++k) {
1041 DML_LOG_VERBOSE("DML::%s: Calculate DCC configuration for surface k=%u\n", __func__, k);
1042 dcn5_calculate_dcc_configuration(
1043 display_cfg->plane_descriptors[k].surface.dcc.enable,
1044 display_cfg->overrides.dcc_programming_assumes_scan_direction_unknown,
1045 display_cfg->plane_descriptors[k].pixel_format,
1046 display_cfg->plane_descriptors[k].surface.plane0.width,
1047 display_cfg->plane_descriptors[k].surface.plane1.width,
1048 display_cfg->plane_descriptors[k].surface.plane0.height,
1049 display_cfg->plane_descriptors[k].surface.plane1.height,
1050 s->NomDETInKByte,
1051 mode_lib->mp.Read256BlockHeightY[k],
1052 mode_lib->mp.Read256BlockHeightC[k],
1053 display_cfg->plane_descriptors[k].surface.tiling,
1054 mode_lib->mp.BytePerPixelY[k],
1055 mode_lib->mp.BytePerPixelC[k],
1056 mode_lib->mp.BytePerPixelInDETY[k],
1057 mode_lib->mp.BytePerPixelInDETC[k],
1058 display_cfg->plane_descriptors[k].composition.rotation_angle,
1059
1060 /* Output */
1061 &mode_lib->mp.RequestLuma[k],
1062 &mode_lib->mp.RequestChroma[k],
1063 &mode_lib->mp.DCCYMaxUncompressedBlock[k],
1064 &mode_lib->mp.DCCCMaxUncompressedBlock[k],
1065 &mode_lib->mp.DCCYMaxCompressedBlock[k],
1066 &mode_lib->mp.DCCCMaxCompressedBlock[k],
1067 &mode_lib->mp.DCCYIndependentBlock[k],
1068 &mode_lib->mp.DCCCIndependentBlock[k]);
1069 }
1070
1071 //Watermarks and NB P-State/DRAM Clock Change Support
1072 s->mmSOCParameters.UrgentLatency = mode_lib->mp.UrgentLatency;
1073 s->mmSOCParameters.ExtraLatency = mode_lib->mp.ExtraLatency;
1074 s->mmSOCParameters.ExtraLatency_sr = mode_lib->mp.ExtraLatency_sr;
1075 s->mmSOCParameters.WritebackLatency = utm_soc_bb->writeback_base_latency_us;
1076 s->mmSOCParameters.DRAMClockChangeLatency = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
1077 s->mmSOCParameters.FCLKChangeLatency = utm_soc_bb->power_management_parameters.fclk_change_blackout_us;
1078 s->mmSOCParameters.SRExitTime = utm_soc_bb->power_management_parameters.stutter_exit_latency_us;
1079 s->mmSOCParameters.SREnterPlusExitTime = utm_soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us;
1080 s->mmSOCParameters.SRExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_exit_latency_us;
1081 s->mmSOCParameters.SREnterPlusExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_enter_plus_exit_latency_us;
1082 s->mmSOCParameters.USRRetrainingLatency = 0;
1083 s->mmSOCParameters.SMNLatency = 0;
1084 s->mmSOCParameters.temp_read_or_ppt_blackout_us = utm_soc_bb->power_management_parameters.g7_ppt_blackout_us;
1085 s->mmSOCParameters.qos_type = dml2_qos_param_type_dcn4x;
1086
1087 CalculateWatermarks_params->display_cfg = display_cfg;
1088 CalculateWatermarks_params->USRRetrainingRequired = false;
1089 CalculateWatermarks_params->NumberOfActiveSurfaces = s->num_active_planes;
1090 CalculateWatermarks_params->MaxLineBufferLines = mode_lib->ip.max_line_buffer_lines;
1091 CalculateWatermarks_params->LineBufferSize = mode_lib->ip.line_buffer_size_bits;
1092 CalculateWatermarks_params->WritebackInterfaceBufferSize = mode_lib->ip.writeback_interface_buffer_size_kbytes;
1093 CalculateWatermarks_params->DCFCLK = mode_lib->mp.Dcfclk;
1094 CalculateWatermarks_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings;
1095 CalculateWatermarks_params->SynchronizeDRRDisplaysForUCLKPStateChange = display_cfg->overrides.synchronize_ddr_displays_for_uclk_pstate_change;
1096 CalculateWatermarks_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
1097 CalculateWatermarks_params->mmSOCParameters = s->mmSOCParameters;
1098 CalculateWatermarks_params->WritebackChunkSize = mode_lib->ip.writeback_chunk_size_kbytes;
1099 CalculateWatermarks_params->SOCCLK = s->SOCCLK;
1100 CalculateWatermarks_params->DCFClkDeepSleep = mode_lib->mp.DCFCLKDeepSleep;
1101 CalculateWatermarks_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
1102 CalculateWatermarks_params->DETBufferSizeC = mode_lib->mp.DETBufferSizeC;
1103 CalculateWatermarks_params->SwathHeightY = mode_lib->mp.SwathHeightY;
1104 CalculateWatermarks_params->SwathHeightC = mode_lib->mp.SwathHeightC;
1105 //CalculateWatermarks_params->LBBitPerPixel = 57; //FIXME_STAGE2
1106 CalculateWatermarks_params->SwathWidthY = mode_lib->mp.SwathWidthY;
1107 CalculateWatermarks_params->SwathWidthC = mode_lib->mp.SwathWidthC;
1108 CalculateWatermarks_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY;
1109 CalculateWatermarks_params->BytePerPixelDETC = mode_lib->mp.BytePerPixelInDETC;
1110 CalculateWatermarks_params->DSTXAfterScaler = mode_lib->mp.DSTXAfterScaler;
1111 CalculateWatermarks_params->DSTYAfterScaler = mode_lib->mp.DSTYAfterScaler;
1112 CalculateWatermarks_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled;
1113 CalculateWatermarks_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte;
1114 CalculateWatermarks_params->meta_row_height_l = mode_lib->mp.meta_row_height;
1115 CalculateWatermarks_params->meta_row_height_c = mode_lib->mp.meta_row_height_chroma;
1116 CalculateWatermarks_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
1117 CalculateWatermarks_params->uclk_pstate_switch_modes = mode_lib->mp.uclk_pstate_switch_modes;
1118
1119 // Output
1120 CalculateWatermarks_params->Watermark = &mode_lib->mp.Watermark;
1121 CalculateWatermarks_params->DRAMClockChangeSupport = mode_lib->mp.DRAMClockChangeSupport;
1122 CalculateWatermarks_params->global_dram_clock_change_support_required = &s->dummy_boolean[0];
1123 CalculateWatermarks_params->global_dram_clock_change_supported = &mode_lib->mp.global_dram_clock_change_supported;
1124 CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported;
1125 CalculateWatermarks_params->FCLKChangeSupport = mode_lib->mp.FCLKChangeSupport;
1126 CalculateWatermarks_params->global_fclk_change_supported = &mode_lib->mp.global_fclk_change_supported;
1127 CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &mode_lib->mp.MaxActiveFCLKChangeLatencySupported;
1128 CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport;
1129 CalculateWatermarks_params->temp_read_or_ppt_support = mode_lib->mp.temp_read_or_ppt_support;
1130 CalculateWatermarks_params->global_temp_read_or_ppt_supported = &mode_lib->mp.global_temp_read_or_ppt_supported;
1131 CalculateWatermarks_params->VActiveLatencyHidingMargin = NULL;
1132 CalculateWatermarks_params->VActiveLatencyHidingUs = NULL;
1133
1134 dcn5_calculate_watermarks_and_dram_speed_change_support(&mode_lib->scratch, CalculateWatermarks_params);
1135
1136 for (k = 0; k < s->num_active_planes; ++k) {
1137 if (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].writeback.active_writebacks_per_stream > 0) {
1138 mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
1139 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) - mode_lib->mp.Watermark.WritebackDRAMClockChangeWatermark);
1140 mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = math_max2(0, mode_lib->mp.VStartupMin[k] * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total /
1141 ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000) - mode_lib->mp.Watermark.WritebackFCLKChangeWatermark);
1142 } else {
1143 mode_lib->mp.WritebackAllowDRAMClockChangeEndPosition[k] = 0;
1144 mode_lib->mp.WritebackAllowFCLKChangeEndPosition[k] = 0;
1145 }
1146 }
1147
1148 dcn5_calculate_pstate_keepout_dst_lines(display_cfg, &mode_lib->mp.Watermark, mode_lib->mp.pstate_keepout_dst_lines);
1149
1150 DML_LOG_VERBOSE("DML::%s: DEBUG stream_index = %0d\n", __func__, display_cfg->plane_descriptors[0].stream_index);
1151 DML_LOG_VERBOSE("DML::%s: DEBUG PixelClock = %ld kHz\n", __func__, (display_cfg->stream_descriptors[display_cfg->plane_descriptors[0].stream_index].timing.pixel_clock_khz));
1152
1153 //Display Pipeline Delivery Time in Prefetch, Groups
1154 dcn5_calculate_pixel_delivery_times(
1155 display_cfg,
1156 mode_lib->mp.NoOfDPP,
1157 s->num_active_planes,
1158 mode_lib->mp.VRatioPrefetchY,
1159 mode_lib->mp.VRatioPrefetchC,
1160 mode_lib->mp.swath_width_luma_ub,
1161 mode_lib->mp.swath_width_chroma_ub,
1162 mode_lib->mp.PSCL_THROUGHPUT,
1163 mode_lib->mp.PSCL_THROUGHPUT_CHROMA,
1164 mode_lib->mp.Dppclk,
1165 mode_lib->mp.DCFCLKDeepSleep,
1166 mode_lib->mp.BytePerPixelY,
1167 mode_lib->mp.BytePerPixelC,
1168 mode_lib->mp.req_per_swath_ub_l,
1169 mode_lib->mp.req_per_swath_ub_c,
1170
1171 /* Output */
1172 mode_lib->mp.DisplayPipeLineDeliveryTimeLuma,
1173 mode_lib->mp.DisplayPipeLineDeliveryTimeChroma,
1174 mode_lib->mp.DisplayPipeLineDeliveryTimeLumaPrefetch,
1175 mode_lib->mp.DisplayPipeLineDeliveryTimeChromaPrefetch,
1176 mode_lib->mp.DisplayPipeRequestDeliveryTimeLuma,
1177 mode_lib->mp.DisplayPipeRequestDeliveryTimeChroma,
1178 mode_lib->mp.DisplayPipeRequestDeliveryTimeLumaPrefetch,
1179 mode_lib->mp.DisplayPipeRequestDeliveryTimeChromaPrefetch);
1180
1181 CalculateMetaAndPTETimes_params->scratch = &mode_lib->scratch;
1182 CalculateMetaAndPTETimes_params->display_cfg = display_cfg;
1183 CalculateMetaAndPTETimes_params->NumberOfActiveSurfaces = s->num_active_planes;
1184 CalculateMetaAndPTETimes_params->use_one_row_for_frame = mode_lib->mp.use_one_row_for_frame;
1185 CalculateMetaAndPTETimes_params->dst_y_per_row_vblank = mode_lib->mp.dst_y_per_row_vblank;
1186 CalculateMetaAndPTETimes_params->dst_y_per_row_flip = mode_lib->mp.dst_y_per_row_flip;
1187 CalculateMetaAndPTETimes_params->BytePerPixelY = mode_lib->mp.BytePerPixelY;
1188 CalculateMetaAndPTETimes_params->BytePerPixelC = mode_lib->mp.BytePerPixelC;
1189 CalculateMetaAndPTETimes_params->dpte_row_height = mode_lib->mp.dpte_row_height;
1190 CalculateMetaAndPTETimes_params->dpte_row_height_chroma = mode_lib->mp.dpte_row_height_chroma;
1191 CalculateMetaAndPTETimes_params->dpte_group_bytes = mode_lib->mp.dpte_group_bytes;
1192 CalculateMetaAndPTETimes_params->PTERequestSizeY = mode_lib->mp.PTERequestSizeY;
1193 CalculateMetaAndPTETimes_params->PTERequestSizeC = mode_lib->mp.PTERequestSizeC;
1194 CalculateMetaAndPTETimes_params->PixelPTEReqWidthY = mode_lib->mp.PixelPTEReqWidthY;
1195 CalculateMetaAndPTETimes_params->PixelPTEReqHeightY = mode_lib->mp.PixelPTEReqHeightY;
1196 CalculateMetaAndPTETimes_params->PixelPTEReqWidthC = mode_lib->mp.PixelPTEReqWidthC;
1197 CalculateMetaAndPTETimes_params->PixelPTEReqHeightC = mode_lib->mp.PixelPTEReqHeightC;
1198 CalculateMetaAndPTETimes_params->dpte_row_width_luma_ub = mode_lib->mp.dpte_row_width_luma_ub;
1199 CalculateMetaAndPTETimes_params->dpte_row_width_chroma_ub = mode_lib->mp.dpte_row_width_chroma_ub;
1200 CalculateMetaAndPTETimes_params->tdlut_groups_per_2row_ub = s->tdlut_groups_per_2row_ub;
1201 CalculateMetaAndPTETimes_params->mrq_present = mode_lib->ip.dcn_mrq_present;
1202
1203 CalculateMetaAndPTETimes_params->MetaChunkSize = mode_lib->ip.meta_chunk_size_kbytes;
1204 CalculateMetaAndPTETimes_params->MinMetaChunkSizeBytes = mode_lib->ip.min_meta_chunk_size_bytes;
1205 CalculateMetaAndPTETimes_params->meta_row_width = mode_lib->mp.meta_row_width;
1206 CalculateMetaAndPTETimes_params->meta_row_width_chroma = mode_lib->mp.meta_row_width_chroma;
1207 CalculateMetaAndPTETimes_params->meta_row_height = mode_lib->mp.meta_row_height;
1208 CalculateMetaAndPTETimes_params->meta_row_height_chroma = mode_lib->mp.meta_row_height_chroma;
1209 CalculateMetaAndPTETimes_params->meta_req_width = mode_lib->mp.meta_req_width;
1210 CalculateMetaAndPTETimes_params->meta_req_width_chroma = mode_lib->mp.meta_req_width_chroma;
1211 CalculateMetaAndPTETimes_params->meta_req_height = mode_lib->mp.meta_req_height;
1212 CalculateMetaAndPTETimes_params->meta_req_height_chroma = mode_lib->mp.meta_req_height_chroma;
1213
1214 CalculateMetaAndPTETimes_params->time_per_tdlut_group = mode_lib->mp.time_per_tdlut_group;
1215 CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_L = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_L;
1216 CalculateMetaAndPTETimes_params->DST_Y_PER_PTE_ROW_NOM_C = mode_lib->mp.DST_Y_PER_PTE_ROW_NOM_C;
1217 CalculateMetaAndPTETimes_params->time_per_pte_group_nom_luma = mode_lib->mp.time_per_pte_group_nom_luma;
1218 CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_luma = mode_lib->mp.time_per_pte_group_vblank_luma;
1219 CalculateMetaAndPTETimes_params->time_per_pte_group_flip_luma = mode_lib->mp.time_per_pte_group_flip_luma;
1220 CalculateMetaAndPTETimes_params->time_per_pte_group_nom_chroma = mode_lib->mp.time_per_pte_group_nom_chroma;
1221 CalculateMetaAndPTETimes_params->time_per_pte_group_vblank_chroma = mode_lib->mp.time_per_pte_group_vblank_chroma;
1222 CalculateMetaAndPTETimes_params->time_per_pte_group_flip_chroma = mode_lib->mp.time_per_pte_group_flip_chroma;
1223 CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_L = mode_lib->mp.DST_Y_PER_META_ROW_NOM_L;
1224 CalculateMetaAndPTETimes_params->DST_Y_PER_META_ROW_NOM_C = mode_lib->mp.DST_Y_PER_META_ROW_NOM_C;
1225 CalculateMetaAndPTETimes_params->TimePerMetaChunkNominal = mode_lib->mp.TimePerMetaChunkNominal;
1226 CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkNominal = mode_lib->mp.TimePerChromaMetaChunkNominal;
1227 CalculateMetaAndPTETimes_params->TimePerMetaChunkVBlank = mode_lib->mp.TimePerMetaChunkVBlank;
1228 CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkVBlank = mode_lib->mp.TimePerChromaMetaChunkVBlank;
1229 CalculateMetaAndPTETimes_params->TimePerMetaChunkFlip = mode_lib->mp.TimePerMetaChunkFlip;
1230 CalculateMetaAndPTETimes_params->TimePerChromaMetaChunkFlip = mode_lib->mp.TimePerChromaMetaChunkFlip;
1231
1232 dcn5_calculate_meta_and_pte_times(CalculateMetaAndPTETimes_params);
1233
1234 dcn5_calculate_vm_group_and_request_times(
1235 display_cfg,
1236 s->num_active_planes,
1237 mode_lib->mp.BytePerPixelC,
1238 mode_lib->mp.dst_y_per_vm_vblank,
1239 mode_lib->mp.dst_y_per_vm_flip,
1240 mode_lib->mp.dpte_row_width_luma_ub,
1241 mode_lib->mp.dpte_row_width_chroma_ub,
1242 mode_lib->mp.vm_group_bytes,
1243 mode_lib->mp.dpde0_bytes_per_frame_ub_l,
1244 mode_lib->mp.dpde0_bytes_per_frame_ub_c,
1245 s->tdlut_pte_bytes_per_frame,
1246 mode_lib->mp.meta_pte_bytes_per_frame_ub_l,
1247 mode_lib->mp.meta_pte_bytes_per_frame_ub_c,
1248 mode_lib->ip.dcn_mrq_present,
1249
1250 /* Output */
1251 mode_lib->mp.TimePerVMGroupVBlank,
1252 mode_lib->mp.TimePerVMGroupFlip,
1253 mode_lib->mp.TimePerVMRequestVBlank,
1254 mode_lib->mp.TimePerVMRequestFlip);
1255
1256 // VStartup Adjustment
1257 for (k = 0; k < s->num_active_planes; ++k) {
1258 bool isInterlaceTiming;
1259
1260 mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TWait[k] + mode_lib->mp.ExtraLatency;
1261 if (!display_cfg->plane_descriptors[k].dynamic_meta_data.enable)
1262 mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.TCalc + mode_lib->mp.MinTTUVBlank[k];
1263
1264 DML_LOG_VERBOSE("DML::%s: k=%u, MinTTUVBlank = %f (before vstartup margin)\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]);
1265 s->Tvstartup_margin = (s->MaxVStartupLines[k] - mode_lib->mp.VStartupMin[k]) * display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000);
1266 mode_lib->mp.MinTTUVBlank[k] = mode_lib->mp.MinTTUVBlank[k] + s->Tvstartup_margin;
1267
1268 DML_LOG_VERBOSE("DML::%s: k=%u, Tvstartup_margin = %f\n", __func__, k, s->Tvstartup_margin);
1269 DML_LOG_VERBOSE("DML::%s: k=%u, MaxVStartupLines = %u\n", __func__, k, s->MaxVStartupLines[k]);
1270 DML_LOG_VERBOSE("DML::%s: k=%u, MinTTUVBlank = %f\n", __func__, k, mode_lib->mp.MinTTUVBlank[k]);
1271
1272 mode_lib->mp.Tdmdl[k] = mode_lib->mp.Tdmdl[k] + s->Tvstartup_margin;
1273 if (display_cfg->plane_descriptors[k].dynamic_meta_data.enable && mode_lib->ip.dynamic_metadata_vm_enabled) {
1274 mode_lib->mp.Tdmdl_vm[k] = mode_lib->mp.Tdmdl_vm[k] + s->Tvstartup_margin;
1275 }
1276
1277 isInterlaceTiming = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.interlaced && !mode_lib->ip.ptoi_supported);
1278
1279 // The actual positioning of the vstartup
1280 mode_lib->mp.VStartup[k] = (isInterlaceTiming ? (2 * s->MaxVStartupLines[k]) : s->MaxVStartupLines[k]);
1281
1282 s->dlg_vblank_start = ((isInterlaceTiming ? math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch) / 2.0, 1.0) :
1283 display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total) - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch);
1284 s->LSetup = math_floor2(4.0 * mode_lib->mp.TSetup[k] / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total / ((double)display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.pixel_clock_khz / 1000)), 1.0) / 4.0;
1285 s->blank_lines_remaining = (display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active) - mode_lib->mp.VStartup[k];
1286
1287 if (s->blank_lines_remaining < 0) {
1288 DML_LOG_VERBOSE("ERROR: Vstartup is larger than vblank!?\n");
1289 s->blank_lines_remaining = 0;
1290 DML_ASSERT(0);
1291 }
1292 mode_lib->mp.MIN_DST_Y_NEXT_START[k] = s->dlg_vblank_start + s->blank_lines_remaining + s->LSetup;
1293
1294 // debug only
1295 if (((mode_lib->mp.VUpdateOffsetPix[k] + mode_lib->mp.VUpdateWidthPix[k] + mode_lib->mp.VReadyOffsetPix[k]) / (double) display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total) <=
1296 (isInterlaceTiming ?
1297 math_floor2((display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]) / 2.0, 1.0) :
1298 (int)(display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active - display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch - mode_lib->mp.VStartup[k]))) {
1299 mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = true;
1300 } else {
1301 mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k] = false;
1302 }
1303 DML_LOG_VERBOSE("DML::%s: k=%u, VStartup = %u (max)\n", __func__, k, mode_lib->mp.VStartup[k]);
1304 DML_LOG_VERBOSE("DML::%s: k=%u, VStartupMin = %u (max)\n", __func__, k, mode_lib->mp.VStartupMin[k]);
1305 DML_LOG_VERBOSE("DML::%s: k=%u, VUpdateOffsetPix = %u\n", __func__, k, mode_lib->mp.VUpdateOffsetPix[k]);
1306 DML_LOG_VERBOSE("DML::%s: k=%u, VUpdateWidthPix = %u\n", __func__, k, mode_lib->mp.VUpdateWidthPix[k]);
1307 DML_LOG_VERBOSE("DML::%s: k=%u, VReadyOffsetPix = %u\n", __func__, k, mode_lib->mp.VReadyOffsetPix[k]);
1308 DML_LOG_VERBOSE("DML::%s: k=%u, HTotal = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.h_total);
1309 DML_LOG_VERBOSE("DML::%s: k=%u, VTotal = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_total);
1310 DML_LOG_VERBOSE("DML::%s: k=%u, VActive = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_active);
1311 DML_LOG_VERBOSE("DML::%s: k=%u, VFrontPorch = %lu\n", __func__, k, display_cfg->stream_descriptors[display_cfg->plane_descriptors[k].stream_index].timing.v_front_porch);
1312 DML_LOG_VERBOSE("DML::%s: k=%u, TSetup = %f\n", __func__, k, mode_lib->mp.TSetup[k]);
1313 DML_LOG_VERBOSE("DML::%s: k=%u, MIN_DST_Y_NEXT_START = %f\n", __func__, k, mode_lib->mp.MIN_DST_Y_NEXT_START[k]);
1314 DML_LOG_VERBOSE("DML::%s: k=%u, VREADY_AT_OR_AFTER_VSYNC = %u\n", __func__, k, mode_lib->mp.VREADY_AT_OR_AFTER_VSYNC[k]);
1315 }
1316
1317 //Maximum Bandwidth Used
1318 mode_lib->mp.TotalWRBandwidth = 0;
1319 for (k = 0; k < display_cfg->num_streams; ++k) {
1320 for (j = 0; j < display_cfg->stream_descriptors[k].writeback.active_writebacks_per_stream; ++j) {
1321 double writeback_bytes_per_pixel;
1322 if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_444_64)
1323 writeback_bytes_per_pixel = 8.0;
1324 else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_444_32)
1325 writeback_bytes_per_pixel = 4.0;
1326 else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_420_8)
1327 writeback_bytes_per_pixel = 1.5;
1328 else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_420_10)
1329 writeback_bytes_per_pixel = 3.0;
1330 else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_422_packed_8)
1331 writeback_bytes_per_pixel = 2.0;
1332 else if (display_cfg->stream_descriptors[k].writeback.writeback_stream[j].pixel_format == dml2_422_packed_10)
1333 writeback_bytes_per_pixel = 4.0;
1334 else
1335 writeback_bytes_per_pixel = 0.0;
1336 s->WRBandwidth = display_cfg->stream_descriptors[k].writeback.writeback_stream[j].output_height
1337 * display_cfg->stream_descriptors[k].writeback.writeback_stream[j].output_width
1338 / (display_cfg->stream_descriptors[k].timing.h_total
1339 * display_cfg->stream_descriptors[k].writeback.writeback_stream[j].input_height
1340 / ((double)display_cfg->stream_descriptors[k].timing.pixel_clock_khz / 1000)) * writeback_bytes_per_pixel;
1341 mode_lib->mp.TotalWRBandwidth = mode_lib->mp.TotalWRBandwidth + s->WRBandwidth;
1342 }
1343 }
1344
1345 mode_lib->mp.TotalDataReadBandwidth = 0;
1346 for (k = 0; k < s->num_active_planes; ++k) {
1347 mode_lib->mp.TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth + mode_lib->mp.vactive_sw_bw_l[k] + mode_lib->mp.vactive_sw_bw_c[k];
1348 DML_LOG_VERBOSE("DML::%s: k=%u, TotalDataReadBandwidth = %f\n", __func__, k, mode_lib->mp.TotalDataReadBandwidth);
1349 DML_LOG_VERBOSE("DML::%s: k=%u, vactive_sw_bw_l = %f\n", __func__, k, mode_lib->mp.vactive_sw_bw_l[k]);
1350 DML_LOG_VERBOSE("DML::%s: k=%u, vactive_sw_bw_c = %f\n", __func__, k, mode_lib->mp.vactive_sw_bw_c[k]);
1351 }
1352
1353 CalculateStutterEfficiency_params->display_cfg = display_cfg;
1354 CalculateStutterEfficiency_params->CompressedBufferSizeInkByte = mode_lib->mp.CompressedBufferSizeInkByte;
1355 CalculateStutterEfficiency_params->UnboundedRequestEnabled = mode_lib->mp.UnboundedRequestEnabled;
1356 CalculateStutterEfficiency_params->MetaFIFOSizeInKEntries = mode_lib->ip.meta_fifo_size_in_kentries;
1357 CalculateStutterEfficiency_params->ZeroSizeBufferEntries = mode_lib->ip.zero_size_buffer_entries;
1358 CalculateStutterEfficiency_params->PixelChunkSizeInKByte = mode_lib->ip.pixel_chunk_size_kbytes;
1359 CalculateStutterEfficiency_params->NumberOfActiveSurfaces = s->num_active_planes;
1360 CalculateStutterEfficiency_params->ROBBufferSizeInKByte = mode_lib->ip.rob_buffer_size_kbytes;
1361 CalculateStutterEfficiency_params->TotalDataReadBandwidth = mode_lib->mp.TotalDataReadBandwidth;
1362 CalculateStutterEfficiency_params->DCFCLK = mode_lib->mp.Dcfclk;
1363 CalculateStutterEfficiency_params->ReturnBW = mode_lib->mp.dram_bw_mbps;
1364 CalculateStutterEfficiency_params->CompbufReservedSpace64B = mode_lib->mp.compbuf_reserved_space_64b;
1365 CalculateStutterEfficiency_params->CompbufReservedSpaceZs = mode_lib->ip.compbuf_reserved_space_zs;
1366 CalculateStutterEfficiency_params->SRExitTime = utm_soc_bb->power_management_parameters.stutter_exit_latency_us;
1367 CalculateStutterEfficiency_params->SRExitZ8Time = utm_soc_bb->power_management_parameters.z8_stutter_exit_latency_us;
1368 CalculateStutterEfficiency_params->SynchronizeTimings = display_cfg->overrides.synchronize_timings;
1369 CalculateStutterEfficiency_params->StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.StutterEnterPlusExitWatermark;
1370 CalculateStutterEfficiency_params->Z8StutterEnterPlusExitWatermark = mode_lib->mp.Watermark.Z8StutterEnterPlusExitWatermark;
1371 CalculateStutterEfficiency_params->ProgressiveToInterlaceUnitInOPP = mode_lib->ip.ptoi_supported;
1372 CalculateStutterEfficiency_params->MinTTUVBlank = mode_lib->mp.MinTTUVBlank;
1373 CalculateStutterEfficiency_params->DPPPerSurface = mode_lib->mp.NoOfDPP;
1374 CalculateStutterEfficiency_params->DETBufferSizeY = mode_lib->mp.DETBufferSizeY;
1375 CalculateStutterEfficiency_params->BytePerPixelY = mode_lib->mp.BytePerPixelY;
1376 CalculateStutterEfficiency_params->BytePerPixelDETY = mode_lib->mp.BytePerPixelInDETY;
1377 CalculateStutterEfficiency_params->SwathWidthY = mode_lib->mp.SwathWidthY;
1378 CalculateStutterEfficiency_params->SwathHeightY = mode_lib->mp.SwathHeightY;
1379 CalculateStutterEfficiency_params->SwathHeightC = mode_lib->mp.SwathHeightC;
1380 CalculateStutterEfficiency_params->BlockHeight256BytesY = mode_lib->mp.Read256BlockHeightY;
1381 CalculateStutterEfficiency_params->BlockWidth256BytesY = mode_lib->mp.Read256BlockWidthY;
1382 CalculateStutterEfficiency_params->BlockHeight256BytesC = mode_lib->mp.Read256BlockHeightC;
1383 CalculateStutterEfficiency_params->BlockWidth256BytesC = mode_lib->mp.Read256BlockWidthC;
1384 CalculateStutterEfficiency_params->DCCYMaxUncompressedBlock = mode_lib->mp.DCCYMaxUncompressedBlock;
1385 CalculateStutterEfficiency_params->DCCCMaxUncompressedBlock = mode_lib->mp.DCCCMaxUncompressedBlock;
1386 CalculateStutterEfficiency_params->ReadBandwidthSurfaceLuma = mode_lib->mp.vactive_sw_bw_l;
1387 CalculateStutterEfficiency_params->ReadBandwidthSurfaceChroma = mode_lib->mp.vactive_sw_bw_c;
1388 CalculateStutterEfficiency_params->dpte_row_bw = mode_lib->mp.dpte_row_bw;
1389 CalculateStutterEfficiency_params->meta_row_bw = mode_lib->mp.meta_row_bw;
1390 CalculateStutterEfficiency_params->rob_alloc_compressed = mode_lib->ip.dcn_mrq_present;
1391
1392 // output
1393 CalculateStutterEfficiency_params->StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.StutterEfficiencyNotIncludingVBlank;
1394 CalculateStutterEfficiency_params->StutterEfficiency = &mode_lib->mp.StutterEfficiency;
1395 CalculateStutterEfficiency_params->NumberOfStutterBurstsPerFrame = &mode_lib->mp.NumberOfStutterBurstsPerFrame;
1396 CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank;
1397 CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiency;
1398 CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrame;
1399 CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriod;
1400 CalculateStutterEfficiency_params->DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE = &mode_lib->mp.DCHUBBUB_ARB_CSTATE_MAX_CAP_MODE;
1401
1402 // Stutter Efficiency
1403 dcn5_calculate_stutter_efficiency(&mode_lib->scratch, CalculateStutterEfficiency_params);
1404
1405 #ifdef __DML_VBA_ALLOW_DELTA__
1406 // Calculate z8 stutter eff assuming 0 reserved space
1407 CalculateStutterEfficiency_params->CompbufReservedSpace64B = 0;
1408 CalculateStutterEfficiency_params->CompbufReservedSpaceZs = 0;
1409
1410 CalculateStutterEfficiency_params->Z8StutterEfficiencyNotIncludingVBlank = &mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase;
1411 CalculateStutterEfficiency_params->Z8StutterEfficiency = &mode_lib->mp.Z8StutterEfficiencyBestCase;
1412 CalculateStutterEfficiency_params->Z8NumberOfStutterBurstsPerFrame = &mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase;
1413 CalculateStutterEfficiency_params->StutterPeriod = &mode_lib->mp.StutterPeriodBestCase;
1414
1415 // Stutter Efficiency
1416 dcn5_calculate_stutter_efficiency(&mode_lib->scratch, CalculateStutterEfficiency_params);
1417 #else
1418 mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlankBestCase = mode_lib->mp.Z8StutterEfficiencyNotIncludingVBlank;
1419 mode_lib->mp.Z8StutterEfficiencyBestCase = mode_lib->mp.Z8StutterEfficiency;
1420 mode_lib->mp.Z8NumberOfStutterBurstsPerFrameBestCase = mode_lib->mp.Z8NumberOfStutterBurstsPerFrame;
1421 mode_lib->mp.StutterPeriodBestCase = mode_lib->mp.StutterPeriod;
1422 #endif
1423 } // PrefetchAndImmediateFlipSupported
1424
1425 min_return_latency_in_DCFCLK_cycles = (min_return_uclk_cycles / (max_sop.uclk_khz / 1000.0) + min_return_fclk_cycles / (max_sop.fclk_khz / 1000.0)) * mode_lib->mp.Dcfclk;
1426 mode_lib->mp.min_return_latency_in_dcfclk = (unsigned int)min_return_latency_in_DCFCLK_cycles;
1427 mode_lib->mp.dcfclk_deep_sleep_hysteresis = (unsigned int)math_max2(32, (double)mode_lib->ip.pixel_chunk_size_kbytes * 1024 * 3 / 4 / 64 - min_return_latency_in_DCFCLK_cycles);
1428 DML_ASSERT(mode_lib->mp.dcfclk_deep_sleep_hysteresis < 256);
1429
1430 DML_LOG_VERBOSE("DML::%s: max_sop.fclk_khz = %d\n", __func__, max_sop.fclk_khz);
1431 DML_LOG_VERBOSE("DML::%s: max_sop.dcfclk_khz = %d\n", __func__, max_sop.dcfclk_khz);
1432 DML_LOG_VERBOSE("DML::%s: max_sop.uclk_khz = %d\n", __func__, max_sop.uclk_khz);
1433 DML_LOG_VERBOSE("DML::%s: min_sop.fclk_khz = %d\n", __func__, min_sop.fclk_khz);
1434 DML_LOG_VERBOSE("DML::%s: min_sop.dcfclk_khz = %d\n", __func__, min_sop.dcfclk_khz);
1435 DML_LOG_VERBOSE("DML::%s: min_sop.uclk_khz = %d\n", __func__, min_sop.uclk_khz);
1436 DML_LOG_VERBOSE("DML::%s: min_return_uclk_cycles = %ld\n", __func__, min_return_uclk_cycles);
1437 DML_LOG_VERBOSE("DML::%s: min_return_fclk_cycles = %ld\n", __func__, min_return_fclk_cycles);
1438 DML_LOG_VERBOSE("DML::%s: min_return_latency_in_DCFCLK_cycles = %f\n", __func__, min_return_latency_in_DCFCLK_cycles);
1439 DML_LOG_VERBOSE("DML::%s: dcfclk_deep_sleep_hysteresis = %d \n", __func__, mode_lib->mp.dcfclk_deep_sleep_hysteresis);
1440 DML_LOG_VERBOSE("DML::%s: --- END --- \n", __func__);
1441 return in_out_params->mode_lib->mp.PrefetchAndImmediateFlipSupported;
1442 }
1443
dcn5_get_global_sync_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,union dml2_global_sync_programming * out,int pipe_index)1444 static void dcn5_get_global_sync_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, union dml2_global_sync_programming *out, int pipe_index)
1445 {
1446 out->dcn4x.vready_offset_pixels = mode_lib->mp.VReadyOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
1447 out->dcn4x.vstartup_lines = mode_lib->mp.VStartup[mode_lib->mp.pipe_plane[pipe_index]];
1448 out->dcn4x.vupdate_offset_pixels = mode_lib->mp.VUpdateOffsetPix[mode_lib->mp.pipe_plane[pipe_index]];
1449 out->dcn4x.vupdate_vupdate_width_pixels = mode_lib->mp.VUpdateWidthPix[mode_lib->mp.pipe_plane[pipe_index]];
1450 out->dcn4x.pstate_keepout_start_lines = mode_lib->mp.pstate_keepout_dst_lines[mode_lib->mp.pipe_plane[pipe_index]];
1451 }
1452
dcn5_get_stream_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,struct dml2_per_stream_programming * out,int pipe_index)1453 static void dcn5_get_stream_programming(const struct dml2_core_internal_display_mode_lib *mode_lib, struct dml2_per_stream_programming *out, int pipe_index)
1454 {
1455 dcn5_get_global_sync_programming(mode_lib, &out->global_sync, pipe_index);
1456 }
1457
dcn5_populate_fams2_programming(const struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_core_calcs_mode_programming_ex * mode_prog,union dmub_cmd_fams2_config * fams2_base_programming,union dmub_cmd_fams2_config * fams2_sub_programming,enum dml2_pstate_method pstate_method,int plane_index)1458 static void dcn5_populate_fams2_programming(const struct dml2_core_internal_display_mode_lib *mode_lib,
1459 const struct dml2_core_calcs_mode_programming_ex *mode_prog,
1460 union dmub_cmd_fams2_config *fams2_base_programming,
1461 union dmub_cmd_fams2_config *fams2_sub_programming,
1462 enum dml2_pstate_method pstate_method,
1463 int plane_index)
1464 {
1465 const struct dml2_display_cfg *disp_cfg = mode_prog->in_display_cfg;
1466 const struct dml2_plane_parameters *plane_descriptor = &disp_cfg->plane_descriptors[plane_index];
1467 const struct dml2_stream_parameters *stream_descriptor = &disp_cfg->stream_descriptors[plane_descriptor->stream_index];
1468 const struct dml2_pstate_meta *stream_pstate_meta = &mode_prog->uclk_params->stream_pstate_meta[plane_descriptor->stream_index];
1469
1470 struct dmub_fams2_cmd_stream_static_base_state *base_programming = &fams2_base_programming->stream_v1.base;
1471 union dmub_fams2_cmd_stream_static_sub_state *sub_programming = &fams2_sub_programming->stream_v1.sub_state;
1472
1473 unsigned int i;
1474
1475 if (disp_cfg->overrides.all_streams_blanked) {
1476 /* stream is blanked, so do nothing */
1477 return;
1478 }
1479
1480 /* from display configuration */
1481 base_programming->htotal = (uint16_t)stream_descriptor->timing.h_total;
1482 base_programming->vtotal = (uint16_t)stream_descriptor->timing.v_total;
1483 base_programming->vblank_start = (uint16_t)(stream_pstate_meta->nom_vtotal -
1484 stream_descriptor->timing.v_front_porch);
1485 base_programming->vblank_end = (uint16_t)(stream_pstate_meta->nom_vtotal -
1486 stream_descriptor->timing.v_front_porch -
1487 stream_descriptor->timing.v_active);
1488 base_programming->config.bits.is_drr = stream_descriptor->timing.drr_config.enabled;
1489
1490 /* from meta */
1491 base_programming->otg_vline_time_ns =
1492 (unsigned int)(stream_pstate_meta->otg_vline_time_us * 1000.0);
1493 base_programming->scheduling_delay_otg_vlines = (uint8_t)stream_pstate_meta->scheduling_delay_otg_vlines;
1494 base_programming->contention_delay_otg_vlines = (uint8_t)stream_pstate_meta->contention_delay_otg_vlines;
1495 base_programming->vline_int_ack_delay_otg_vlines = (uint8_t)stream_pstate_meta->vertical_interrupt_ack_delay_otg_vlines;
1496 base_programming->drr_keepout_otg_vline = (uint16_t)(stream_pstate_meta->nom_vtotal -
1497 stream_descriptor->timing.v_front_porch -
1498 stream_pstate_meta->method_drr.programming_delay_otg_vlines);
1499 base_programming->allow_to_target_delay_otg_vlines = (uint8_t)stream_pstate_meta->allow_to_target_delay_otg_vlines;
1500 base_programming->max_vtotal = (uint16_t)stream_pstate_meta->max_vtotal;
1501
1502 /* from core */
1503 base_programming->config.bits.min_ttu_vblank_usable = true;
1504 for (i = 0; i < disp_cfg->num_planes; i++) {
1505 /* check if all planes support p-state in blank */
1506 if (disp_cfg->plane_descriptors[i].stream_index == plane_descriptor->stream_index &&
1507 mode_lib->mp.MinTTUVBlank[i] <= mode_lib->mp.Watermark.DRAMClockChangeWatermark) {
1508 base_programming->config.bits.min_ttu_vblank_usable = false;
1509 break;
1510 }
1511 }
1512
1513 switch (pstate_method) {
1514 case dml2_pstate_method_vactive:
1515 case dml2_pstate_method_fw_vactive_drr:
1516 /* legacy vactive */
1517 base_programming->type = FAMS2_STREAM_TYPE_VACTIVE;
1518 sub_programming->legacy.vactive_det_fill_delay_otg_vlines =
1519 (uint8_t)stream_pstate_meta->method_vactive.max_vactive_det_fill_delay_otg_vlines;
1520 base_programming->allow_start_otg_vline =
1521 (uint16_t)stream_pstate_meta->method_vactive.common.allow_start_otg_vline;
1522 base_programming->allow_end_otg_vline =
1523 (uint16_t)stream_pstate_meta->method_vactive.common.allow_end_otg_vline;
1524 base_programming->config.bits.clamp_vtotal_min = true;
1525 break;
1526 case dml2_pstate_method_vblank:
1527 case dml2_pstate_method_fw_vblank_drr:
1528 /* legacy vblank */
1529 base_programming->type = FAMS2_STREAM_TYPE_VBLANK;
1530 base_programming->allow_start_otg_vline =
1531 (uint16_t)stream_pstate_meta->method_vblank.common.allow_start_otg_vline;
1532 base_programming->allow_end_otg_vline =
1533 (uint16_t)stream_pstate_meta->method_vblank.common.allow_end_otg_vline;
1534 base_programming->config.bits.clamp_vtotal_min = true;
1535 break;
1536 case dml2_pstate_method_fw_drr:
1537 /* drr */
1538 base_programming->type = FAMS2_STREAM_TYPE_DRR;
1539 sub_programming->drr.programming_delay_otg_vlines =
1540 (uint8_t)stream_pstate_meta->method_drr.programming_delay_otg_vlines;
1541 sub_programming->drr.nom_stretched_vtotal =
1542 (uint16_t)stream_pstate_meta->method_drr.stretched_vtotal;
1543 base_programming->allow_start_otg_vline =
1544 (uint16_t)stream_pstate_meta->method_drr.common.allow_start_otg_vline;
1545 base_programming->allow_end_otg_vline =
1546 (uint16_t)stream_pstate_meta->method_drr.common.allow_end_otg_vline;
1547 /* drr only clamps to vtotal min for single display */
1548 base_programming->config.bits.clamp_vtotal_min = disp_cfg->num_streams == 1;
1549 sub_programming->drr.only_stretch_if_required = true;
1550 break;
1551 case dml2_pstate_method_fw_svp:
1552 case dml2_pstate_method_fw_svp_drr:
1553 case dml2_pstate_method_alternate:
1554 case dml2_pstate_method_reserved_hw:
1555 case dml2_pstate_method_reserved_fw:
1556 case dml2_pstate_method_reserved_fw_drr_clamped:
1557 case dml2_pstate_method_reserved_fw_drr_var:
1558 case dml2_pstate_method_na:
1559 case dml2_pstate_method_count:
1560 default:
1561 /* this should never happen */
1562 break;
1563 }
1564 }
1565
dcn5_populate_global_fams2_programming(struct dml2_core_internal_display_mode_lib * mode_lib,const struct dml2_core_calcs_mode_programming_ex * mode_prog,struct dmub_cmd_fams2_global_config * fams2_global_config)1566 static void dcn5_populate_global_fams2_programming(struct dml2_core_internal_display_mode_lib *mode_lib,
1567 const struct dml2_core_calcs_mode_programming_ex *mode_prog,
1568 struct dmub_cmd_fams2_global_config *fams2_global_config)
1569 {
1570 fams2_global_config->features.bits.enable = mode_prog->uclk_params->fams2_required;
1571
1572 if (fams2_global_config->features.bits.enable) {
1573 fams2_global_config->features.bits.enable_stall_recovery = true;
1574 fams2_global_config->features.bits.allow_delay_check_mode = FAMS2_ALLOW_DELAY_CHECK_FROM_START;
1575
1576 fams2_global_config->max_allow_delay_us = mode_lib->ip_caps.fams2.max_allow_delay_us;
1577 fams2_global_config->lock_wait_time_us = mode_lib->ip_caps.fams2.lock_timeout_us;
1578 fams2_global_config->recovery_timeout_us = mode_lib->ip_caps.fams2.recovery_timeout_us;
1579 fams2_global_config->hwfq_flip_programming_delay_us = mode_lib->ip_caps.fams2.flip_programming_delay_us;
1580
1581 fams2_global_config->num_streams = mode_prog->in_display_cfg->num_streams;
1582 }
1583 }
1584
dcn5_populate_mcache_allocation(struct dml2_display_cfg_programming * programming,const struct dml2_display_solution * solution)1585 static void dcn5_populate_mcache_allocation(struct dml2_display_cfg_programming *programming,
1586 const struct dml2_display_solution *solution)
1587 {
1588 unsigned int i;
1589
1590 for (i = 0; i < solution->dispcfg.num_planes; i++)
1591 programming->plane_programming[i].mcache_allocation = solution->mcache_allocations[i];
1592 }
1593
dcn5_pack_mode_programming_params(struct dml2_core_instance * core,struct dml2_core_calcs_mode_programming_ex * mode_prog,struct dml2_display_cfg_programming * programming)1594 static void dcn5_pack_mode_programming_params(
1595 struct dml2_core_instance *core,
1596 struct dml2_core_calcs_mode_programming_ex *mode_prog,
1597 struct dml2_display_cfg_programming *programming)
1598 {
1599 struct dml2_core_internal_display_mode_lib *mode_lib = mode_prog->mode_lib;
1600 const struct dml2_utm_soc_bb *utm_soc_bb = core->utm_soc_bb;
1601 unsigned int pipe_offset;
1602 int dml_internal_pipe_index;
1603 int total_pipe_regs_copied = 0;
1604 int total_dwb_regs_copied = 0;
1605 int stream_already_populated_mask = 0;
1606
1607 int main_stream_index;
1608 unsigned int plane_index;
1609 unsigned int dwb_index;
1610
1611 memcpy(&programming->display_config, mode_prog->in_display_cfg, sizeof(struct dml2_display_cfg));
1612
1613 dcn5_get_arb_params(&programming->display_config, mode_lib, utm_soc_bb, &programming->global_regs.arb_regs);
1614 programming->global_regs.num_watermark_sets = 1;
1615 dcn5_get_watermarks(&programming->display_config, mode_lib, utm_soc_bb, &programming->global_regs.wm_regs[0]);
1616 dcn5_populate_mcache_allocation(programming, mode_prog->solution);
1617
1618 dcn5_get_mcif_arb_params(mode_lib, &programming->mcif_global_regs);
1619 programming->mcif_global_regs.num_watermark_sets = 1;
1620
1621 dml_internal_pipe_index = 0;
1622
1623 if (mode_prog->uclk_params) {
1624 if (programming->uclk_pstate_supported) {
1625 programming->fams2_required = mode_prog->uclk_params->fams2_required;
1626 dcn5_populate_global_fams2_programming(mode_lib, mode_prog, &programming->fams2_global_config);
1627 }
1628 }
1629
1630 DML_LOG_VERBOSE("DML::%s: num_planes=%d\n", __func__, programming->display_config.num_planes);
1631
1632 for (plane_index = 0; plane_index < programming->display_config.num_planes; plane_index++) {
1633 programming->plane_programming[plane_index].num_dpps_required = mode_lib->mp.NoOfDPP[plane_index];
1634
1635 // Setup the appropriate p-state strategy for each plane
1636 if (mode_prog->uclk_params) {
1637 if (programming->uclk_pstate_supported)
1638 programming->plane_programming[plane_index].uclk_pstate_support_method = mode_prog->uclk_params->pstate_switch_modes[plane_index];
1639 else
1640 programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
1641 } else {
1642 if (mode_lib->mp.MaxActiveDRAMClockChangeLatencySupported[plane_index] >= utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us)
1643 programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vactive;
1644 else if (mode_lib->mp.TWait[plane_index] >= utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us)
1645 programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_vblank;
1646 else
1647 programming->plane_programming[plane_index].uclk_pstate_support_method = dml2_pstate_method_na;
1648 }
1649
1650 for (pipe_offset = 0; pipe_offset < programming->plane_programming[plane_index].num_dpps_required; pipe_offset++) {
1651 programming->plane_programming[plane_index].plane_descriptor = &programming->display_config.plane_descriptors[plane_index];
1652
1653 // Assign storage for this pipe's register values
1654 programming->plane_programming[plane_index].pipe_regs[pipe_offset] = &programming->pipe_regs[total_pipe_regs_copied];
1655 memset(programming->plane_programming[plane_index].pipe_regs[pipe_offset], 0, sizeof(struct dml2_dchub_per_pipe_register_set));
1656 total_pipe_regs_copied++;
1657
1658 // Populate
1659 dcn5_get_pipe_regs(&programming->display_config, mode_lib, programming->plane_programming[plane_index].pipe_regs[pipe_offset], dml_internal_pipe_index, utm_soc_bb, &mode_lib->scratch);
1660
1661 main_stream_index = programming->display_config.plane_descriptors[plane_index].stream_index;
1662
1663 // Multiple planes can refer to the same stream index, so it's only necessary to populate it once
1664 if (!(stream_already_populated_mask & (0x1 << main_stream_index))) {
1665 programming->stream_programming[main_stream_index].uclk_pstate_method = programming->plane_programming[plane_index].uclk_pstate_support_method;
1666 programming->stream_programming[main_stream_index].stream_descriptor = &programming->display_config.stream_descriptors[main_stream_index];
1667 programming->stream_programming[main_stream_index].num_odms_required = mode_prog->cfg_support_info->stream_support_info[main_stream_index].odms_used;
1668 dcn5_get_stream_programming(mode_lib, &programming->stream_programming[main_stream_index], dml_internal_pipe_index);
1669
1670 if (mode_prog->uclk_params) {
1671 dcn5_populate_fams2_programming(mode_lib,
1672 mode_prog,
1673 &programming->stream_programming[main_stream_index].fams2_base_params,
1674 &programming->stream_programming[main_stream_index].fams2_sub_params,
1675 programming->stream_programming[main_stream_index].uclk_pstate_method,
1676 plane_index);
1677 }
1678
1679 /* populate DWB */
1680 for (dwb_index = 0; dwb_index < programming->display_config.stream_descriptors[main_stream_index].writeback.active_writebacks_per_stream; dwb_index++) {
1681 programming->stream_programming[main_stream_index].mcif_regs[dwb_index] = &programming->mcif_regs[total_dwb_regs_copied];
1682 memset(programming->stream_programming[main_stream_index].mcif_regs[dwb_index], 0, sizeof(struct dml2_mcif_per_pipe_register_set));
1683 total_dwb_regs_copied++;
1684
1685 dcn5_get_per_dwb_params(&programming->display_config,
1686 mode_lib,
1687 programming->stream_programming[main_stream_index].mcif_regs[dwb_index],
1688 main_stream_index,
1689 dwb_index);
1690 }
1691
1692 stream_already_populated_mask |= (0x1 << main_stream_index);
1693 }
1694 dml_internal_pipe_index++;
1695 }
1696 }
1697
1698 // DCN5: Calculate reduced viewport pstate recout reduction lines per plane
1699 // Complete the formula calculation using memory clock and base calculation from prefetch schedule
1700
1701 // Initialize all planes to default value
1702 for (unsigned int plane_idx = 0; plane_idx < DML2_MAX_PLANES; plane_idx++) {
1703 programming->informative.misc.pstate_recout_reduction_lines[plane_idx] = 0;
1704 }
1705
1706 // DCN5: Calculate pstate recout reduction lines feature
1707 // Get DRAM clock change latency from SOC parameters
1708 double dram_clk_change_latency_us = utm_soc_bb->power_management_parameters.dram_clk_change_blackout_us;
1709
1710 if (programming->display_config.num_planes == 1) {
1711 // Calculate for all planes (inactive planes should naturally yield 0)
1712 for (unsigned int plane_idx = 0; plane_idx < programming->display_config.num_planes; plane_idx++) {
1713 // Use original equation from specifications
1714 // Formula: (Tmclk – (Tvstartup – (Tsetup + Tcalc + Tpre + Tout))) / LineTime
1715 // Where Tpre = dst_y_prefetch * line_time (as specified)
1716
1717 int stream_index = programming->display_config.plane_descriptors[plane_idx].stream_index;
1718
1719 // Calculate line time from display config timing (HTotal / PixelClock)
1720 double pixel_clock_mhz = (double)programming->display_config.stream_descriptors[stream_index].timing.pixel_clock_khz / 1000.0;
1721 double htotal = (double)programming->display_config.stream_descriptors[stream_index].timing.h_total;
1722 double line_time_us = htotal / pixel_clock_mhz;
1723
1724 // Use actual calculated values from mode library (not hardcoded defaults)
1725 double tmclk_us = dram_clk_change_latency_us;
1726 double tvstartup_us = mode_lib->mp.VStartup[plane_idx] * line_time_us;
1727 double tsetup_us = mode_lib->mp.TSetup[plane_idx];
1728 double tcalc_us = mode_lib->mp.TCalc;
1729 double tpre_us = mode_lib->mp.dst_y_prefetch[plane_idx] * line_time_us; // As specified: dst_y_prefetch * line_time
1730 double tout_us = (mode_lib->mp.DSTYAfterScaler[plane_idx] +
1731 ((double)mode_lib->mp.DSTXAfterScaler[plane_idx] / htotal)) * line_time_us; // delay_after_scaler per spec
1732
1733 // Formula: (Tmclk - (Tvstartup - (Tsetup + Tcalc + Tpre + Tout))) / LineTime
1734 programming->informative.misc.pstate_recout_reduction_lines[plane_idx] =
1735 (unsigned int) math_max2(0.0, (tmclk_us - (tvstartup_us - (tsetup_us + tcalc_us + tpre_us + tout_us))) / line_time_us);
1736 }
1737 }
1738 }
1739
dcn5_mp_assign_qos_bound(struct dml2_core_instance * core,struct dml2_display_cfg_programming * programming)1740 static void dcn5_mp_assign_qos_bound(struct dml2_core_instance *core,
1741 struct dml2_display_cfg_programming *programming)
1742 {
1743 struct dml2_core_internal_display_mode_lib *mode_lib = &core->clean_me_up.mode_lib;
1744 struct dml2_core_calcs_mode_programming_locals *s = &mode_lib->scratch.dml_core_mode_programming_locals;
1745
1746 mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0;
1747 mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0;
1748 mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0;
1749 mode_lib->mp.dram_bw_mbps = programming->qos_bound.bandwidth_lb.dcn5.urgent_bandwidth_kbps / 1000.0;
1750 mode_lib->mp.urg_bandwidth_available[dml2_core_internal_soc_state_sys_active][dml2_core_internal_bw_dram] = mode_lib->mp.dram_bw_mbps;
1751 mode_lib->mp.UrgentLatency = programming->qos_bound.latency_ub.dcn5.urgent_ramp;
1752 mode_lib->mp.TripToMemory = programming->qos_bound.latency_ub.dcn5.t_trip;
1753 mode_lib->mp.MetaTripToMemory = programming->qos_bound.latency_ub.dcn5.meta_trip_to_mem;
1754 s->mmSOCParameters.max_urgent_latency_us = programming->qos_bound.latency_ub.dcn5.max_req_latency_urg;
1755 s->mmSOCParameters.df_response_time_us = programming->qos_bound.latency_ub.dcn5.df_response_time_us;
1756
1757 DML_LOG_VERBOSE("DML::%s: Dcfclk = %f\n", __func__, mode_lib->mp.Dcfclk);
1758 DML_LOG_VERBOSE("DML::%s: FabricClock = %f\n", __func__, mode_lib->mp.FabricClock);
1759 DML_LOG_VERBOSE("DML::%s: uclk_freq_mhz = %f\n", __func__, mode_lib->mp.uclk_freq_mhz);
1760 DML_LOG_VERBOSE("DML::%s: dram_bw_mbps = %f\n", __func__, mode_lib->mp.dram_bw_mbps);
1761 DML_LOG_VERBOSE("DML::%s: UrgentLatency (urgent ramp) = %f\n", __func__, programming->qos_bound.latency_ub.dcn5.urgent_ramp);
1762 DML_LOG_VERBOSE("DML::%s: TripToMemory = %f\n", __func__, mode_lib->mp.TripToMemory);
1763 DML_LOG_VERBOSE("DML::%s: max_urgent_latency_us = %f\n", __func__, s->mmSOCParameters.max_urgent_latency_us);
1764 DML_LOG_VERBOSE("DML::%s: GlobalDPPCLK = %f\n", __func__, mode_lib->mp.GlobalDPPCLK);
1765 }
1766
dml2_core_dcn5_funcs_populate_programming(struct dml2_core_instance * core,const struct dml2_display_solution * solution,struct dml2_display_cfg_programming * programming)1767 enum dml2_status dml2_core_dcn5_funcs_populate_programming(struct dml2_core_instance *core,
1768 const struct dml2_display_solution *solution,
1769 struct dml2_display_cfg_programming *programming)
1770 {
1771 struct dml2_core_calcs_mode_programming_ex *params = &core->scratch.mode_programming_locals.mode_programming_ex_params;
1772 struct dml2_core_internal_display_mode_lib *mode_lib = &core->clean_me_up.mode_lib;
1773 bool result;
1774
1775 memset(&mode_lib->scratch, 0, sizeof(struct dml2_core_internal_scratch));
1776 memset(&mode_lib->mp, 0, sizeof(struct dml2_core_internal_mode_program));
1777
1778 dcn5_mp_assign_qos_bound(core, programming);
1779 params->mode_lib = mode_lib;
1780 params->in_display_cfg = &solution->dispcfg;
1781 params->cfg_support_info = &solution->validation_result.mode_support.cfg_support_info;
1782 params->programming = programming;
1783 params->uclk_params = &solution->uclk_pstate_params;
1784 params->utm_soc_bb = core->utm_soc_bb;
1785 params->solution = solution;
1786 result = dcn5_mode_programming(params);
1787 if (result)
1788 dcn5_pack_mode_programming_params(core, params, programming);
1789
1790 return result ? DML2_STATUS_OK : DML2_STATUS_POPULATE_FAIL_PROGRAMMING;
1791 }
1792