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