1 /* 2 * Copyright 2012-15 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 #include "dm_services.h" 27 28 #include "ObjectID.h" 29 #include "atomfirmware.h" 30 31 #include "dc_bios_types.h" 32 #include "include/grph_object_ctrl_defs.h" 33 #include "include/bios_parser_interface.h" 34 #include "include/i2caux_interface.h" 35 #include "include/logger_interface.h" 36 37 #include "command_table2.h" 38 39 #include "bios_parser_helper.h" 40 #include "command_table_helper2.h" 41 #include "bios_parser2.h" 42 #include "bios_parser_types_internal2.h" 43 #include "bios_parser_interface.h" 44 45 #include "bios_parser_common.h" 46 47 /* Temporarily add in defines until ObjectID.h patch is updated in a few days */ 48 #ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT 49 #define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05 50 #endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */ 51 52 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 53 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \ 54 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ 55 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ 56 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) 57 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */ 58 59 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 60 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \ 61 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ 62 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ 63 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT) 64 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */ 65 66 #define DC_LOGGER \ 67 bp->base.ctx->logger 68 69 #define LAST_RECORD_TYPE 0xff 70 #define SMU9_SYSPLL0_ID 0 71 72 struct i2c_id_config_access { 73 uint8_t bfI2C_LineMux:4; 74 uint8_t bfHW_EngineID:3; 75 uint8_t bfHW_Capable:1; 76 uint8_t ucAccess; 77 }; 78 79 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, 80 struct atom_i2c_record *record, 81 struct graphics_object_i2c_info *info); 82 83 static enum bp_result bios_parser_get_firmware_info( 84 struct dc_bios *dcb, 85 struct dc_firmware_info *info); 86 87 static enum bp_result bios_parser_get_encoder_cap_info( 88 struct dc_bios *dcb, 89 struct graphics_object_id object_id, 90 struct bp_encoder_cap_info *info); 91 92 static enum bp_result get_firmware_info_v3_1( 93 struct bios_parser *bp, 94 struct dc_firmware_info *info); 95 96 static enum bp_result get_firmware_info_v3_2( 97 struct bios_parser *bp, 98 struct dc_firmware_info *info); 99 100 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, 101 struct atom_display_object_path_v2 *object); 102 103 static struct atom_encoder_caps_record *get_encoder_cap_record( 104 struct bios_parser *bp, 105 struct atom_display_object_path_v2 *object); 106 107 #define BIOS_IMAGE_SIZE_OFFSET 2 108 #define BIOS_IMAGE_SIZE_UNIT 512 109 110 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) 111 112 static void destruct(struct bios_parser *bp) 113 { 114 kfree(bp->base.bios_local_image); 115 kfree(bp->base.integrated_info); 116 } 117 118 static void firmware_parser_destroy(struct dc_bios **dcb) 119 { 120 struct bios_parser *bp = BP_FROM_DCB(*dcb); 121 122 if (!bp) { 123 BREAK_TO_DEBUGGER(); 124 return; 125 } 126 127 destruct(bp); 128 129 kfree(bp); 130 *dcb = NULL; 131 } 132 133 static void get_atom_data_table_revision( 134 struct atom_common_table_header *atom_data_tbl, 135 struct atom_data_revision *tbl_revision) 136 { 137 if (!tbl_revision) 138 return; 139 140 /* initialize the revision to 0 which is invalid revision */ 141 tbl_revision->major = 0; 142 tbl_revision->minor = 0; 143 144 if (!atom_data_tbl) 145 return; 146 147 tbl_revision->major = 148 (uint32_t) atom_data_tbl->format_revision & 0x3f; 149 tbl_revision->minor = 150 (uint32_t) atom_data_tbl->content_revision & 0x3f; 151 } 152 153 /* BIOS oject table displaypath is per connector. 154 * There is extra path not for connector. BIOS fill its encoderid as 0 155 */ 156 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb) 157 { 158 struct bios_parser *bp = BP_FROM_DCB(dcb); 159 unsigned int count = 0; 160 unsigned int i; 161 162 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 163 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0) 164 count++; 165 } 166 return count; 167 } 168 169 static struct graphics_object_id bios_parser_get_connector_id( 170 struct dc_bios *dcb, 171 uint8_t i) 172 { 173 struct bios_parser *bp = BP_FROM_DCB(dcb); 174 struct graphics_object_id object_id = dal_graphics_object_id_init( 175 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); 176 struct object_info_table *tbl = &bp->object_info_tbl; 177 struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4; 178 179 if (v1_4->number_of_path > i) { 180 /* If display_objid is generic object id, the encoderObj 181 * /extencoderobjId should be 0 182 */ 183 if (v1_4->display_path[i].encoderobjid != 0 && 184 v1_4->display_path[i].display_objid != 0) 185 object_id = object_id_from_bios_object_id( 186 v1_4->display_path[i].display_objid); 187 } 188 189 return object_id; 190 } 191 192 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, 193 struct graphics_object_id object_id, uint32_t index, 194 struct graphics_object_id *src_object_id) 195 { 196 struct bios_parser *bp = BP_FROM_DCB(dcb); 197 unsigned int i; 198 enum bp_result bp_result = BP_RESULT_BADINPUT; 199 struct graphics_object_id obj_id = {0}; 200 struct object_info_table *tbl = &bp->object_info_tbl; 201 202 if (!src_object_id) 203 return bp_result; 204 205 switch (object_id.type) { 206 /* Encoder's Source is GPU. BIOS does not provide GPU, since all 207 * displaypaths point to same GPU (0x1100). Hardcode GPU object type 208 */ 209 case OBJECT_TYPE_ENCODER: 210 /* TODO: since num of src must be less than 2. 211 * If found in for loop, should break. 212 * DAL2 implementation may be changed too 213 */ 214 for (i = 0; i < tbl->v1_4->number_of_path; i++) { 215 obj_id = object_id_from_bios_object_id( 216 tbl->v1_4->display_path[i].encoderobjid); 217 if (object_id.type == obj_id.type && 218 object_id.id == obj_id.id && 219 object_id.enum_id == 220 obj_id.enum_id) { 221 *src_object_id = 222 object_id_from_bios_object_id(0x1100); 223 /* break; */ 224 } 225 } 226 bp_result = BP_RESULT_OK; 227 break; 228 case OBJECT_TYPE_CONNECTOR: 229 for (i = 0; i < tbl->v1_4->number_of_path; i++) { 230 obj_id = object_id_from_bios_object_id( 231 tbl->v1_4->display_path[i].display_objid); 232 233 if (object_id.type == obj_id.type && 234 object_id.id == obj_id.id && 235 object_id.enum_id == obj_id.enum_id) { 236 *src_object_id = 237 object_id_from_bios_object_id( 238 tbl->v1_4->display_path[i].encoderobjid); 239 /* break; */ 240 } 241 } 242 bp_result = BP_RESULT_OK; 243 break; 244 default: 245 break; 246 } 247 248 return bp_result; 249 } 250 251 /* from graphics_object_id, find display path which includes the object_id */ 252 static struct atom_display_object_path_v2 *get_bios_object( 253 struct bios_parser *bp, 254 struct graphics_object_id id) 255 { 256 unsigned int i; 257 struct graphics_object_id obj_id = {0}; 258 259 switch (id.type) { 260 case OBJECT_TYPE_ENCODER: 261 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 262 obj_id = object_id_from_bios_object_id( 263 bp->object_info_tbl.v1_4->display_path[i].encoderobjid); 264 if (id.type == obj_id.type && id.id == obj_id.id 265 && id.enum_id == obj_id.enum_id) 266 return &bp->object_info_tbl.v1_4->display_path[i]; 267 } 268 case OBJECT_TYPE_CONNECTOR: 269 case OBJECT_TYPE_GENERIC: 270 /* Both Generic and Connector Object ID 271 * will be stored on display_objid 272 */ 273 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 274 obj_id = object_id_from_bios_object_id( 275 bp->object_info_tbl.v1_4->display_path[i].display_objid); 276 if (id.type == obj_id.type && id.id == obj_id.id 277 && id.enum_id == obj_id.enum_id) 278 return &bp->object_info_tbl.v1_4->display_path[i]; 279 } 280 default: 281 return NULL; 282 } 283 } 284 285 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, 286 struct graphics_object_id id, 287 struct graphics_object_i2c_info *info) 288 { 289 uint32_t offset; 290 struct atom_display_object_path_v2 *object; 291 struct atom_common_record_header *header; 292 struct atom_i2c_record *record; 293 struct bios_parser *bp = BP_FROM_DCB(dcb); 294 295 if (!info) 296 return BP_RESULT_BADINPUT; 297 298 object = get_bios_object(bp, id); 299 300 if (!object) 301 return BP_RESULT_BADINPUT; 302 303 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 304 305 for (;;) { 306 header = GET_IMAGE(struct atom_common_record_header, offset); 307 308 if (!header) 309 return BP_RESULT_BADBIOSTABLE; 310 311 if (header->record_type == LAST_RECORD_TYPE || 312 !header->record_size) 313 break; 314 315 if (header->record_type == ATOM_I2C_RECORD_TYPE 316 && sizeof(struct atom_i2c_record) <= 317 header->record_size) { 318 /* get the I2C info */ 319 record = (struct atom_i2c_record *) header; 320 321 if (get_gpio_i2c_info(bp, record, info) == 322 BP_RESULT_OK) 323 return BP_RESULT_OK; 324 } 325 326 offset += header->record_size; 327 } 328 329 return BP_RESULT_NORECORD; 330 } 331 332 static enum bp_result get_gpio_i2c_info( 333 struct bios_parser *bp, 334 struct atom_i2c_record *record, 335 struct graphics_object_i2c_info *info) 336 { 337 struct atom_gpio_pin_lut_v2_1 *header; 338 uint32_t count = 0; 339 unsigned int table_index = 0; 340 341 if (!info) 342 return BP_RESULT_BADINPUT; 343 344 /* get the GPIO_I2C info */ 345 if (!DATA_TABLES(gpio_pin_lut)) 346 return BP_RESULT_BADBIOSTABLE; 347 348 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 349 DATA_TABLES(gpio_pin_lut)); 350 if (!header) 351 return BP_RESULT_BADBIOSTABLE; 352 353 if (sizeof(struct atom_common_table_header) + 354 sizeof(struct atom_gpio_pin_assignment) > 355 le16_to_cpu(header->table_header.structuresize)) 356 return BP_RESULT_BADBIOSTABLE; 357 358 /* TODO: is version change? */ 359 if (header->table_header.content_revision != 1) 360 return BP_RESULT_UNSUPPORTED; 361 362 /* get data count */ 363 count = (le16_to_cpu(header->table_header.structuresize) 364 - sizeof(struct atom_common_table_header)) 365 / sizeof(struct atom_gpio_pin_assignment); 366 367 table_index = record->i2c_id & I2C_HW_LANE_MUX; 368 369 if (count < table_index) { 370 bool find_valid = false; 371 372 for (table_index = 0; table_index < count; table_index++) { 373 if (((record->i2c_id & I2C_HW_CAP) == ( 374 header->gpio_pin[table_index].gpio_id & 375 I2C_HW_CAP)) && 376 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == 377 (header->gpio_pin[table_index].gpio_id & 378 I2C_HW_ENGINE_ID_MASK)) && 379 ((record->i2c_id & I2C_HW_LANE_MUX) == 380 (header->gpio_pin[table_index].gpio_id & 381 I2C_HW_LANE_MUX))) { 382 /* still valid */ 383 find_valid = true; 384 break; 385 } 386 } 387 /* If we don't find the entry that we are looking for then 388 * we will return BP_Result_BadBiosTable. 389 */ 390 if (find_valid == false) 391 return BP_RESULT_BADBIOSTABLE; 392 } 393 394 /* get the GPIO_I2C_INFO */ 395 info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false; 396 info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX; 397 info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4; 398 info->i2c_slave_address = record->i2c_slave_addr; 399 400 /* TODO: check how to get register offset for en, Y, etc. */ 401 info->gpio_info.clk_a_register_index = 402 le16_to_cpu( 403 header->gpio_pin[table_index].data_a_reg_index); 404 info->gpio_info.clk_a_shift = 405 header->gpio_pin[table_index].gpio_bitshift; 406 407 return BP_RESULT_OK; 408 } 409 410 static enum bp_result bios_parser_get_hpd_info( 411 struct dc_bios *dcb, 412 struct graphics_object_id id, 413 struct graphics_object_hpd_info *info) 414 { 415 struct bios_parser *bp = BP_FROM_DCB(dcb); 416 struct atom_display_object_path_v2 *object; 417 struct atom_hpd_int_record *record = NULL; 418 419 if (!info) 420 return BP_RESULT_BADINPUT; 421 422 object = get_bios_object(bp, id); 423 424 if (!object) 425 return BP_RESULT_BADINPUT; 426 427 record = get_hpd_record(bp, object); 428 429 if (record != NULL) { 430 info->hpd_int_gpio_uid = record->pin_id; 431 info->hpd_active = record->plugin_pin_state; 432 return BP_RESULT_OK; 433 } 434 435 return BP_RESULT_NORECORD; 436 } 437 438 static struct atom_hpd_int_record *get_hpd_record( 439 struct bios_parser *bp, 440 struct atom_display_object_path_v2 *object) 441 { 442 struct atom_common_record_header *header; 443 uint32_t offset; 444 445 if (!object) { 446 BREAK_TO_DEBUGGER(); /* Invalid object */ 447 return NULL; 448 } 449 450 offset = le16_to_cpu(object->disp_recordoffset) 451 + bp->object_info_tbl_offset; 452 453 for (;;) { 454 header = GET_IMAGE(struct atom_common_record_header, offset); 455 456 if (!header) 457 return NULL; 458 459 if (header->record_type == LAST_RECORD_TYPE || 460 !header->record_size) 461 break; 462 463 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE 464 && sizeof(struct atom_hpd_int_record) <= 465 header->record_size) 466 return (struct atom_hpd_int_record *) header; 467 468 offset += header->record_size; 469 } 470 471 return NULL; 472 } 473 474 /** 475 * bios_parser_get_gpio_pin_info 476 * Get GpioPin information of input gpio id 477 * 478 * @param gpio_id, GPIO ID 479 * @param info, GpioPin information structure 480 * @return Bios parser result code 481 * @note 482 * to get the GPIO PIN INFO, we need: 483 * 1. get the GPIO_ID from other object table, see GetHPDInfo() 484 * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, 485 * to get the registerA offset/mask 486 */ 487 static enum bp_result bios_parser_get_gpio_pin_info( 488 struct dc_bios *dcb, 489 uint32_t gpio_id, 490 struct gpio_pin_info *info) 491 { 492 struct bios_parser *bp = BP_FROM_DCB(dcb); 493 struct atom_gpio_pin_lut_v2_1 *header; 494 uint32_t count = 0; 495 uint32_t i = 0; 496 497 if (!DATA_TABLES(gpio_pin_lut)) 498 return BP_RESULT_BADBIOSTABLE; 499 500 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 501 DATA_TABLES(gpio_pin_lut)); 502 if (!header) 503 return BP_RESULT_BADBIOSTABLE; 504 505 if (sizeof(struct atom_common_table_header) + 506 sizeof(struct atom_gpio_pin_assignment) 507 > le16_to_cpu(header->table_header.structuresize)) 508 return BP_RESULT_BADBIOSTABLE; 509 510 if (header->table_header.content_revision != 1) 511 return BP_RESULT_UNSUPPORTED; 512 513 /* Temporary hard code gpio pin info */ 514 #if defined(FOR_SIMNOW_BOOT) 515 { 516 struct atom_gpio_pin_assignment gpio_pin[8] = { 517 {0x5db5, 0, 0, 1, 0}, 518 {0x5db5, 8, 8, 2, 0}, 519 {0x5db5, 0x10, 0x10, 3, 0}, 520 {0x5db5, 0x18, 0x14, 4, 0}, 521 {0x5db5, 0x1A, 0x18, 5, 0}, 522 {0x5db5, 0x1C, 0x1C, 6, 0}, 523 }; 524 525 count = 6; 526 memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin)); 527 } 528 #else 529 count = (le16_to_cpu(header->table_header.structuresize) 530 - sizeof(struct atom_common_table_header)) 531 / sizeof(struct atom_gpio_pin_assignment); 532 #endif 533 for (i = 0; i < count; ++i) { 534 if (header->gpio_pin[i].gpio_id != gpio_id) 535 continue; 536 537 info->offset = 538 (uint32_t) le16_to_cpu( 539 header->gpio_pin[i].data_a_reg_index); 540 info->offset_y = info->offset + 2; 541 info->offset_en = info->offset + 1; 542 info->offset_mask = info->offset - 1; 543 544 info->mask = (uint32_t) (1 << 545 header->gpio_pin[i].gpio_bitshift); 546 info->mask_y = info->mask + 2; 547 info->mask_en = info->mask + 1; 548 info->mask_mask = info->mask - 1; 549 550 return BP_RESULT_OK; 551 } 552 553 return BP_RESULT_NORECORD; 554 } 555 556 static struct device_id device_type_from_device_id(uint16_t device_id) 557 { 558 559 struct device_id result_device_id; 560 561 result_device_id.raw_device_tag = device_id; 562 563 switch (device_id) { 564 case ATOM_DISPLAY_LCD1_SUPPORT: 565 result_device_id.device_type = DEVICE_TYPE_LCD; 566 result_device_id.enum_id = 1; 567 break; 568 569 case ATOM_DISPLAY_DFP1_SUPPORT: 570 result_device_id.device_type = DEVICE_TYPE_DFP; 571 result_device_id.enum_id = 1; 572 break; 573 574 case ATOM_DISPLAY_DFP2_SUPPORT: 575 result_device_id.device_type = DEVICE_TYPE_DFP; 576 result_device_id.enum_id = 2; 577 break; 578 579 case ATOM_DISPLAY_DFP3_SUPPORT: 580 result_device_id.device_type = DEVICE_TYPE_DFP; 581 result_device_id.enum_id = 3; 582 break; 583 584 case ATOM_DISPLAY_DFP4_SUPPORT: 585 result_device_id.device_type = DEVICE_TYPE_DFP; 586 result_device_id.enum_id = 4; 587 break; 588 589 case ATOM_DISPLAY_DFP5_SUPPORT: 590 result_device_id.device_type = DEVICE_TYPE_DFP; 591 result_device_id.enum_id = 5; 592 break; 593 594 case ATOM_DISPLAY_DFP6_SUPPORT: 595 result_device_id.device_type = DEVICE_TYPE_DFP; 596 result_device_id.enum_id = 6; 597 break; 598 599 default: 600 BREAK_TO_DEBUGGER(); /* Invalid device Id */ 601 result_device_id.device_type = DEVICE_TYPE_UNKNOWN; 602 result_device_id.enum_id = 0; 603 } 604 return result_device_id; 605 } 606 607 static enum bp_result bios_parser_get_device_tag( 608 struct dc_bios *dcb, 609 struct graphics_object_id connector_object_id, 610 uint32_t device_tag_index, 611 struct connector_device_tag_info *info) 612 { 613 struct bios_parser *bp = BP_FROM_DCB(dcb); 614 struct atom_display_object_path_v2 *object; 615 616 if (!info) 617 return BP_RESULT_BADINPUT; 618 619 /* getBiosObject will return MXM object */ 620 object = get_bios_object(bp, connector_object_id); 621 622 if (!object) { 623 BREAK_TO_DEBUGGER(); /* Invalid object id */ 624 return BP_RESULT_BADINPUT; 625 } 626 627 info->acpi_device = 0; /* BIOS no longer provides this */ 628 info->dev_id = device_type_from_device_id(object->device_tag); 629 630 return BP_RESULT_OK; 631 } 632 633 static enum bp_result get_ss_info_v4_1( 634 struct bios_parser *bp, 635 uint32_t id, 636 uint32_t index, 637 struct spread_spectrum_info *ss_info) 638 { 639 enum bp_result result = BP_RESULT_OK; 640 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; 641 642 if (!ss_info) 643 return BP_RESULT_BADINPUT; 644 645 if (!DATA_TABLES(dce_info)) 646 return BP_RESULT_BADBIOSTABLE; 647 648 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, 649 DATA_TABLES(dce_info)); 650 if (!disp_cntl_tbl) 651 return BP_RESULT_BADBIOSTABLE; 652 653 ss_info->type.STEP_AND_DELAY_INFO = false; 654 ss_info->spread_percentage_divider = 1000; 655 /* BIOS no longer uses target clock. Always enable for now */ 656 ss_info->target_clock_range = 0xffffffff; 657 658 switch (id) { 659 case AS_SIGNAL_TYPE_DVI: 660 ss_info->spread_spectrum_percentage = 661 disp_cntl_tbl->dvi_ss_percentage; 662 ss_info->spread_spectrum_range = 663 disp_cntl_tbl->dvi_ss_rate_10hz * 10; 664 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 665 ss_info->type.CENTER_MODE = true; 666 break; 667 case AS_SIGNAL_TYPE_HDMI: 668 ss_info->spread_spectrum_percentage = 669 disp_cntl_tbl->hdmi_ss_percentage; 670 ss_info->spread_spectrum_range = 671 disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 672 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 673 ss_info->type.CENTER_MODE = true; 674 break; 675 /* TODO LVDS not support anymore? */ 676 case AS_SIGNAL_TYPE_DISPLAY_PORT: 677 ss_info->spread_spectrum_percentage = 678 disp_cntl_tbl->dp_ss_percentage; 679 ss_info->spread_spectrum_range = 680 disp_cntl_tbl->dp_ss_rate_10hz * 10; 681 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 682 ss_info->type.CENTER_MODE = true; 683 break; 684 case AS_SIGNAL_TYPE_GPU_PLL: 685 /* atom_firmware: DAL only get data from dce_info table. 686 * if data within smu_info is needed for DAL, VBIOS should 687 * copy it into dce_info 688 */ 689 result = BP_RESULT_UNSUPPORTED; 690 break; 691 default: 692 result = BP_RESULT_UNSUPPORTED; 693 } 694 695 return result; 696 } 697 698 static enum bp_result get_ss_info_v4_2( 699 struct bios_parser *bp, 700 uint32_t id, 701 uint32_t index, 702 struct spread_spectrum_info *ss_info) 703 { 704 enum bp_result result = BP_RESULT_OK; 705 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; 706 struct atom_smu_info_v3_1 *smu_info = NULL; 707 708 if (!ss_info) 709 return BP_RESULT_BADINPUT; 710 711 if (!DATA_TABLES(dce_info)) 712 return BP_RESULT_BADBIOSTABLE; 713 714 if (!DATA_TABLES(smu_info)) 715 return BP_RESULT_BADBIOSTABLE; 716 717 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, 718 DATA_TABLES(dce_info)); 719 if (!disp_cntl_tbl) 720 return BP_RESULT_BADBIOSTABLE; 721 722 smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info)); 723 if (!smu_info) 724 return BP_RESULT_BADBIOSTABLE; 725 726 ss_info->type.STEP_AND_DELAY_INFO = false; 727 ss_info->spread_percentage_divider = 1000; 728 /* BIOS no longer uses target clock. Always enable for now */ 729 ss_info->target_clock_range = 0xffffffff; 730 731 switch (id) { 732 case AS_SIGNAL_TYPE_DVI: 733 ss_info->spread_spectrum_percentage = 734 disp_cntl_tbl->dvi_ss_percentage; 735 ss_info->spread_spectrum_range = 736 disp_cntl_tbl->dvi_ss_rate_10hz * 10; 737 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 738 ss_info->type.CENTER_MODE = true; 739 break; 740 case AS_SIGNAL_TYPE_HDMI: 741 ss_info->spread_spectrum_percentage = 742 disp_cntl_tbl->hdmi_ss_percentage; 743 ss_info->spread_spectrum_range = 744 disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 745 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 746 ss_info->type.CENTER_MODE = true; 747 break; 748 /* TODO LVDS not support anymore? */ 749 case AS_SIGNAL_TYPE_DISPLAY_PORT: 750 ss_info->spread_spectrum_percentage = 751 smu_info->gpuclk_ss_percentage; 752 ss_info->spread_spectrum_range = 753 smu_info->gpuclk_ss_rate_10hz * 10; 754 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 755 ss_info->type.CENTER_MODE = true; 756 break; 757 case AS_SIGNAL_TYPE_GPU_PLL: 758 /* atom_firmware: DAL only get data from dce_info table. 759 * if data within smu_info is needed for DAL, VBIOS should 760 * copy it into dce_info 761 */ 762 result = BP_RESULT_UNSUPPORTED; 763 break; 764 default: 765 result = BP_RESULT_UNSUPPORTED; 766 } 767 768 return result; 769 } 770 771 /** 772 * bios_parser_get_spread_spectrum_info 773 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or 774 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info 775 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info 776 * ver 3.1, 777 * there is only one entry for each signal /ss id. However, there is 778 * no planning of supporting multiple spread Sprectum entry for EverGreen 779 * @param [in] this 780 * @param [in] signal, ASSignalType to be converted to info index 781 * @param [in] index, number of entries that match the converted info index 782 * @param [out] ss_info, sprectrum information structure, 783 * @return Bios parser result code 784 */ 785 static enum bp_result bios_parser_get_spread_spectrum_info( 786 struct dc_bios *dcb, 787 enum as_signal_type signal, 788 uint32_t index, 789 struct spread_spectrum_info *ss_info) 790 { 791 struct bios_parser *bp = BP_FROM_DCB(dcb); 792 enum bp_result result = BP_RESULT_UNSUPPORTED; 793 struct atom_common_table_header *header; 794 struct atom_data_revision tbl_revision; 795 796 if (!ss_info) /* check for bad input */ 797 return BP_RESULT_BADINPUT; 798 799 if (!DATA_TABLES(dce_info)) 800 return BP_RESULT_UNSUPPORTED; 801 802 header = GET_IMAGE(struct atom_common_table_header, 803 DATA_TABLES(dce_info)); 804 get_atom_data_table_revision(header, &tbl_revision); 805 806 switch (tbl_revision.major) { 807 case 4: 808 switch (tbl_revision.minor) { 809 case 1: 810 return get_ss_info_v4_1(bp, signal, index, ss_info); 811 case 2: 812 return get_ss_info_v4_2(bp, signal, index, ss_info); 813 default: 814 break; 815 } 816 break; 817 default: 818 break; 819 } 820 /* there can not be more then one entry for SS Info table */ 821 return result; 822 } 823 824 static enum bp_result get_embedded_panel_info_v2_1( 825 struct bios_parser *bp, 826 struct embedded_panel_info *info) 827 { 828 struct lcd_info_v2_1 *lvds; 829 830 if (!info) 831 return BP_RESULT_BADINPUT; 832 833 if (!DATA_TABLES(lcd_info)) 834 return BP_RESULT_UNSUPPORTED; 835 836 lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info)); 837 838 if (!lvds) 839 return BP_RESULT_BADBIOSTABLE; 840 841 /* TODO: previous vv1_3, should v2_1 */ 842 if (!((lvds->table_header.format_revision == 2) 843 && (lvds->table_header.content_revision >= 1))) 844 return BP_RESULT_UNSUPPORTED; 845 846 memset(info, 0, sizeof(struct embedded_panel_info)); 847 848 /* We need to convert from 10KHz units into KHz units */ 849 info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10; 850 /* usHActive does not include borders, according to VBIOS team */ 851 info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active); 852 /* usHBlanking_Time includes borders, so we should really be 853 * subtractingborders duing this translation, but LVDS generally 854 * doesn't have borders, so we should be okay leaving this as is for 855 * now. May need to revisit if we ever have LVDS with borders 856 */ 857 info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time); 858 /* usVActive does not include borders, according to VBIOS team*/ 859 info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active); 860 /* usVBlanking_Time includes borders, so we should really be 861 * subtracting borders duing this translation, but LVDS generally 862 * doesn't have borders, so we should be okay leaving this as is for 863 * now. May need to revisit if we ever have LVDS with borders 864 */ 865 info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time); 866 info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset); 867 info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width); 868 info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset); 869 info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth); 870 info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border; 871 info->lcd_timing.vertical_border = lvds->lcd_timing.v_border; 872 873 /* not provided by VBIOS */ 874 info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; 875 876 info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 877 & ATOM_HSYNC_POLARITY); 878 info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 879 & ATOM_VSYNC_POLARITY); 880 881 /* not provided by VBIOS */ 882 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; 883 884 info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 885 & ATOM_H_REPLICATIONBY2); 886 info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 887 & ATOM_V_REPLICATIONBY2); 888 info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo 889 & ATOM_COMPOSITESYNC); 890 info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); 891 892 /* not provided by VBIOS*/ 893 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; 894 /* not provided by VBIOS*/ 895 info->ss_id = 0; 896 897 info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); 898 899 return BP_RESULT_OK; 900 } 901 902 static enum bp_result bios_parser_get_embedded_panel_info( 903 struct dc_bios *dcb, 904 struct embedded_panel_info *info) 905 { 906 struct bios_parser 907 *bp = BP_FROM_DCB(dcb); 908 struct atom_common_table_header *header; 909 struct atom_data_revision tbl_revision; 910 911 if (!DATA_TABLES(lcd_info)) 912 return BP_RESULT_FAILURE; 913 914 header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info)); 915 916 if (!header) 917 return BP_RESULT_BADBIOSTABLE; 918 919 get_atom_data_table_revision(header, &tbl_revision); 920 921 switch (tbl_revision.major) { 922 case 2: 923 switch (tbl_revision.minor) { 924 case 1: 925 return get_embedded_panel_info_v2_1(bp, info); 926 default: 927 break; 928 } 929 default: 930 break; 931 } 932 933 return BP_RESULT_FAILURE; 934 } 935 936 static uint32_t get_support_mask_for_device_id(struct device_id device_id) 937 { 938 enum dal_device_type device_type = device_id.device_type; 939 uint32_t enum_id = device_id.enum_id; 940 941 switch (device_type) { 942 case DEVICE_TYPE_LCD: 943 switch (enum_id) { 944 case 1: 945 return ATOM_DISPLAY_LCD1_SUPPORT; 946 default: 947 break; 948 } 949 break; 950 case DEVICE_TYPE_DFP: 951 switch (enum_id) { 952 case 1: 953 return ATOM_DISPLAY_DFP1_SUPPORT; 954 case 2: 955 return ATOM_DISPLAY_DFP2_SUPPORT; 956 case 3: 957 return ATOM_DISPLAY_DFP3_SUPPORT; 958 case 4: 959 return ATOM_DISPLAY_DFP4_SUPPORT; 960 case 5: 961 return ATOM_DISPLAY_DFP5_SUPPORT; 962 case 6: 963 return ATOM_DISPLAY_DFP6_SUPPORT; 964 default: 965 break; 966 } 967 break; 968 default: 969 break; 970 }; 971 972 /* Unidentified device ID, return empty support mask. */ 973 return 0; 974 } 975 976 static bool bios_parser_is_device_id_supported( 977 struct dc_bios *dcb, 978 struct device_id id) 979 { 980 struct bios_parser *bp = BP_FROM_DCB(dcb); 981 982 uint32_t mask = get_support_mask_for_device_id(id); 983 984 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & 985 mask) != 0; 986 } 987 988 static uint32_t bios_parser_get_ss_entry_number( 989 struct dc_bios *dcb, 990 enum as_signal_type signal) 991 { 992 /* TODO: DAL2 atomfirmware implementation does not need this. 993 * why DAL3 need this? 994 */ 995 return 1; 996 } 997 998 static enum bp_result bios_parser_transmitter_control( 999 struct dc_bios *dcb, 1000 struct bp_transmitter_control *cntl) 1001 { 1002 struct bios_parser *bp = BP_FROM_DCB(dcb); 1003 1004 if (!bp->cmd_tbl.transmitter_control) 1005 return BP_RESULT_FAILURE; 1006 1007 return bp->cmd_tbl.transmitter_control(bp, cntl); 1008 } 1009 1010 static enum bp_result bios_parser_encoder_control( 1011 struct dc_bios *dcb, 1012 struct bp_encoder_control *cntl) 1013 { 1014 struct bios_parser *bp = BP_FROM_DCB(dcb); 1015 1016 if (!bp->cmd_tbl.dig_encoder_control) 1017 return BP_RESULT_FAILURE; 1018 1019 return bp->cmd_tbl.dig_encoder_control(bp, cntl); 1020 } 1021 1022 static enum bp_result bios_parser_set_pixel_clock( 1023 struct dc_bios *dcb, 1024 struct bp_pixel_clock_parameters *bp_params) 1025 { 1026 struct bios_parser *bp = BP_FROM_DCB(dcb); 1027 1028 if (!bp->cmd_tbl.set_pixel_clock) 1029 return BP_RESULT_FAILURE; 1030 1031 return bp->cmd_tbl.set_pixel_clock(bp, bp_params); 1032 } 1033 1034 static enum bp_result bios_parser_set_dce_clock( 1035 struct dc_bios *dcb, 1036 struct bp_set_dce_clock_parameters *bp_params) 1037 { 1038 struct bios_parser *bp = BP_FROM_DCB(dcb); 1039 1040 if (!bp->cmd_tbl.set_dce_clock) 1041 return BP_RESULT_FAILURE; 1042 1043 return bp->cmd_tbl.set_dce_clock(bp, bp_params); 1044 } 1045 1046 static enum bp_result bios_parser_program_crtc_timing( 1047 struct dc_bios *dcb, 1048 struct bp_hw_crtc_timing_parameters *bp_params) 1049 { 1050 struct bios_parser *bp = BP_FROM_DCB(dcb); 1051 1052 if (!bp->cmd_tbl.set_crtc_timing) 1053 return BP_RESULT_FAILURE; 1054 1055 return bp->cmd_tbl.set_crtc_timing(bp, bp_params); 1056 } 1057 1058 static enum bp_result bios_parser_enable_crtc( 1059 struct dc_bios *dcb, 1060 enum controller_id id, 1061 bool enable) 1062 { 1063 struct bios_parser *bp = BP_FROM_DCB(dcb); 1064 1065 if (!bp->cmd_tbl.enable_crtc) 1066 return BP_RESULT_FAILURE; 1067 1068 return bp->cmd_tbl.enable_crtc(bp, id, enable); 1069 } 1070 1071 static enum bp_result bios_parser_crtc_source_select( 1072 struct dc_bios *dcb, 1073 struct bp_crtc_source_select *bp_params) 1074 { 1075 struct bios_parser *bp = BP_FROM_DCB(dcb); 1076 1077 if (!bp->cmd_tbl.select_crtc_source) 1078 return BP_RESULT_FAILURE; 1079 1080 return bp->cmd_tbl.select_crtc_source(bp, bp_params); 1081 } 1082 1083 static enum bp_result bios_parser_enable_disp_power_gating( 1084 struct dc_bios *dcb, 1085 enum controller_id controller_id, 1086 enum bp_pipe_control_action action) 1087 { 1088 struct bios_parser *bp = BP_FROM_DCB(dcb); 1089 1090 if (!bp->cmd_tbl.enable_disp_power_gating) 1091 return BP_RESULT_FAILURE; 1092 1093 return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id, 1094 action); 1095 } 1096 1097 static bool bios_parser_is_accelerated_mode( 1098 struct dc_bios *dcb) 1099 { 1100 return bios_is_accelerated_mode(dcb); 1101 } 1102 1103 /** 1104 * bios_parser_set_scratch_critical_state 1105 * 1106 * @brief 1107 * update critical state bit in VBIOS scratch register 1108 * 1109 * @param 1110 * bool - to set or reset state 1111 */ 1112 static void bios_parser_set_scratch_critical_state( 1113 struct dc_bios *dcb, 1114 bool state) 1115 { 1116 bios_set_scratch_critical_state(dcb, state); 1117 } 1118 1119 static enum bp_result bios_parser_get_firmware_info( 1120 struct dc_bios *dcb, 1121 struct dc_firmware_info *info) 1122 { 1123 struct bios_parser *bp = BP_FROM_DCB(dcb); 1124 enum bp_result result = BP_RESULT_BADBIOSTABLE; 1125 struct atom_common_table_header *header; 1126 1127 struct atom_data_revision revision; 1128 1129 if (info && DATA_TABLES(firmwareinfo)) { 1130 header = GET_IMAGE(struct atom_common_table_header, 1131 DATA_TABLES(firmwareinfo)); 1132 get_atom_data_table_revision(header, &revision); 1133 switch (revision.major) { 1134 case 3: 1135 switch (revision.minor) { 1136 case 1: 1137 result = get_firmware_info_v3_1(bp, info); 1138 break; 1139 case 2: 1140 result = get_firmware_info_v3_2(bp, info); 1141 break; 1142 case 3: 1143 result = get_firmware_info_v3_2(bp, info); 1144 break; 1145 default: 1146 break; 1147 } 1148 break; 1149 default: 1150 break; 1151 } 1152 } 1153 1154 return result; 1155 } 1156 1157 static enum bp_result get_firmware_info_v3_1( 1158 struct bios_parser *bp, 1159 struct dc_firmware_info *info) 1160 { 1161 struct atom_firmware_info_v3_1 *firmware_info; 1162 struct atom_display_controller_info_v4_1 *dce_info = NULL; 1163 1164 if (!info) 1165 return BP_RESULT_BADINPUT; 1166 1167 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1, 1168 DATA_TABLES(firmwareinfo)); 1169 1170 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1171 DATA_TABLES(dce_info)); 1172 1173 if (!firmware_info || !dce_info) 1174 return BP_RESULT_BADBIOSTABLE; 1175 1176 memset(info, 0, sizeof(*info)); 1177 1178 /* Pixel clock pll information. */ 1179 /* We need to convert from 10KHz units into KHz units */ 1180 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1181 info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10; 1182 1183 /* 27MHz for Vega10: */ 1184 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1185 1186 /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1187 if (info->pll_info.crystal_frequency == 0) 1188 info->pll_info.crystal_frequency = 27000; 1189 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1190 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1191 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1192 1193 /* Get GPU PLL VCO Clock */ 1194 1195 if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1196 /* VBIOS gives in 10KHz */ 1197 info->smu_gpu_pll_output_freq = 1198 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1199 } 1200 1201 return BP_RESULT_OK; 1202 } 1203 1204 static enum bp_result get_firmware_info_v3_2( 1205 struct bios_parser *bp, 1206 struct dc_firmware_info *info) 1207 { 1208 struct atom_firmware_info_v3_2 *firmware_info; 1209 struct atom_display_controller_info_v4_1 *dce_info = NULL; 1210 struct atom_common_table_header *header; 1211 struct atom_data_revision revision; 1212 struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL; 1213 struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL; 1214 1215 if (!info) 1216 return BP_RESULT_BADINPUT; 1217 1218 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2, 1219 DATA_TABLES(firmwareinfo)); 1220 1221 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1222 DATA_TABLES(dce_info)); 1223 1224 if (!firmware_info || !dce_info) 1225 return BP_RESULT_BADBIOSTABLE; 1226 1227 memset(info, 0, sizeof(*info)); 1228 1229 header = GET_IMAGE(struct atom_common_table_header, 1230 DATA_TABLES(smu_info)); 1231 get_atom_data_table_revision(header, &revision); 1232 1233 if (revision.minor == 2) { 1234 /* Vega12 */ 1235 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2, 1236 DATA_TABLES(smu_info)); 1237 1238 if (!smu_info_v3_2) 1239 return BP_RESULT_BADBIOSTABLE; 1240 1241 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10; 1242 } else if (revision.minor == 3) { 1243 /* Vega20 */ 1244 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3, 1245 DATA_TABLES(smu_info)); 1246 1247 if (!smu_info_v3_3) 1248 return BP_RESULT_BADBIOSTABLE; 1249 1250 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10; 1251 } 1252 1253 // We need to convert from 10KHz units into KHz units. 1254 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1255 1256 /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */ 1257 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1258 /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1259 if (info->pll_info.crystal_frequency == 0) { 1260 if (revision.minor == 2) 1261 info->pll_info.crystal_frequency = 27000; 1262 else if (revision.minor == 3) 1263 info->pll_info.crystal_frequency = 100000; 1264 } 1265 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1266 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1267 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1268 1269 /* Get GPU PLL VCO Clock */ 1270 if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1271 if (revision.minor == 2) 1272 info->smu_gpu_pll_output_freq = 1273 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1274 else if (revision.minor == 3) 1275 info->smu_gpu_pll_output_freq = 1276 bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10; 1277 } 1278 1279 return BP_RESULT_OK; 1280 } 1281 1282 static enum bp_result bios_parser_get_encoder_cap_info( 1283 struct dc_bios *dcb, 1284 struct graphics_object_id object_id, 1285 struct bp_encoder_cap_info *info) 1286 { 1287 struct bios_parser *bp = BP_FROM_DCB(dcb); 1288 struct atom_display_object_path_v2 *object; 1289 struct atom_encoder_caps_record *record = NULL; 1290 1291 if (!info) 1292 return BP_RESULT_BADINPUT; 1293 1294 object = get_bios_object(bp, object_id); 1295 1296 if (!object) 1297 return BP_RESULT_BADINPUT; 1298 1299 record = get_encoder_cap_record(bp, object); 1300 if (!record) 1301 return BP_RESULT_NORECORD; 1302 1303 info->DP_HBR2_CAP = (record->encodercaps & 1304 ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0; 1305 info->DP_HBR2_EN = (record->encodercaps & 1306 ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0; 1307 info->DP_HBR3_EN = (record->encodercaps & 1308 ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; 1309 info->HDMI_6GB_EN = (record->encodercaps & 1310 ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; 1311 1312 return BP_RESULT_OK; 1313 } 1314 1315 1316 static struct atom_encoder_caps_record *get_encoder_cap_record( 1317 struct bios_parser *bp, 1318 struct atom_display_object_path_v2 *object) 1319 { 1320 struct atom_common_record_header *header; 1321 uint32_t offset; 1322 1323 if (!object) { 1324 BREAK_TO_DEBUGGER(); /* Invalid object */ 1325 return NULL; 1326 } 1327 1328 offset = object->encoder_recordoffset + bp->object_info_tbl_offset; 1329 1330 for (;;) { 1331 header = GET_IMAGE(struct atom_common_record_header, offset); 1332 1333 if (!header) 1334 return NULL; 1335 1336 offset += header->record_size; 1337 1338 if (header->record_type == LAST_RECORD_TYPE || 1339 !header->record_size) 1340 break; 1341 1342 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE) 1343 continue; 1344 1345 if (sizeof(struct atom_encoder_caps_record) <= 1346 header->record_size) 1347 return (struct atom_encoder_caps_record *)header; 1348 } 1349 1350 return NULL; 1351 } 1352 1353 /* 1354 * get_integrated_info_v11 1355 * 1356 * @brief 1357 * Get V8 integrated BIOS information 1358 * 1359 * @param 1360 * bios_parser *bp - [in]BIOS parser handler to get master data table 1361 * integrated_info *info - [out] store and output integrated info 1362 * 1363 * @return 1364 * enum bp_result - BP_RESULT_OK if information is available, 1365 * BP_RESULT_BADBIOSTABLE otherwise. 1366 */ 1367 static enum bp_result get_integrated_info_v11( 1368 struct bios_parser *bp, 1369 struct integrated_info *info) 1370 { 1371 struct atom_integrated_system_info_v1_11 *info_v11; 1372 uint32_t i; 1373 1374 info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11, 1375 DATA_TABLES(integratedsysteminfo)); 1376 1377 if (info_v11 == NULL) 1378 return BP_RESULT_BADBIOSTABLE; 1379 1380 info->gpu_cap_info = 1381 le32_to_cpu(info_v11->gpucapinfo); 1382 /* 1383 * system_config: Bit[0] = 0 : PCIE power gating disabled 1384 * = 1 : PCIE power gating enabled 1385 * Bit[1] = 0 : DDR-PLL shut down disabled 1386 * = 1 : DDR-PLL shut down enabled 1387 * Bit[2] = 0 : DDR-PLL power down disabled 1388 * = 1 : DDR-PLL power down enabled 1389 */ 1390 info->system_config = le32_to_cpu(info_v11->system_config); 1391 info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo); 1392 info->memory_type = info_v11->memorytype; 1393 info->ma_channel_number = info_v11->umachannelnumber; 1394 info->lvds_ss_percentage = 1395 le16_to_cpu(info_v11->lvds_ss_percentage); 1396 info->lvds_sspread_rate_in_10hz = 1397 le16_to_cpu(info_v11->lvds_ss_rate_10hz); 1398 info->hdmi_ss_percentage = 1399 le16_to_cpu(info_v11->hdmi_ss_percentage); 1400 info->hdmi_sspread_rate_in_10hz = 1401 le16_to_cpu(info_v11->hdmi_ss_rate_10hz); 1402 info->dvi_ss_percentage = 1403 le16_to_cpu(info_v11->dvi_ss_percentage); 1404 info->dvi_sspread_rate_in_10_hz = 1405 le16_to_cpu(info_v11->dvi_ss_rate_10hz); 1406 info->lvds_misc = info_v11->lvds_misc; 1407 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 1408 info->ext_disp_conn_info.gu_id[i] = 1409 info_v11->extdispconninfo.guid[i]; 1410 } 1411 1412 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 1413 info->ext_disp_conn_info.path[i].device_connector_id = 1414 object_id_from_bios_object_id( 1415 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid)); 1416 1417 info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 1418 object_id_from_bios_object_id( 1419 le16_to_cpu( 1420 info_v11->extdispconninfo.path[i].ext_encoder_objid)); 1421 1422 info->ext_disp_conn_info.path[i].device_tag = 1423 le16_to_cpu( 1424 info_v11->extdispconninfo.path[i].device_tag); 1425 info->ext_disp_conn_info.path[i].device_acpi_enum = 1426 le16_to_cpu( 1427 info_v11->extdispconninfo.path[i].device_acpi_enum); 1428 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 1429 info_v11->extdispconninfo.path[i].auxddclut_index; 1430 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 1431 info_v11->extdispconninfo.path[i].hpdlut_index; 1432 info->ext_disp_conn_info.path[i].channel_mapping.raw = 1433 info_v11->extdispconninfo.path[i].channelmapping; 1434 info->ext_disp_conn_info.path[i].caps = 1435 le16_to_cpu(info_v11->extdispconninfo.path[i].caps); 1436 } 1437 info->ext_disp_conn_info.checksum = 1438 info_v11->extdispconninfo.checksum; 1439 1440 info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr; 1441 info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum; 1442 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 1443 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 1444 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1445 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 1446 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1447 } 1448 info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum; 1449 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 1450 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1451 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1452 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1453 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1454 } 1455 1456 info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr; 1457 info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum; 1458 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 1459 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 1460 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1461 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 1462 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1463 } 1464 info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum; 1465 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 1466 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1467 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1468 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1469 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1470 } 1471 1472 info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr; 1473 info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum; 1474 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 1475 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 1476 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1477 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 1478 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1479 } 1480 info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum; 1481 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 1482 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1483 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1484 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1485 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1486 } 1487 1488 info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr; 1489 info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum; 1490 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 1491 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 1492 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 1493 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 1494 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 1495 } 1496 info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum; 1497 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 1498 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 1499 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 1500 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 1501 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 1502 } 1503 1504 1505 /** TODO - review **/ 1506 #if 0 1507 info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock) 1508 * 10; 1509 info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10; 1510 info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10; 1511 1512 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 1513 /* Convert [10KHz] into [KHz] */ 1514 info->disp_clk_voltage[i].max_supported_clk = 1515 le32_to_cpu(info_v11->sDISPCLK_Voltage[i]. 1516 ulMaximumSupportedCLK) * 10; 1517 info->disp_clk_voltage[i].voltage_index = 1518 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex); 1519 } 1520 1521 info->boot_up_req_display_vector = 1522 le32_to_cpu(info_v11->ulBootUpReqDisplayVector); 1523 info->boot_up_nb_voltage = 1524 le16_to_cpu(info_v11->usBootUpNBVoltage); 1525 info->ext_disp_conn_info_offset = 1526 le16_to_cpu(info_v11->usExtDispConnInfoOffset); 1527 info->gmc_restore_reset_time = 1528 le32_to_cpu(info_v11->ulGMCRestoreResetTime); 1529 info->minimum_n_clk = 1530 le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]); 1531 for (i = 1; i < 4; ++i) 1532 info->minimum_n_clk = 1533 info->minimum_n_clk < 1534 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ? 1535 info->minimum_n_clk : le32_to_cpu( 1536 info_v11->ulNbpStateNClkFreq[i]); 1537 1538 info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk); 1539 info->ddr_dll_power_up_time = 1540 le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime); 1541 info->ddr_pll_power_up_time = 1542 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime); 1543 info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType); 1544 info->max_lvds_pclk_freq_in_single_link = 1545 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 1546 info->max_lvds_pclk_freq_in_single_link = 1547 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 1548 info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = 1549 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; 1550 info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = 1551 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; 1552 info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = 1553 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; 1554 info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = 1555 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; 1556 info->lvds_pwr_off_seq_de_to_dig_on_in4ms = 1557 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; 1558 info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = 1559 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; 1560 info->lvds_off_to_on_delay_in_4ms = 1561 info_v11->ucLVDSOffToOnDelay_in4Ms; 1562 info->lvds_bit_depth_control_val = 1563 le32_to_cpu(info_v11->ulLCDBitDepthControlVal); 1564 1565 for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { 1566 /* Convert [10KHz] into [KHz] */ 1567 info->avail_s_clk[i].supported_s_clk = 1568 le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK) 1569 * 10; 1570 info->avail_s_clk[i].voltage_index = 1571 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex); 1572 info->avail_s_clk[i].voltage_id = 1573 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID); 1574 } 1575 #endif /* TODO*/ 1576 1577 return BP_RESULT_OK; 1578 } 1579 1580 1581 /* 1582 * construct_integrated_info 1583 * 1584 * @brief 1585 * Get integrated BIOS information based on table revision 1586 * 1587 * @param 1588 * bios_parser *bp - [in]BIOS parser handler to get master data table 1589 * integrated_info *info - [out] store and output integrated info 1590 * 1591 * @return 1592 * enum bp_result - BP_RESULT_OK if information is available, 1593 * BP_RESULT_BADBIOSTABLE otherwise. 1594 */ 1595 static enum bp_result construct_integrated_info( 1596 struct bios_parser *bp, 1597 struct integrated_info *info) 1598 { 1599 enum bp_result result = BP_RESULT_BADBIOSTABLE; 1600 1601 struct atom_common_table_header *header; 1602 struct atom_data_revision revision; 1603 1604 struct clock_voltage_caps temp = {0, 0}; 1605 uint32_t i; 1606 uint32_t j; 1607 1608 if (info && DATA_TABLES(integratedsysteminfo)) { 1609 header = GET_IMAGE(struct atom_common_table_header, 1610 DATA_TABLES(integratedsysteminfo)); 1611 1612 get_atom_data_table_revision(header, &revision); 1613 1614 /* Don't need to check major revision as they are all 1 */ 1615 switch (revision.minor) { 1616 case 11: 1617 result = get_integrated_info_v11(bp, info); 1618 break; 1619 default: 1620 return result; 1621 } 1622 } 1623 1624 if (result != BP_RESULT_OK) 1625 return result; 1626 1627 /* Sort voltage table from low to high*/ 1628 for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 1629 for (j = i; j > 0; --j) { 1630 if (info->disp_clk_voltage[j].max_supported_clk < 1631 info->disp_clk_voltage[j-1].max_supported_clk 1632 ) { 1633 /* swap j and j - 1*/ 1634 temp = info->disp_clk_voltage[j-1]; 1635 info->disp_clk_voltage[j-1] = 1636 info->disp_clk_voltage[j]; 1637 info->disp_clk_voltage[j] = temp; 1638 } 1639 } 1640 } 1641 1642 return result; 1643 } 1644 1645 static struct integrated_info *bios_parser_create_integrated_info( 1646 struct dc_bios *dcb) 1647 { 1648 struct bios_parser *bp = BP_FROM_DCB(dcb); 1649 struct integrated_info *info = NULL; 1650 1651 info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); 1652 1653 if (info == NULL) { 1654 ASSERT_CRITICAL(0); 1655 return NULL; 1656 } 1657 1658 if (construct_integrated_info(bp, info) == BP_RESULT_OK) 1659 return info; 1660 1661 kfree(info); 1662 1663 return NULL; 1664 } 1665 1666 static enum bp_result update_slot_layout_info( 1667 struct dc_bios *dcb, 1668 unsigned int i, 1669 struct slot_layout_info *slot_layout_info) 1670 { 1671 unsigned int record_offset; 1672 unsigned int j; 1673 struct atom_display_object_path_v2 *object; 1674 struct atom_bracket_layout_record *record; 1675 struct atom_common_record_header *record_header; 1676 enum bp_result result; 1677 struct bios_parser *bp; 1678 struct object_info_table *tbl; 1679 struct display_object_info_table_v1_4 *v1_4; 1680 1681 record = NULL; 1682 record_header = NULL; 1683 result = BP_RESULT_NORECORD; 1684 1685 bp = BP_FROM_DCB(dcb); 1686 tbl = &bp->object_info_tbl; 1687 v1_4 = tbl->v1_4; 1688 1689 object = &v1_4->display_path[i]; 1690 record_offset = (unsigned int) 1691 (object->disp_recordoffset) + 1692 (unsigned int)(bp->object_info_tbl_offset); 1693 1694 for (;;) { 1695 1696 record_header = (struct atom_common_record_header *) 1697 GET_IMAGE(struct atom_common_record_header, 1698 record_offset); 1699 if (record_header == NULL) { 1700 result = BP_RESULT_BADBIOSTABLE; 1701 break; 1702 } 1703 1704 /* the end of the list */ 1705 if (record_header->record_type == 0xff || 1706 record_header->record_size == 0) { 1707 break; 1708 } 1709 1710 if (record_header->record_type == 1711 ATOM_BRACKET_LAYOUT_RECORD_TYPE && 1712 sizeof(struct atom_bracket_layout_record) 1713 <= record_header->record_size) { 1714 record = (struct atom_bracket_layout_record *) 1715 (record_header); 1716 result = BP_RESULT_OK; 1717 break; 1718 } 1719 1720 record_offset += record_header->record_size; 1721 } 1722 1723 /* return if the record not found */ 1724 if (result != BP_RESULT_OK) 1725 return result; 1726 1727 /* get slot sizes */ 1728 slot_layout_info->length = record->bracketlen; 1729 slot_layout_info->width = record->bracketwidth; 1730 1731 /* get info for each connector in the slot */ 1732 slot_layout_info->num_of_connectors = record->conn_num; 1733 for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { 1734 slot_layout_info->connectors[j].connector_type = 1735 (enum connector_layout_type) 1736 (record->conn_info[j].connector_type); 1737 switch (record->conn_info[j].connector_type) { 1738 case CONNECTOR_TYPE_DVI_D: 1739 slot_layout_info->connectors[j].connector_type = 1740 CONNECTOR_LAYOUT_TYPE_DVI_D; 1741 slot_layout_info->connectors[j].length = 1742 CONNECTOR_SIZE_DVI; 1743 break; 1744 1745 case CONNECTOR_TYPE_HDMI: 1746 slot_layout_info->connectors[j].connector_type = 1747 CONNECTOR_LAYOUT_TYPE_HDMI; 1748 slot_layout_info->connectors[j].length = 1749 CONNECTOR_SIZE_HDMI; 1750 break; 1751 1752 case CONNECTOR_TYPE_DISPLAY_PORT: 1753 slot_layout_info->connectors[j].connector_type = 1754 CONNECTOR_LAYOUT_TYPE_DP; 1755 slot_layout_info->connectors[j].length = 1756 CONNECTOR_SIZE_DP; 1757 break; 1758 1759 case CONNECTOR_TYPE_MINI_DISPLAY_PORT: 1760 slot_layout_info->connectors[j].connector_type = 1761 CONNECTOR_LAYOUT_TYPE_MINI_DP; 1762 slot_layout_info->connectors[j].length = 1763 CONNECTOR_SIZE_MINI_DP; 1764 break; 1765 1766 default: 1767 slot_layout_info->connectors[j].connector_type = 1768 CONNECTOR_LAYOUT_TYPE_UNKNOWN; 1769 slot_layout_info->connectors[j].length = 1770 CONNECTOR_SIZE_UNKNOWN; 1771 } 1772 1773 slot_layout_info->connectors[j].position = 1774 record->conn_info[j].position; 1775 slot_layout_info->connectors[j].connector_id = 1776 object_id_from_bios_object_id( 1777 record->conn_info[j].connectorobjid); 1778 } 1779 return result; 1780 } 1781 1782 1783 static enum bp_result get_bracket_layout_record( 1784 struct dc_bios *dcb, 1785 unsigned int bracket_layout_id, 1786 struct slot_layout_info *slot_layout_info) 1787 { 1788 unsigned int i; 1789 struct bios_parser *bp = BP_FROM_DCB(dcb); 1790 enum bp_result result; 1791 struct object_info_table *tbl; 1792 struct display_object_info_table_v1_4 *v1_4; 1793 1794 if (slot_layout_info == NULL) { 1795 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); 1796 return BP_RESULT_BADINPUT; 1797 } 1798 tbl = &bp->object_info_tbl; 1799 v1_4 = tbl->v1_4; 1800 1801 result = BP_RESULT_NORECORD; 1802 for (i = 0; i < v1_4->number_of_path; ++i) { 1803 1804 if (bracket_layout_id == 1805 v1_4->display_path[i].display_objid) { 1806 result = update_slot_layout_info(dcb, i, 1807 slot_layout_info); 1808 break; 1809 } 1810 } 1811 return result; 1812 } 1813 1814 static enum bp_result bios_get_board_layout_info( 1815 struct dc_bios *dcb, 1816 struct board_layout_info *board_layout_info) 1817 { 1818 unsigned int i; 1819 struct bios_parser *bp; 1820 enum bp_result record_result; 1821 1822 const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { 1823 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, 1824 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, 1825 0, 0 1826 }; 1827 1828 bp = BP_FROM_DCB(dcb); 1829 if (board_layout_info == NULL) { 1830 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); 1831 return BP_RESULT_BADINPUT; 1832 } 1833 1834 board_layout_info->num_of_slots = 0; 1835 1836 for (i = 0; i < MAX_BOARD_SLOTS; ++i) { 1837 record_result = get_bracket_layout_record(dcb, 1838 slot_index_to_vbios_id[i], 1839 &board_layout_info->slots[i]); 1840 1841 if (record_result == BP_RESULT_NORECORD && i > 0) 1842 break; /* no more slots present in bios */ 1843 else if (record_result != BP_RESULT_OK) 1844 return record_result; /* fail */ 1845 1846 ++board_layout_info->num_of_slots; 1847 } 1848 1849 /* all data is valid */ 1850 board_layout_info->is_number_of_slots_valid = 1; 1851 board_layout_info->is_slots_size_valid = 1; 1852 board_layout_info->is_connector_offsets_valid = 1; 1853 board_layout_info->is_connector_lengths_valid = 1; 1854 1855 return BP_RESULT_OK; 1856 } 1857 1858 static const struct dc_vbios_funcs vbios_funcs = { 1859 .get_connectors_number = bios_parser_get_connectors_number, 1860 1861 .get_connector_id = bios_parser_get_connector_id, 1862 1863 .get_src_obj = bios_parser_get_src_obj, 1864 1865 .get_i2c_info = bios_parser_get_i2c_info, 1866 1867 .get_hpd_info = bios_parser_get_hpd_info, 1868 1869 .get_device_tag = bios_parser_get_device_tag, 1870 1871 .get_firmware_info = bios_parser_get_firmware_info, 1872 1873 .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, 1874 1875 .get_ss_entry_number = bios_parser_get_ss_entry_number, 1876 1877 .get_embedded_panel_info = bios_parser_get_embedded_panel_info, 1878 1879 .get_gpio_pin_info = bios_parser_get_gpio_pin_info, 1880 1881 .get_encoder_cap_info = bios_parser_get_encoder_cap_info, 1882 1883 .is_device_id_supported = bios_parser_is_device_id_supported, 1884 1885 .is_accelerated_mode = bios_parser_is_accelerated_mode, 1886 1887 .set_scratch_critical_state = bios_parser_set_scratch_critical_state, 1888 1889 1890 /* COMMANDS */ 1891 .encoder_control = bios_parser_encoder_control, 1892 1893 .transmitter_control = bios_parser_transmitter_control, 1894 1895 .enable_crtc = bios_parser_enable_crtc, 1896 1897 .set_pixel_clock = bios_parser_set_pixel_clock, 1898 1899 .set_dce_clock = bios_parser_set_dce_clock, 1900 1901 .program_crtc_timing = bios_parser_program_crtc_timing, 1902 1903 .crtc_source_select = bios_parser_crtc_source_select, 1904 1905 .enable_disp_power_gating = bios_parser_enable_disp_power_gating, 1906 1907 .bios_parser_destroy = firmware_parser_destroy, 1908 1909 .get_board_layout_info = bios_get_board_layout_info, 1910 }; 1911 1912 static bool bios_parser_construct( 1913 struct bios_parser *bp, 1914 struct bp_init_data *init, 1915 enum dce_version dce_version) 1916 { 1917 uint16_t *rom_header_offset = NULL; 1918 struct atom_rom_header_v2_2 *rom_header = NULL; 1919 struct display_object_info_table_v1_4 *object_info_tbl; 1920 struct atom_data_revision tbl_rev = {0}; 1921 1922 if (!init) 1923 return false; 1924 1925 if (!init->bios) 1926 return false; 1927 1928 bp->base.funcs = &vbios_funcs; 1929 bp->base.bios = init->bios; 1930 bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT; 1931 1932 bp->base.ctx = init->ctx; 1933 1934 bp->base.bios_local_image = NULL; 1935 1936 rom_header_offset = 1937 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER); 1938 1939 if (!rom_header_offset) 1940 return false; 1941 1942 rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset); 1943 1944 if (!rom_header) 1945 return false; 1946 1947 get_atom_data_table_revision(&rom_header->table_header, &tbl_rev); 1948 if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2)) 1949 return false; 1950 1951 bp->master_data_tbl = 1952 GET_IMAGE(struct atom_master_data_table_v2_1, 1953 rom_header->masterdatatable_offset); 1954 1955 if (!bp->master_data_tbl) 1956 return false; 1957 1958 bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo); 1959 1960 if (!bp->object_info_tbl_offset) 1961 return false; 1962 1963 object_info_tbl = 1964 GET_IMAGE(struct display_object_info_table_v1_4, 1965 bp->object_info_tbl_offset); 1966 1967 if (!object_info_tbl) 1968 return false; 1969 1970 get_atom_data_table_revision(&object_info_tbl->table_header, 1971 &bp->object_info_tbl.revision); 1972 1973 if (bp->object_info_tbl.revision.major == 1 1974 && bp->object_info_tbl.revision.minor >= 4) { 1975 struct display_object_info_table_v1_4 *tbl_v1_4; 1976 1977 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4, 1978 bp->object_info_tbl_offset); 1979 if (!tbl_v1_4) 1980 return false; 1981 1982 bp->object_info_tbl.v1_4 = tbl_v1_4; 1983 } else 1984 return false; 1985 1986 dal_firmware_parser_init_cmd_tbl(bp); 1987 dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); 1988 1989 bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); 1990 1991 return true; 1992 } 1993 1994 struct dc_bios *firmware_parser_create( 1995 struct bp_init_data *init, 1996 enum dce_version dce_version) 1997 { 1998 struct bios_parser *bp = NULL; 1999 2000 bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); 2001 if (!bp) 2002 return NULL; 2003 2004 if (bios_parser_construct(bp, init, dce_version)) 2005 return &bp->base; 2006 2007 kfree(bp); 2008 return NULL; 2009 } 2010 2011 2012