xref: /linux/drivers/gpu/drm/amd/display/dc/link/link_factory.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 /*
2  * Copyright 2023 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 /* FILE POLICY AND INTENDED USAGE:
27  * This file owns the creation/destruction of link structure.
28  */
29 #include "link_factory.h"
30 #include "link_detection.h"
31 #include "link_resource.h"
32 #include "link_validation.h"
33 #include "link_dpms.h"
34 #include "accessories/link_dp_cts.h"
35 #include "accessories/link_dp_trace.h"
36 #include "protocols/link_ddc.h"
37 #include "protocols/link_dp_capability.h"
38 #include "protocols/link_dp_dpia_bw.h"
39 #include "protocols/link_dp_dpia.h"
40 #include "protocols/link_dp_irq_handler.h"
41 #include "protocols/link_dp_phy.h"
42 #include "protocols/link_dp_training.h"
43 #include "protocols/link_edp_panel_control.h"
44 #include "protocols/link_dp_panel_replay.h"
45 #include "protocols/link_hpd.h"
46 #include "gpio_service_interface.h"
47 #include "atomfirmware.h"
48 
49 #define DC_LOGGER \
50 	dc_ctx->logger
51 #define DC_LOGGER_INIT(logger)
52 
53 #define LINK_INFO(...) \
54 	DC_LOG_HW_HOTPLUG(  \
55 		__VA_ARGS__)
56 
57 /* link factory owns the creation/destruction of link structures. */
construct_link_service_factory(struct link_service * link_srv)58 static void construct_link_service_factory(struct link_service *link_srv)
59 {
60 
61 	link_srv->create_link = link_create;
62 	link_srv->destroy_link = link_destroy;
63 }
64 
65 /* link_detection manages link detection states and receiver states by using
66  * various link protocols. It also provides helper functions to interpret
67  * certain capabilities or status based on the states it manages or retrieve
68  * them directly from connected receivers.
69  */
construct_link_service_detection(struct link_service * link_srv)70 static void construct_link_service_detection(struct link_service *link_srv)
71 {
72 	link_srv->detect_link = link_detect;
73 	link_srv->detect_connection_type = link_detect_connection_type;
74 	link_srv->add_remote_sink = link_add_remote_sink;
75 	link_srv->remove_remote_sink = link_remove_remote_sink;
76 	link_srv->get_hpd_state = link_get_hpd_state;
77 	link_srv->enable_hpd = link_enable_hpd;
78 	link_srv->disable_hpd = link_disable_hpd;
79 	link_srv->enable_hpd_filter = link_enable_hpd_filter;
80 	link_srv->reset_cur_dp_mst_topology = link_reset_cur_dp_mst_topology;
81 	link_srv->get_status = link_get_status;
82 	link_srv->is_hdcp1x_supported = link_is_hdcp14;
83 	link_srv->is_hdcp2x_supported = link_is_hdcp22;
84 	link_srv->clear_dprx_states = link_clear_dprx_states;
85 }
86 
87 /* link resource implements accessors to link resource. */
construct_link_service_resource(struct link_service * link_srv)88 static void construct_link_service_resource(struct link_service *link_srv)
89 {
90 	link_srv->get_cur_res_map = link_get_cur_res_map;
91 	link_srv->restore_res_map = link_restore_res_map;
92 	link_srv->get_cur_link_res = link_get_cur_link_res;
93 }
94 
95 /* link validation owns timing validation against various link limitations. (ex.
96  * link bandwidth, receiver capability or our hardware capability) It also
97  * provides helper functions exposing bandwidth formulas used in validation.
98  */
construct_link_service_validation(struct link_service * link_srv)99 static void construct_link_service_validation(struct link_service *link_srv)
100 {
101 	link_srv->validate_mode_timing = link_validate_mode_timing;
102 	link_srv->dp_link_bandwidth_kbps = dp_link_bandwidth_kbps;
103 	link_srv->validate_dp_tunnel_bandwidth = link_validate_dp_tunnel_bandwidth;
104 	link_srv->dp_required_hblank_size_bytes = dp_required_hblank_size_bytes;
105 }
106 
107 /* link dpms owns the programming sequence of stream's dpms state associated
108  * with the link and link's enable/disable sequences as result of the stream's
109  * dpms state change.
110  */
construct_link_service_dpms(struct link_service * link_srv)111 static void construct_link_service_dpms(struct link_service *link_srv)
112 {
113 	link_srv->set_dpms_on = link_set_dpms_on;
114 	link_srv->set_dpms_off = link_set_dpms_off;
115 	link_srv->resume = link_resume;
116 	link_srv->blank_all_dp_displays = link_blank_all_dp_displays;
117 	link_srv->blank_all_edp_displays = link_blank_all_edp_displays;
118 	link_srv->blank_dp_stream = link_blank_dp_stream;
119 	link_srv->increase_mst_payload = link_increase_mst_payload;
120 	link_srv->reduce_mst_payload = link_reduce_mst_payload;
121 	link_srv->set_dsc_on_stream = link_set_dsc_on_stream;
122 	link_srv->set_dsc_enable = link_set_dsc_enable;
123 	link_srv->update_dsc_config = link_update_dsc_config;
124 }
125 
126 /* link ddc implements generic display communication protocols such as i2c, aux
127  * and scdc. It should not contain any specific applications of these
128  * protocols such as display capability query, detection, or handshaking such as
129  * link training.
130  */
construct_link_service_ddc(struct link_service * link_srv)131 static void construct_link_service_ddc(struct link_service *link_srv)
132 {
133 	link_srv->create_ddc_service = link_create_ddc_service;
134 	link_srv->destroy_ddc_service = link_destroy_ddc_service;
135 	link_srv->query_ddc_data = link_query_ddc_data;
136 	link_srv->aux_transfer_raw = link_aux_transfer_raw;
137 	link_srv->configure_fixed_vs_pe_retimer = link_configure_fixed_vs_pe_retimer;
138 	link_srv->aux_transfer_with_retries_no_mutex =
139 			link_aux_transfer_with_retries_no_mutex;
140 	link_srv->is_in_aux_transaction_mode = link_is_in_aux_transaction_mode;
141 	link_srv->get_aux_defer_delay = link_get_aux_defer_delay;
142 }
143 
144 /* link dp capability implements dp specific link capability retrieval sequence.
145  * It is responsible for retrieving, parsing, overriding, deciding capability
146  * obtained from dp link. Link capability consists of encoders, DPRXs, cables,
147  * retimers, usb and all other possible backend capabilities.
148  */
construct_link_service_dp_capability(struct link_service * link_srv)149 static void construct_link_service_dp_capability(struct link_service *link_srv)
150 {
151 	link_srv->dp_is_sink_present = dp_is_sink_present;
152 	link_srv->dp_is_fec_supported = dp_is_fec_supported;
153 	link_srv->dp_is_128b_132b_signal = dp_is_128b_132b_signal;
154 	link_srv->dp_get_max_link_enc_cap = dp_get_max_link_enc_cap;
155 	link_srv->dp_get_verified_link_cap = dp_get_verified_link_cap;
156 	link_srv->dp_get_encoding_format = link_dp_get_encoding_format;
157 	link_srv->dp_should_enable_fec = dp_should_enable_fec;
158 	link_srv->dp_decide_link_settings = link_decide_link_settings;
159 	link_srv->dp_decide_tunnel_settings = link_decide_dp_tunnel_settings;
160 	link_srv->mst_decide_link_encoding_format =
161 			mst_decide_link_encoding_format;
162 	link_srv->edp_decide_link_settings = edp_decide_link_settings;
163 	link_srv->bw_kbps_from_raw_frl_link_rate_data =
164 			link_bw_kbps_from_raw_frl_link_rate_data;
165 	link_srv->dp_overwrite_extended_receiver_cap =
166 			dp_overwrite_extended_receiver_cap;
167 	link_srv->dp_decide_lttpr_mode = dp_decide_lttpr_mode;
168 	link_srv->dp_get_lttpr_count = dp_get_lttpr_count;
169 	link_srv->edp_get_alpm_support = edp_get_alpm_support;
170 }
171 
172 /* link dp phy/dpia implements basic dp phy/dpia functionality such as
173  * enable/disable output and set lane/drive settings. It is responsible for
174  * maintaining and update software state representing current phy/dpia status
175  * such as current link settings.
176  */
construct_link_service_dp_phy_or_dpia(struct link_service * link_srv)177 static void construct_link_service_dp_phy_or_dpia(struct link_service *link_srv)
178 {
179 	link_srv->dpia_handle_usb4_bandwidth_allocation_for_link =
180 			dpia_handle_usb4_bandwidth_allocation_for_link;
181 	link_srv->dp_set_drive_settings = dp_set_drive_settings;
182 	link_srv->dpcd_write_rx_power_ctrl = dpcd_write_rx_power_ctrl;
183 }
184 
185 /* link dp irq handler implements DP HPD short pulse handling sequence according
186  * to DP specifications
187  */
construct_link_service_dp_irq_handler(struct link_service * link_srv)188 static void construct_link_service_dp_irq_handler(struct link_service *link_srv)
189 {
190 	link_srv->dp_parse_link_loss_status = dp_parse_link_loss_status;
191 	link_srv->dp_should_allow_hpd_rx_irq = dp_should_allow_hpd_rx_irq;
192 	link_srv->dp_handle_link_loss = dp_handle_link_loss;
193 	link_srv->dp_read_hpd_rx_irq_data = dp_read_hpd_rx_irq_data;
194 	link_srv->dp_handle_hpd_rx_irq = dp_handle_hpd_rx_irq;
195 }
196 
197 /* link edp panel control implements retrieval and configuration of eDP panel
198  * features such as PSR and ABM and it also manages specs defined eDP panel
199  * power sequences.
200  */
construct_link_service_edp_panel_control(struct link_service * link_srv)201 static void construct_link_service_edp_panel_control(struct link_service *link_srv)
202 {
203 	link_srv->edp_panel_backlight_power_on = edp_panel_backlight_power_on;
204 	link_srv->edp_get_backlight_level = edp_get_backlight_level;
205 	link_srv->edp_get_backlight_level_nits = edp_get_backlight_level_nits;
206 	link_srv->edp_set_backlight_level = edp_set_backlight_level;
207 	link_srv->edp_set_backlight_level_nits = edp_set_backlight_level_nits;
208 	link_srv->edp_get_target_backlight_pwm = edp_get_target_backlight_pwm;
209 	link_srv->edp_get_psr_state = edp_get_psr_state;
210 	link_srv->edp_set_psr_allow_active = edp_set_psr_allow_active;
211 	link_srv->edp_setup_psr = edp_setup_psr;
212 	link_srv->edp_set_sink_vtotal_in_psr_active =
213 			edp_set_sink_vtotal_in_psr_active;
214 	link_srv->edp_get_psr_residency = edp_get_psr_residency;
215 
216 	link_srv->edp_get_replay_state = edp_get_replay_state;
217 	link_srv->edp_set_replay_allow_active = edp_set_replay_allow_active;
218 	link_srv->edp_send_replay_cmd = edp_send_replay_cmd;
219 	link_srv->edp_set_coasting_vtotal = edp_set_coasting_vtotal;
220 	link_srv->edp_replay_residency = edp_replay_residency;
221 	link_srv->edp_set_replay_power_opt_and_coasting_vtotal = edp_set_replay_power_opt_and_coasting_vtotal;
222 
223 	link_srv->edp_wait_for_t12 = edp_wait_for_t12;
224 	link_srv->edp_is_ilr_optimization_required =
225 			edp_is_ilr_optimization_required;
226 	link_srv->edp_backlight_enable_aux = edp_backlight_enable_aux;
227 	link_srv->edp_add_delay_for_T9 = edp_add_delay_for_T9;
228 	link_srv->edp_receiver_ready_T9 = edp_receiver_ready_T9;
229 	link_srv->edp_receiver_ready_T7 = edp_receiver_ready_T7;
230 	link_srv->edp_power_alpm_dpcd_enable = edp_power_alpm_dpcd_enable;
231 	link_srv->edp_set_panel_power = edp_set_panel_power;
232 }
233 
234 /* link dp panel replay implements DP panel replay functionality.
235  */
construct_link_service_dp_panel_replay(struct link_service * link_srv)236 static void construct_link_service_dp_panel_replay(struct link_service *link_srv)
237 {
238 	link_srv->dp_setup_replay = dp_setup_replay;
239 	link_srv->dp_pr_get_panel_inst = dp_pr_get_panel_inst;
240 	link_srv->dp_pr_enable = dp_pr_enable;
241 	link_srv->dp_pr_update_state = dp_pr_update_state;
242 	link_srv->dp_pr_set_general_cmd = dp_pr_set_general_cmd;
243 	link_srv->dp_pr_get_state = dp_pr_get_state;
244 }
245 
246 /* link dp cts implements dp compliance test automation protocols and manual
247  * testing interfaces for debugging and certification purpose.
248  */
construct_link_service_dp_cts(struct link_service * link_srv)249 static void construct_link_service_dp_cts(struct link_service *link_srv)
250 {
251 	link_srv->dp_handle_automated_test = dp_handle_automated_test;
252 	link_srv->dp_set_test_pattern = dp_set_test_pattern;
253 	link_srv->dp_set_preferred_link_settings =
254 			dp_set_preferred_link_settings;
255 	link_srv->dp_set_preferred_training_settings =
256 			dp_set_preferred_training_settings;
257 }
258 
259 /* link dp trace implements tracing interfaces for tracking major dp sequences
260  * including execution status and timestamps
261  */
construct_link_service_dp_trace(struct link_service * link_srv)262 static void construct_link_service_dp_trace(struct link_service *link_srv)
263 {
264 	link_srv->dp_trace_is_initialized = dp_trace_is_initialized;
265 	link_srv->dp_trace_set_is_logged_flag = dp_trace_set_is_logged_flag;
266 	link_srv->dp_trace_is_logged = dp_trace_is_logged;
267 	link_srv->dp_trace_get_lt_end_timestamp = dp_trace_get_lt_end_timestamp;
268 	link_srv->dp_trace_get_lt_counts = dp_trace_get_lt_counts;
269 	link_srv->dp_trace_get_link_loss_count = dp_trace_get_link_loss_count;
270 	link_srv->dp_trace_set_edp_power_timestamp =
271 			dp_trace_set_edp_power_timestamp;
272 	link_srv->dp_trace_get_edp_poweron_timestamp =
273 			dp_trace_get_edp_poweron_timestamp;
274 	link_srv->dp_trace_get_edp_poweroff_timestamp =
275 			dp_trace_get_edp_poweroff_timestamp;
276 	link_srv->dp_trace_source_sequence = dp_trace_source_sequence;
277 }
278 
construct_link_service(struct link_service * link_srv)279 static void construct_link_service(struct link_service *link_srv)
280 {
281 	/* All link service functions should fall under some sub categories.
282 	 * If a new function doesn't perfectly fall under an existing sub
283 	 * category, it must be that you are either adding a whole new aspect of
284 	 * responsibility to link service or something doesn't belong to link
285 	 * service. In that case please contact the arch owner to arrange a
286 	 * design review meeting.
287 	 */
288 	construct_link_service_factory(link_srv);
289 	construct_link_service_detection(link_srv);
290 	construct_link_service_resource(link_srv);
291 	construct_link_service_validation(link_srv);
292 	construct_link_service_dpms(link_srv);
293 	construct_link_service_ddc(link_srv);
294 	construct_link_service_dp_capability(link_srv);
295 	construct_link_service_dp_phy_or_dpia(link_srv);
296 	construct_link_service_dp_irq_handler(link_srv);
297 	construct_link_service_edp_panel_control(link_srv);
298 	construct_link_service_dp_panel_replay(link_srv);
299 	construct_link_service_dp_cts(link_srv);
300 	construct_link_service_dp_trace(link_srv);
301 }
302 
link_create_link_service(void)303 struct link_service *link_create_link_service(void)
304 {
305 	struct link_service *link_srv = kzalloc_obj(*link_srv);
306 
307 	if (link_srv == NULL)
308 		goto fail;
309 
310 	construct_link_service(link_srv);
311 
312 	return link_srv;
313 fail:
314 	return NULL;
315 }
316 
link_destroy_link_service(struct link_service ** link_srv)317 void link_destroy_link_service(struct link_service **link_srv)
318 {
319 	kfree(*link_srv);
320 	*link_srv = NULL;
321 }
322 
translate_encoder_to_transmitter(struct graphics_object_id encoder)323 static enum transmitter translate_encoder_to_transmitter(
324 		struct graphics_object_id encoder)
325 {
326 	switch (encoder.id) {
327 	case ENCODER_ID_INTERNAL_UNIPHY:
328 		switch (encoder.enum_id) {
329 		case ENUM_ID_1:
330 			return TRANSMITTER_UNIPHY_A;
331 		case ENUM_ID_2:
332 			return TRANSMITTER_UNIPHY_B;
333 		default:
334 			return TRANSMITTER_UNKNOWN;
335 		}
336 	break;
337 	case ENCODER_ID_INTERNAL_UNIPHY1:
338 		switch (encoder.enum_id) {
339 		case ENUM_ID_1:
340 			return TRANSMITTER_UNIPHY_C;
341 		case ENUM_ID_2:
342 			return TRANSMITTER_UNIPHY_D;
343 		default:
344 			return TRANSMITTER_UNKNOWN;
345 		}
346 	break;
347 	case ENCODER_ID_INTERNAL_UNIPHY2:
348 		switch (encoder.enum_id) {
349 		case ENUM_ID_1:
350 			return TRANSMITTER_UNIPHY_E;
351 		case ENUM_ID_2:
352 			return TRANSMITTER_UNIPHY_F;
353 		default:
354 			return TRANSMITTER_UNKNOWN;
355 		}
356 	break;
357 	case ENCODER_ID_INTERNAL_UNIPHY3:
358 		switch (encoder.enum_id) {
359 		case ENUM_ID_1:
360 			return TRANSMITTER_UNIPHY_G;
361 		default:
362 			return TRANSMITTER_UNKNOWN;
363 		}
364 	break;
365 	default:
366 		return TRANSMITTER_UNKNOWN;
367 	}
368 }
369 
link_destruct(struct dc_link * link)370 static void link_destruct(struct dc_link *link)
371 {
372 	int i;
373 
374 	if (link->ddc)
375 		link_destroy_ddc_service(&link->ddc);
376 
377 	if (link->panel_cntl)
378 		link->panel_cntl->funcs->destroy(&link->panel_cntl);
379 
380 	if (link->link_enc && !link->is_dig_mapping_flexible) {
381 		/* Update link encoder resource tracking variables. These are used for
382 		 * the dynamic assignment of link encoders to streams. Virtual links
383 		 * are not assigned encoder resources on creation.
384 		 */
385 		if (link->link_id.id != CONNECTOR_ID_VIRTUAL && link->eng_id != ENGINE_ID_UNKNOWN) {
386 			link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = NULL;
387 			link->dc->res_pool->dig_link_enc_count--;
388 		}
389 		link->link_enc->funcs->destroy(&link->link_enc);
390 	}
391 
392 	if (link->local_sink)
393 		dc_sink_release(link->local_sink);
394 
395 	for (i = 0; i < link->sink_count; ++i)
396 		dc_sink_release(link->remote_sinks[i]);
397 }
398 
get_ddc_line(struct dc_link * link)399 static enum channel_id get_ddc_line(struct dc_link *link)
400 {
401 	struct ddc *ddc;
402 	enum channel_id channel;
403 
404 	channel = CHANNEL_ID_UNKNOWN;
405 
406 	ddc = get_ddc_pin(link->ddc);
407 
408 	if (ddc) {
409 		switch (dal_ddc_get_line(ddc)) {
410 		case GPIO_DDC_LINE_DDC1:
411 			channel = CHANNEL_ID_DDC1;
412 			break;
413 		case GPIO_DDC_LINE_DDC2:
414 			channel = CHANNEL_ID_DDC2;
415 			break;
416 		case GPIO_DDC_LINE_DDC3:
417 			channel = CHANNEL_ID_DDC3;
418 			break;
419 		case GPIO_DDC_LINE_DDC4:
420 			channel = CHANNEL_ID_DDC4;
421 			break;
422 		case GPIO_DDC_LINE_DDC5:
423 			channel = CHANNEL_ID_DDC5;
424 			break;
425 		case GPIO_DDC_LINE_DDC6:
426 			channel = CHANNEL_ID_DDC6;
427 			break;
428 		case GPIO_DDC_LINE_DDC_VGA:
429 			channel = CHANNEL_ID_DDC_VGA;
430 			break;
431 		case GPIO_DDC_LINE_I2C_PAD:
432 			channel = CHANNEL_ID_I2C_PAD;
433 			break;
434 		default:
435 			BREAK_TO_DEBUGGER();
436 			break;
437 		}
438 	}
439 
440 	return channel;
441 }
442 
find_analog_engine(struct dc_link * link,struct graphics_object_id * enc)443 static enum engine_id find_analog_engine(struct dc_link *link, struct graphics_object_id *enc)
444 {
445 	struct dc_bios *bp = link->ctx->dc_bios;
446 	enum bp_result bp_result = BP_RESULT_OK;
447 	int i;
448 
449 	for (i = 0; i < 3; i++) {
450 		bp_result = bp->funcs->get_src_obj(bp, link->link_id, i, enc);
451 
452 		if (bp_result != BP_RESULT_OK)
453 			return ENGINE_ID_UNKNOWN;
454 
455 		switch (enc->id) {
456 		case ENCODER_ID_INTERNAL_DAC1:
457 		case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
458 			return ENGINE_ID_DACA;
459 		case ENCODER_ID_INTERNAL_DAC2:
460 		case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
461 			return ENGINE_ID_DACB;
462 		}
463 	}
464 
465 	memset(enc, 0, sizeof(*enc));
466 	return ENGINE_ID_UNKNOWN;
467 }
468 
analog_engine_supported(const enum engine_id engine_id)469 static bool analog_engine_supported(const enum engine_id engine_id)
470 {
471 	return engine_id == ENGINE_ID_DACA ||
472 		engine_id == ENGINE_ID_DACB;
473 }
474 
construct_phy(struct dc_link * link,const struct link_init_data * init_params)475 static bool construct_phy(struct dc_link *link,
476 			      const struct link_init_data *init_params)
477 {
478 	uint8_t i;
479 	struct ddc_service_init_data ddc_service_init_data = { 0 };
480 	struct dc_context *dc_ctx = init_params->ctx;
481 	struct encoder_init_data enc_init_data = { 0 };
482 	struct panel_cntl_init_data panel_cntl_init_data = { 0 };
483 	struct dc_bios *bios = init_params->dc->ctx->dc_bios;
484 	const struct dc_vbios_funcs *bp_funcs = bios->funcs;
485 	struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
486 	struct graphics_object_id link_encoder = { 0 };
487 	enum transmitter transmitter_from_encoder;
488 	enum engine_id link_analog_engine;
489 
490 	DC_LOGGER_INIT(dc_ctx->logger);
491 
492 	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
493 	link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
494 	link->irq_source_read_request = DC_IRQ_SOURCE_INVALID;
495 	link->link_status.dpcd_caps = &link->dpcd_caps;
496 
497 	link->dc = init_params->dc;
498 	link->ctx = dc_ctx;
499 	link->link_index = init_params->link_index;
500 
501 	memset(&link->preferred_training_settings, 0,
502 	       sizeof(struct dc_link_training_overrides));
503 	memset(&link->preferred_link_setting, 0,
504 	       sizeof(struct dc_link_settings));
505 
506 	link->link_id =
507 		bios->funcs->get_connector_id(bios, init_params->connector_index);
508 
509 	link->ep_type = DISPLAY_ENDPOINT_PHY;
510 
511 	DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id);
512 
513 	/* Determine early if the link has any supported encoders,
514 	 * so that we avoid initializing DDC and HPD, etc.
515 	 */
516 	bp_funcs->get_src_obj(bios, link->link_id, 0, &link_encoder);
517 	transmitter_from_encoder = translate_encoder_to_transmitter(link_encoder);
518 	link_analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder);
519 
520 	if (transmitter_from_encoder == TRANSMITTER_UNKNOWN &&
521 	    !analog_engine_supported(link_analog_engine)) {
522 		DC_LOG_WARNING("link_id %d has unsupported encoder\n", link->link_id.id);
523 		goto create_fail;
524 	}
525 
526 	if (bios->funcs->get_disp_connector_caps_info) {
527 		bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
528 		link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
529 		DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
530 	}
531 
532 	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
533 		dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
534 				     __func__, init_params->connector_index,
535 				     link->link_id.type, OBJECT_TYPE_CONNECTOR);
536 		goto create_fail;
537 	}
538 
539 	if (link->dc->res_pool->funcs->link_init)
540 		link->dc->res_pool->funcs->link_init(link);
541 
542 	ddc_service_init_data.ctx = link->ctx;
543 	ddc_service_init_data.id = link->link_id;
544 	ddc_service_init_data.link = link;
545 	link->ddc = link_create_ddc_service(&ddc_service_init_data);
546 
547 	if (!link->ddc) {
548 		DC_ERROR("Failed to create ddc_service!\n");
549 		goto ddc_create_fail;
550 	}
551 
552 	if (!link->ddc->ddc_pin) {
553 		DC_ERROR("Failed to get I2C info for connector!\n");
554 		goto ddc_create_fail;
555 	}
556 
557 	link->ddc_hw_inst =
558 		dal_ddc_get_line(get_ddc_pin(link->ddc));
559 
560 	enc_init_data.ctx = dc_ctx;
561 	enc_init_data.connector = link->link_id;
562 	enc_init_data.channel = get_ddc_line(link);
563 	enc_init_data.transmitter = transmitter_from_encoder;
564 	enc_init_data.encoder = link_encoder;
565 	enc_init_data.analog_engine = link_analog_engine;
566 	if (link->ctx->dce_version <= DCN_VERSION_4_01)
567 		enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
568 					      link->ctx->gpio_service);
569 	else
570 		enc_init_data.hpd_gpio = NULL;
571 	if (enc_init_data.hpd_gpio) {
572 		dal_gpio_open(enc_init_data.hpd_gpio, GPIO_MODE_INTERRUPT);
573 		dal_gpio_unlock_pin(enc_init_data.hpd_gpio);
574 		link->irq_source_hpd = dal_irq_get_source(enc_init_data.hpd_gpio);
575 		enc_init_data.hpd_source = get_hpd_line(link);
576 		link->hpd_src = enc_init_data.hpd_source;
577 
578 		DC_LOG_DC("BIOS object table - hpd_gpio id: %d", enc_init_data.hpd_gpio->id);
579 		DC_LOG_DC("BIOS object table - hpd_gpio en: %d", enc_init_data.hpd_gpio->en);
580 	} else {
581 		struct graphics_object_hpd_info hpd_info;
582 
583 		if (link->ctx->dc_bios->funcs->get_hpd_info(link->ctx->dc_bios, link->link_id, &hpd_info) == BP_RESULT_OK) {
584 			link->hpd_src = hpd_info.hpd_int_gpio_uid - 1;
585 			link->irq_source_hpd =  DC_IRQ_SOURCE_HPD1 + link->hpd_src;
586 			enc_init_data.hpd_source = link->hpd_src;
587 			DC_LOG_DC("BIOS object table - hpd_int_gpio_uid id: %d", hpd_info.hpd_int_gpio_uid);
588 		} else {
589 			ASSERT(0);
590 			enc_init_data.hpd_source = HPD_SOURCEID_UNKNOWN;
591 		}
592 	}
593 
594 	link->link_enc =
595 		link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
596 
597 	if (!link->link_enc) {
598 		DC_ERROR("Failed to create link encoder!\n");
599 		goto link_enc_create_fail;
600 	}
601 
602 	DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
603 	DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
604 
605 	switch (link->link_id.id) {
606 	case CONNECTOR_ID_HDMI_TYPE_A:
607 		link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
608 
609 		if (link->link_enc->hpd_gpio)
610 			link->irq_source_read_request =
611 					dal_irq_get_read_request(link->link_enc->hpd_gpio);
612 		else if (link->hpd_src != HPD_SOURCEID_UNKNOWN)
613 			link->irq_source_read_request = DC_IRQ_SOURCE_DCI2C_RR_DDC1 + link->hpd_src;
614 		break;
615 	case CONNECTOR_ID_SINGLE_LINK_DVID:
616 	case CONNECTOR_ID_SINGLE_LINK_DVII:
617 		link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
618 		break;
619 	case CONNECTOR_ID_DUAL_LINK_DVID:
620 	case CONNECTOR_ID_DUAL_LINK_DVII:
621 		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
622 		break;
623 	case CONNECTOR_ID_VGA:
624 		link->connector_signal = SIGNAL_TYPE_RGB;
625 		break;
626 	case CONNECTOR_ID_DISPLAY_PORT:
627 	case CONNECTOR_ID_MXM:
628 	case CONNECTOR_ID_USBC:
629 		link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
630 
631 		if (link->link_enc->hpd_gpio)
632 			link->irq_source_hpd_rx =
633 					dal_irq_get_rx_source(link->link_enc->hpd_gpio);
634 		else if (link->hpd_src != HPD_SOURCEID_UNKNOWN)
635 			link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
636 
637 		break;
638 	case CONNECTOR_ID_EDP:
639 		// If smartmux is supported, only create the link on the primary eDP.
640 		// Dual eDP is not supported with smartmux.
641 		if (!(!link->dc->config.smart_mux_version || dc_ctx->dc_edp_id_count == 0))
642 			goto create_fail;
643 
644 		link->connector_signal = SIGNAL_TYPE_EDP;
645 		if (!link->dc->config.allow_edp_hotplug_detection
646 			&& !is_smartmux_suported(link))
647 			link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
648 
649 		switch (link->dc->config.allow_edp_hotplug_detection) {
650 		case HPD_EN_FOR_ALL_EDP:
651 			if (link->link_enc->hpd_gpio) {
652 				link->irq_source_hpd_rx =
653 						dal_irq_get_rx_source(link->link_enc->hpd_gpio);
654 				} else if (link->hpd_src != HPD_SOURCEID_UNKNOWN) {
655 					link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
656 				}
657 			break;
658 		case HPD_EN_FOR_PRIMARY_EDP_ONLY:
659 			if (link->link_index == 0) {
660 				if (link->link_enc->hpd_gpio) {
661 					link->irq_source_hpd_rx =
662 						dal_irq_get_rx_source(link->link_enc->hpd_gpio);
663 				} else if (link->hpd_src != HPD_SOURCEID_UNKNOWN) {
664 					link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
665 				}
666 			} else
667 				link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
668 			break;
669 		case HPD_EN_FOR_SECONDARY_EDP_ONLY:
670 			if (link->link_index == 1) {
671 				if (link->link_enc->hpd_gpio) {
672 					link->irq_source_hpd_rx =
673 						dal_irq_get_rx_source(link->link_enc->hpd_gpio);
674 				} else if (link->hpd_src != HPD_SOURCEID_UNKNOWN) {
675 					link->irq_source_hpd_rx = DC_IRQ_SOURCE_HPD1RX + link->hpd_src;
676 				}
677 			} else
678 				link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
679 			break;
680 		default:
681 			link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
682 			break;
683 		}
684 		break;
685 	case CONNECTOR_ID_LVDS:
686 		link->connector_signal = SIGNAL_TYPE_LVDS;
687 		break;
688 	default:
689 		DC_LOG_WARNING("Unsupported Connector type:%d!\n",
690 			       link->link_id.id);
691 		goto create_fail;
692 	}
693 
694 	LINK_INFO("Connector[%d] description: signal: %s\n",
695 		  init_params->connector_index,
696 		  signal_type_to_string(link->connector_signal));
697 
698 	/* Update link encoder tracking variables. These are used for the dynamic
699 	 * assignment of link encoders to streams.
700 	 */
701 	link->eng_id = link->link_enc->preferred_engine;
702 	link->dc->res_pool->link_encoders[link->eng_id - ENGINE_ID_DIGA] = link->link_enc;
703 	link->dc->res_pool->dig_link_enc_count++;
704 
705 	link->link_enc_hw_inst = link->link_enc->transmitter;
706 
707 	if (link->dc->res_pool->funcs->panel_cntl_create &&
708 		(link->link_id.id == CONNECTOR_ID_EDP ||
709 			link->link_id.id == CONNECTOR_ID_LVDS)) {
710 		panel_cntl_init_data.ctx = dc_ctx;
711 		panel_cntl_init_data.inst = panel_cntl_init_data.ctx->dc_edp_id_count;
712 		panel_cntl_init_data.eng_id = link->eng_id;
713 		link->panel_cntl =
714 			link->dc->res_pool->funcs->panel_cntl_create(
715 								&panel_cntl_init_data);
716 		panel_cntl_init_data.ctx->dc_edp_id_count++;
717 
718 		if (link->panel_cntl == NULL) {
719 			DC_ERROR("Failed to create link panel_cntl!\n");
720 			goto panel_cntl_create_fail;
721 		}
722 	}
723 	for (i = 0; i < 4; i++) {
724 		if (bp_funcs->get_device_tag(dc_ctx->dc_bios,
725 					     link->link_id, i,
726 					     &link->device_tag) != BP_RESULT_OK) {
727 			DC_ERROR("Failed to find device tag!\n");
728 			goto device_tag_fail;
729 		}
730 
731 		/* Look for device tag that matches connector signal,
732 		 * CRT for rgb, LCD for other supported signal types
733 		 */
734 		if (!bp_funcs->is_device_id_supported(dc_ctx->dc_bios,
735 						      link->device_tag.dev_id))
736 			continue;
737 		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_CRT &&
738 		    link->connector_signal != SIGNAL_TYPE_RGB)
739 			continue;
740 		if (link->device_tag.dev_id.device_type == DEVICE_TYPE_LCD &&
741 		    link->connector_signal == SIGNAL_TYPE_RGB)
742 			continue;
743 
744 		DC_LOG_DC("BIOS object table - device_tag.acpi_device: %d", link->device_tag.acpi_device);
745 		DC_LOG_DC("BIOS object table - device_tag.dev_id.device_type: %d", link->device_tag.dev_id.device_type);
746 		DC_LOG_DC("BIOS object table - device_tag.dev_id.enum_id: %d", link->device_tag.dev_id.enum_id);
747 		break;
748 	}
749 
750 	if (bios->integrated_info) {
751 		/* Look for channel mapping corresponding to connector and device tag */
752 		for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
753 			struct external_display_path *path =
754 				&bios->integrated_info->ext_disp_conn_info.path[i];
755 
756 			if (path->device_connector_id.enum_id == link->link_id.enum_id &&
757 			    path->device_connector_id.id == link->link_id.id &&
758 			    path->device_connector_id.type == link->link_id.type) {
759 				if (link->device_tag.acpi_device != 0 &&
760 				    path->device_acpi_enum == link->device_tag.acpi_device) {
761 					link->ddi_channel_mapping = path->channel_mapping;
762 					link->chip_caps = path->caps;
763 					DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X",
764 						  link->ddi_channel_mapping.raw);
765 					DC_LOG_DC("BIOS object table - chip_caps: %d",
766 						  link->chip_caps);
767 				} else if (path->device_tag ==
768 					   link->device_tag.dev_id.raw_device_tag) {
769 					link->ddi_channel_mapping = path->channel_mapping;
770 					link->chip_caps = path->caps;
771 					DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X",
772 						  link->ddi_channel_mapping.raw);
773 					DC_LOG_DC("BIOS object table - chip_caps: %d",
774 						  link->chip_caps);
775 				}
776 
777 				if ((link->chip_caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
778 					link->bios_forced_drive_settings.VOLTAGE_SWING =
779 						(bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing & 0x3);
780 					link->bios_forced_drive_settings.PRE_EMPHASIS =
781 						((bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
782 				}
783 
784 				break;
785 			}
786 		}
787 	}
788 	if (bios->funcs->get_atom_dc_golden_table)
789 		bios->funcs->get_atom_dc_golden_table(bios);
790 
791 	/*
792 	 * TODO check if GPIO programmed correctly
793 	 *
794 	 * If GPIO isn't programmed correctly HPD might not rise or drain
795 	 * fast enough, leading to bounces.
796 	 */
797 	program_hpd_filter(link);
798 
799 	link->psr_settings.psr_vtotal_control_support = false;
800 	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
801 	link->replay_settings.config.replay_version = DC_REPLAY_VERSION_UNSUPPORTED;
802 
803 	DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
804 	return true;
805 device_tag_fail:
806 link_enc_create_fail:
807 panel_cntl_create_fail:
808 ddc_create_fail:
809 create_fail:
810 	if (link->ddc)
811 		link_destroy_ddc_service(&link->ddc);
812 	if (link->panel_cntl)
813 		link->panel_cntl->funcs->destroy(&link->panel_cntl);
814 	if (link->link_enc)
815 		link->link_enc->funcs->destroy(&link->link_enc);
816 
817 	DC_LOG_DC("BIOS object table - %s failed.\n", __func__);
818 	return false;
819 }
820 
construct_dpia(struct dc_link * link,const struct link_init_data * init_params)821 static bool construct_dpia(struct dc_link *link,
822 			      const struct link_init_data *init_params)
823 {
824 	struct ddc_service_init_data ddc_service_init_data = { 0 };
825 	struct dc_context *dc_ctx = init_params->ctx;
826 
827 	DC_LOGGER_INIT(dc_ctx->logger);
828 
829 	/* Initialized irq source for hpd and hpd rx */
830 	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
831 	link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
832 	link->link_status.dpcd_caps = &link->dpcd_caps;
833 
834 	link->dc = init_params->dc;
835 	link->ctx = dc_ctx;
836 	link->link_index = init_params->link_index;
837 
838 	memset(&link->preferred_training_settings, 0,
839 	       sizeof(struct dc_link_training_overrides));
840 	memset(&link->preferred_link_setting, 0,
841 	       sizeof(struct dc_link_settings));
842 
843 	/* Dummy Init for linkid */
844 	link->link_id.type = OBJECT_TYPE_CONNECTOR;
845 	link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
846 	link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
847 	link->is_internal_display = false;
848 	link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
849 	LINK_INFO("Connector[%d] description:signal %d\n",
850 		  init_params->connector_index,
851 		  link->connector_signal);
852 
853 	link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
854 	link->is_dig_mapping_flexible = true;
855 
856 	/* TODO: Initialize link : funcs->link_init */
857 
858 	ddc_service_init_data.ctx = link->ctx;
859 	ddc_service_init_data.id = link->link_id;
860 	ddc_service_init_data.link = link;
861 	/* Set indicator for dpia link so that ddc wont be created */
862 	ddc_service_init_data.is_dpia_link = true;
863 
864 	link->ddc = link_create_ddc_service(&ddc_service_init_data);
865 	if (!link->ddc) {
866 		DC_ERROR("Failed to create ddc_service!\n");
867 		goto ddc_create_fail;
868 	}
869 
870 	/* Set dpia port index : 0 to number of dpia ports */
871 	link->ddc_hw_inst = init_params->connector_index;
872 
873 	// Assign Dpia preferred eng_id
874 	if (link->dc->res_pool->funcs->get_preferred_eng_id_dpia)
875 		link->dpia_preferred_eng_id = link->dc->res_pool->funcs->get_preferred_eng_id_dpia(link->ddc_hw_inst);
876 
877 	/* TODO: Create link encoder */
878 
879 	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
880 	link->replay_settings.config.replay_version = DC_REPLAY_VERSION_UNSUPPORTED;
881 
882 	return true;
883 
884 ddc_create_fail:
885 	return false;
886 }
887 
link_construct(struct dc_link * link,const struct link_init_data * init_params)888 static bool link_construct(struct dc_link *link,
889 			      const struct link_init_data *init_params)
890 {
891 	/* Handle dpia case */
892 	if (init_params->is_dpia_link == true)
893 		return construct_dpia(link, init_params);
894 	else
895 		return construct_phy(link, init_params);
896 }
897 
link_create(const struct link_init_data * init_params)898 struct dc_link *link_create(const struct link_init_data *init_params)
899 {
900 	struct dc_link *link = kzalloc_obj(*link);
901 
902 	if (NULL == link)
903 		goto alloc_fail;
904 
905 	if (false == link_construct(link, init_params))
906 		goto construct_fail;
907 
908 	return link;
909 
910 construct_fail:
911 	kfree(link);
912 
913 alloc_fail:
914 	return NULL;
915 }
916 
link_destroy(struct dc_link ** link)917 void link_destroy(struct dc_link **link)
918 {
919 	link_destruct(*link);
920 	kfree(*link);
921 	*link = NULL;
922 }
923