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