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