xref: /linux/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c (revision 5f2b6c5f6b692c696a232d12c43b8e41c0d393b9)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4 
5 
6 #include "dml21_wrapper.h"
7 #include "dml2_core_dcn4_calcs.h"
8 #include "dml2_internal_shared_types.h"
9 #include "dml2_internal_types.h"
10 #include "dml21_utils.h"
11 #include "dml21_translation_helper.h"
12 #include "bounding_boxes/dcn4_soc_bb.h"
13 
dml21_init_socbb_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)14 static void dml21_init_socbb_params(struct dml2_initialize_instance_in_out *dml_init,
15 		const struct dml2_configuration_options *config,
16 		const struct dc *in_dc)
17 {
18 	const struct dml2_soc_bb *soc_bb;
19 	const struct dml2_soc_qos_parameters *qos_params;
20 
21 	switch (in_dc->ctx->dce_version) {
22 	case DCN_VERSION_4_01:
23 	default:
24 		if (config->bb_from_dmub)
25 			soc_bb = config->bb_from_dmub;
26 		else
27 			soc_bb = &dml2_socbb_dcn401;
28 
29 		qos_params = &dml_dcn4_variant_a_soc_qos_params;
30 	}
31 
32 	/* patch soc bb */
33 	memcpy(&dml_init->soc_bb, soc_bb, sizeof(struct dml2_soc_bb));
34 
35 	/* patch qos params */
36 	memcpy(&dml_init->soc_bb.qos_parameters, qos_params, sizeof(struct dml2_soc_qos_parameters));
37 }
38 
dml21_external_socbb_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config)39 static void dml21_external_socbb_params(struct dml2_initialize_instance_in_out *dml_init,
40 		const struct dml2_configuration_options *config)
41 {
42 	memcpy(&dml_init->soc_bb, &config->external_socbb_ip_params->soc_bb, sizeof(struct dml2_soc_bb));
43 }
44 
dml21_external_ip_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config)45 static void dml21_external_ip_params(struct dml2_initialize_instance_in_out *dml_init,
46 		const struct dml2_configuration_options *config)
47 {
48 	memcpy(&dml_init->ip_caps, &config->external_socbb_ip_params->ip_params, sizeof(struct dml2_ip_capabilities));
49 }
50 
dml21_init_ip_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)51 static void dml21_init_ip_params(struct dml2_initialize_instance_in_out *dml_init,
52 		const struct dml2_configuration_options *config,
53 		const struct dc *in_dc)
54 {
55 	const struct dml2_ip_capabilities *ip_caps;
56 
57 	switch (in_dc->ctx->dce_version) {
58 	case DCN_VERSION_4_01:
59 	default:
60 		ip_caps = &dml2_dcn401_max_ip_caps;
61 	}
62 
63 	memcpy(&dml_init->ip_caps, ip_caps, sizeof(struct dml2_ip_capabilities));
64 }
65 
dml21_initialize_soc_bb_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)66 void dml21_initialize_soc_bb_params(struct dml2_initialize_instance_in_out *dml_init,
67 		const struct dml2_configuration_options *config,
68 		const struct dc *in_dc)
69 {
70 	if (config->use_native_soc_bb_construction)
71 		dml21_init_socbb_params(dml_init, config, in_dc);
72 	else
73 		dml21_external_socbb_params(dml_init, config);
74 }
75 
dml21_initialize_ip_params(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)76 void dml21_initialize_ip_params(struct dml2_initialize_instance_in_out *dml_init,
77 		const struct dml2_configuration_options *config,
78 		const struct dc *in_dc)
79 {
80 	if (config->use_native_soc_bb_construction)
81 		dml21_init_ip_params(dml_init, config, in_dc);
82 	else
83 		dml21_external_ip_params(dml_init, config);
84 }
85 
dml21_apply_soc_bb_overrides(struct dml2_initialize_instance_in_out * dml_init,const struct dml2_configuration_options * config,const struct dc * in_dc)86 void dml21_apply_soc_bb_overrides(struct dml2_initialize_instance_in_out *dml_init,
87 		const struct dml2_configuration_options *config, const struct dc *in_dc)
88 {
89 	int i;
90 
91 	const struct clk_bw_params *dc_bw_params = in_dc->clk_mgr->bw_params;
92 	const struct clk_limit_table *dc_clk_table = &dc_bw_params->clk_table;
93 	struct dml2_soc_bb *dml_soc_bb = &dml_init->soc_bb;
94 	struct dml2_soc_state_table *dml_clk_table = &dml_soc_bb->clk_table;
95 
96 	/* override clocks if smu is present */
97 	if (in_dc->clk_mgr->funcs->is_smu_present && in_dc->clk_mgr->funcs->is_smu_present(in_dc->clk_mgr)) {
98 		/* dcfclk */
99 		if (dc_clk_table->num_entries_per_clk.num_dcfclk_levels) {
100 			dml_clk_table->dcfclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dcfclk_levels;
101 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
102 				if (i < dml_clk_table->dcfclk.num_clk_values) {
103 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dcfclk_mhz &&
104 							dc_clk_table->entries[i].dcfclk_mhz > dc_bw_params->dc_mode_limit.dcfclk_mhz) {
105 						if (i == 0 || dc_clk_table->entries[i-1].dcfclk_mhz < dc_bw_params->dc_mode_limit.dcfclk_mhz) {
106 							dml_clk_table->dcfclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dcfclk_mhz * 1000;
107 							dml_clk_table->dcfclk.num_clk_values = i + 1;
108 						} else {
109 							dml_clk_table->dcfclk.clk_values_khz[i] = 0;
110 							dml_clk_table->dcfclk.num_clk_values = i;
111 						}
112 					} else {
113 						dml_clk_table->dcfclk.clk_values_khz[i] = dc_clk_table->entries[i].dcfclk_mhz * 1000;
114 					}
115 				} else {
116 					dml_clk_table->dcfclk.clk_values_khz[i] = 0;
117 				}
118 			}
119 		}
120 
121 		/* fclk */
122 		if (dc_clk_table->num_entries_per_clk.num_fclk_levels) {
123 			dml_clk_table->fclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_fclk_levels;
124 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
125 				if (i < dml_clk_table->fclk.num_clk_values) {
126 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.fclk_mhz &&
127 							dc_clk_table->entries[i].fclk_mhz > dc_bw_params->dc_mode_limit.fclk_mhz) {
128 						if (i == 0 || dc_clk_table->entries[i-1].fclk_mhz < dc_bw_params->dc_mode_limit.fclk_mhz) {
129 							dml_clk_table->fclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.fclk_mhz * 1000;
130 							dml_clk_table->fclk.num_clk_values = i + 1;
131 						} else {
132 							dml_clk_table->fclk.clk_values_khz[i] = 0;
133 							dml_clk_table->fclk.num_clk_values = i;
134 						}
135 					} else {
136 						dml_clk_table->fclk.clk_values_khz[i] = dc_clk_table->entries[i].fclk_mhz * 1000;
137 					}
138 				} else {
139 					dml_clk_table->fclk.clk_values_khz[i] = 0;
140 				}
141 			}
142 		}
143 
144 		/* uclk */
145 		if (dc_clk_table->num_entries_per_clk.num_memclk_levels) {
146 			dml_clk_table->uclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_memclk_levels;
147 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
148 				if (i < dml_clk_table->uclk.num_clk_values) {
149 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.memclk_mhz &&
150 							dc_clk_table->entries[i].memclk_mhz > dc_bw_params->dc_mode_limit.memclk_mhz) {
151 						if (i == 0 || dc_clk_table->entries[i-1].memclk_mhz < dc_bw_params->dc_mode_limit.memclk_mhz) {
152 							dml_clk_table->uclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.memclk_mhz * 1000;
153 							dml_clk_table->uclk.num_clk_values = i + 1;
154 						} else {
155 							dml_clk_table->uclk.clk_values_khz[i] = 0;
156 							dml_clk_table->uclk.num_clk_values = i;
157 						}
158 					} else {
159 						dml_clk_table->uclk.clk_values_khz[i] = dc_clk_table->entries[i].memclk_mhz * 1000;
160 					}
161 				} else {
162 					dml_clk_table->uclk.clk_values_khz[i] = 0;
163 				}
164 			}
165 		}
166 
167 		/* dispclk */
168 		if (dc_clk_table->num_entries_per_clk.num_dispclk_levels) {
169 			dml_clk_table->dispclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dispclk_levels;
170 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
171 				if (i < dml_clk_table->dispclk.num_clk_values) {
172 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dispclk_mhz &&
173 							dc_clk_table->entries[i].dispclk_mhz > dc_bw_params->dc_mode_limit.dispclk_mhz) {
174 						if (i == 0 || dc_clk_table->entries[i-1].dispclk_mhz < dc_bw_params->dc_mode_limit.dispclk_mhz) {
175 							dml_clk_table->dispclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dispclk_mhz * 1000;
176 							dml_clk_table->dispclk.num_clk_values = i + 1;
177 						} else {
178 							dml_clk_table->dispclk.clk_values_khz[i] = 0;
179 							dml_clk_table->dispclk.num_clk_values = i;
180 						}
181 					} else {
182 						dml_clk_table->dispclk.clk_values_khz[i] = dc_clk_table->entries[i].dispclk_mhz * 1000;
183 					}
184 				} else {
185 					dml_clk_table->dispclk.clk_values_khz[i] = 0;
186 				}
187 			}
188 		}
189 
190 		/* dppclk */
191 		if (dc_clk_table->num_entries_per_clk.num_dppclk_levels) {
192 			dml_clk_table->dppclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dppclk_levels;
193 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
194 				if (i < dml_clk_table->dppclk.num_clk_values) {
195 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dppclk_mhz &&
196 							dc_clk_table->entries[i].dppclk_mhz > dc_bw_params->dc_mode_limit.dppclk_mhz) {
197 						if (i == 0 || dc_clk_table->entries[i-1].dppclk_mhz < dc_bw_params->dc_mode_limit.dppclk_mhz) {
198 							dml_clk_table->dppclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dppclk_mhz * 1000;
199 							dml_clk_table->dppclk.num_clk_values = i + 1;
200 						} else {
201 							dml_clk_table->dppclk.clk_values_khz[i] = 0;
202 							dml_clk_table->dppclk.num_clk_values = i;
203 						}
204 					} else {
205 						dml_clk_table->dppclk.clk_values_khz[i] = dc_clk_table->entries[i].dppclk_mhz * 1000;
206 					}
207 				} else {
208 					dml_clk_table->dppclk.clk_values_khz[i] = 0;
209 				}
210 			}
211 		}
212 
213 		/* dtbclk */
214 		if (dc_clk_table->num_entries_per_clk.num_dtbclk_levels) {
215 			dml_clk_table->dtbclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_dtbclk_levels;
216 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
217 				if (i < dml_clk_table->dtbclk.num_clk_values) {
218 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.dtbclk_mhz &&
219 							dc_clk_table->entries[i].dtbclk_mhz > dc_bw_params->dc_mode_limit.dtbclk_mhz) {
220 						if (i == 0 || dc_clk_table->entries[i-1].dtbclk_mhz < dc_bw_params->dc_mode_limit.dtbclk_mhz) {
221 							dml_clk_table->dtbclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.dtbclk_mhz * 1000;
222 							dml_clk_table->dtbclk.num_clk_values = i + 1;
223 						} else {
224 							dml_clk_table->dtbclk.clk_values_khz[i] = 0;
225 							dml_clk_table->dtbclk.num_clk_values = i;
226 						}
227 					} else {
228 						dml_clk_table->dtbclk.clk_values_khz[i] = dc_clk_table->entries[i].dtbclk_mhz * 1000;
229 					}
230 				} else {
231 					dml_clk_table->dtbclk.clk_values_khz[i] = 0;
232 				}
233 			}
234 		}
235 
236 		/* socclk */
237 		if (dc_clk_table->num_entries_per_clk.num_socclk_levels) {
238 			dml_clk_table->socclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_socclk_levels;
239 			for (i = 0; i < min(DML_MAX_CLK_TABLE_SIZE, MAX_NUM_DPM_LVL); i++) {
240 				if (i < dml_clk_table->socclk.num_clk_values) {
241 					if (config->use_clock_dc_limits && dc_bw_params->dc_mode_limit.socclk_mhz &&
242 							dc_clk_table->entries[i].socclk_mhz > dc_bw_params->dc_mode_limit.socclk_mhz) {
243 						if (i == 0 || dc_clk_table->entries[i-1].socclk_mhz < dc_bw_params->dc_mode_limit.socclk_mhz) {
244 							dml_clk_table->socclk.clk_values_khz[i] = dc_bw_params->dc_mode_limit.socclk_mhz * 1000;
245 							dml_clk_table->socclk.num_clk_values = i + 1;
246 						} else {
247 							dml_clk_table->socclk.clk_values_khz[i] = 0;
248 							dml_clk_table->socclk.num_clk_values = i;
249 						}
250 					} else {
251 						dml_clk_table->socclk.clk_values_khz[i] = dc_clk_table->entries[i].socclk_mhz * 1000;
252 					}
253 				} else {
254 					dml_clk_table->socclk.clk_values_khz[i] = 0;
255 				}
256 			}
257 		}
258 
259 		/* do not override phyclks for now */
260 		/* phyclk */
261 		// dml_clk_table->phyclk.num_clk_values = dc_clk_table->num_entries_per_clk.num_phyclk_levels;
262 		// for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
263 		// 	dml_clk_table->phyclk.clk_values_khz[i] = dc_clk_table->entries[i].phyclk_mhz * 1000;
264 		// }
265 
266 		/* phyclk_d18 */
267 		// dml_clk_table->phyclk_d18.num_clk_values = dc_clk_table->num_entries_per_clk.num_phyclk_d18_levels;
268 		// for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
269 		// 	dml_clk_table->phyclk_d18.clk_values_khz[i] = dc_clk_table->entries[i].phyclk_d18_mhz * 1000;
270 		// }
271 
272 		/* phyclk_d32 */
273 		// dml_clk_table->phyclk_d32.num_clk_values = dc_clk_table->num_entries_per_clk.num_phyclk_d32_levels;
274 		// for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) {
275 		// 	dml_clk_table->phyclk_d32.clk_values_khz[i] = dc_clk_table->entries[i].phyclk_d32_mhz * 1000;
276 		// }
277 	}
278 
279 	dml_soc_bb->dchub_refclk_mhz = in_dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
280 	dml_soc_bb->dprefclk_mhz = in_dc->clk_mgr->dprefclk_khz / 1000;
281 	dml_soc_bb->xtalclk_mhz = in_dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency / 1000;
282 	dml_soc_bb->dispclk_dppclk_vco_speed_mhz = in_dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
283 
284 	/* override bounding box paramters from VBIOS */
285 	if (in_dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns > 0)
286 		dml_soc_bb->power_management_parameters.dram_clk_change_blackout_us =
287 				(in_dc->ctx->dc_bios->bb_info.dram_clock_change_latency_100ns + 9) / 10;
288 
289 	if (in_dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns > 0)
290 		dml_soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us =
291 				(in_dc->ctx->dc_bios->bb_info.dram_sr_enter_exit_latency_100ns + 9) / 10;
292 
293 	if (in_dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns > 0)
294 		dml_soc_bb->power_management_parameters.stutter_exit_latency_us =
295 			(in_dc->ctx->dc_bios->bb_info.dram_sr_exit_latency_100ns + 9) / 10;
296 
297 	if (dc_bw_params->num_channels) {
298 		dml_clk_table->dram_config.channel_count = dc_bw_params->num_channels;
299 		dml_soc_bb->mall_allocated_for_dcn_mbytes = in_dc->caps.mall_size_total / 1048576;
300 	} else if (in_dc->ctx->dc_bios->vram_info.num_chans) {
301 		dml_clk_table->dram_config.channel_count = in_dc->ctx->dc_bios->vram_info.num_chans;
302 		dml_soc_bb->mall_allocated_for_dcn_mbytes = in_dc->caps.mall_size_total / 1048576;
303 	}
304 
305 	if (dc_bw_params->dram_channel_width_bytes) {
306 		dml_clk_table->dram_config.channel_width_bytes = dc_bw_params->dram_channel_width_bytes;
307 	} else if (in_dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) {
308 		dml_clk_table->dram_config.channel_width_bytes = in_dc->ctx->dc_bios->vram_info.dram_channel_width_bytes;
309 	}
310 
311 	/* override bounding box paramters from DC config */
312 	if (in_dc->bb_overrides.sr_exit_time_ns) {
313 		dml_soc_bb->power_management_parameters.stutter_exit_latency_us =
314 				in_dc->bb_overrides.sr_exit_time_ns / 1000.0;
315 	}
316 
317 	if (in_dc->bb_overrides.sr_enter_plus_exit_time_ns) {
318 		dml_soc_bb->power_management_parameters.stutter_enter_plus_exit_latency_us =
319 				in_dc->bb_overrides.sr_enter_plus_exit_time_ns / 1000.0;
320 	}
321 
322 	if (in_dc->bb_overrides.dram_clock_change_latency_ns) {
323 		dml_soc_bb->power_management_parameters.dram_clk_change_blackout_us =
324 				in_dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
325 	}
326 
327 	if (in_dc->bb_overrides.fclk_clock_change_latency_ns) {
328 		dml_soc_bb->power_management_parameters.fclk_change_blackout_us =
329 				in_dc->bb_overrides.fclk_clock_change_latency_ns / 1000.0;
330 	}
331 
332 	//TODO
333 	// if (in_dc->bb_overrides.dummy_clock_change_latency_ns) {
334 	// 	dml_soc_bb->power_management_parameters.dram_clk_change_blackout_us =
335 	// 			in_dc->bb_overrides.dram_clock_change_latency_ns / 1000.0;
336 	// }
337 }
338 
calc_max_hardware_v_total(const struct dc_stream_state * stream)339 static unsigned int calc_max_hardware_v_total(const struct dc_stream_state *stream)
340 {
341 	unsigned int max_hw_v_total = stream->ctx->dc->caps.max_v_total;
342 
343 	if (stream->ctx->dc->caps.vtotal_limited_by_fp2) {
344 		max_hw_v_total -= stream->timing.v_front_porch + 1;
345 	}
346 
347 	return max_hw_v_total;
348 }
349 
populate_dml21_timing_config_from_stream_state(struct dml2_timing_cfg * timing,struct dc_stream_state * stream,struct dml2_context * dml_ctx)350 static void populate_dml21_timing_config_from_stream_state(struct dml2_timing_cfg *timing,
351 		struct dc_stream_state *stream,
352 		struct dml2_context *dml_ctx)
353 {
354 	unsigned int hblank_start, vblank_start, min_hardware_refresh_in_uhz;
355 
356 	timing->h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
357 	timing->v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
358 	timing->h_front_porch = stream->timing.h_front_porch;
359 	timing->v_front_porch = stream->timing.v_front_porch;
360 	timing->pixel_clock_khz = stream->timing.pix_clk_100hz / 10;
361 	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
362 		timing->pixel_clock_khz *= 2;
363 	timing->h_total = stream->timing.h_total;
364 	timing->v_total = stream->timing.v_total;
365 	timing->h_sync_width = stream->timing.h_sync_width;
366 	timing->interlaced = stream->timing.flags.INTERLACE;
367 
368 	hblank_start = stream->timing.h_total - stream->timing.h_front_porch;
369 
370 	timing->h_blank_end = hblank_start - stream->timing.h_addressable
371 		- stream->timing.h_border_left - stream->timing.h_border_right;
372 
373 	if (hblank_start < stream->timing.h_addressable)
374 		timing->h_blank_end = 0;
375 
376 	vblank_start = stream->timing.v_total - stream->timing.v_front_porch;
377 
378 	timing->v_blank_end = vblank_start - stream->timing.v_addressable
379 		- stream->timing.v_border_top - stream->timing.v_border_bottom;
380 
381 	timing->drr_config.enabled = stream->ignore_msa_timing_param;
382 	timing->drr_config.drr_active_variable = stream->vrr_active_variable;
383 	timing->drr_config.drr_active_fixed = stream->vrr_active_fixed;
384 	timing->drr_config.disallowed = !stream->allow_freesync;
385 
386 	/* limit min refresh rate to DC cap */
387 	min_hardware_refresh_in_uhz = stream->timing.min_refresh_in_uhz;
388 	if (stream->ctx->dc->caps.max_v_total != 0) {
389 		min_hardware_refresh_in_uhz = div64_u64((stream->timing.pix_clk_100hz * 100000000ULL),
390 				(stream->timing.h_total * (long long)calc_max_hardware_v_total(stream)));
391 	}
392 
393 	if (stream->timing.min_refresh_in_uhz > min_hardware_refresh_in_uhz) {
394 		timing->drr_config.min_refresh_uhz = stream->timing.min_refresh_in_uhz;
395 	} else {
396 		timing->drr_config.min_refresh_uhz = min_hardware_refresh_in_uhz;
397 	}
398 
399 	if (dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase &&
400 			stream->ctx->dc->config.enable_fpo_flicker_detection == 1)
401 		timing->drr_config.max_instant_vtotal_delta = dml_ctx->config.callbacks.get_max_flickerless_instant_vtotal_increase(stream, false);
402 	else
403 		timing->drr_config.max_instant_vtotal_delta = 0;
404 
405 	if (stream->timing.flags.DSC) {
406 		timing->dsc.enable = dml2_dsc_enable;
407 		timing->dsc.overrides.num_slices = stream->timing.dsc_cfg.num_slices_h;
408 		timing->dsc.dsc_compressed_bpp_x16 = stream->timing.dsc_cfg.bits_per_pixel;
409 	} else
410 		timing->dsc.enable = dml2_dsc_disable;
411 
412 	switch (stream->timing.display_color_depth) {
413 	case COLOR_DEPTH_666:
414 		timing->bpc = 6;
415 		break;
416 	case COLOR_DEPTH_888:
417 		timing->bpc = 8;
418 		break;
419 	case COLOR_DEPTH_101010:
420 		timing->bpc = 10;
421 		break;
422 	case COLOR_DEPTH_121212:
423 		timing->bpc = 12;
424 		break;
425 	case COLOR_DEPTH_141414:
426 		timing->bpc = 14;
427 		break;
428 	case COLOR_DEPTH_161616:
429 		timing->bpc = 16;
430 		break;
431 	case COLOR_DEPTH_999:
432 		timing->bpc = 9;
433 		break;
434 	case COLOR_DEPTH_111111:
435 		timing->bpc = 11;
436 		break;
437 	default:
438 		timing->bpc = 8;
439 		break;
440 	}
441 
442 	timing->vblank_nom = timing->v_total - timing->v_active;
443 }
444 
445 /**
446  * adjust_dml21_hblank_timing_config_from_pipe_ctx - Adjusts the horizontal blanking timing configuration
447  *                                                   based on the pipe context.
448  * @timing: Pointer to the dml2_timing_cfg structure to be adjusted.
449  * @pipe: Pointer to the pipe_ctx structure containing the horizontal blanking borrow value.
450  *
451  * This function modifies the horizontal active and blank end timings by adding and subtracting
452  * the horizontal blanking borrow value from the pipe context, respectively.
453  */
adjust_dml21_hblank_timing_config_from_pipe_ctx(struct dml2_timing_cfg * timing,struct pipe_ctx * pipe)454 static void adjust_dml21_hblank_timing_config_from_pipe_ctx(struct dml2_timing_cfg *timing, struct pipe_ctx *pipe)
455 {
456 	timing->h_active += pipe->hblank_borrow;
457 	timing->h_blank_end -= pipe->hblank_borrow;
458 }
459 
populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg * output,struct dc_stream_state * stream,const struct pipe_ctx * pipe)460 static void populate_dml21_output_config_from_stream_state(struct dml2_link_output_cfg *output,
461 		struct dc_stream_state *stream, const struct pipe_ctx *pipe)
462 {
463 	output->output_dp_lane_count = 4;
464 
465 	switch (stream->signal) {
466 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
467 	case SIGNAL_TYPE_DISPLAY_PORT:
468 		output->output_encoder = dml2_dp;
469 		if (check_dp2p0_output_encoder(pipe))
470 			output->output_encoder = dml2_dp2p0;
471 		break;
472 	case SIGNAL_TYPE_EDP:
473 		output->output_encoder = dml2_edp;
474 		break;
475 	case SIGNAL_TYPE_HDMI_TYPE_A:
476 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
477 	case SIGNAL_TYPE_DVI_DUAL_LINK:
478 		output->output_encoder = dml2_hdmi;
479 		break;
480 	default:
481 			output->output_encoder = dml2_dp;
482 	}
483 
484 	switch (stream->timing.pixel_encoding) {
485 	case PIXEL_ENCODING_RGB:
486 	case PIXEL_ENCODING_YCBCR444:
487 		output->output_format = dml2_444;
488 		break;
489 	case PIXEL_ENCODING_YCBCR420:
490 		output->output_format = dml2_420;
491 		break;
492 	case PIXEL_ENCODING_YCBCR422:
493 		if (stream->timing.flags.DSC && !stream->timing.dsc_cfg.ycbcr422_simple)
494 			output->output_format = dml2_n422;
495 		else
496 			output->output_format = dml2_s422;
497 		break;
498 	default:
499 		output->output_format = dml2_444;
500 		break;
501 	}
502 
503 	switch (stream->signal) {
504 	case SIGNAL_TYPE_NONE:
505 	case SIGNAL_TYPE_DVI_SINGLE_LINK:
506 	case SIGNAL_TYPE_DVI_DUAL_LINK:
507 	case SIGNAL_TYPE_HDMI_TYPE_A:
508 	case SIGNAL_TYPE_LVDS:
509 	case SIGNAL_TYPE_RGB:
510 	case SIGNAL_TYPE_DISPLAY_PORT:
511 	case SIGNAL_TYPE_DISPLAY_PORT_MST:
512 	case SIGNAL_TYPE_EDP:
513 	case SIGNAL_TYPE_VIRTUAL:
514 	default:
515 		output->output_dp_link_rate = dml2_dp_rate_na;
516 		break;
517 	}
518 
519 	output->audio_sample_layout = stream->audio_info.modes->sample_size;
520 	output->audio_sample_rate = stream->audio_info.modes->max_bit_rate;
521 	output->output_disabled = true;
522 
523 	//TODO : New to DML2.1. How do we populate this ?
524 	// output->validate_output
525 }
526 
populate_dml21_stream_overrides_from_stream_state(struct dml2_stream_parameters * stream_desc,struct dc_stream_state * stream,struct dc_stream_status * stream_status)527 static void populate_dml21_stream_overrides_from_stream_state(
528 		struct dml2_stream_parameters *stream_desc,
529 		struct dc_stream_state *stream,
530 		struct dc_stream_status *stream_status)
531 {
532 	switch (stream->debug.force_odm_combine_segments) {
533 	case 0:
534 		stream_desc->overrides.odm_mode = dml2_odm_mode_auto;
535 		break;
536 	case 1:
537 		stream_desc->overrides.odm_mode = dml2_odm_mode_bypass;
538 		break;
539 	case 2:
540 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_2to1;
541 		break;
542 	case 3:
543 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_3to1;
544 		break;
545 	case 4:
546 		stream_desc->overrides.odm_mode = dml2_odm_mode_combine_4to1;
547 		break;
548 	default:
549 		stream_desc->overrides.odm_mode =  dml2_odm_mode_auto;
550 		break;
551 	}
552 	if (!stream->ctx->dc->debug.enable_single_display_2to1_odm_policy ||
553 			stream->debug.force_odm_combine_segments > 0)
554 		stream_desc->overrides.disable_dynamic_odm = true;
555 	stream_desc->overrides.disable_subvp = stream->ctx->dc->debug.force_disable_subvp ||
556 			stream->hw_cursor_req ||
557 			stream_status->mall_stream_config.cursor_size_limit_subvp;
558 }
559 
gfx_addr3_to_dml2_swizzle_mode(enum swizzle_mode_addr3_values addr3_mode)560 static enum dml2_swizzle_mode gfx_addr3_to_dml2_swizzle_mode(enum swizzle_mode_addr3_values addr3_mode)
561 {
562 	enum dml2_swizzle_mode dml2_mode = dml2_sw_linear;
563 
564 	switch (addr3_mode) {
565 	case DC_ADDR3_SW_LINEAR:
566 		dml2_mode = dml2_sw_linear;
567 		break;
568 	case DC_ADDR3_SW_256B_2D:
569 		dml2_mode = dml2_sw_256b_2d;
570 		break;
571 	case DC_ADDR3_SW_4KB_2D:
572 		dml2_mode = dml2_sw_4kb_2d;
573 		break;
574 	case DC_ADDR3_SW_64KB_2D:
575 		dml2_mode = dml2_sw_64kb_2d;
576 		break;
577 	case DC_ADDR3_SW_256KB_2D:
578 		dml2_mode = dml2_sw_256kb_2d;
579 		break;
580 	default:
581 		/* invalid swizzle mode for DML2.1 */
582 		ASSERT(false);
583 		dml2_mode = dml2_sw_linear;
584 	}
585 
586 	return dml2_mode;
587 }
588 
gfx9_to_dml2_swizzle_mode(enum swizzle_mode_values gfx9_mode)589 static enum dml2_swizzle_mode gfx9_to_dml2_swizzle_mode(enum swizzle_mode_values gfx9_mode)
590 {
591 	enum dml2_swizzle_mode dml2_mode = dml2_sw_64kb_2d;
592 
593 	switch (gfx9_mode) {
594 	case DC_SW_LINEAR:
595 		dml2_mode = dml2_sw_linear;
596 		break;
597 	case DC_SW_256_D:
598 	case DC_SW_256_R:
599 		dml2_mode = dml2_sw_256b_2d;
600 		break;
601 	case DC_SW_4KB_D:
602 	case DC_SW_4KB_R:
603 	case DC_SW_4KB_R_X:
604 		dml2_mode = dml2_sw_4kb_2d;
605 		break;
606 	case DC_SW_64KB_D:
607 	case DC_SW_64KB_D_X:
608 	case DC_SW_64KB_R:
609 	case DC_SW_64KB_R_X:
610 		dml2_mode = dml2_sw_64kb_2d;
611 		break;
612 	case DC_SW_256B_S:
613 	case DC_SW_4KB_S:
614 	case DC_SW_64KB_S:
615 	case DC_SW_VAR_S:
616 	case DC_SW_VAR_D:
617 	case DC_SW_VAR_R:
618 	case DC_SW_64KB_S_T:
619 	case DC_SW_64KB_D_T:
620 	case DC_SW_4KB_S_X:
621 	case DC_SW_4KB_D_X:
622 	case DC_SW_64KB_S_X:
623 	case DC_SW_VAR_S_X:
624 	case DC_SW_VAR_D_X:
625 	case DC_SW_VAR_R_X:
626 	default:
627 		/*
628 		 * invalid swizzle mode for DML2.1. This could happen because
629 		 * DML21 is not intended to be used by N-1 in production. To
630 		 * properly filter out unsupported swizzle modes, we will need
631 		 * to fix capability reporting when DML2.1 is used for N-1 in
632 		 * dc. So DML will only receive DML21 supported swizzle modes.
633 		 * This implementation is not added and has a low value because
634 		 * the supported swizzle modes should already cover most of our
635 		 * N-1 test cases.
636 		 */
637 		return dml2_sw_64kb_2d;
638 	}
639 
640 	return dml2_mode;
641 }
642 
populate_dml21_dummy_surface_cfg(struct dml2_surface_cfg * surface,const struct dc_stream_state * stream)643 static void populate_dml21_dummy_surface_cfg(struct dml2_surface_cfg *surface, const struct dc_stream_state *stream)
644 {
645 	surface->plane0.width = stream->timing.h_addressable;
646 	surface->plane0.height = stream->timing.v_addressable;
647 	surface->plane1.width = stream->timing.h_addressable;
648 	surface->plane1.height = stream->timing.v_addressable;
649 	surface->plane0.pitch = ((surface->plane0.width + 127) / 128) * 128;
650 	surface->plane1.pitch = 0;
651 	surface->dcc.enable = false;
652 	surface->dcc.informative.dcc_rate_plane0 = 1.0;
653 	surface->dcc.informative.dcc_rate_plane1 = 1.0;
654 	surface->dcc.informative.fraction_of_zero_size_request_plane0 = 0;
655 	surface->dcc.informative.fraction_of_zero_size_request_plane1 = 0;
656 	surface->tiling = dml2_sw_64kb_2d;
657 }
658 
populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters * plane,const struct dc_stream_state * stream)659 static void populate_dml21_dummy_plane_cfg(struct dml2_plane_parameters *plane, const struct dc_stream_state *stream)
660 {
661 	unsigned int width, height;
662 
663 	if (stream->timing.h_addressable > 3840)
664 		width = 3840;
665 	else
666 		width = stream->timing.h_addressable;	// 4K max
667 
668 	if (stream->timing.v_addressable > 2160)
669 		height = 2160;
670 	else
671 		height = stream->timing.v_addressable;	// 4K max
672 
673 	plane->cursor.cursor_bpp = 32;
674 
675 	plane->cursor.cursor_width = 256;
676 	plane->cursor.num_cursors = 1;
677 
678 	plane->composition.viewport.plane0.width = width;
679 	plane->composition.viewport.plane0.height = height;
680 	plane->composition.viewport.plane1.width = 0;
681 	plane->composition.viewport.plane1.height = 0;
682 
683 	plane->composition.viewport.stationary = false;
684 	plane->composition.viewport.plane0.x_start = 0;
685 	plane->composition.viewport.plane0.y_start = 0;
686 	plane->composition.viewport.plane1.x_start = 0;
687 	plane->composition.viewport.plane1.y_start = 0;
688 
689 	plane->composition.scaler_info.enabled = false;
690 	plane->composition.rotation_angle = dml2_rotation_0;
691 	plane->composition.scaler_info.plane0.h_ratio = 1.0;
692 	plane->composition.scaler_info.plane0.v_ratio = 1.0;
693 	plane->composition.scaler_info.plane1.h_ratio = 0;
694 	plane->composition.scaler_info.plane1.v_ratio = 0;
695 	plane->composition.scaler_info.plane0.h_taps = 1;
696 	plane->composition.scaler_info.plane0.v_taps = 1;
697 	plane->composition.scaler_info.plane1.h_taps = 0;
698 	plane->composition.scaler_info.plane1.v_taps = 0;
699 	plane->composition.scaler_info.rect_out_width = width;
700 	plane->pixel_format = dml2_444_32;
701 
702 	plane->dynamic_meta_data.enable = false;
703 	plane->overrides.gpuvm_min_page_size_kbytes = 256;
704 }
705 
populate_dml21_surface_config_from_plane_state(const struct dc * in_dc,struct dml2_surface_cfg * surface,const struct dc_plane_state * plane_state)706 static void populate_dml21_surface_config_from_plane_state(
707 		const struct dc *in_dc,
708 		struct dml2_surface_cfg *surface,
709 		const struct dc_plane_state *plane_state)
710 {
711 	surface->plane0.pitch = plane_state->plane_size.surface_pitch;
712 	surface->plane1.pitch = plane_state->plane_size.chroma_pitch;
713 	surface->plane0.height = plane_state->plane_size.surface_size.height;
714 	surface->plane0.width = plane_state->plane_size.surface_size.width;
715 	surface->plane1.height = plane_state->plane_size.chroma_size.height;
716 	surface->plane1.width = plane_state->plane_size.chroma_size.width;
717 	surface->dcc.enable = plane_state->dcc.enable;
718 	surface->dcc.informative.dcc_rate_plane0 = 1.0;
719 	surface->dcc.informative.dcc_rate_plane1 = 1.0;
720 	surface->dcc.informative.fraction_of_zero_size_request_plane0 = plane_state->dcc.independent_64b_blks;
721 	surface->dcc.informative.fraction_of_zero_size_request_plane1 = plane_state->dcc.independent_64b_blks_c;
722 	surface->dcc.plane0.pitch = plane_state->dcc.meta_pitch;
723 	surface->dcc.plane1.pitch = plane_state->dcc.meta_pitch_c;
724 
725 	// Update swizzle / array mode based on the gfx_format
726 	switch (plane_state->tiling_info.gfxversion) {
727 	case DcGfxVersion7:
728 	case DcGfxVersion8:
729 		// Placeholder for programming the array_mode
730 		break;
731 	case DcGfxVersion9:
732 	case DcGfxVersion10:
733 	case DcGfxVersion11:
734 		surface->tiling = gfx9_to_dml2_swizzle_mode(plane_state->tiling_info.gfx9.swizzle);
735 		break;
736 	case DcGfxAddr3:
737 		surface->tiling = gfx_addr3_to_dml2_swizzle_mode(plane_state->tiling_info.gfx_addr3.swizzle);
738 		break;
739 	}
740 }
741 
get_scaler_data_for_plane(struct dml2_context * dml_ctx,const struct dc_plane_state * in,const struct dc_state * context)742 static const struct scaler_data *get_scaler_data_for_plane(
743 		struct dml2_context *dml_ctx,
744 		const struct dc_plane_state *in,
745 		const struct dc_state *context)
746 {
747 	int i;
748 	struct pipe_ctx *temp_pipe = &dml_ctx->v21.scratch.temp_pipe;
749 
750 	memset(temp_pipe, 0, sizeof(struct pipe_ctx));
751 
752 	for (i = 0; i < MAX_PIPES; i++)	{
753 		const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
754 
755 		if (pipe->plane_state == in && !pipe->prev_odm_pipe) {
756 			temp_pipe->stream = pipe->stream;
757 			temp_pipe->plane_state = pipe->plane_state;
758 			temp_pipe->plane_res.scl_data.taps = pipe->plane_res.scl_data.taps;
759 			temp_pipe->stream_res = pipe->stream_res;
760 			temp_pipe->hblank_borrow = pipe->hblank_borrow;
761 			dml_ctx->config.callbacks.build_scaling_params(temp_pipe);
762 			break;
763 		}
764 	}
765 
766 	ASSERT(i < MAX_PIPES);
767 	return &temp_pipe->plane_res.scl_data;
768 }
769 
populate_dml21_plane_config_from_plane_state(struct dml2_context * dml_ctx,struct dml2_plane_parameters * plane,const struct dc_plane_state * plane_state,const struct dc_state * context,unsigned int stream_index)770 static void populate_dml21_plane_config_from_plane_state(struct dml2_context *dml_ctx,
771 		struct dml2_plane_parameters *plane, const struct dc_plane_state *plane_state,
772 		const struct dc_state *context, unsigned int stream_index)
773 {
774 	const struct scaler_data *scaler_data = get_scaler_data_for_plane(dml_ctx, plane_state, context);
775 	struct dc_stream_state *stream = context->streams[stream_index];
776 
777 	plane->cursor.cursor_bpp = 32;
778 	plane->cursor.cursor_width = 256;
779 	plane->cursor.num_cursors = 1;
780 
781 	switch (plane_state->format) {
782 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
783 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
784 		plane->pixel_format = dml2_420_8;
785 		break;
786 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
787 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
788 		plane->pixel_format = dml2_420_10;
789 		break;
790 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
791 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
792 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
793 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
794 		plane->pixel_format = dml2_444_64;
795 		break;
796 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
797 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
798 		plane->pixel_format = dml2_444_16;
799 		break;
800 	case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
801 		plane->pixel_format = dml2_444_8;
802 		break;
803 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
804 		plane->pixel_format = dml2_rgbe_alpha;
805 		break;
806 	default:
807 		plane->pixel_format = dml2_444_32;
808 		break;
809 	}
810 
811 	plane->composition.viewport.plane0.height = scaler_data->viewport.height;
812 	plane->composition.viewport.plane0.width = scaler_data->viewport.width;
813 	plane->composition.viewport.plane1.height = scaler_data->viewport_c.height;
814 	plane->composition.viewport.plane1.width = scaler_data->viewport_c.width;
815 	plane->composition.viewport.plane0.x_start = scaler_data->viewport.x;
816 	plane->composition.viewport.plane0.y_start = scaler_data->viewport.y;
817 	plane->composition.viewport.plane1.x_start = scaler_data->viewport_c.x;
818 	plane->composition.viewport.plane1.y_start = scaler_data->viewport_c.y;
819 	plane->composition.viewport.stationary = false;
820 	plane->composition.scaler_info.enabled = scaler_data->ratios.horz.value != dc_fixpt_one.value ||
821 		scaler_data->ratios.horz_c.value != dc_fixpt_one.value ||
822 		scaler_data->ratios.vert.value != dc_fixpt_one.value ||
823 		scaler_data->ratios.vert_c.value != dc_fixpt_one.value;
824 
825 	if (!scaler_data->taps.h_taps) {
826 		/* Above logic determines scaling should be enabled even when there are no taps for
827 		 * certain cases. Hence do corrective active and disable scaling.
828 		 */
829 		plane->composition.scaler_info.enabled = false;
830 	} else if ((plane_state->ctx->dc->config.use_spl == true) &&
831 		(plane->composition.scaler_info.enabled == false)) {
832 		/* To enable sharpener for 1:1, scaler must be enabled.  If use_spl is set, then
833 		 *  allow case where ratio is 1 but taps > 1
834 		 */
835 		if ((scaler_data->taps.h_taps > 1) || (scaler_data->taps.v_taps > 1) ||
836 			(scaler_data->taps.h_taps_c > 1) || (scaler_data->taps.v_taps_c > 1))
837 			plane->composition.scaler_info.enabled = true;
838 	}
839 
840 	/* always_scale is only used for debug purposes not used in production but has to be
841 	 * maintained for certain complainces. */
842 	if (plane_state->ctx->dc->debug.always_scale == true) {
843 		plane->composition.scaler_info.enabled = true;
844 	}
845 
846 	if (plane->composition.scaler_info.enabled == false) {
847 		plane->composition.scaler_info.plane0.h_ratio = 1.0;
848 		plane->composition.scaler_info.plane0.v_ratio = 1.0;
849 		plane->composition.scaler_info.plane1.h_ratio = 1.0;
850 		plane->composition.scaler_info.plane1.v_ratio = 1.0;
851 	} else {
852 		plane->composition.scaler_info.plane0.h_ratio = (double)scaler_data->ratios.horz.value / (1ULL << 32);
853 		plane->composition.scaler_info.plane0.v_ratio = (double)scaler_data->ratios.vert.value / (1ULL << 32);
854 		plane->composition.scaler_info.plane1.h_ratio = (double)scaler_data->ratios.horz_c.value / (1ULL << 32);
855 		plane->composition.scaler_info.plane1.v_ratio = (double)scaler_data->ratios.vert_c.value / (1ULL << 32);
856 	}
857 
858 	if (!scaler_data->taps.h_taps) {
859 		plane->composition.scaler_info.plane0.h_taps = 1;
860 		plane->composition.scaler_info.plane1.h_taps = 1;
861 	} else {
862 		plane->composition.scaler_info.plane0.h_taps = scaler_data->taps.h_taps;
863 		plane->composition.scaler_info.plane1.h_taps = scaler_data->taps.h_taps_c;
864 	}
865 	if (!scaler_data->taps.v_taps) {
866 		plane->composition.scaler_info.plane0.v_taps = 1;
867 		plane->composition.scaler_info.plane1.v_taps = 1;
868 	} else {
869 		plane->composition.scaler_info.plane0.v_taps = scaler_data->taps.v_taps;
870 		plane->composition.scaler_info.plane1.v_taps = scaler_data->taps.v_taps_c;
871 	}
872 
873 	plane->composition.viewport.stationary = false;
874 
875 	if (plane_state->mcm_luts.lut3d_data.lut3d_src == DC_CM2_TRANSFER_FUNC_SOURCE_VIDMEM) {
876 		plane->tdlut.setup_for_tdlut = true;
877 
878 		switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.layout) {
879 		case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_RGB:
880 		case DC_CM2_GPU_MEM_LAYOUT_3D_SWIZZLE_LINEAR_BGR:
881 			plane->tdlut.tdlut_addressing_mode = dml2_tdlut_sw_linear;
882 			break;
883 		case DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR:
884 			plane->tdlut.tdlut_addressing_mode = dml2_tdlut_simple_linear;
885 			break;
886 		}
887 
888 		switch (plane_state->mcm_luts.lut3d_data.gpu_mem_params.size) {
889 		case DC_CM2_GPU_MEM_SIZE_171717:
890 			plane->tdlut.tdlut_width_mode = dml2_tdlut_width_17_cube;
891 			break;
892 		case DC_CM2_GPU_MEM_SIZE_333333:
893 			plane->tdlut.tdlut_width_mode = dml2_tdlut_width_33_cube;
894 			break;
895 		case DC_CM2_GPU_MEM_SIZE_TRANSFORMED:
896 			//plane->tdlut.tdlut_width_mode = dml2_tdlut_width_flatten; // dml2_tdlut_width_flatten undefined
897 			break;
898 		}
899 	}
900 	plane->tdlut.setup_for_tdlut |= dml_ctx->config.force_tdlut_enable;
901 
902 	plane->dynamic_meta_data.enable = false;
903 	plane->dynamic_meta_data.lines_before_active_required = 0;
904 	plane->dynamic_meta_data.transmitted_bytes = 0;
905 
906 	plane->composition.scaler_info.rect_out_width = plane_state->dst_rect.width;
907 	plane->composition.rotation_angle = (enum dml2_rotation_angle) plane_state->rotation;
908 	plane->stream_index = stream_index;
909 
910 	plane->overrides.gpuvm_min_page_size_kbytes = 256;
911 
912 	plane->immediate_flip = plane_state->flip_immediate;
913 
914 	plane->composition.rect_out_height_spans_vactive =
915 		plane_state->dst_rect.height >= stream->src.height &&
916 		stream->dst.height >= stream->timing.v_addressable;
917 }
918 
919 //TODO : Could be possibly moved to a common helper layer.
dml21_wrapper_get_plane_id(const struct dc_state * context,unsigned int stream_id,const struct dc_plane_state * plane,unsigned int * plane_id)920 static bool dml21_wrapper_get_plane_id(const struct dc_state *context, unsigned int stream_id, const struct dc_plane_state *plane, unsigned int *plane_id)
921 {
922 	int i, j;
923 
924 	if (!plane_id)
925 		return false;
926 
927 	for (i = 0; i < context->stream_count; i++) {
928 		if (context->streams[i]->stream_id == stream_id) {
929 			for (j = 0; j < context->stream_status[i].plane_count; j++) {
930 				if (context->stream_status[i].plane_states[j] == plane) {
931 					*plane_id = (i << 16) | j;
932 					return true;
933 				}
934 			}
935 		}
936 	}
937 
938 	return false;
939 }
940 
map_stream_to_dml21_display_cfg(const struct dml2_context * dml_ctx,const struct dc_stream_state * stream)941 static unsigned int map_stream_to_dml21_display_cfg(const struct dml2_context *dml_ctx, const struct dc_stream_state *stream)
942 {
943 	int i = 0;
944 	int location = -1;
945 
946 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
947 		if (dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[i] && dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i] == stream->stream_id) {
948 			location = i;
949 			break;
950 		}
951 	}
952 
953 	return location;
954 }
955 
map_plane_to_dml21_display_cfg(const struct dml2_context * dml_ctx,unsigned int stream_id,const struct dc_plane_state * plane,const struct dc_state * context)956 unsigned int map_plane_to_dml21_display_cfg(const struct dml2_context *dml_ctx, unsigned int stream_id,
957 		const struct dc_plane_state *plane, const struct dc_state *context)
958 {
959 	unsigned int plane_id;
960 	int i = 0;
961 	int location = -1;
962 
963 	if (!dml21_wrapper_get_plane_id(context, stream_id, plane, &plane_id)) {
964 		ASSERT(false);
965 		return -1;
966 	}
967 
968 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
969 		if (dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[i] && dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i] == plane_id) {
970 			location = i;
971 			break;
972 		}
973 	}
974 
975 	return location;
976 }
977 
dml21_force_pstate_method_to_uclk_state_change_strategy(enum dml2_force_pstate_methods force_pstate_method)978 static enum dml2_uclk_pstate_change_strategy dml21_force_pstate_method_to_uclk_state_change_strategy(enum dml2_force_pstate_methods force_pstate_method)
979 {
980 	enum dml2_uclk_pstate_change_strategy val = dml2_uclk_pstate_change_strategy_auto;
981 
982 	switch (force_pstate_method) {
983 	case dml2_force_pstate_method_vactive:
984 		val = dml2_uclk_pstate_change_strategy_force_vactive;
985 		break;
986 	case dml2_force_pstate_method_vblank:
987 		val = dml2_uclk_pstate_change_strategy_force_vblank;
988 		break;
989 	case dml2_force_pstate_method_drr:
990 		val = dml2_uclk_pstate_change_strategy_force_drr;
991 		break;
992 	case dml2_force_pstate_method_subvp:
993 		val = dml2_uclk_pstate_change_strategy_force_mall_svp;
994 		break;
995 	case dml2_force_pstate_method_auto:
996 	default:
997 		val = dml2_uclk_pstate_change_strategy_auto;
998 	}
999 
1000 	return val;
1001 }
1002 
dml21_map_dc_state_into_dml_display_cfg(const struct dc * in_dc,struct dc_state * context,struct dml2_context * dml_ctx)1003 bool dml21_map_dc_state_into_dml_display_cfg(const struct dc *in_dc, struct dc_state *context, struct dml2_context *dml_ctx)
1004 {
1005 	int stream_index, plane_index;
1006 	int disp_cfg_stream_location, disp_cfg_plane_location;
1007 	struct dml2_display_cfg *dml_dispcfg = &dml_ctx->v21.display_config;
1008 	unsigned int plane_count = 0;
1009 
1010 	memset(&dml_ctx->v21.dml_to_dc_pipe_mapping, 0, sizeof(struct dml2_dml_to_dc_pipe_mapping));
1011 
1012 	dml_dispcfg->gpuvm_enable = dml_ctx->config.gpuvm_enable;
1013 	dml_dispcfg->gpuvm_max_page_table_levels = 4;
1014 	dml_dispcfg->hostvm_enable = false;
1015 	dml_dispcfg->minimize_det_reallocation = true;
1016 	dml_dispcfg->overrides.enable_subvp_implicit_pmo = true;
1017 
1018 	if (in_dc->debug.disable_unbounded_requesting) {
1019 		dml_dispcfg->overrides.hw.force_unbounded_requesting.enable = true;
1020 		dml_dispcfg->overrides.hw.force_unbounded_requesting.value = false;
1021 	}
1022 
1023 	for (stream_index = 0; stream_index < context->stream_count; stream_index++) {
1024 		disp_cfg_stream_location = map_stream_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]);
1025 
1026 		if (disp_cfg_stream_location < 0)
1027 			disp_cfg_stream_location = dml_dispcfg->num_streams++;
1028 
1029 		ASSERT(disp_cfg_stream_location >= 0 && disp_cfg_stream_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
1030 		populate_dml21_timing_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, context->streams[stream_index], dml_ctx);
1031 		adjust_dml21_hblank_timing_config_from_pipe_ctx(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].timing, &context->res_ctx.pipe_ctx[stream_index]);
1032 		populate_dml21_output_config_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location].output, context->streams[stream_index], &context->res_ctx.pipe_ctx[stream_index]);
1033 		populate_dml21_stream_overrides_from_stream_state(&dml_dispcfg->stream_descriptors[disp_cfg_stream_location], context->streams[stream_index], &context->stream_status[stream_index]);
1034 
1035 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.fclk_pstate = dml2_twait_budgeting_setting_if_needed;
1036 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.uclk_pstate = dml2_twait_budgeting_setting_if_needed;
1037 		dml_dispcfg->stream_descriptors[disp_cfg_stream_location].overrides.hw.twait_budgeting.stutter_enter_exit = dml2_twait_budgeting_setting_if_needed;
1038 
1039 		dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[disp_cfg_stream_location] = context->streams[stream_index]->stream_id;
1040 		dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id_valid[disp_cfg_stream_location] = true;
1041 
1042 		if (context->stream_status[stream_index].plane_count == 0) {
1043 			disp_cfg_plane_location = dml_dispcfg->num_planes++;
1044 			populate_dml21_dummy_surface_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->streams[stream_index]);
1045 			populate_dml21_dummy_plane_cfg(&dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->streams[stream_index]);
1046 			dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
1047 		} else {
1048 			for (plane_index = 0; plane_index < context->stream_status[stream_index].plane_count; plane_index++) {
1049 				disp_cfg_plane_location = map_plane_to_dml21_display_cfg(dml_ctx, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], context);
1050 
1051 				if (disp_cfg_plane_location < 0)
1052 					disp_cfg_plane_location = dml_dispcfg->num_planes++;
1053 
1054 				ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location < __DML2_WRAPPER_MAX_STREAMS_PLANES__);
1055 
1056 				populate_dml21_surface_config_from_plane_state(in_dc, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location].surface, context->stream_status[stream_index].plane_states[plane_index]);
1057 				populate_dml21_plane_config_from_plane_state(dml_ctx, &dml_dispcfg->plane_descriptors[disp_cfg_plane_location], context->stream_status[stream_index].plane_states[plane_index], context, stream_index);
1058 				dml_dispcfg->plane_descriptors[disp_cfg_plane_location].stream_index = disp_cfg_stream_location;
1059 
1060 				if (dml21_wrapper_get_plane_id(context, context->streams[stream_index]->stream_id, context->stream_status[stream_index].plane_states[plane_index], &dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[disp_cfg_plane_location]))
1061 					dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id_valid[disp_cfg_plane_location] = true;
1062 
1063 				/* apply forced pstate policy */
1064 				if (dml_ctx->config.pmo.force_pstate_method_enable) {
1065 					dml_dispcfg->plane_descriptors[disp_cfg_plane_location].overrides.uclk_pstate_change_strategy =
1066 							dml21_force_pstate_method_to_uclk_state_change_strategy(dml_ctx->config.pmo.force_pstate_method_values[stream_index]);
1067 				}
1068 
1069 				plane_count++;
1070 			}
1071 		}
1072 	}
1073 
1074 	if (plane_count == 0) {
1075 		dml_dispcfg->overrides.all_streams_blanked = true;
1076 	}
1077 
1078 	return true;
1079 }
1080 
dml21_copy_clocks_to_dc_state(struct dml2_context * in_ctx,struct dc_state * context)1081 void dml21_copy_clocks_to_dc_state(struct dml2_context *in_ctx, struct dc_state *context)
1082 {
1083 	/* TODO these should be the max of active, svp prefetch and idle should be tracked seperately */
1084 	context->bw_ctx.bw.dcn.clk.dispclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dispclk_khz;
1085 	context->bw_ctx.bw.dcn.clk.dcfclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.dcfclk_khz;
1086 	context->bw_ctx.bw.dcn.clk.dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.uclk_khz;
1087 	context->bw_ctx.bw.dcn.clk.fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.active.fclk_khz;
1088 	context->bw_ctx.bw.dcn.clk.idle_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.uclk_khz;
1089 	context->bw_ctx.bw.dcn.clk.idle_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.idle.fclk_khz;
1090 	context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.deepsleep_dcfclk_khz;
1091 	context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = in_ctx->v21.mode_programming.programming->fclk_pstate_supported;
1092 	context->bw_ctx.bw.dcn.clk.p_state_change_support = in_ctx->v21.mode_programming.programming->uclk_pstate_supported;
1093 	context->bw_ctx.bw.dcn.clk.dtbclk_en = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz > 0;
1094 	context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.dtbrefclk_khz;
1095 	context->bw_ctx.bw.dcn.clk.socclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.socclk_khz;
1096 	context->bw_ctx.bw.dcn.clk.subvp_prefetch_dramclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.uclk_khz;
1097 	context->bw_ctx.bw.dcn.clk.subvp_prefetch_fclk_khz = in_ctx->v21.mode_programming.programming->min_clocks.dcn4x.svp_prefetch_no_throttle.fclk_khz;
1098 }
1099 
wm_set_index_to_dc_wm_set(union dcn_watermark_set * watermarks,const enum dml2_dchub_watermark_reg_set_index wm_index)1100 static struct dml2_dchub_watermark_regs *wm_set_index_to_dc_wm_set(union dcn_watermark_set *watermarks, const enum dml2_dchub_watermark_reg_set_index wm_index)
1101 {
1102 	struct dml2_dchub_watermark_regs *wm_regs = NULL;
1103 
1104 	switch (wm_index) {
1105 	case DML2_DCHUB_WATERMARK_SET_A:
1106 		wm_regs = &watermarks->dcn4x.a;
1107 		break;
1108 	case DML2_DCHUB_WATERMARK_SET_B:
1109 		wm_regs = &watermarks->dcn4x.b;
1110 		break;
1111 	case DML2_DCHUB_WATERMARK_SET_C:
1112 		wm_regs = &watermarks->dcn4x.c;
1113 		break;
1114 	case DML2_DCHUB_WATERMARK_SET_D:
1115 		wm_regs = &watermarks->dcn4x.d;
1116 		break;
1117 	case DML2_DCHUB_WATERMARK_SET_NUM:
1118 	default:
1119 		/* invalid wm set index */
1120 		wm_regs = NULL;
1121 	}
1122 
1123 	return wm_regs;
1124 }
1125 
dml21_extract_watermark_sets(const struct dc * in_dc,union dcn_watermark_set * watermarks,struct dml2_context * in_ctx)1126 void dml21_extract_watermark_sets(const struct dc *in_dc, union dcn_watermark_set *watermarks, struct dml2_context *in_ctx)
1127 {
1128 	const struct dml2_display_cfg_programming *programming = in_ctx->v21.mode_programming.programming;
1129 
1130 	unsigned int wm_index;
1131 
1132 	/* copy watermark sets from DML */
1133 	for (wm_index = 0; wm_index < programming->global_regs.num_watermark_sets; wm_index++) {
1134 		struct dml2_dchub_watermark_regs *wm_regs = wm_set_index_to_dc_wm_set(watermarks, wm_index);
1135 
1136 		if (wm_regs)
1137 			memcpy(wm_regs,
1138 				&programming->global_regs.wm_regs[wm_index],
1139 				sizeof(struct dml2_dchub_watermark_regs));
1140 	}
1141 }
1142 
dml21_map_hw_resources(struct dml2_context * dml_ctx)1143 void dml21_map_hw_resources(struct dml2_context *dml_ctx)
1144 {
1145 	unsigned int i = 0;
1146 
1147 	for (i = 0; i < __DML2_WRAPPER_MAX_STREAMS_PLANES__; i++) {
1148 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[i] = dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_stream_id[i];
1149 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[i] = true;
1150 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id[i] = dml_ctx->v21.dml_to_dc_pipe_mapping.disp_cfg_to_plane_id[i];
1151 		dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id_valid[i] = true;
1152 	}
1153 
1154 }
1155 
dml21_get_pipe_mcache_config(struct dc_state * context,struct pipe_ctx * pipe_ctx,struct dml2_per_plane_programming * pln_prog,struct dml2_pipe_configuration_descriptor * mcache_pipe_config)1156 void dml21_get_pipe_mcache_config(
1157 	struct dc_state *context,
1158 	struct pipe_ctx *pipe_ctx,
1159 	struct dml2_per_plane_programming *pln_prog,
1160 	struct dml2_pipe_configuration_descriptor *mcache_pipe_config)
1161 {
1162 	mcache_pipe_config->plane0.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport.x;
1163 	mcache_pipe_config->plane0.viewport_width = pipe_ctx->plane_res.scl_data.viewport.width;
1164 
1165 	mcache_pipe_config->plane1.viewport_x_start = pipe_ctx->plane_res.scl_data.viewport_c.x;
1166 	mcache_pipe_config->plane1.viewport_width = pipe_ctx->plane_res.scl_data.viewport_c.width;
1167 
1168 	mcache_pipe_config->plane1_enabled =
1169 			dml21_is_plane1_enabled(pln_prog->plane_descriptor->pixel_format);
1170 }
1171 
dml21_set_dc_p_state_type(struct pipe_ctx * pipe_ctx,struct dml2_per_stream_programming * stream_programming,bool sub_vp_enabled)1172 void dml21_set_dc_p_state_type(
1173 		struct pipe_ctx *pipe_ctx,
1174 		struct dml2_per_stream_programming *stream_programming,
1175 		bool sub_vp_enabled)
1176 {
1177 	switch (stream_programming->uclk_pstate_method) {
1178 	case dml2_pstate_method_vactive:
1179 	case dml2_pstate_method_fw_vactive_drr:
1180 		pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
1181 		break;
1182 	case dml2_pstate_method_vblank:
1183 	case dml2_pstate_method_fw_vblank_drr:
1184 		if (sub_vp_enabled)
1185 			pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
1186 		else
1187 			pipe_ctx->p_state_type = P_STATE_V_BLANK;
1188 		break;
1189 	case dml2_pstate_method_fw_svp:
1190 	case dml2_pstate_method_fw_svp_drr:
1191 		pipe_ctx->p_state_type = P_STATE_SUB_VP;
1192 		break;
1193 	case dml2_pstate_method_fw_drr:
1194 		if (sub_vp_enabled)
1195 			pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
1196 		else
1197 			pipe_ctx->p_state_type = P_STATE_FPO;
1198 		break;
1199 	default:
1200 		pipe_ctx->p_state_type = P_STATE_UNKNOWN;
1201 		break;
1202 	}
1203 }
1204 
1205