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