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