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. */
construct_link_service_factory(struct link_service * link_srv)57  static 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   */
construct_link_service_detection(struct link_service * link_srv)69  static 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. */
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_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   */
construct_link_service_dpms(struct link_service * link_srv)110  static 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   */
construct_link_service_ddc(struct link_service * link_srv)130  static 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   */
construct_link_service_dp_capability(struct link_service * link_srv)148  static 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   */
construct_link_service_dp_phy_or_dpia(struct link_service * link_srv)173  static 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   */
construct_link_service_dp_irq_handler(struct link_service * link_srv)185  static 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   */
construct_link_service_edp_panel_control(struct link_service * link_srv)198  static 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   */
construct_link_service_dp_cts(struct link_service * link_srv)235  static 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   */
construct_link_service_dp_trace(struct link_service * link_srv)248  static 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  
construct_link_service(struct link_service * link_srv)265  static 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  
link_create_link_service(void)288  struct 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;
298  fail:
299  	return NULL;
300  }
301  
link_destroy_link_service(struct link_service ** link_srv)302  void link_destroy_link_service(struct link_service **link_srv)
303  {
304  	kfree(*link_srv);
305  	*link_srv = NULL;
306  }
307  
translate_encoder_to_transmitter(struct graphics_object_id encoder)308  static 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  
link_destruct(struct dc_link * link)373  static 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 && !link->is_dig_mapping_flexible) {
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 && link->eng_id != ENGINE_ID_UNKNOWN) {
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  
get_ddc_line(struct dc_link * link)407  static 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  
construct_phy(struct dc_link * link,const struct link_init_data * init_params)451  static 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 dc_bios *bios = init_params->dc->ctx->dc_bios;
460  	const struct dc_vbios_funcs *bp_funcs = bios->funcs;
461  	struct bp_disp_connector_caps_info disp_connect_caps_info = { 0 };
462  
463  	DC_LOGGER_INIT(dc_ctx->logger);
464  
465  	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
466  	link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
467  	link->link_status.dpcd_caps = &link->dpcd_caps;
468  
469  	link->dc = init_params->dc;
470  	link->ctx = dc_ctx;
471  	link->link_index = init_params->link_index;
472  
473  	memset(&link->preferred_training_settings, 0,
474  	       sizeof(struct dc_link_training_overrides));
475  	memset(&link->preferred_link_setting, 0,
476  	       sizeof(struct dc_link_settings));
477  
478  	link->link_id =
479  		bios->funcs->get_connector_id(bios, init_params->connector_index);
480  
481  	link->ep_type = DISPLAY_ENDPOINT_PHY;
482  
483  	DC_LOG_DC("BIOS object table - link_id: %d", link->link_id.id);
484  
485  	if (bios->funcs->get_disp_connector_caps_info) {
486  		bios->funcs->get_disp_connector_caps_info(bios, link->link_id, &disp_connect_caps_info);
487  		link->is_internal_display = disp_connect_caps_info.INTERNAL_DISPLAY;
488  		DC_LOG_DC("BIOS object table - is_internal_display: %d", link->is_internal_display);
489  	}
490  
491  	if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
492  		dm_output_to_console("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d! type %d expected %d\n",
493  				     __func__, init_params->connector_index,
494  				     link->link_id.type, OBJECT_TYPE_CONNECTOR);
495  		goto create_fail;
496  	}
497  
498  	if (link->dc->res_pool->funcs->link_init)
499  		link->dc->res_pool->funcs->link_init(link);
500  
501  	link->hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
502  				      link->ctx->gpio_service);
503  
504  	if (link->hpd_gpio) {
505  		dal_gpio_open(link->hpd_gpio, GPIO_MODE_INTERRUPT);
506  		dal_gpio_unlock_pin(link->hpd_gpio);
507  		link->irq_source_hpd = dal_irq_get_source(link->hpd_gpio);
508  
509  		DC_LOG_DC("BIOS object table - hpd_gpio id: %d", link->hpd_gpio->id);
510  		DC_LOG_DC("BIOS object table - hpd_gpio en: %d", link->hpd_gpio->en);
511  	}
512  
513  	switch (link->link_id.id) {
514  	case CONNECTOR_ID_HDMI_TYPE_A:
515  		link->connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
516  
517  		break;
518  	case CONNECTOR_ID_SINGLE_LINK_DVID:
519  	case CONNECTOR_ID_SINGLE_LINK_DVII:
520  		link->connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
521  		break;
522  	case CONNECTOR_ID_DUAL_LINK_DVID:
523  	case CONNECTOR_ID_DUAL_LINK_DVII:
524  		link->connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
525  		break;
526  	case CONNECTOR_ID_DISPLAY_PORT:
527  	case CONNECTOR_ID_MXM:
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  	if (!link->link_enc) {
615  		DC_ERROR("Failed to create link encoder!\n");
616  		goto link_enc_create_fail;
617  	}
618  
619  	DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
620  	DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
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  		/* Look for channel mapping corresponding to connector and device tag */
676  		for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
677  			struct external_display_path *path =
678  				&bios->integrated_info->ext_disp_conn_info.path[i];
679  
680  			if (path->device_connector_id.enum_id == link->link_id.enum_id &&
681  			    path->device_connector_id.id == link->link_id.id &&
682  			    path->device_connector_id.type == link->link_id.type) {
683  				if (link->device_tag.acpi_device != 0 &&
684  				    path->device_acpi_enum == link->device_tag.acpi_device) {
685  					link->ddi_channel_mapping = path->channel_mapping;
686  					link->chip_caps = path->caps;
687  					DC_LOG_DC("BIOS object table - ddi_channel_mapping: 0x%04X",
688  						  link->ddi_channel_mapping.raw);
689  					DC_LOG_DC("BIOS object table - chip_caps: %d",
690  						  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",
696  						  link->ddi_channel_mapping.raw);
697  					DC_LOG_DC("BIOS object table - chip_caps: %d",
698  						  link->chip_caps);
699  				}
700  
701  				if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) {
702  					link->bios_forced_drive_settings.VOLTAGE_SWING =
703  						(bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing & 0x3);
704  					link->bios_forced_drive_settings.PRE_EMPHASIS =
705  						((bios->integrated_info->ext_disp_conn_info.fixdpvoltageswing >> 2) & 0x3);
706  				}
707  
708  				break;
709  			}
710  		}
711  	}
712  	if (bios->funcs->get_atom_dc_golden_table)
713  		bios->funcs->get_atom_dc_golden_table(bios);
714  
715  	/*
716  	 * TODO check if GPIO programmed correctly
717  	 *
718  	 * If GPIO isn't programmed correctly HPD might not rise or drain
719  	 * fast enough, leading to bounces.
720  	 */
721  	program_hpd_filter(link);
722  
723  	link->psr_settings.psr_vtotal_control_support = false;
724  	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
725  
726  	DC_LOG_DC("BIOS object table - %s finished successfully.\n", __func__);
727  	return true;
728  device_tag_fail:
729  	link->link_enc->funcs->destroy(&link->link_enc);
730  link_enc_create_fail:
731  	if (link->panel_cntl != NULL)
732  		link->panel_cntl->funcs->destroy(&link->panel_cntl);
733  panel_cntl_create_fail:
734  	link_destroy_ddc_service(&link->ddc);
735  ddc_create_fail:
736  create_fail:
737  
738  	if (link->hpd_gpio) {
739  		dal_gpio_destroy_irq(&link->hpd_gpio);
740  		link->hpd_gpio = NULL;
741  	}
742  
743  	DC_LOG_DC("BIOS object table - %s failed.\n", __func__);
744  	return false;
745  }
746  
construct_dpia(struct dc_link * link,const struct link_init_data * init_params)747  static bool construct_dpia(struct dc_link *link,
748  			      const struct link_init_data *init_params)
749  {
750  	struct ddc_service_init_data ddc_service_init_data = { 0 };
751  	struct dc_context *dc_ctx = init_params->ctx;
752  
753  	DC_LOGGER_INIT(dc_ctx->logger);
754  
755  	/* Initialized irq source for hpd and hpd rx */
756  	link->irq_source_hpd = DC_IRQ_SOURCE_INVALID;
757  	link->irq_source_hpd_rx = DC_IRQ_SOURCE_INVALID;
758  	link->link_status.dpcd_caps = &link->dpcd_caps;
759  
760  	link->dc = init_params->dc;
761  	link->ctx = dc_ctx;
762  	link->link_index = init_params->link_index;
763  
764  	memset(&link->preferred_training_settings, 0,
765  	       sizeof(struct dc_link_training_overrides));
766  	memset(&link->preferred_link_setting, 0,
767  	       sizeof(struct dc_link_settings));
768  
769  	/* Dummy Init for linkid */
770  	link->link_id.type = OBJECT_TYPE_CONNECTOR;
771  	link->link_id.id = CONNECTOR_ID_DISPLAY_PORT;
772  	link->link_id.enum_id = ENUM_ID_1 + init_params->connector_index;
773  	link->is_internal_display = false;
774  	link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
775  	LINK_INFO("Connector[%d] description:signal %d\n",
776  		  init_params->connector_index,
777  		  link->connector_signal);
778  
779  	link->ep_type = DISPLAY_ENDPOINT_USB4_DPIA;
780  	link->is_dig_mapping_flexible = true;
781  
782  	/* TODO: Initialize link : funcs->link_init */
783  
784  	ddc_service_init_data.ctx = link->ctx;
785  	ddc_service_init_data.id = link->link_id;
786  	ddc_service_init_data.link = link;
787  	/* Set indicator for dpia link so that ddc wont be created */
788  	ddc_service_init_data.is_dpia_link = true;
789  
790  	link->ddc = link_create_ddc_service(&ddc_service_init_data);
791  	if (!link->ddc) {
792  		DC_ERROR("Failed to create ddc_service!\n");
793  		goto ddc_create_fail;
794  	}
795  
796  	/* Set dpia port index : 0 to number of dpia ports */
797  	link->ddc_hw_inst = init_params->connector_index;
798  
799  	// Assign Dpia preferred eng_id
800  	if (link->dc->res_pool->funcs->get_preferred_eng_id_dpia)
801  		link->dpia_preferred_eng_id = link->dc->res_pool->funcs->get_preferred_eng_id_dpia(link->ddc_hw_inst);
802  
803  	/* TODO: Create link encoder */
804  
805  	link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
806  
807  	/* Some docks seem to NAK I2C writes to segment pointer with mot=0. */
808  	link->wa_flags.dp_mot_reset_segment = true;
809  
810  	return true;
811  
812  ddc_create_fail:
813  	return false;
814  }
815  
link_construct(struct dc_link * link,const struct link_init_data * init_params)816  static bool link_construct(struct dc_link *link,
817  			      const struct link_init_data *init_params)
818  {
819  	/* Handle dpia case */
820  	if (init_params->is_dpia_link == true)
821  		return construct_dpia(link, init_params);
822  	else
823  		return construct_phy(link, init_params);
824  }
825  
link_create(const struct link_init_data * init_params)826  struct dc_link *link_create(const struct link_init_data *init_params)
827  {
828  	struct dc_link *link =
829  			kzalloc(sizeof(*link), GFP_KERNEL);
830  
831  	if (NULL == link)
832  		goto alloc_fail;
833  
834  	if (false == link_construct(link, init_params))
835  		goto construct_fail;
836  
837  	return link;
838  
839  construct_fail:
840  	kfree(link);
841  
842  alloc_fail:
843  	return NULL;
844  }
845  
link_destroy(struct dc_link ** link)846  void link_destroy(struct dc_link **link)
847  {
848  	link_destruct(*link);
849  	kfree(*link);
850  	*link = NULL;
851  }
852