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 #define DC_LOGGER \ 48 bp->base.ctx->logger 49 50 #define LAST_RECORD_TYPE 0xff 51 #define SMU9_SYSPLL0_ID 0 52 53 struct i2c_id_config_access { 54 uint8_t bfI2C_LineMux:4; 55 uint8_t bfHW_EngineID:3; 56 uint8_t bfHW_Capable:1; 57 uint8_t ucAccess; 58 }; 59 60 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, 61 struct atom_i2c_record *record, 62 struct graphics_object_i2c_info *info); 63 64 static enum bp_result bios_parser_get_firmware_info( 65 struct dc_bios *dcb, 66 struct dc_firmware_info *info); 67 68 static enum bp_result bios_parser_get_encoder_cap_info( 69 struct dc_bios *dcb, 70 struct graphics_object_id object_id, 71 struct bp_encoder_cap_info *info); 72 73 static enum bp_result get_firmware_info_v3_1( 74 struct bios_parser *bp, 75 struct dc_firmware_info *info); 76 77 static enum bp_result get_firmware_info_v3_2( 78 struct bios_parser *bp, 79 struct dc_firmware_info *info); 80 81 static enum bp_result get_firmware_info_v3_4( 82 struct bios_parser *bp, 83 struct dc_firmware_info *info); 84 85 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, 86 struct atom_display_object_path_v2 *object); 87 88 static struct atom_encoder_caps_record *get_encoder_cap_record( 89 struct bios_parser *bp, 90 struct atom_display_object_path_v2 *object); 91 92 #define BIOS_IMAGE_SIZE_OFFSET 2 93 #define BIOS_IMAGE_SIZE_UNIT 512 94 95 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) 96 97 static void bios_parser2_destruct(struct bios_parser *bp) 98 { 99 kfree(bp->base.bios_local_image); 100 kfree(bp->base.integrated_info); 101 } 102 103 static void firmware_parser_destroy(struct dc_bios **dcb) 104 { 105 struct bios_parser *bp = BP_FROM_DCB(*dcb); 106 107 if (!bp) { 108 BREAK_TO_DEBUGGER(); 109 return; 110 } 111 112 bios_parser2_destruct(bp); 113 114 kfree(bp); 115 *dcb = NULL; 116 } 117 118 static void get_atom_data_table_revision( 119 struct atom_common_table_header *atom_data_tbl, 120 struct atom_data_revision *tbl_revision) 121 { 122 if (!tbl_revision) 123 return; 124 125 /* initialize the revision to 0 which is invalid revision */ 126 tbl_revision->major = 0; 127 tbl_revision->minor = 0; 128 129 if (!atom_data_tbl) 130 return; 131 132 tbl_revision->major = 133 (uint32_t) atom_data_tbl->format_revision & 0x3f; 134 tbl_revision->minor = 135 (uint32_t) atom_data_tbl->content_revision & 0x3f; 136 } 137 138 /* BIOS oject table displaypath is per connector. 139 * There is extra path not for connector. BIOS fill its encoderid as 0 140 */ 141 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb) 142 { 143 struct bios_parser *bp = BP_FROM_DCB(dcb); 144 unsigned int count = 0; 145 unsigned int i; 146 147 switch (bp->object_info_tbl.revision.minor) { 148 default: 149 case 4: 150 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) 151 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0) 152 count++; 153 154 break; 155 156 case 5: 157 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) 158 if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0) 159 count++; 160 161 break; 162 } 163 return count; 164 } 165 166 static struct graphics_object_id bios_parser_get_connector_id( 167 struct dc_bios *dcb, 168 uint8_t i) 169 { 170 struct bios_parser *bp = BP_FROM_DCB(dcb); 171 struct graphics_object_id object_id = dal_graphics_object_id_init( 172 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); 173 struct object_info_table *tbl = &bp->object_info_tbl; 174 struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4; 175 176 struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5; 177 178 switch (bp->object_info_tbl.revision.minor) { 179 default: 180 case 4: 181 if (v1_4->number_of_path > i) { 182 /* If display_objid is generic object id, the encoderObj 183 * /extencoderobjId should be 0 184 */ 185 if (v1_4->display_path[i].encoderobjid != 0 && 186 v1_4->display_path[i].display_objid != 0) 187 object_id = object_id_from_bios_object_id( 188 v1_4->display_path[i].display_objid); 189 } 190 break; 191 192 case 5: 193 if (v1_5->number_of_path > i) { 194 /* If display_objid is generic object id, the encoderObjId 195 * should be 0 196 */ 197 if (v1_5->display_path[i].encoderobjid != 0 && 198 v1_5->display_path[i].display_objid != 0) 199 object_id = object_id_from_bios_object_id( 200 v1_5->display_path[i].display_objid); 201 } 202 break; 203 } 204 return object_id; 205 } 206 207 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, 208 struct graphics_object_id object_id, uint32_t index, 209 struct graphics_object_id *src_object_id) 210 { 211 struct bios_parser *bp = BP_FROM_DCB(dcb); 212 unsigned int i; 213 enum bp_result bp_result = BP_RESULT_BADINPUT; 214 struct graphics_object_id obj_id = { 0 }; 215 struct object_info_table *tbl = &bp->object_info_tbl; 216 217 if (!src_object_id) 218 return bp_result; 219 220 switch (object_id.type) { 221 /* Encoder's Source is GPU. BIOS does not provide GPU, since all 222 * displaypaths point to same GPU (0x1100). Hardcode GPU object type 223 */ 224 case OBJECT_TYPE_ENCODER: 225 /* TODO: since num of src must be less than 2. 226 * If found in for loop, should break. 227 * DAL2 implementation may be changed too 228 */ 229 switch (bp->object_info_tbl.revision.minor) { 230 default: 231 case 4: 232 for (i = 0; i < tbl->v1_4->number_of_path; i++) { 233 obj_id = object_id_from_bios_object_id( 234 tbl->v1_4->display_path[i].encoderobjid); 235 if (object_id.type == obj_id.type && 236 object_id.id == obj_id.id && 237 object_id.enum_id == obj_id.enum_id) { 238 *src_object_id = 239 object_id_from_bios_object_id( 240 0x1100); 241 /* break; */ 242 } 243 } 244 bp_result = BP_RESULT_OK; 245 break; 246 247 case 5: 248 for (i = 0; i < tbl->v1_5->number_of_path; i++) { 249 obj_id = object_id_from_bios_object_id( 250 tbl->v1_5->display_path[i].encoderobjid); 251 if (object_id.type == obj_id.type && 252 object_id.id == obj_id.id && 253 object_id.enum_id == obj_id.enum_id) { 254 *src_object_id = 255 object_id_from_bios_object_id( 256 0x1100); 257 /* break; */ 258 } 259 } 260 bp_result = BP_RESULT_OK; 261 break; 262 } 263 break; 264 case OBJECT_TYPE_CONNECTOR: 265 switch (bp->object_info_tbl.revision.minor) { 266 default: 267 case 4: 268 for (i = 0; i < tbl->v1_4->number_of_path; i++) { 269 obj_id = object_id_from_bios_object_id( 270 tbl->v1_4->display_path[i] 271 .display_objid); 272 273 if (object_id.type == obj_id.type && 274 object_id.id == obj_id.id && 275 object_id.enum_id == obj_id.enum_id) { 276 *src_object_id = 277 object_id_from_bios_object_id( 278 tbl->v1_4 279 ->display_path[i] 280 .encoderobjid); 281 /* break; */ 282 } 283 } 284 bp_result = BP_RESULT_OK; 285 break; 286 } 287 bp_result = BP_RESULT_OK; 288 break; 289 case 5: 290 for (i = 0; i < tbl->v1_5->number_of_path; i++) { 291 obj_id = object_id_from_bios_object_id( 292 tbl->v1_5->display_path[i].display_objid); 293 294 if (object_id.type == obj_id.type && 295 object_id.id == obj_id.id && 296 object_id.enum_id == obj_id.enum_id) { 297 *src_object_id = object_id_from_bios_object_id( 298 tbl->v1_5->display_path[i].encoderobjid); 299 /* break; */ 300 } 301 } 302 bp_result = BP_RESULT_OK; 303 break; 304 305 default: 306 bp_result = BP_RESULT_OK; 307 break; 308 } 309 310 return bp_result; 311 } 312 313 /* from graphics_object_id, find display path which includes the object_id */ 314 static struct atom_display_object_path_v2 *get_bios_object( 315 struct bios_parser *bp, 316 struct graphics_object_id id) 317 { 318 unsigned int i; 319 struct graphics_object_id obj_id = {0}; 320 321 switch (id.type) { 322 case OBJECT_TYPE_ENCODER: 323 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 324 obj_id = object_id_from_bios_object_id( 325 bp->object_info_tbl.v1_4->display_path[i].encoderobjid); 326 if (id.type == obj_id.type && id.id == obj_id.id 327 && id.enum_id == obj_id.enum_id) 328 return &bp->object_info_tbl.v1_4->display_path[i]; 329 } 330 fallthrough; 331 case OBJECT_TYPE_CONNECTOR: 332 case OBJECT_TYPE_GENERIC: 333 /* Both Generic and Connector Object ID 334 * will be stored on display_objid 335 */ 336 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { 337 obj_id = object_id_from_bios_object_id( 338 bp->object_info_tbl.v1_4->display_path[i].display_objid); 339 if (id.type == obj_id.type && id.id == obj_id.id 340 && id.enum_id == obj_id.enum_id) 341 return &bp->object_info_tbl.v1_4->display_path[i]; 342 } 343 fallthrough; 344 default: 345 return NULL; 346 } 347 } 348 349 /* from graphics_object_id, find display path which includes the object_id */ 350 static struct atom_display_object_path_v3 *get_bios_object_from_path_v3( 351 struct bios_parser *bp, 352 struct graphics_object_id id) 353 { 354 unsigned int i; 355 struct graphics_object_id obj_id = {0}; 356 357 switch (id.type) { 358 case OBJECT_TYPE_ENCODER: 359 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) { 360 obj_id = object_id_from_bios_object_id( 361 bp->object_info_tbl.v1_5->display_path[i].encoderobjid); 362 if (id.type == obj_id.type && id.id == obj_id.id 363 && id.enum_id == obj_id.enum_id) 364 return &bp->object_info_tbl.v1_5->display_path[i]; 365 } 366 break; 367 368 case OBJECT_TYPE_CONNECTOR: 369 case OBJECT_TYPE_GENERIC: 370 /* Both Generic and Connector Object ID 371 * will be stored on display_objid 372 */ 373 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) { 374 obj_id = object_id_from_bios_object_id( 375 bp->object_info_tbl.v1_5->display_path[i].display_objid); 376 if (id.type == obj_id.type && id.id == obj_id.id 377 && id.enum_id == obj_id.enum_id) 378 return &bp->object_info_tbl.v1_5->display_path[i]; 379 } 380 break; 381 382 default: 383 return NULL; 384 } 385 386 return NULL; 387 } 388 389 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, 390 struct graphics_object_id id, 391 struct graphics_object_i2c_info *info) 392 { 393 uint32_t offset; 394 struct atom_display_object_path_v2 *object; 395 396 struct atom_display_object_path_v3 *object_path_v3; 397 398 struct atom_common_record_header *header; 399 struct atom_i2c_record *record; 400 struct atom_i2c_record dummy_record = {0}; 401 struct bios_parser *bp = BP_FROM_DCB(dcb); 402 403 if (!info) 404 return BP_RESULT_BADINPUT; 405 406 if (id.type == OBJECT_TYPE_GENERIC) { 407 dummy_record.i2c_id = id.id; 408 409 if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK) 410 return BP_RESULT_OK; 411 else 412 return BP_RESULT_NORECORD; 413 } 414 415 switch (bp->object_info_tbl.revision.minor) { 416 case 4: 417 default: 418 object = get_bios_object(bp, id); 419 420 if (!object) 421 return BP_RESULT_BADINPUT; 422 423 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 424 break; 425 case 5: 426 object_path_v3 = get_bios_object_from_path_v3(bp, id); 427 428 if (!object_path_v3) 429 return BP_RESULT_BADINPUT; 430 431 offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset; 432 break; 433 } 434 435 for (;;) { 436 header = GET_IMAGE(struct atom_common_record_header, offset); 437 438 if (!header) 439 return BP_RESULT_BADBIOSTABLE; 440 441 if (header->record_type == LAST_RECORD_TYPE || 442 !header->record_size) 443 break; 444 445 if (header->record_type == ATOM_I2C_RECORD_TYPE 446 && sizeof(struct atom_i2c_record) <= 447 header->record_size) { 448 /* get the I2C info */ 449 record = (struct atom_i2c_record *) header; 450 451 if (get_gpio_i2c_info(bp, record, info) == 452 BP_RESULT_OK) 453 return BP_RESULT_OK; 454 } 455 456 offset += header->record_size; 457 } 458 459 return BP_RESULT_NORECORD; 460 } 461 462 static enum bp_result get_gpio_i2c_info( 463 struct bios_parser *bp, 464 struct atom_i2c_record *record, 465 struct graphics_object_i2c_info *info) 466 { 467 struct atom_gpio_pin_lut_v2_1 *header; 468 uint32_t count = 0; 469 unsigned int table_index = 0; 470 bool find_valid = false; 471 472 if (!info) 473 return BP_RESULT_BADINPUT; 474 475 /* get the GPIO_I2C info */ 476 if (!DATA_TABLES(gpio_pin_lut)) 477 return BP_RESULT_BADBIOSTABLE; 478 479 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 480 DATA_TABLES(gpio_pin_lut)); 481 if (!header) 482 return BP_RESULT_BADBIOSTABLE; 483 484 if (sizeof(struct atom_common_table_header) + 485 sizeof(struct atom_gpio_pin_assignment) > 486 le16_to_cpu(header->table_header.structuresize)) 487 return BP_RESULT_BADBIOSTABLE; 488 489 /* TODO: is version change? */ 490 if (header->table_header.content_revision != 1) 491 return BP_RESULT_UNSUPPORTED; 492 493 /* get data count */ 494 count = (le16_to_cpu(header->table_header.structuresize) 495 - sizeof(struct atom_common_table_header)) 496 / sizeof(struct atom_gpio_pin_assignment); 497 498 for (table_index = 0; table_index < count; table_index++) { 499 if (((record->i2c_id & I2C_HW_CAP) == ( 500 header->gpio_pin[table_index].gpio_id & 501 I2C_HW_CAP)) && 502 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == 503 (header->gpio_pin[table_index].gpio_id & 504 I2C_HW_ENGINE_ID_MASK)) && 505 ((record->i2c_id & I2C_HW_LANE_MUX) == 506 (header->gpio_pin[table_index].gpio_id & 507 I2C_HW_LANE_MUX))) { 508 /* still valid */ 509 find_valid = true; 510 break; 511 } 512 } 513 514 /* If we don't find the entry that we are looking for then 515 * we will return BP_Result_BadBiosTable. 516 */ 517 if (find_valid == false) 518 return BP_RESULT_BADBIOSTABLE; 519 520 /* get the GPIO_I2C_INFO */ 521 info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false; 522 info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX; 523 info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4; 524 info->i2c_slave_address = record->i2c_slave_addr; 525 526 /* TODO: check how to get register offset for en, Y, etc. */ 527 info->gpio_info.clk_a_register_index = 528 le16_to_cpu( 529 header->gpio_pin[table_index].data_a_reg_index); 530 info->gpio_info.clk_a_shift = 531 header->gpio_pin[table_index].gpio_bitshift; 532 533 return BP_RESULT_OK; 534 } 535 536 static struct atom_hpd_int_record *get_hpd_record_for_path_v3( 537 struct bios_parser *bp, 538 struct atom_display_object_path_v3 *object) 539 { 540 struct atom_common_record_header *header; 541 uint32_t offset; 542 543 if (!object) { 544 BREAK_TO_DEBUGGER(); /* Invalid object */ 545 return NULL; 546 } 547 548 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 549 550 for (;;) { 551 header = GET_IMAGE(struct atom_common_record_header, offset); 552 553 if (!header) 554 return NULL; 555 556 if (header->record_type == ATOM_RECORD_END_TYPE || 557 !header->record_size) 558 break; 559 560 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE 561 && sizeof(struct atom_hpd_int_record) <= 562 header->record_size) 563 return (struct atom_hpd_int_record *) header; 564 565 offset += header->record_size; 566 } 567 568 return NULL; 569 } 570 571 static enum bp_result bios_parser_get_hpd_info( 572 struct dc_bios *dcb, 573 struct graphics_object_id id, 574 struct graphics_object_hpd_info *info) 575 { 576 struct bios_parser *bp = BP_FROM_DCB(dcb); 577 struct atom_display_object_path_v2 *object; 578 struct atom_display_object_path_v3 *object_path_v3; 579 struct atom_hpd_int_record *record = NULL; 580 581 if (!info) 582 return BP_RESULT_BADINPUT; 583 584 switch (bp->object_info_tbl.revision.minor) { 585 case 4: 586 default: 587 object = get_bios_object(bp, id); 588 589 if (!object) 590 return BP_RESULT_BADINPUT; 591 592 record = get_hpd_record(bp, object); 593 594 break; 595 case 5: 596 object_path_v3 = get_bios_object_from_path_v3(bp, id); 597 598 if (!object_path_v3) 599 return BP_RESULT_BADINPUT; 600 601 record = get_hpd_record_for_path_v3(bp, object_path_v3); 602 break; 603 } 604 605 if (record != NULL) { 606 info->hpd_int_gpio_uid = record->pin_id; 607 info->hpd_active = record->plugin_pin_state; 608 return BP_RESULT_OK; 609 } 610 611 return BP_RESULT_NORECORD; 612 } 613 614 static struct atom_hpd_int_record *get_hpd_record( 615 struct bios_parser *bp, 616 struct atom_display_object_path_v2 *object) 617 { 618 struct atom_common_record_header *header; 619 uint32_t offset; 620 621 if (!object) { 622 BREAK_TO_DEBUGGER(); /* Invalid object */ 623 return NULL; 624 } 625 626 offset = le16_to_cpu(object->disp_recordoffset) 627 + bp->object_info_tbl_offset; 628 629 for (;;) { 630 header = GET_IMAGE(struct atom_common_record_header, offset); 631 632 if (!header) 633 return NULL; 634 635 if (header->record_type == LAST_RECORD_TYPE || 636 !header->record_size) 637 break; 638 639 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE 640 && sizeof(struct atom_hpd_int_record) <= 641 header->record_size) 642 return (struct atom_hpd_int_record *) header; 643 644 offset += header->record_size; 645 } 646 647 return NULL; 648 } 649 650 /** 651 * bios_parser_get_gpio_pin_info 652 * Get GpioPin information of input gpio id 653 * 654 * @dcb: pointer to the DC BIOS 655 * @gpio_id: GPIO ID 656 * @info: GpioPin information structure 657 * return: Bios parser result code 658 * note: 659 * to get the GPIO PIN INFO, we need: 660 * 1. get the GPIO_ID from other object table, see GetHPDInfo() 661 * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, 662 * to get the registerA offset/mask 663 */ 664 static enum bp_result bios_parser_get_gpio_pin_info( 665 struct dc_bios *dcb, 666 uint32_t gpio_id, 667 struct gpio_pin_info *info) 668 { 669 struct bios_parser *bp = BP_FROM_DCB(dcb); 670 struct atom_gpio_pin_lut_v2_1 *header; 671 uint32_t count = 0; 672 uint32_t i = 0; 673 674 if (!DATA_TABLES(gpio_pin_lut)) 675 return BP_RESULT_BADBIOSTABLE; 676 677 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, 678 DATA_TABLES(gpio_pin_lut)); 679 if (!header) 680 return BP_RESULT_BADBIOSTABLE; 681 682 if (sizeof(struct atom_common_table_header) + 683 sizeof(struct atom_gpio_pin_assignment) 684 > le16_to_cpu(header->table_header.structuresize)) 685 return BP_RESULT_BADBIOSTABLE; 686 687 if (header->table_header.content_revision != 1) 688 return BP_RESULT_UNSUPPORTED; 689 690 /* Temporary hard code gpio pin info */ 691 count = (le16_to_cpu(header->table_header.structuresize) 692 - sizeof(struct atom_common_table_header)) 693 / sizeof(struct atom_gpio_pin_assignment); 694 for (i = 0; i < count; ++i) { 695 if (header->gpio_pin[i].gpio_id != gpio_id) 696 continue; 697 698 info->offset = 699 (uint32_t) le16_to_cpu( 700 header->gpio_pin[i].data_a_reg_index); 701 info->offset_y = info->offset + 2; 702 info->offset_en = info->offset + 1; 703 info->offset_mask = info->offset - 1; 704 705 info->mask = (uint32_t) (1 << 706 header->gpio_pin[i].gpio_bitshift); 707 info->mask_y = info->mask + 2; 708 info->mask_en = info->mask + 1; 709 info->mask_mask = info->mask - 1; 710 711 return BP_RESULT_OK; 712 } 713 714 return BP_RESULT_NORECORD; 715 } 716 717 static struct device_id device_type_from_device_id(uint16_t device_id) 718 { 719 720 struct device_id result_device_id; 721 722 result_device_id.raw_device_tag = device_id; 723 724 switch (device_id) { 725 case ATOM_DISPLAY_LCD1_SUPPORT: 726 result_device_id.device_type = DEVICE_TYPE_LCD; 727 result_device_id.enum_id = 1; 728 break; 729 730 case ATOM_DISPLAY_LCD2_SUPPORT: 731 result_device_id.device_type = DEVICE_TYPE_LCD; 732 result_device_id.enum_id = 2; 733 break; 734 735 case ATOM_DISPLAY_DFP1_SUPPORT: 736 result_device_id.device_type = DEVICE_TYPE_DFP; 737 result_device_id.enum_id = 1; 738 break; 739 740 case ATOM_DISPLAY_DFP2_SUPPORT: 741 result_device_id.device_type = DEVICE_TYPE_DFP; 742 result_device_id.enum_id = 2; 743 break; 744 745 case ATOM_DISPLAY_DFP3_SUPPORT: 746 result_device_id.device_type = DEVICE_TYPE_DFP; 747 result_device_id.enum_id = 3; 748 break; 749 750 case ATOM_DISPLAY_DFP4_SUPPORT: 751 result_device_id.device_type = DEVICE_TYPE_DFP; 752 result_device_id.enum_id = 4; 753 break; 754 755 case ATOM_DISPLAY_DFP5_SUPPORT: 756 result_device_id.device_type = DEVICE_TYPE_DFP; 757 result_device_id.enum_id = 5; 758 break; 759 760 case ATOM_DISPLAY_DFP6_SUPPORT: 761 result_device_id.device_type = DEVICE_TYPE_DFP; 762 result_device_id.enum_id = 6; 763 break; 764 765 default: 766 BREAK_TO_DEBUGGER(); /* Invalid device Id */ 767 result_device_id.device_type = DEVICE_TYPE_UNKNOWN; 768 result_device_id.enum_id = 0; 769 } 770 return result_device_id; 771 } 772 773 static enum bp_result bios_parser_get_device_tag( 774 struct dc_bios *dcb, 775 struct graphics_object_id connector_object_id, 776 uint32_t device_tag_index, 777 struct connector_device_tag_info *info) 778 { 779 struct bios_parser *bp = BP_FROM_DCB(dcb); 780 struct atom_display_object_path_v2 *object; 781 782 struct atom_display_object_path_v3 *object_path_v3; 783 784 785 if (!info) 786 return BP_RESULT_BADINPUT; 787 788 switch (bp->object_info_tbl.revision.minor) { 789 case 4: 790 default: 791 /* getBiosObject will return MXM object */ 792 object = get_bios_object(bp, connector_object_id); 793 794 if (!object) { 795 BREAK_TO_DEBUGGER(); /* Invalid object id */ 796 return BP_RESULT_BADINPUT; 797 } 798 799 info->acpi_device = 0; /* BIOS no longer provides this */ 800 info->dev_id = device_type_from_device_id(object->device_tag); 801 break; 802 case 5: 803 object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id); 804 805 if (!object_path_v3) { 806 BREAK_TO_DEBUGGER(); /* Invalid object id */ 807 return BP_RESULT_BADINPUT; 808 } 809 info->acpi_device = 0; /* BIOS no longer provides this */ 810 info->dev_id = device_type_from_device_id(object_path_v3->device_tag); 811 break; 812 } 813 814 return BP_RESULT_OK; 815 } 816 817 static enum bp_result get_ss_info_v4_1( 818 struct bios_parser *bp, 819 uint32_t id, 820 uint32_t index, 821 struct spread_spectrum_info *ss_info) 822 { 823 enum bp_result result = BP_RESULT_OK; 824 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; 825 struct atom_smu_info_v3_3 *smu_info = NULL; 826 827 if (!ss_info) 828 return BP_RESULT_BADINPUT; 829 830 if (!DATA_TABLES(dce_info)) 831 return BP_RESULT_BADBIOSTABLE; 832 833 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, 834 DATA_TABLES(dce_info)); 835 if (!disp_cntl_tbl) 836 return BP_RESULT_BADBIOSTABLE; 837 838 839 ss_info->type.STEP_AND_DELAY_INFO = false; 840 ss_info->spread_percentage_divider = 1000; 841 /* BIOS no longer uses target clock. Always enable for now */ 842 ss_info->target_clock_range = 0xffffffff; 843 844 switch (id) { 845 case AS_SIGNAL_TYPE_DVI: 846 ss_info->spread_spectrum_percentage = 847 disp_cntl_tbl->dvi_ss_percentage; 848 ss_info->spread_spectrum_range = 849 disp_cntl_tbl->dvi_ss_rate_10hz * 10; 850 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 851 ss_info->type.CENTER_MODE = true; 852 break; 853 case AS_SIGNAL_TYPE_HDMI: 854 ss_info->spread_spectrum_percentage = 855 disp_cntl_tbl->hdmi_ss_percentage; 856 ss_info->spread_spectrum_range = 857 disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 858 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 859 ss_info->type.CENTER_MODE = true; 860 break; 861 /* TODO LVDS not support anymore? */ 862 case AS_SIGNAL_TYPE_DISPLAY_PORT: 863 ss_info->spread_spectrum_percentage = 864 disp_cntl_tbl->dp_ss_percentage; 865 ss_info->spread_spectrum_range = 866 disp_cntl_tbl->dp_ss_rate_10hz * 10; 867 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 868 ss_info->type.CENTER_MODE = true; 869 break; 870 case AS_SIGNAL_TYPE_GPU_PLL: 871 /* atom_firmware: DAL only get data from dce_info table. 872 * if data within smu_info is needed for DAL, VBIOS should 873 * copy it into dce_info 874 */ 875 result = BP_RESULT_UNSUPPORTED; 876 break; 877 case AS_SIGNAL_TYPE_XGMI: 878 smu_info = GET_IMAGE(struct atom_smu_info_v3_3, 879 DATA_TABLES(smu_info)); 880 if (!smu_info) 881 return BP_RESULT_BADBIOSTABLE; 882 883 ss_info->spread_spectrum_percentage = 884 smu_info->waflclk_ss_percentage; 885 ss_info->spread_spectrum_range = 886 smu_info->gpuclk_ss_rate_10hz * 10; 887 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 888 ss_info->type.CENTER_MODE = true; 889 break; 890 default: 891 result = BP_RESULT_UNSUPPORTED; 892 } 893 894 return result; 895 } 896 897 static enum bp_result get_ss_info_v4_2( 898 struct bios_parser *bp, 899 uint32_t id, 900 uint32_t index, 901 struct spread_spectrum_info *ss_info) 902 { 903 enum bp_result result = BP_RESULT_OK; 904 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; 905 struct atom_smu_info_v3_1 *smu_info = NULL; 906 907 if (!ss_info) 908 return BP_RESULT_BADINPUT; 909 910 if (!DATA_TABLES(dce_info)) 911 return BP_RESULT_BADBIOSTABLE; 912 913 if (!DATA_TABLES(smu_info)) 914 return BP_RESULT_BADBIOSTABLE; 915 916 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, 917 DATA_TABLES(dce_info)); 918 if (!disp_cntl_tbl) 919 return BP_RESULT_BADBIOSTABLE; 920 921 smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info)); 922 if (!smu_info) 923 return BP_RESULT_BADBIOSTABLE; 924 925 ss_info->type.STEP_AND_DELAY_INFO = false; 926 ss_info->spread_percentage_divider = 1000; 927 /* BIOS no longer uses target clock. Always enable for now */ 928 ss_info->target_clock_range = 0xffffffff; 929 930 switch (id) { 931 case AS_SIGNAL_TYPE_DVI: 932 ss_info->spread_spectrum_percentage = 933 disp_cntl_tbl->dvi_ss_percentage; 934 ss_info->spread_spectrum_range = 935 disp_cntl_tbl->dvi_ss_rate_10hz * 10; 936 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 937 ss_info->type.CENTER_MODE = true; 938 break; 939 case AS_SIGNAL_TYPE_HDMI: 940 ss_info->spread_spectrum_percentage = 941 disp_cntl_tbl->hdmi_ss_percentage; 942 ss_info->spread_spectrum_range = 943 disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 944 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 945 ss_info->type.CENTER_MODE = true; 946 break; 947 /* TODO LVDS not support anymore? */ 948 case AS_SIGNAL_TYPE_DISPLAY_PORT: 949 ss_info->spread_spectrum_percentage = 950 smu_info->gpuclk_ss_percentage; 951 ss_info->spread_spectrum_range = 952 smu_info->gpuclk_ss_rate_10hz * 10; 953 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 954 ss_info->type.CENTER_MODE = true; 955 break; 956 case AS_SIGNAL_TYPE_GPU_PLL: 957 /* atom_firmware: DAL only get data from dce_info table. 958 * if data within smu_info is needed for DAL, VBIOS should 959 * copy it into dce_info 960 */ 961 result = BP_RESULT_UNSUPPORTED; 962 break; 963 default: 964 result = BP_RESULT_UNSUPPORTED; 965 } 966 967 return result; 968 } 969 970 static enum bp_result get_ss_info_v4_5( 971 struct bios_parser *bp, 972 uint32_t id, 973 uint32_t index, 974 struct spread_spectrum_info *ss_info) 975 { 976 enum bp_result result = BP_RESULT_OK; 977 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 978 979 if (!ss_info) 980 return BP_RESULT_BADINPUT; 981 982 if (!DATA_TABLES(dce_info)) 983 return BP_RESULT_BADBIOSTABLE; 984 985 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 986 DATA_TABLES(dce_info)); 987 if (!disp_cntl_tbl) 988 return BP_RESULT_BADBIOSTABLE; 989 990 ss_info->type.STEP_AND_DELAY_INFO = false; 991 ss_info->spread_percentage_divider = 1000; 992 /* BIOS no longer uses target clock. Always enable for now */ 993 ss_info->target_clock_range = 0xffffffff; 994 995 switch (id) { 996 case AS_SIGNAL_TYPE_DVI: 997 ss_info->spread_spectrum_percentage = 998 disp_cntl_tbl->dvi_ss_percentage; 999 ss_info->spread_spectrum_range = 1000 disp_cntl_tbl->dvi_ss_rate_10hz * 10; 1001 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 1002 ss_info->type.CENTER_MODE = true; 1003 break; 1004 case AS_SIGNAL_TYPE_HDMI: 1005 ss_info->spread_spectrum_percentage = 1006 disp_cntl_tbl->hdmi_ss_percentage; 1007 ss_info->spread_spectrum_range = 1008 disp_cntl_tbl->hdmi_ss_rate_10hz * 10; 1009 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 1010 ss_info->type.CENTER_MODE = true; 1011 break; 1012 case AS_SIGNAL_TYPE_DISPLAY_PORT: 1013 ss_info->spread_spectrum_percentage = 1014 disp_cntl_tbl->dp_ss_percentage; 1015 ss_info->spread_spectrum_range = 1016 disp_cntl_tbl->dp_ss_rate_10hz * 10; 1017 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) 1018 ss_info->type.CENTER_MODE = true; 1019 break; 1020 case AS_SIGNAL_TYPE_GPU_PLL: 1021 /* atom_smu_info_v4_0 does not have fields for SS for SMU Display PLL anymore. 1022 * SMU Display PLL supposed to be without spread. 1023 * Better place for it would be in atom_display_controller_info_v4_5 table. 1024 */ 1025 result = BP_RESULT_UNSUPPORTED; 1026 break; 1027 default: 1028 result = BP_RESULT_UNSUPPORTED; 1029 break; 1030 } 1031 1032 return result; 1033 } 1034 1035 /** 1036 * bios_parser_get_spread_spectrum_info 1037 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or 1038 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info 1039 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info 1040 * ver 3.1, 1041 * there is only one entry for each signal /ss id. However, there is 1042 * no planning of supporting multiple spread Sprectum entry for EverGreen 1043 * @dcb: pointer to the DC BIOS 1044 * @signal: ASSignalType to be converted to info index 1045 * @index: number of entries that match the converted info index 1046 * @ss_info: sprectrum information structure, 1047 * return: Bios parser result code 1048 */ 1049 static enum bp_result bios_parser_get_spread_spectrum_info( 1050 struct dc_bios *dcb, 1051 enum as_signal_type signal, 1052 uint32_t index, 1053 struct spread_spectrum_info *ss_info) 1054 { 1055 struct bios_parser *bp = BP_FROM_DCB(dcb); 1056 enum bp_result result = BP_RESULT_UNSUPPORTED; 1057 struct atom_common_table_header *header; 1058 struct atom_data_revision tbl_revision; 1059 1060 if (!ss_info) /* check for bad input */ 1061 return BP_RESULT_BADINPUT; 1062 1063 if (!DATA_TABLES(dce_info)) 1064 return BP_RESULT_UNSUPPORTED; 1065 1066 header = GET_IMAGE(struct atom_common_table_header, 1067 DATA_TABLES(dce_info)); 1068 get_atom_data_table_revision(header, &tbl_revision); 1069 1070 switch (tbl_revision.major) { 1071 case 4: 1072 switch (tbl_revision.minor) { 1073 case 1: 1074 return get_ss_info_v4_1(bp, signal, index, ss_info); 1075 case 2: 1076 case 3: 1077 case 4: 1078 return get_ss_info_v4_2(bp, signal, index, ss_info); 1079 case 5: 1080 return get_ss_info_v4_5(bp, signal, index, ss_info); 1081 1082 default: 1083 ASSERT(0); 1084 break; 1085 } 1086 break; 1087 default: 1088 break; 1089 } 1090 /* there can not be more then one entry for SS Info table */ 1091 return result; 1092 } 1093 1094 static enum bp_result get_soc_bb_info_v4_4( 1095 struct bios_parser *bp, 1096 struct bp_soc_bb_info *soc_bb_info) 1097 { 1098 enum bp_result result = BP_RESULT_OK; 1099 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; 1100 1101 if (!soc_bb_info) 1102 return BP_RESULT_BADINPUT; 1103 1104 if (!DATA_TABLES(dce_info)) 1105 return BP_RESULT_BADBIOSTABLE; 1106 1107 if (!DATA_TABLES(smu_info)) 1108 return BP_RESULT_BADBIOSTABLE; 1109 1110 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, 1111 DATA_TABLES(dce_info)); 1112 if (!disp_cntl_tbl) 1113 return BP_RESULT_BADBIOSTABLE; 1114 1115 soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat; 1116 soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat; 1117 soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat; 1118 1119 return result; 1120 } 1121 1122 static enum bp_result get_soc_bb_info_v4_5( 1123 struct bios_parser *bp, 1124 struct bp_soc_bb_info *soc_bb_info) 1125 { 1126 enum bp_result result = BP_RESULT_OK; 1127 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 1128 1129 if (!soc_bb_info) 1130 return BP_RESULT_BADINPUT; 1131 1132 if (!DATA_TABLES(dce_info)) 1133 return BP_RESULT_BADBIOSTABLE; 1134 1135 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 1136 DATA_TABLES(dce_info)); 1137 if (!disp_cntl_tbl) 1138 return BP_RESULT_BADBIOSTABLE; 1139 1140 soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat; 1141 soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat; 1142 soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat; 1143 1144 return result; 1145 } 1146 1147 static enum bp_result bios_parser_get_soc_bb_info( 1148 struct dc_bios *dcb, 1149 struct bp_soc_bb_info *soc_bb_info) 1150 { 1151 struct bios_parser *bp = BP_FROM_DCB(dcb); 1152 enum bp_result result = BP_RESULT_UNSUPPORTED; 1153 struct atom_common_table_header *header; 1154 struct atom_data_revision tbl_revision; 1155 1156 if (!soc_bb_info) /* check for bad input */ 1157 return BP_RESULT_BADINPUT; 1158 1159 if (!DATA_TABLES(dce_info)) 1160 return BP_RESULT_UNSUPPORTED; 1161 1162 header = GET_IMAGE(struct atom_common_table_header, 1163 DATA_TABLES(dce_info)); 1164 get_atom_data_table_revision(header, &tbl_revision); 1165 1166 switch (tbl_revision.major) { 1167 case 4: 1168 switch (tbl_revision.minor) { 1169 case 1: 1170 case 2: 1171 case 3: 1172 break; 1173 case 4: 1174 result = get_soc_bb_info_v4_4(bp, soc_bb_info); 1175 break; 1176 case 5: 1177 result = get_soc_bb_info_v4_5(bp, soc_bb_info); 1178 break; 1179 default: 1180 break; 1181 } 1182 break; 1183 default: 1184 break; 1185 } 1186 1187 return result; 1188 } 1189 1190 static enum bp_result get_disp_caps_v4_1( 1191 struct bios_parser *bp, 1192 uint8_t *dce_caps) 1193 { 1194 enum bp_result result = BP_RESULT_OK; 1195 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; 1196 1197 if (!dce_caps) 1198 return BP_RESULT_BADINPUT; 1199 1200 if (!DATA_TABLES(dce_info)) 1201 return BP_RESULT_BADBIOSTABLE; 1202 1203 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1, 1204 DATA_TABLES(dce_info)); 1205 1206 if (!disp_cntl_tbl) 1207 return BP_RESULT_BADBIOSTABLE; 1208 1209 *dce_caps = disp_cntl_tbl->display_caps; 1210 1211 return result; 1212 } 1213 1214 static enum bp_result get_disp_caps_v4_2( 1215 struct bios_parser *bp, 1216 uint8_t *dce_caps) 1217 { 1218 enum bp_result result = BP_RESULT_OK; 1219 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL; 1220 1221 if (!dce_caps) 1222 return BP_RESULT_BADINPUT; 1223 1224 if (!DATA_TABLES(dce_info)) 1225 return BP_RESULT_BADBIOSTABLE; 1226 1227 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2, 1228 DATA_TABLES(dce_info)); 1229 1230 if (!disp_cntl_tbl) 1231 return BP_RESULT_BADBIOSTABLE; 1232 1233 *dce_caps = disp_cntl_tbl->display_caps; 1234 1235 return result; 1236 } 1237 1238 static enum bp_result get_disp_caps_v4_3( 1239 struct bios_parser *bp, 1240 uint8_t *dce_caps) 1241 { 1242 enum bp_result result = BP_RESULT_OK; 1243 struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL; 1244 1245 if (!dce_caps) 1246 return BP_RESULT_BADINPUT; 1247 1248 if (!DATA_TABLES(dce_info)) 1249 return BP_RESULT_BADBIOSTABLE; 1250 1251 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3, 1252 DATA_TABLES(dce_info)); 1253 1254 if (!disp_cntl_tbl) 1255 return BP_RESULT_BADBIOSTABLE; 1256 1257 *dce_caps = disp_cntl_tbl->display_caps; 1258 1259 return result; 1260 } 1261 1262 static enum bp_result get_disp_caps_v4_4( 1263 struct bios_parser *bp, 1264 uint8_t *dce_caps) 1265 { 1266 enum bp_result result = BP_RESULT_OK; 1267 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL; 1268 1269 if (!dce_caps) 1270 return BP_RESULT_BADINPUT; 1271 1272 if (!DATA_TABLES(dce_info)) 1273 return BP_RESULT_BADBIOSTABLE; 1274 1275 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4, 1276 DATA_TABLES(dce_info)); 1277 1278 if (!disp_cntl_tbl) 1279 return BP_RESULT_BADBIOSTABLE; 1280 1281 *dce_caps = disp_cntl_tbl->display_caps; 1282 1283 return result; 1284 } 1285 1286 static enum bp_result get_disp_caps_v4_5( 1287 struct bios_parser *bp, 1288 uint8_t *dce_caps) 1289 { 1290 enum bp_result result = BP_RESULT_OK; 1291 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL; 1292 1293 if (!dce_caps) 1294 return BP_RESULT_BADINPUT; 1295 1296 if (!DATA_TABLES(dce_info)) 1297 return BP_RESULT_BADBIOSTABLE; 1298 1299 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5, 1300 DATA_TABLES(dce_info)); 1301 1302 if (!disp_cntl_tbl) 1303 return BP_RESULT_BADBIOSTABLE; 1304 1305 *dce_caps = disp_cntl_tbl->display_caps; 1306 1307 return result; 1308 } 1309 1310 static enum bp_result bios_parser_get_lttpr_interop( 1311 struct dc_bios *dcb, 1312 uint8_t *dce_caps) 1313 { 1314 struct bios_parser *bp = BP_FROM_DCB(dcb); 1315 enum bp_result result = BP_RESULT_UNSUPPORTED; 1316 struct atom_common_table_header *header; 1317 struct atom_data_revision tbl_revision; 1318 1319 if (!DATA_TABLES(dce_info)) 1320 return BP_RESULT_UNSUPPORTED; 1321 1322 header = GET_IMAGE(struct atom_common_table_header, 1323 DATA_TABLES(dce_info)); 1324 get_atom_data_table_revision(header, &tbl_revision); 1325 switch (tbl_revision.major) { 1326 case 4: 1327 switch (tbl_revision.minor) { 1328 case 1: 1329 result = get_disp_caps_v4_1(bp, dce_caps); 1330 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 1331 break; 1332 case 2: 1333 result = get_disp_caps_v4_2(bp, dce_caps); 1334 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 1335 break; 1336 case 3: 1337 result = get_disp_caps_v4_3(bp, dce_caps); 1338 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 1339 break; 1340 case 4: 1341 result = get_disp_caps_v4_4(bp, dce_caps); 1342 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 1343 break; 1344 case 5: 1345 result = get_disp_caps_v4_5(bp, dce_caps); 1346 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE); 1347 break; 1348 1349 default: 1350 break; 1351 } 1352 break; 1353 default: 1354 break; 1355 } 1356 1357 return result; 1358 } 1359 1360 static enum bp_result bios_parser_get_lttpr_caps( 1361 struct dc_bios *dcb, 1362 uint8_t *dce_caps) 1363 { 1364 struct bios_parser *bp = BP_FROM_DCB(dcb); 1365 enum bp_result result = BP_RESULT_UNSUPPORTED; 1366 struct atom_common_table_header *header; 1367 struct atom_data_revision tbl_revision; 1368 1369 if (!DATA_TABLES(dce_info)) 1370 return BP_RESULT_UNSUPPORTED; 1371 1372 header = GET_IMAGE(struct atom_common_table_header, 1373 DATA_TABLES(dce_info)); 1374 get_atom_data_table_revision(header, &tbl_revision); 1375 switch (tbl_revision.major) { 1376 case 4: 1377 switch (tbl_revision.minor) { 1378 case 1: 1379 result = get_disp_caps_v4_1(bp, dce_caps); 1380 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 1381 break; 1382 case 2: 1383 result = get_disp_caps_v4_2(bp, dce_caps); 1384 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 1385 break; 1386 case 3: 1387 result = get_disp_caps_v4_3(bp, dce_caps); 1388 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 1389 break; 1390 case 4: 1391 result = get_disp_caps_v4_4(bp, dce_caps); 1392 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 1393 break; 1394 case 5: 1395 result = get_disp_caps_v4_5(bp, dce_caps); 1396 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE); 1397 break; 1398 default: 1399 break; 1400 } 1401 break; 1402 default: 1403 break; 1404 } 1405 1406 return result; 1407 } 1408 1409 static enum bp_result get_embedded_panel_info_v2_1( 1410 struct bios_parser *bp, 1411 struct embedded_panel_info *info) 1412 { 1413 struct lcd_info_v2_1 *lvds; 1414 1415 if (!info) 1416 return BP_RESULT_BADINPUT; 1417 1418 if (!DATA_TABLES(lcd_info)) 1419 return BP_RESULT_UNSUPPORTED; 1420 1421 lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info)); 1422 1423 if (!lvds) 1424 return BP_RESULT_BADBIOSTABLE; 1425 1426 /* TODO: previous vv1_3, should v2_1 */ 1427 if (!((lvds->table_header.format_revision == 2) 1428 && (lvds->table_header.content_revision >= 1))) 1429 return BP_RESULT_UNSUPPORTED; 1430 1431 memset(info, 0, sizeof(struct embedded_panel_info)); 1432 1433 /* We need to convert from 10KHz units into KHz units */ 1434 info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10; 1435 /* usHActive does not include borders, according to VBIOS team */ 1436 info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active); 1437 /* usHBlanking_Time includes borders, so we should really be 1438 * subtractingborders duing this translation, but LVDS generally 1439 * doesn't have borders, so we should be okay leaving this as is for 1440 * now. May need to revisit if we ever have LVDS with borders 1441 */ 1442 info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time); 1443 /* usVActive does not include borders, according to VBIOS team*/ 1444 info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active); 1445 /* usVBlanking_Time includes borders, so we should really be 1446 * subtracting borders duing this translation, but LVDS generally 1447 * doesn't have borders, so we should be okay leaving this as is for 1448 * now. May need to revisit if we ever have LVDS with borders 1449 */ 1450 info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time); 1451 info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset); 1452 info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width); 1453 info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset); 1454 info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth); 1455 info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border; 1456 info->lcd_timing.vertical_border = lvds->lcd_timing.v_border; 1457 1458 /* not provided by VBIOS */ 1459 info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; 1460 1461 info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 1462 & ATOM_HSYNC_POLARITY); 1463 info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo 1464 & ATOM_VSYNC_POLARITY); 1465 1466 /* not provided by VBIOS */ 1467 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; 1468 1469 info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 1470 & ATOM_H_REPLICATIONBY2); 1471 info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo 1472 & ATOM_V_REPLICATIONBY2); 1473 info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo 1474 & ATOM_COMPOSITESYNC); 1475 info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE); 1476 1477 /* not provided by VBIOS*/ 1478 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; 1479 /* not provided by VBIOS*/ 1480 info->ss_id = 0; 1481 1482 info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID); 1483 1484 return BP_RESULT_OK; 1485 } 1486 1487 static enum bp_result bios_parser_get_embedded_panel_info( 1488 struct dc_bios *dcb, 1489 struct embedded_panel_info *info) 1490 { 1491 struct bios_parser 1492 *bp = BP_FROM_DCB(dcb); 1493 struct atom_common_table_header *header; 1494 struct atom_data_revision tbl_revision; 1495 1496 if (!DATA_TABLES(lcd_info)) 1497 return BP_RESULT_FAILURE; 1498 1499 header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info)); 1500 1501 if (!header) 1502 return BP_RESULT_BADBIOSTABLE; 1503 1504 get_atom_data_table_revision(header, &tbl_revision); 1505 1506 switch (tbl_revision.major) { 1507 case 2: 1508 switch (tbl_revision.minor) { 1509 case 1: 1510 return get_embedded_panel_info_v2_1(bp, info); 1511 default: 1512 break; 1513 } 1514 break; 1515 default: 1516 break; 1517 } 1518 1519 return BP_RESULT_FAILURE; 1520 } 1521 1522 static uint32_t get_support_mask_for_device_id(struct device_id device_id) 1523 { 1524 enum dal_device_type device_type = device_id.device_type; 1525 uint32_t enum_id = device_id.enum_id; 1526 1527 switch (device_type) { 1528 case DEVICE_TYPE_LCD: 1529 switch (enum_id) { 1530 case 1: 1531 return ATOM_DISPLAY_LCD1_SUPPORT; 1532 default: 1533 break; 1534 } 1535 break; 1536 case DEVICE_TYPE_DFP: 1537 switch (enum_id) { 1538 case 1: 1539 return ATOM_DISPLAY_DFP1_SUPPORT; 1540 case 2: 1541 return ATOM_DISPLAY_DFP2_SUPPORT; 1542 case 3: 1543 return ATOM_DISPLAY_DFP3_SUPPORT; 1544 case 4: 1545 return ATOM_DISPLAY_DFP4_SUPPORT; 1546 case 5: 1547 return ATOM_DISPLAY_DFP5_SUPPORT; 1548 case 6: 1549 return ATOM_DISPLAY_DFP6_SUPPORT; 1550 default: 1551 break; 1552 } 1553 break; 1554 default: 1555 break; 1556 } 1557 1558 /* Unidentified device ID, return empty support mask. */ 1559 return 0; 1560 } 1561 1562 static bool bios_parser_is_device_id_supported( 1563 struct dc_bios *dcb, 1564 struct device_id id) 1565 { 1566 struct bios_parser *bp = BP_FROM_DCB(dcb); 1567 1568 uint32_t mask = get_support_mask_for_device_id(id); 1569 1570 switch (bp->object_info_tbl.revision.minor) { 1571 case 4: 1572 default: 1573 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0; 1574 break; 1575 case 5: 1576 return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0; 1577 break; 1578 } 1579 1580 return false; 1581 } 1582 1583 static uint32_t bios_parser_get_ss_entry_number( 1584 struct dc_bios *dcb, 1585 enum as_signal_type signal) 1586 { 1587 /* TODO: DAL2 atomfirmware implementation does not need this. 1588 * why DAL3 need this? 1589 */ 1590 return 1; 1591 } 1592 1593 static enum bp_result bios_parser_transmitter_control( 1594 struct dc_bios *dcb, 1595 struct bp_transmitter_control *cntl) 1596 { 1597 struct bios_parser *bp = BP_FROM_DCB(dcb); 1598 1599 if (!bp->cmd_tbl.transmitter_control) 1600 return BP_RESULT_FAILURE; 1601 1602 return bp->cmd_tbl.transmitter_control(bp, cntl); 1603 } 1604 1605 static enum bp_result bios_parser_encoder_control( 1606 struct dc_bios *dcb, 1607 struct bp_encoder_control *cntl) 1608 { 1609 struct bios_parser *bp = BP_FROM_DCB(dcb); 1610 1611 if (!bp->cmd_tbl.dig_encoder_control) 1612 return BP_RESULT_FAILURE; 1613 1614 return bp->cmd_tbl.dig_encoder_control(bp, cntl); 1615 } 1616 1617 static enum bp_result bios_parser_set_pixel_clock( 1618 struct dc_bios *dcb, 1619 struct bp_pixel_clock_parameters *bp_params) 1620 { 1621 struct bios_parser *bp = BP_FROM_DCB(dcb); 1622 1623 if (!bp->cmd_tbl.set_pixel_clock) 1624 return BP_RESULT_FAILURE; 1625 1626 return bp->cmd_tbl.set_pixel_clock(bp, bp_params); 1627 } 1628 1629 static enum bp_result bios_parser_set_dce_clock( 1630 struct dc_bios *dcb, 1631 struct bp_set_dce_clock_parameters *bp_params) 1632 { 1633 struct bios_parser *bp = BP_FROM_DCB(dcb); 1634 1635 if (!bp->cmd_tbl.set_dce_clock) 1636 return BP_RESULT_FAILURE; 1637 1638 return bp->cmd_tbl.set_dce_clock(bp, bp_params); 1639 } 1640 1641 static enum bp_result bios_parser_program_crtc_timing( 1642 struct dc_bios *dcb, 1643 struct bp_hw_crtc_timing_parameters *bp_params) 1644 { 1645 struct bios_parser *bp = BP_FROM_DCB(dcb); 1646 1647 if (!bp->cmd_tbl.set_crtc_timing) 1648 return BP_RESULT_FAILURE; 1649 1650 return bp->cmd_tbl.set_crtc_timing(bp, bp_params); 1651 } 1652 1653 static enum bp_result bios_parser_enable_crtc( 1654 struct dc_bios *dcb, 1655 enum controller_id id, 1656 bool enable) 1657 { 1658 struct bios_parser *bp = BP_FROM_DCB(dcb); 1659 1660 if (!bp->cmd_tbl.enable_crtc) 1661 return BP_RESULT_FAILURE; 1662 1663 return bp->cmd_tbl.enable_crtc(bp, id, enable); 1664 } 1665 1666 static enum bp_result bios_parser_enable_disp_power_gating( 1667 struct dc_bios *dcb, 1668 enum controller_id controller_id, 1669 enum bp_pipe_control_action action) 1670 { 1671 struct bios_parser *bp = BP_FROM_DCB(dcb); 1672 1673 if (!bp->cmd_tbl.enable_disp_power_gating) 1674 return BP_RESULT_FAILURE; 1675 1676 return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id, 1677 action); 1678 } 1679 1680 static enum bp_result bios_parser_enable_lvtma_control( 1681 struct dc_bios *dcb, 1682 uint8_t uc_pwr_on, 1683 uint8_t panel_instance) 1684 { 1685 struct bios_parser *bp = BP_FROM_DCB(dcb); 1686 1687 if (!bp->cmd_tbl.enable_lvtma_control) 1688 return BP_RESULT_FAILURE; 1689 1690 return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance); 1691 } 1692 1693 static bool bios_parser_is_accelerated_mode( 1694 struct dc_bios *dcb) 1695 { 1696 return bios_is_accelerated_mode(dcb); 1697 } 1698 1699 /** 1700 * bios_parser_set_scratch_critical_state - update critical state bit 1701 * in VBIOS scratch register 1702 * 1703 * @dcb: pointer to the DC BIO 1704 * @state: set or reset state 1705 */ 1706 static void bios_parser_set_scratch_critical_state( 1707 struct dc_bios *dcb, 1708 bool state) 1709 { 1710 bios_set_scratch_critical_state(dcb, state); 1711 } 1712 1713 struct atom_dig_transmitter_info_header_v5_3 { 1714 struct atom_common_table_header table_header; 1715 uint16_t dpphy_hdmi_settings_offset; 1716 uint16_t dpphy_dvi_settings_offset; 1717 uint16_t dpphy_dp_setting_table_offset; 1718 uint16_t uniphy_xbar_settings_v2_table_offset; 1719 uint16_t dpphy_internal_reg_overide_offset; 1720 }; 1721 1722 static enum bp_result bios_parser_get_firmware_info( 1723 struct dc_bios *dcb, 1724 struct dc_firmware_info *info) 1725 { 1726 struct bios_parser *bp = BP_FROM_DCB(dcb); 1727 static enum bp_result result = BP_RESULT_BADBIOSTABLE; 1728 struct atom_common_table_header *header; 1729 1730 struct atom_data_revision revision; 1731 1732 if (info && DATA_TABLES(firmwareinfo)) { 1733 header = GET_IMAGE(struct atom_common_table_header, 1734 DATA_TABLES(firmwareinfo)); 1735 get_atom_data_table_revision(header, &revision); 1736 switch (revision.major) { 1737 case 3: 1738 switch (revision.minor) { 1739 case 1: 1740 result = get_firmware_info_v3_1(bp, info); 1741 break; 1742 case 2: 1743 case 3: 1744 result = get_firmware_info_v3_2(bp, info); 1745 break; 1746 case 4: 1747 result = get_firmware_info_v3_4(bp, info); 1748 break; 1749 default: 1750 break; 1751 } 1752 break; 1753 default: 1754 break; 1755 } 1756 } 1757 1758 return result; 1759 } 1760 1761 static enum bp_result get_firmware_info_v3_1( 1762 struct bios_parser *bp, 1763 struct dc_firmware_info *info) 1764 { 1765 struct atom_firmware_info_v3_1 *firmware_info; 1766 struct atom_display_controller_info_v4_1 *dce_info = NULL; 1767 1768 if (!info) 1769 return BP_RESULT_BADINPUT; 1770 1771 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1, 1772 DATA_TABLES(firmwareinfo)); 1773 1774 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1775 DATA_TABLES(dce_info)); 1776 1777 if (!firmware_info || !dce_info) 1778 return BP_RESULT_BADBIOSTABLE; 1779 1780 memset(info, 0, sizeof(*info)); 1781 1782 /* Pixel clock pll information. */ 1783 /* We need to convert from 10KHz units into KHz units */ 1784 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1785 info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10; 1786 1787 /* 27MHz for Vega10: */ 1788 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1789 1790 /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1791 if (info->pll_info.crystal_frequency == 0) 1792 info->pll_info.crystal_frequency = 27000; 1793 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1794 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1795 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1796 1797 /* Get GPU PLL VCO Clock */ 1798 1799 if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1800 /* VBIOS gives in 10KHz */ 1801 info->smu_gpu_pll_output_freq = 1802 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1803 } 1804 1805 info->oem_i2c_present = false; 1806 1807 return BP_RESULT_OK; 1808 } 1809 1810 static enum bp_result get_firmware_info_v3_2( 1811 struct bios_parser *bp, 1812 struct dc_firmware_info *info) 1813 { 1814 struct atom_firmware_info_v3_2 *firmware_info; 1815 struct atom_display_controller_info_v4_1 *dce_info = NULL; 1816 struct atom_common_table_header *header; 1817 struct atom_data_revision revision; 1818 struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL; 1819 struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL; 1820 1821 if (!info) 1822 return BP_RESULT_BADINPUT; 1823 1824 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2, 1825 DATA_TABLES(firmwareinfo)); 1826 1827 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, 1828 DATA_TABLES(dce_info)); 1829 1830 if (!firmware_info || !dce_info) 1831 return BP_RESULT_BADBIOSTABLE; 1832 1833 memset(info, 0, sizeof(*info)); 1834 1835 header = GET_IMAGE(struct atom_common_table_header, 1836 DATA_TABLES(smu_info)); 1837 get_atom_data_table_revision(header, &revision); 1838 1839 if (revision.minor == 2) { 1840 /* Vega12 */ 1841 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2, 1842 DATA_TABLES(smu_info)); 1843 1844 if (!smu_info_v3_2) 1845 return BP_RESULT_BADBIOSTABLE; 1846 1847 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10; 1848 } else if (revision.minor == 3) { 1849 /* Vega20 */ 1850 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3, 1851 DATA_TABLES(smu_info)); 1852 1853 if (!smu_info_v3_3) 1854 return BP_RESULT_BADBIOSTABLE; 1855 1856 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10; 1857 } 1858 1859 // We need to convert from 10KHz units into KHz units. 1860 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 1861 1862 /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */ 1863 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; 1864 /* Hardcode frequency if BIOS gives no DCE Ref Clk */ 1865 if (info->pll_info.crystal_frequency == 0) { 1866 if (revision.minor == 2) 1867 info->pll_info.crystal_frequency = 27000; 1868 else if (revision.minor == 3) 1869 info->pll_info.crystal_frequency = 100000; 1870 } 1871 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/ 1872 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; 1873 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; 1874 1875 /* Get GPU PLL VCO Clock */ 1876 if (bp->cmd_tbl.get_smu_clock_info != NULL) { 1877 if (revision.minor == 2) 1878 info->smu_gpu_pll_output_freq = 1879 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10; 1880 else if (revision.minor == 3) 1881 info->smu_gpu_pll_output_freq = 1882 bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10; 1883 } 1884 1885 if (firmware_info->board_i2c_feature_id == 0x2) { 1886 info->oem_i2c_present = true; 1887 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; 1888 } else { 1889 info->oem_i2c_present = false; 1890 } 1891 1892 return BP_RESULT_OK; 1893 } 1894 1895 static enum bp_result get_firmware_info_v3_4( 1896 struct bios_parser *bp, 1897 struct dc_firmware_info *info) 1898 { 1899 struct atom_firmware_info_v3_4 *firmware_info; 1900 struct atom_common_table_header *header; 1901 struct atom_data_revision revision; 1902 struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL; 1903 struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL; 1904 1905 struct atom_smu_info_v3_5 *smu_info_v3_5 = NULL; 1906 struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL; 1907 struct atom_smu_info_v4_0 *smu_info_v4_0 = NULL; 1908 1909 if (!info) 1910 return BP_RESULT_BADINPUT; 1911 1912 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4, 1913 DATA_TABLES(firmwareinfo)); 1914 1915 if (!firmware_info) 1916 return BP_RESULT_BADBIOSTABLE; 1917 1918 memset(info, 0, sizeof(*info)); 1919 1920 header = GET_IMAGE(struct atom_common_table_header, 1921 DATA_TABLES(dce_info)); 1922 1923 get_atom_data_table_revision(header, &revision); 1924 1925 switch (revision.major) { 1926 case 4: 1927 switch (revision.minor) { 1928 case 5: 1929 dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5, 1930 DATA_TABLES(dce_info)); 1931 1932 if (!dce_info_v4_5) 1933 return BP_RESULT_BADBIOSTABLE; 1934 1935 /* 100MHz expected */ 1936 info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10; 1937 info->dp_phy_ref_clk = dce_info_v4_5->dpphy_refclk_10khz * 10; 1938 /* 50MHz expected */ 1939 info->i2c_engine_ref_clk = dce_info_v4_5->i2c_engine_refclk_10khz * 10; 1940 1941 /* For DCN32/321 Display PLL VCO Frequency from dce_info_v4_5 may not be reliable */ 1942 break; 1943 1944 case 4: 1945 dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, 1946 DATA_TABLES(dce_info)); 1947 1948 if (!dce_info_v4_4) 1949 return BP_RESULT_BADBIOSTABLE; 1950 1951 /* 100MHz expected */ 1952 info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10; 1953 info->dp_phy_ref_clk = dce_info_v4_4->dpphy_refclk_10khz * 10; 1954 /* 50MHz expected */ 1955 info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10; 1956 1957 /* Get SMU Display PLL VCO Frequency in KHz*/ 1958 info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10; 1959 break; 1960 1961 default: 1962 /* should not come here, keep as backup, as was before */ 1963 dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1, 1964 DATA_TABLES(dce_info)); 1965 1966 if (!dce_info_v4_1) 1967 return BP_RESULT_BADBIOSTABLE; 1968 1969 info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10; 1970 info->dp_phy_ref_clk = dce_info_v4_1->dpphy_refclk_10khz * 10; 1971 info->i2c_engine_ref_clk = dce_info_v4_1->i2c_engine_refclk_10khz * 10; 1972 break; 1973 } 1974 break; 1975 1976 default: 1977 ASSERT(0); 1978 break; 1979 } 1980 1981 header = GET_IMAGE(struct atom_common_table_header, 1982 DATA_TABLES(smu_info)); 1983 get_atom_data_table_revision(header, &revision); 1984 1985 switch (revision.major) { 1986 case 3: 1987 switch (revision.minor) { 1988 case 5: 1989 smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5, 1990 DATA_TABLES(smu_info)); 1991 1992 if (!smu_info_v3_5) 1993 return BP_RESULT_BADBIOSTABLE; 1994 1995 info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10; 1996 break; 1997 1998 default: 1999 break; 2000 } 2001 break; 2002 2003 case 4: 2004 switch (revision.minor) { 2005 case 0: 2006 smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0, 2007 DATA_TABLES(smu_info)); 2008 2009 if (!smu_info_v4_0) 2010 return BP_RESULT_BADBIOSTABLE; 2011 2012 /* For DCN32/321 bootup DCFCLK from smu_info_v4_0 may not be reliable */ 2013 break; 2014 2015 default: 2016 break; 2017 } 2018 break; 2019 2020 default: 2021 break; 2022 } 2023 2024 // We need to convert from 10KHz units into KHz units. 2025 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; 2026 2027 if (firmware_info->board_i2c_feature_id == 0x2) { 2028 info->oem_i2c_present = true; 2029 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id; 2030 } else { 2031 info->oem_i2c_present = false; 2032 } 2033 2034 return BP_RESULT_OK; 2035 } 2036 2037 static enum bp_result bios_parser_get_encoder_cap_info( 2038 struct dc_bios *dcb, 2039 struct graphics_object_id object_id, 2040 struct bp_encoder_cap_info *info) 2041 { 2042 struct bios_parser *bp = BP_FROM_DCB(dcb); 2043 struct atom_display_object_path_v2 *object; 2044 struct atom_encoder_caps_record *record = NULL; 2045 2046 if (!info) 2047 return BP_RESULT_BADINPUT; 2048 2049 #if defined(CONFIG_DRM_AMD_DC_DCN) 2050 /* encoder cap record not available in v1_5 */ 2051 if (bp->object_info_tbl.revision.minor == 5) 2052 return BP_RESULT_NORECORD; 2053 #endif 2054 2055 object = get_bios_object(bp, object_id); 2056 2057 if (!object) 2058 return BP_RESULT_BADINPUT; 2059 2060 record = get_encoder_cap_record(bp, object); 2061 if (!record) 2062 return BP_RESULT_NORECORD; 2063 DC_LOG_BIOS("record->encodercaps 0x%x for object_id 0x%x", record->encodercaps, object_id.id); 2064 2065 info->DP_HBR2_CAP = (record->encodercaps & 2066 ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0; 2067 info->DP_HBR2_EN = (record->encodercaps & 2068 ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0; 2069 info->DP_HBR3_EN = (record->encodercaps & 2070 ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; 2071 info->HDMI_6GB_EN = (record->encodercaps & 2072 ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; 2073 info->IS_DP2_CAPABLE = (record->encodercaps & 2074 ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0; 2075 info->DP_UHBR10_EN = (record->encodercaps & 2076 ATOM_ENCODER_CAP_RECORD_UHBR10_EN) ? 1 : 0; 2077 info->DP_UHBR13_5_EN = (record->encodercaps & 2078 ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0; 2079 info->DP_UHBR20_EN = (record->encodercaps & 2080 ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0; 2081 info->DP_IS_USB_C = (record->encodercaps & 2082 ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0; 2083 DC_LOG_BIOS("\t info->DP_IS_USB_C %d", info->DP_IS_USB_C); 2084 2085 return BP_RESULT_OK; 2086 } 2087 2088 2089 static struct atom_encoder_caps_record *get_encoder_cap_record( 2090 struct bios_parser *bp, 2091 struct atom_display_object_path_v2 *object) 2092 { 2093 struct atom_common_record_header *header; 2094 uint32_t offset; 2095 2096 if (!object) { 2097 BREAK_TO_DEBUGGER(); /* Invalid object */ 2098 return NULL; 2099 } 2100 2101 offset = object->encoder_recordoffset + bp->object_info_tbl_offset; 2102 2103 for (;;) { 2104 header = GET_IMAGE(struct atom_common_record_header, offset); 2105 2106 if (!header) 2107 return NULL; 2108 2109 offset += header->record_size; 2110 2111 if (header->record_type == LAST_RECORD_TYPE || 2112 !header->record_size) 2113 break; 2114 2115 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE) 2116 continue; 2117 2118 if (sizeof(struct atom_encoder_caps_record) <= 2119 header->record_size) 2120 return (struct atom_encoder_caps_record *)header; 2121 } 2122 2123 return NULL; 2124 } 2125 2126 static struct atom_disp_connector_caps_record *get_disp_connector_caps_record( 2127 struct bios_parser *bp, 2128 struct atom_display_object_path_v2 *object) 2129 { 2130 struct atom_common_record_header *header; 2131 uint32_t offset; 2132 2133 if (!object) { 2134 BREAK_TO_DEBUGGER(); /* Invalid object */ 2135 return NULL; 2136 } 2137 2138 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 2139 2140 for (;;) { 2141 header = GET_IMAGE(struct atom_common_record_header, offset); 2142 2143 if (!header) 2144 return NULL; 2145 2146 offset += header->record_size; 2147 2148 if (header->record_type == LAST_RECORD_TYPE || 2149 !header->record_size) 2150 break; 2151 2152 if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE) 2153 continue; 2154 2155 if (sizeof(struct atom_disp_connector_caps_record) <= 2156 header->record_size) 2157 return (struct atom_disp_connector_caps_record *)header; 2158 } 2159 2160 return NULL; 2161 } 2162 2163 static struct atom_connector_caps_record *get_connector_caps_record( 2164 struct bios_parser *bp, 2165 struct atom_display_object_path_v3 *object) 2166 { 2167 struct atom_common_record_header *header; 2168 uint32_t offset; 2169 2170 if (!object) { 2171 BREAK_TO_DEBUGGER(); /* Invalid object */ 2172 return NULL; 2173 } 2174 2175 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 2176 2177 for (;;) { 2178 header = GET_IMAGE(struct atom_common_record_header, offset); 2179 2180 if (!header) 2181 return NULL; 2182 2183 offset += header->record_size; 2184 2185 if (header->record_type == ATOM_RECORD_END_TYPE || 2186 !header->record_size) 2187 break; 2188 2189 if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE) 2190 continue; 2191 2192 if (sizeof(struct atom_connector_caps_record) <= header->record_size) 2193 return (struct atom_connector_caps_record *)header; 2194 } 2195 2196 return NULL; 2197 } 2198 2199 static enum bp_result bios_parser_get_disp_connector_caps_info( 2200 struct dc_bios *dcb, 2201 struct graphics_object_id object_id, 2202 struct bp_disp_connector_caps_info *info) 2203 { 2204 struct bios_parser *bp = BP_FROM_DCB(dcb); 2205 struct atom_display_object_path_v2 *object; 2206 2207 struct atom_display_object_path_v3 *object_path_v3; 2208 struct atom_connector_caps_record *record_path_v3; 2209 2210 struct atom_disp_connector_caps_record *record = NULL; 2211 2212 if (!info) 2213 return BP_RESULT_BADINPUT; 2214 2215 switch (bp->object_info_tbl.revision.minor) { 2216 case 4: 2217 default: 2218 object = get_bios_object(bp, object_id); 2219 2220 if (!object) 2221 return BP_RESULT_BADINPUT; 2222 2223 record = get_disp_connector_caps_record(bp, object); 2224 if (!record) 2225 return BP_RESULT_NORECORD; 2226 2227 info->INTERNAL_DISPLAY = 2228 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) ? 1 : 0; 2229 info->INTERNAL_DISPLAY_BL = 2230 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) ? 1 : 0; 2231 break; 2232 case 5: 2233 object_path_v3 = get_bios_object_from_path_v3(bp, object_id); 2234 2235 if (!object_path_v3) 2236 return BP_RESULT_BADINPUT; 2237 2238 record_path_v3 = get_connector_caps_record(bp, object_path_v3); 2239 if (!record_path_v3) 2240 return BP_RESULT_NORECORD; 2241 2242 info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) 2243 ? 1 : 0; 2244 info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) 2245 ? 1 : 0; 2246 break; 2247 } 2248 2249 return BP_RESULT_OK; 2250 } 2251 2252 static struct atom_connector_speed_record *get_connector_speed_cap_record( 2253 struct bios_parser *bp, 2254 struct atom_display_object_path_v3 *object) 2255 { 2256 struct atom_common_record_header *header; 2257 uint32_t offset; 2258 2259 if (!object) { 2260 BREAK_TO_DEBUGGER(); /* Invalid object */ 2261 return NULL; 2262 } 2263 2264 offset = object->disp_recordoffset + bp->object_info_tbl_offset; 2265 2266 for (;;) { 2267 header = GET_IMAGE(struct atom_common_record_header, offset); 2268 2269 if (!header) 2270 return NULL; 2271 2272 offset += header->record_size; 2273 2274 if (header->record_type == ATOM_RECORD_END_TYPE || 2275 !header->record_size) 2276 break; 2277 2278 if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO) 2279 continue; 2280 2281 if (sizeof(struct atom_connector_speed_record) <= header->record_size) 2282 return (struct atom_connector_speed_record *)header; 2283 } 2284 2285 return NULL; 2286 } 2287 2288 static enum bp_result bios_parser_get_connector_speed_cap_info( 2289 struct dc_bios *dcb, 2290 struct graphics_object_id object_id, 2291 struct bp_connector_speed_cap_info *info) 2292 { 2293 struct bios_parser *bp = BP_FROM_DCB(dcb); 2294 struct atom_display_object_path_v3 *object_path_v3; 2295 //struct atom_connector_speed_record *record = NULL; 2296 struct atom_connector_speed_record *record; 2297 2298 if (!info) 2299 return BP_RESULT_BADINPUT; 2300 2301 object_path_v3 = get_bios_object_from_path_v3(bp, object_id); 2302 2303 if (!object_path_v3) 2304 return BP_RESULT_BADINPUT; 2305 2306 record = get_connector_speed_cap_record(bp, object_path_v3); 2307 if (!record) 2308 return BP_RESULT_NORECORD; 2309 2310 info->DP_HBR2_EN = (record->connector_max_speed >= 5400) ? 1 : 0; 2311 info->DP_HBR3_EN = (record->connector_max_speed >= 8100) ? 1 : 0; 2312 info->HDMI_6GB_EN = (record->connector_max_speed >= 5940) ? 1 : 0; 2313 info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0; 2314 info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0; 2315 info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0; 2316 return BP_RESULT_OK; 2317 } 2318 2319 static enum bp_result get_vram_info_v23( 2320 struct bios_parser *bp, 2321 struct dc_vram_info *info) 2322 { 2323 struct atom_vram_info_header_v2_3 *info_v23; 2324 static enum bp_result result = BP_RESULT_OK; 2325 2326 info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3, 2327 DATA_TABLES(vram_info)); 2328 2329 if (info_v23 == NULL) 2330 return BP_RESULT_BADBIOSTABLE; 2331 2332 info->num_chans = info_v23->vram_module[0].channel_num; 2333 info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8; 2334 2335 return result; 2336 } 2337 2338 static enum bp_result get_vram_info_v24( 2339 struct bios_parser *bp, 2340 struct dc_vram_info *info) 2341 { 2342 struct atom_vram_info_header_v2_4 *info_v24; 2343 static enum bp_result result = BP_RESULT_OK; 2344 2345 info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4, 2346 DATA_TABLES(vram_info)); 2347 2348 if (info_v24 == NULL) 2349 return BP_RESULT_BADBIOSTABLE; 2350 2351 info->num_chans = info_v24->vram_module[0].channel_num; 2352 info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8; 2353 2354 return result; 2355 } 2356 2357 static enum bp_result get_vram_info_v25( 2358 struct bios_parser *bp, 2359 struct dc_vram_info *info) 2360 { 2361 struct atom_vram_info_header_v2_5 *info_v25; 2362 static enum bp_result result = BP_RESULT_OK; 2363 2364 info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5, 2365 DATA_TABLES(vram_info)); 2366 2367 if (info_v25 == NULL) 2368 return BP_RESULT_BADBIOSTABLE; 2369 2370 info->num_chans = info_v25->vram_module[0].channel_num; 2371 info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8; 2372 2373 return result; 2374 } 2375 2376 /* 2377 * get_integrated_info_v11 2378 * 2379 * @brief 2380 * Get V8 integrated BIOS information 2381 * 2382 * @param 2383 * bios_parser *bp - [in]BIOS parser handler to get master data table 2384 * integrated_info *info - [out] store and output integrated info 2385 * 2386 * @return 2387 * static enum bp_result - BP_RESULT_OK if information is available, 2388 * BP_RESULT_BADBIOSTABLE otherwise. 2389 */ 2390 static enum bp_result get_integrated_info_v11( 2391 struct bios_parser *bp, 2392 struct integrated_info *info) 2393 { 2394 struct atom_integrated_system_info_v1_11 *info_v11; 2395 uint32_t i; 2396 2397 info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11, 2398 DATA_TABLES(integratedsysteminfo)); 2399 2400 if (info_v11 == NULL) 2401 return BP_RESULT_BADBIOSTABLE; 2402 2403 info->gpu_cap_info = 2404 le32_to_cpu(info_v11->gpucapinfo); 2405 /* 2406 * system_config: Bit[0] = 0 : PCIE power gating disabled 2407 * = 1 : PCIE power gating enabled 2408 * Bit[1] = 0 : DDR-PLL shut down disabled 2409 * = 1 : DDR-PLL shut down enabled 2410 * Bit[2] = 0 : DDR-PLL power down disabled 2411 * = 1 : DDR-PLL power down enabled 2412 */ 2413 info->system_config = le32_to_cpu(info_v11->system_config); 2414 info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo); 2415 info->memory_type = info_v11->memorytype; 2416 info->ma_channel_number = info_v11->umachannelnumber; 2417 info->lvds_ss_percentage = 2418 le16_to_cpu(info_v11->lvds_ss_percentage); 2419 info->dp_ss_control = 2420 le16_to_cpu(info_v11->reserved1); 2421 info->lvds_sspread_rate_in_10hz = 2422 le16_to_cpu(info_v11->lvds_ss_rate_10hz); 2423 info->hdmi_ss_percentage = 2424 le16_to_cpu(info_v11->hdmi_ss_percentage); 2425 info->hdmi_sspread_rate_in_10hz = 2426 le16_to_cpu(info_v11->hdmi_ss_rate_10hz); 2427 info->dvi_ss_percentage = 2428 le16_to_cpu(info_v11->dvi_ss_percentage); 2429 info->dvi_sspread_rate_in_10_hz = 2430 le16_to_cpu(info_v11->dvi_ss_rate_10hz); 2431 info->lvds_misc = info_v11->lvds_misc; 2432 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2433 info->ext_disp_conn_info.gu_id[i] = 2434 info_v11->extdispconninfo.guid[i]; 2435 } 2436 2437 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2438 info->ext_disp_conn_info.path[i].device_connector_id = 2439 object_id_from_bios_object_id( 2440 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid)); 2441 2442 info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2443 object_id_from_bios_object_id( 2444 le16_to_cpu( 2445 info_v11->extdispconninfo.path[i].ext_encoder_objid)); 2446 2447 info->ext_disp_conn_info.path[i].device_tag = 2448 le16_to_cpu( 2449 info_v11->extdispconninfo.path[i].device_tag); 2450 info->ext_disp_conn_info.path[i].device_acpi_enum = 2451 le16_to_cpu( 2452 info_v11->extdispconninfo.path[i].device_acpi_enum); 2453 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2454 info_v11->extdispconninfo.path[i].auxddclut_index; 2455 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2456 info_v11->extdispconninfo.path[i].hpdlut_index; 2457 info->ext_disp_conn_info.path[i].channel_mapping.raw = 2458 info_v11->extdispconninfo.path[i].channelmapping; 2459 info->ext_disp_conn_info.path[i].caps = 2460 le16_to_cpu(info_v11->extdispconninfo.path[i].caps); 2461 } 2462 info->ext_disp_conn_info.checksum = 2463 info_v11->extdispconninfo.checksum; 2464 2465 info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr; 2466 info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum; 2467 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 2468 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 2469 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2470 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 2471 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2472 } 2473 info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum; 2474 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 2475 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2476 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2477 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2478 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2479 } 2480 2481 info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr; 2482 info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum; 2483 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 2484 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 2485 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2486 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 2487 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2488 } 2489 info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum; 2490 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 2491 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2492 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2493 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2494 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2495 } 2496 2497 info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr; 2498 info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum; 2499 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 2500 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 2501 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2502 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 2503 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2504 } 2505 info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum; 2506 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 2507 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2508 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2509 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2510 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2511 } 2512 2513 info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr; 2514 info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum; 2515 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 2516 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 2517 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2518 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 2519 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2520 } 2521 info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum; 2522 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 2523 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2524 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2525 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2526 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2527 } 2528 2529 2530 /** TODO - review **/ 2531 #if 0 2532 info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock) 2533 * 10; 2534 info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10; 2535 info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10; 2536 2537 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2538 /* Convert [10KHz] into [KHz] */ 2539 info->disp_clk_voltage[i].max_supported_clk = 2540 le32_to_cpu(info_v11->sDISPCLK_Voltage[i]. 2541 ulMaximumSupportedCLK) * 10; 2542 info->disp_clk_voltage[i].voltage_index = 2543 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex); 2544 } 2545 2546 info->boot_up_req_display_vector = 2547 le32_to_cpu(info_v11->ulBootUpReqDisplayVector); 2548 info->boot_up_nb_voltage = 2549 le16_to_cpu(info_v11->usBootUpNBVoltage); 2550 info->ext_disp_conn_info_offset = 2551 le16_to_cpu(info_v11->usExtDispConnInfoOffset); 2552 info->gmc_restore_reset_time = 2553 le32_to_cpu(info_v11->ulGMCRestoreResetTime); 2554 info->minimum_n_clk = 2555 le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]); 2556 for (i = 1; i < 4; ++i) 2557 info->minimum_n_clk = 2558 info->minimum_n_clk < 2559 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ? 2560 info->minimum_n_clk : le32_to_cpu( 2561 info_v11->ulNbpStateNClkFreq[i]); 2562 2563 info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk); 2564 info->ddr_dll_power_up_time = 2565 le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime); 2566 info->ddr_pll_power_up_time = 2567 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime); 2568 info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType); 2569 info->max_lvds_pclk_freq_in_single_link = 2570 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 2571 info->max_lvds_pclk_freq_in_single_link = 2572 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); 2573 info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = 2574 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; 2575 info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = 2576 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; 2577 info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = 2578 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; 2579 info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = 2580 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; 2581 info->lvds_pwr_off_seq_de_to_dig_on_in4ms = 2582 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; 2583 info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = 2584 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; 2585 info->lvds_off_to_on_delay_in_4ms = 2586 info_v11->ucLVDSOffToOnDelay_in4Ms; 2587 info->lvds_bit_depth_control_val = 2588 le32_to_cpu(info_v11->ulLCDBitDepthControlVal); 2589 2590 for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { 2591 /* Convert [10KHz] into [KHz] */ 2592 info->avail_s_clk[i].supported_s_clk = 2593 le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK) 2594 * 10; 2595 info->avail_s_clk[i].voltage_index = 2596 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex); 2597 info->avail_s_clk[i].voltage_id = 2598 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID); 2599 } 2600 #endif /* TODO*/ 2601 2602 return BP_RESULT_OK; 2603 } 2604 2605 static enum bp_result get_integrated_info_v2_1( 2606 struct bios_parser *bp, 2607 struct integrated_info *info) 2608 { 2609 struct atom_integrated_system_info_v2_1 *info_v2_1; 2610 uint32_t i; 2611 2612 info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1, 2613 DATA_TABLES(integratedsysteminfo)); 2614 2615 if (info_v2_1 == NULL) 2616 return BP_RESULT_BADBIOSTABLE; 2617 2618 info->gpu_cap_info = 2619 le32_to_cpu(info_v2_1->gpucapinfo); 2620 /* 2621 * system_config: Bit[0] = 0 : PCIE power gating disabled 2622 * = 1 : PCIE power gating enabled 2623 * Bit[1] = 0 : DDR-PLL shut down disabled 2624 * = 1 : DDR-PLL shut down enabled 2625 * Bit[2] = 0 : DDR-PLL power down disabled 2626 * = 1 : DDR-PLL power down enabled 2627 */ 2628 info->system_config = le32_to_cpu(info_v2_1->system_config); 2629 info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo); 2630 info->memory_type = info_v2_1->memorytype; 2631 info->ma_channel_number = info_v2_1->umachannelnumber; 2632 info->dp_ss_control = 2633 le16_to_cpu(info_v2_1->reserved1); 2634 2635 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2636 info->ext_disp_conn_info.gu_id[i] = 2637 info_v2_1->extdispconninfo.guid[i]; 2638 } 2639 2640 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2641 info->ext_disp_conn_info.path[i].device_connector_id = 2642 object_id_from_bios_object_id( 2643 le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid)); 2644 2645 info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2646 object_id_from_bios_object_id( 2647 le16_to_cpu( 2648 info_v2_1->extdispconninfo.path[i].ext_encoder_objid)); 2649 2650 info->ext_disp_conn_info.path[i].device_tag = 2651 le16_to_cpu( 2652 info_v2_1->extdispconninfo.path[i].device_tag); 2653 info->ext_disp_conn_info.path[i].device_acpi_enum = 2654 le16_to_cpu( 2655 info_v2_1->extdispconninfo.path[i].device_acpi_enum); 2656 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2657 info_v2_1->extdispconninfo.path[i].auxddclut_index; 2658 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2659 info_v2_1->extdispconninfo.path[i].hpdlut_index; 2660 info->ext_disp_conn_info.path[i].channel_mapping.raw = 2661 info_v2_1->extdispconninfo.path[i].channelmapping; 2662 info->ext_disp_conn_info.path[i].caps = 2663 le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps); 2664 } 2665 2666 info->ext_disp_conn_info.checksum = 2667 info_v2_1->extdispconninfo.checksum; 2668 info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr; 2669 info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum; 2670 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) { 2671 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index = 2672 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2673 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val = 2674 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2675 } 2676 info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum; 2677 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) { 2678 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2679 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2680 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2681 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2682 } 2683 info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr; 2684 info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum; 2685 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) { 2686 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index = 2687 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2688 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val = 2689 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2690 } 2691 info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum; 2692 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) { 2693 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2694 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2695 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2696 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2697 } 2698 info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr; 2699 info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum; 2700 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) { 2701 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index = 2702 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2703 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val = 2704 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2705 } 2706 info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum; 2707 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) { 2708 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2709 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2710 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2711 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2712 } 2713 info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr; 2714 info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum; 2715 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) { 2716 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index = 2717 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex; 2718 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val = 2719 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal; 2720 } 2721 info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum; 2722 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) { 2723 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index = 2724 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex; 2725 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val = 2726 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal; 2727 } 2728 2729 info->edp1_info.edp_backlight_pwm_hz = 2730 le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz); 2731 info->edp1_info.edp_ss_percentage = 2732 le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage); 2733 info->edp1_info.edp_ss_rate_10hz = 2734 le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz); 2735 info->edp1_info.edp_pwr_on_off_delay = 2736 info_v2_1->edp1_info.edp_pwr_on_off_delay; 2737 info->edp1_info.edp_pwr_on_vary_bl_to_blon = 2738 info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon; 2739 info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = 2740 info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff; 2741 info->edp1_info.edp_panel_bpc = 2742 info_v2_1->edp1_info.edp_panel_bpc; 2743 info->edp1_info.edp_bootup_bl_level = info_v2_1->edp1_info.edp_bootup_bl_level; 2744 2745 info->edp2_info.edp_backlight_pwm_hz = 2746 le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz); 2747 info->edp2_info.edp_ss_percentage = 2748 le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage); 2749 info->edp2_info.edp_ss_rate_10hz = 2750 le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz); 2751 info->edp2_info.edp_pwr_on_off_delay = 2752 info_v2_1->edp2_info.edp_pwr_on_off_delay; 2753 info->edp2_info.edp_pwr_on_vary_bl_to_blon = 2754 info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon; 2755 info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = 2756 info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff; 2757 info->edp2_info.edp_panel_bpc = 2758 info_v2_1->edp2_info.edp_panel_bpc; 2759 info->edp2_info.edp_bootup_bl_level = 2760 info_v2_1->edp2_info.edp_bootup_bl_level; 2761 2762 return BP_RESULT_OK; 2763 } 2764 2765 static enum bp_result get_integrated_info_v2_2( 2766 struct bios_parser *bp, 2767 struct integrated_info *info) 2768 { 2769 struct atom_integrated_system_info_v2_2 *info_v2_2; 2770 uint32_t i; 2771 2772 info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2, 2773 DATA_TABLES(integratedsysteminfo)); 2774 2775 if (info_v2_2 == NULL) 2776 return BP_RESULT_BADBIOSTABLE; 2777 2778 info->gpu_cap_info = 2779 le32_to_cpu(info_v2_2->gpucapinfo); 2780 /* 2781 * system_config: Bit[0] = 0 : PCIE power gating disabled 2782 * = 1 : PCIE power gating enabled 2783 * Bit[1] = 0 : DDR-PLL shut down disabled 2784 * = 1 : DDR-PLL shut down enabled 2785 * Bit[2] = 0 : DDR-PLL power down disabled 2786 * = 1 : DDR-PLL power down enabled 2787 */ 2788 info->system_config = le32_to_cpu(info_v2_2->system_config); 2789 info->cpu_cap_info = le32_to_cpu(info_v2_2->cpucapinfo); 2790 info->memory_type = info_v2_2->memorytype; 2791 info->ma_channel_number = info_v2_2->umachannelnumber; 2792 info->dp_ss_control = 2793 le16_to_cpu(info_v2_2->reserved1); 2794 2795 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { 2796 info->ext_disp_conn_info.gu_id[i] = 2797 info_v2_2->extdispconninfo.guid[i]; 2798 } 2799 2800 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { 2801 info->ext_disp_conn_info.path[i].device_connector_id = 2802 object_id_from_bios_object_id( 2803 le16_to_cpu(info_v2_2->extdispconninfo.path[i].connectorobjid)); 2804 2805 info->ext_disp_conn_info.path[i].ext_encoder_obj_id = 2806 object_id_from_bios_object_id( 2807 le16_to_cpu( 2808 info_v2_2->extdispconninfo.path[i].ext_encoder_objid)); 2809 2810 info->ext_disp_conn_info.path[i].device_tag = 2811 le16_to_cpu( 2812 info_v2_2->extdispconninfo.path[i].device_tag); 2813 info->ext_disp_conn_info.path[i].device_acpi_enum = 2814 le16_to_cpu( 2815 info_v2_2->extdispconninfo.path[i].device_acpi_enum); 2816 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = 2817 info_v2_2->extdispconninfo.path[i].auxddclut_index; 2818 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = 2819 info_v2_2->extdispconninfo.path[i].hpdlut_index; 2820 info->ext_disp_conn_info.path[i].channel_mapping.raw = 2821 info_v2_2->extdispconninfo.path[i].channelmapping; 2822 info->ext_disp_conn_info.path[i].caps = 2823 le16_to_cpu(info_v2_2->extdispconninfo.path[i].caps); 2824 } 2825 2826 info->ext_disp_conn_info.checksum = 2827 info_v2_2->extdispconninfo.checksum; 2828 info->ext_disp_conn_info.fixdpvoltageswing = 2829 info_v2_2->extdispconninfo.fixdpvoltageswing; 2830 2831 info->edp1_info.edp_backlight_pwm_hz = 2832 le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz); 2833 info->edp1_info.edp_ss_percentage = 2834 le16_to_cpu(info_v2_2->edp1_info.edp_ss_percentage); 2835 info->edp1_info.edp_ss_rate_10hz = 2836 le16_to_cpu(info_v2_2->edp1_info.edp_ss_rate_10hz); 2837 info->edp1_info.edp_pwr_on_off_delay = 2838 info_v2_2->edp1_info.edp_pwr_on_off_delay; 2839 info->edp1_info.edp_pwr_on_vary_bl_to_blon = 2840 info_v2_2->edp1_info.edp_pwr_on_vary_bl_to_blon; 2841 info->edp1_info.edp_pwr_down_bloff_to_vary_bloff = 2842 info_v2_2->edp1_info.edp_pwr_down_bloff_to_vary_bloff; 2843 info->edp1_info.edp_panel_bpc = 2844 info_v2_2->edp1_info.edp_panel_bpc; 2845 info->edp1_info.edp_bootup_bl_level = 2846 2847 info->edp2_info.edp_backlight_pwm_hz = 2848 le16_to_cpu(info_v2_2->edp2_info.edp_backlight_pwm_hz); 2849 info->edp2_info.edp_ss_percentage = 2850 le16_to_cpu(info_v2_2->edp2_info.edp_ss_percentage); 2851 info->edp2_info.edp_ss_rate_10hz = 2852 le16_to_cpu(info_v2_2->edp2_info.edp_ss_rate_10hz); 2853 info->edp2_info.edp_pwr_on_off_delay = 2854 info_v2_2->edp2_info.edp_pwr_on_off_delay; 2855 info->edp2_info.edp_pwr_on_vary_bl_to_blon = 2856 info_v2_2->edp2_info.edp_pwr_on_vary_bl_to_blon; 2857 info->edp2_info.edp_pwr_down_bloff_to_vary_bloff = 2858 info_v2_2->edp2_info.edp_pwr_down_bloff_to_vary_bloff; 2859 info->edp2_info.edp_panel_bpc = 2860 info_v2_2->edp2_info.edp_panel_bpc; 2861 info->edp2_info.edp_bootup_bl_level = 2862 info_v2_2->edp2_info.edp_bootup_bl_level; 2863 2864 return BP_RESULT_OK; 2865 } 2866 2867 /* 2868 * construct_integrated_info 2869 * 2870 * @brief 2871 * Get integrated BIOS information based on table revision 2872 * 2873 * @param 2874 * bios_parser *bp - [in]BIOS parser handler to get master data table 2875 * integrated_info *info - [out] store and output integrated info 2876 * 2877 * @return 2878 * static enum bp_result - BP_RESULT_OK if information is available, 2879 * BP_RESULT_BADBIOSTABLE otherwise. 2880 */ 2881 static enum bp_result construct_integrated_info( 2882 struct bios_parser *bp, 2883 struct integrated_info *info) 2884 { 2885 static enum bp_result result = BP_RESULT_BADBIOSTABLE; 2886 2887 struct atom_common_table_header *header; 2888 struct atom_data_revision revision; 2889 2890 struct clock_voltage_caps temp = {0, 0}; 2891 uint32_t i; 2892 uint32_t j; 2893 2894 if (info && DATA_TABLES(integratedsysteminfo)) { 2895 header = GET_IMAGE(struct atom_common_table_header, 2896 DATA_TABLES(integratedsysteminfo)); 2897 2898 get_atom_data_table_revision(header, &revision); 2899 2900 switch (revision.major) { 2901 case 1: 2902 switch (revision.minor) { 2903 case 11: 2904 case 12: 2905 result = get_integrated_info_v11(bp, info); 2906 break; 2907 default: 2908 return result; 2909 } 2910 break; 2911 case 2: 2912 switch (revision.minor) { 2913 case 1: 2914 result = get_integrated_info_v2_1(bp, info); 2915 break; 2916 case 2: 2917 result = get_integrated_info_v2_2(bp, info); 2918 break; 2919 default: 2920 return result; 2921 } 2922 break; 2923 default: 2924 return result; 2925 } 2926 } 2927 2928 if (result != BP_RESULT_OK) 2929 return result; 2930 else { 2931 // Log each external path 2932 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) { 2933 if (info->ext_disp_conn_info.path[i].device_tag != 0) 2934 DC_LOG_BIOS("integrated_info:For EXTERNAL DISPLAY PATH %d --------------\n" 2935 "DEVICE_TAG: 0x%x\n" 2936 "DEVICE_ACPI_ENUM: 0x%x\n" 2937 "DEVICE_CONNECTOR_ID: 0x%x\n" 2938 "EXT_AUX_DDC_LUT_INDEX: %d\n" 2939 "EXT_HPD_PIN_LUT_INDEX: %d\n" 2940 "EXT_ENCODER_OBJ_ID: 0x%x\n" 2941 "Encoder CAPS: 0x%x\n", 2942 i, 2943 info->ext_disp_conn_info.path[i].device_tag, 2944 info->ext_disp_conn_info.path[i].device_acpi_enum, 2945 info->ext_disp_conn_info.path[i].device_connector_id.id, 2946 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index, 2947 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index, 2948 info->ext_disp_conn_info.path[i].ext_encoder_obj_id.id, 2949 info->ext_disp_conn_info.path[i].caps 2950 ); 2951 } 2952 2953 // Log the Checksum and Voltage Swing 2954 DC_LOG_BIOS("Integrated info table CHECKSUM: %d\n" 2955 "Integrated info table FIX_DP_VOLTAGE_SWING: %d\n", 2956 info->ext_disp_conn_info.checksum, 2957 info->ext_disp_conn_info.fixdpvoltageswing); 2958 } 2959 /* Sort voltage table from low to high*/ 2960 for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { 2961 for (j = i; j > 0; --j) { 2962 if (info->disp_clk_voltage[j].max_supported_clk < 2963 info->disp_clk_voltage[j-1].max_supported_clk 2964 ) { 2965 /* swap j and j - 1*/ 2966 temp = info->disp_clk_voltage[j-1]; 2967 info->disp_clk_voltage[j-1] = 2968 info->disp_clk_voltage[j]; 2969 info->disp_clk_voltage[j] = temp; 2970 } 2971 } 2972 } 2973 2974 return result; 2975 } 2976 2977 static enum bp_result bios_parser_get_vram_info( 2978 struct dc_bios *dcb, 2979 struct dc_vram_info *info) 2980 { 2981 struct bios_parser *bp = BP_FROM_DCB(dcb); 2982 static enum bp_result result = BP_RESULT_BADBIOSTABLE; 2983 struct atom_common_table_header *header; 2984 struct atom_data_revision revision; 2985 2986 if (info && DATA_TABLES(vram_info)) { 2987 header = GET_IMAGE(struct atom_common_table_header, 2988 DATA_TABLES(vram_info)); 2989 2990 get_atom_data_table_revision(header, &revision); 2991 2992 switch (revision.major) { 2993 case 2: 2994 switch (revision.minor) { 2995 case 3: 2996 result = get_vram_info_v23(bp, info); 2997 break; 2998 case 4: 2999 result = get_vram_info_v24(bp, info); 3000 break; 3001 case 5: 3002 result = get_vram_info_v25(bp, info); 3003 break; 3004 default: 3005 break; 3006 } 3007 break; 3008 3009 default: 3010 return result; 3011 } 3012 3013 } 3014 return result; 3015 } 3016 3017 static struct integrated_info *bios_parser_create_integrated_info( 3018 struct dc_bios *dcb) 3019 { 3020 struct bios_parser *bp = BP_FROM_DCB(dcb); 3021 struct integrated_info *info = NULL; 3022 3023 info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); 3024 3025 if (info == NULL) { 3026 ASSERT_CRITICAL(0); 3027 return NULL; 3028 } 3029 3030 if (construct_integrated_info(bp, info) == BP_RESULT_OK) 3031 return info; 3032 3033 kfree(info); 3034 3035 return NULL; 3036 } 3037 3038 static enum bp_result update_slot_layout_info( 3039 struct dc_bios *dcb, 3040 unsigned int i, 3041 struct slot_layout_info *slot_layout_info) 3042 { 3043 unsigned int record_offset; 3044 unsigned int j; 3045 struct atom_display_object_path_v2 *object; 3046 struct atom_bracket_layout_record *record; 3047 struct atom_common_record_header *record_header; 3048 static enum bp_result result; 3049 struct bios_parser *bp; 3050 struct object_info_table *tbl; 3051 struct display_object_info_table_v1_4 *v1_4; 3052 3053 record = NULL; 3054 record_header = NULL; 3055 result = BP_RESULT_NORECORD; 3056 3057 bp = BP_FROM_DCB(dcb); 3058 tbl = &bp->object_info_tbl; 3059 v1_4 = tbl->v1_4; 3060 3061 object = &v1_4->display_path[i]; 3062 record_offset = (unsigned int) 3063 (object->disp_recordoffset) + 3064 (unsigned int)(bp->object_info_tbl_offset); 3065 3066 for (;;) { 3067 3068 record_header = (struct atom_common_record_header *) 3069 GET_IMAGE(struct atom_common_record_header, 3070 record_offset); 3071 if (record_header == NULL) { 3072 result = BP_RESULT_BADBIOSTABLE; 3073 break; 3074 } 3075 3076 /* the end of the list */ 3077 if (record_header->record_type == 0xff || 3078 record_header->record_size == 0) { 3079 break; 3080 } 3081 3082 if (record_header->record_type == 3083 ATOM_BRACKET_LAYOUT_RECORD_TYPE && 3084 sizeof(struct atom_bracket_layout_record) 3085 <= record_header->record_size) { 3086 record = (struct atom_bracket_layout_record *) 3087 (record_header); 3088 result = BP_RESULT_OK; 3089 break; 3090 } 3091 3092 record_offset += record_header->record_size; 3093 } 3094 3095 /* return if the record not found */ 3096 if (result != BP_RESULT_OK) 3097 return result; 3098 3099 /* get slot sizes */ 3100 slot_layout_info->length = record->bracketlen; 3101 slot_layout_info->width = record->bracketwidth; 3102 3103 /* get info for each connector in the slot */ 3104 slot_layout_info->num_of_connectors = record->conn_num; 3105 for (j = 0; j < slot_layout_info->num_of_connectors; ++j) { 3106 slot_layout_info->connectors[j].connector_type = 3107 (enum connector_layout_type) 3108 (record->conn_info[j].connector_type); 3109 switch (record->conn_info[j].connector_type) { 3110 case CONNECTOR_TYPE_DVI_D: 3111 slot_layout_info->connectors[j].connector_type = 3112 CONNECTOR_LAYOUT_TYPE_DVI_D; 3113 slot_layout_info->connectors[j].length = 3114 CONNECTOR_SIZE_DVI; 3115 break; 3116 3117 case CONNECTOR_TYPE_HDMI: 3118 slot_layout_info->connectors[j].connector_type = 3119 CONNECTOR_LAYOUT_TYPE_HDMI; 3120 slot_layout_info->connectors[j].length = 3121 CONNECTOR_SIZE_HDMI; 3122 break; 3123 3124 case CONNECTOR_TYPE_DISPLAY_PORT: 3125 slot_layout_info->connectors[j].connector_type = 3126 CONNECTOR_LAYOUT_TYPE_DP; 3127 slot_layout_info->connectors[j].length = 3128 CONNECTOR_SIZE_DP; 3129 break; 3130 3131 case CONNECTOR_TYPE_MINI_DISPLAY_PORT: 3132 slot_layout_info->connectors[j].connector_type = 3133 CONNECTOR_LAYOUT_TYPE_MINI_DP; 3134 slot_layout_info->connectors[j].length = 3135 CONNECTOR_SIZE_MINI_DP; 3136 break; 3137 3138 default: 3139 slot_layout_info->connectors[j].connector_type = 3140 CONNECTOR_LAYOUT_TYPE_UNKNOWN; 3141 slot_layout_info->connectors[j].length = 3142 CONNECTOR_SIZE_UNKNOWN; 3143 } 3144 3145 slot_layout_info->connectors[j].position = 3146 record->conn_info[j].position; 3147 slot_layout_info->connectors[j].connector_id = 3148 object_id_from_bios_object_id( 3149 record->conn_info[j].connectorobjid); 3150 } 3151 return result; 3152 } 3153 3154 static enum bp_result update_slot_layout_info_v2( 3155 struct dc_bios *dcb, 3156 unsigned int i, 3157 struct slot_layout_info *slot_layout_info) 3158 { 3159 unsigned int record_offset; 3160 struct atom_display_object_path_v3 *object; 3161 struct atom_bracket_layout_record_v2 *record; 3162 struct atom_common_record_header *record_header; 3163 static enum bp_result result; 3164 struct bios_parser *bp; 3165 struct object_info_table *tbl; 3166 struct display_object_info_table_v1_5 *v1_5; 3167 struct graphics_object_id connector_id; 3168 3169 record = NULL; 3170 record_header = NULL; 3171 result = BP_RESULT_NORECORD; 3172 3173 bp = BP_FROM_DCB(dcb); 3174 tbl = &bp->object_info_tbl; 3175 v1_5 = tbl->v1_5; 3176 3177 object = &v1_5->display_path[i]; 3178 record_offset = (unsigned int) 3179 (object->disp_recordoffset) + 3180 (unsigned int)(bp->object_info_tbl_offset); 3181 3182 for (;;) { 3183 3184 record_header = (struct atom_common_record_header *) 3185 GET_IMAGE(struct atom_common_record_header, 3186 record_offset); 3187 if (record_header == NULL) { 3188 result = BP_RESULT_BADBIOSTABLE; 3189 break; 3190 } 3191 3192 /* the end of the list */ 3193 if (record_header->record_type == ATOM_RECORD_END_TYPE || 3194 record_header->record_size == 0) { 3195 break; 3196 } 3197 3198 if (record_header->record_type == 3199 ATOM_BRACKET_LAYOUT_V2_RECORD_TYPE && 3200 sizeof(struct atom_bracket_layout_record_v2) 3201 <= record_header->record_size) { 3202 record = (struct atom_bracket_layout_record_v2 *) 3203 (record_header); 3204 result = BP_RESULT_OK; 3205 break; 3206 } 3207 3208 record_offset += record_header->record_size; 3209 } 3210 3211 /* return if the record not found */ 3212 if (result != BP_RESULT_OK) 3213 return result; 3214 3215 /* get slot sizes */ 3216 connector_id = object_id_from_bios_object_id(object->display_objid); 3217 3218 slot_layout_info->length = record->bracketlen; 3219 slot_layout_info->width = record->bracketwidth; 3220 slot_layout_info->num_of_connectors = v1_5->number_of_path; 3221 slot_layout_info->connectors[i].position = record->conn_num; 3222 slot_layout_info->connectors[i].connector_id = connector_id; 3223 3224 switch (connector_id.id) { 3225 case CONNECTOR_ID_SINGLE_LINK_DVID: 3226 case CONNECTOR_ID_DUAL_LINK_DVID: 3227 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DVI_D; 3228 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DVI; 3229 break; 3230 3231 case CONNECTOR_ID_HDMI_TYPE_A: 3232 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_HDMI; 3233 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_HDMI; 3234 break; 3235 3236 case CONNECTOR_ID_DISPLAY_PORT: 3237 case CONNECTOR_ID_USBC: 3238 if (record->mini_type == MINI_TYPE_NORMAL) { 3239 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DP; 3240 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DP; 3241 } else { 3242 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP; 3243 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP; 3244 } 3245 break; 3246 3247 default: 3248 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN; 3249 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN; 3250 } 3251 return result; 3252 } 3253 3254 static enum bp_result get_bracket_layout_record( 3255 struct dc_bios *dcb, 3256 unsigned int bracket_layout_id, 3257 struct slot_layout_info *slot_layout_info) 3258 { 3259 unsigned int i; 3260 struct bios_parser *bp = BP_FROM_DCB(dcb); 3261 static enum bp_result result; 3262 struct object_info_table *tbl; 3263 struct display_object_info_table_v1_4 *v1_4; 3264 struct display_object_info_table_v1_5 *v1_5; 3265 3266 if (slot_layout_info == NULL) { 3267 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n"); 3268 return BP_RESULT_BADINPUT; 3269 } 3270 tbl = &bp->object_info_tbl; 3271 v1_4 = tbl->v1_4; 3272 v1_5 = tbl->v1_5; 3273 3274 result = BP_RESULT_NORECORD; 3275 switch (bp->object_info_tbl.revision.minor) { 3276 case 4: 3277 default: 3278 for (i = 0; i < v1_4->number_of_path; ++i) { 3279 if (bracket_layout_id == 3280 v1_4->display_path[i].display_objid) { 3281 result = update_slot_layout_info(dcb, i, slot_layout_info); 3282 break; 3283 } 3284 } 3285 break; 3286 case 5: 3287 for (i = 0; i < v1_5->number_of_path; ++i) 3288 result = update_slot_layout_info_v2(dcb, i, slot_layout_info); 3289 break; 3290 } 3291 return result; 3292 } 3293 3294 static enum bp_result bios_get_board_layout_info( 3295 struct dc_bios *dcb, 3296 struct board_layout_info *board_layout_info) 3297 { 3298 unsigned int i; 3299 3300 struct bios_parser *bp; 3301 3302 static enum bp_result record_result; 3303 3304 const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = { 3305 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1, 3306 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2, 3307 0, 0 3308 }; 3309 3310 3311 bp = BP_FROM_DCB(dcb); 3312 3313 if (board_layout_info == NULL) { 3314 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n"); 3315 return BP_RESULT_BADINPUT; 3316 } 3317 3318 board_layout_info->num_of_slots = 0; 3319 3320 for (i = 0; i < MAX_BOARD_SLOTS; ++i) { 3321 record_result = get_bracket_layout_record(dcb, 3322 slot_index_to_vbios_id[i], 3323 &board_layout_info->slots[i]); 3324 3325 if (record_result == BP_RESULT_NORECORD && i > 0) 3326 break; /* no more slots present in bios */ 3327 else if (record_result != BP_RESULT_OK) 3328 return record_result; /* fail */ 3329 3330 ++board_layout_info->num_of_slots; 3331 } 3332 3333 /* all data is valid */ 3334 board_layout_info->is_number_of_slots_valid = 1; 3335 board_layout_info->is_slots_size_valid = 1; 3336 board_layout_info->is_connector_offsets_valid = 1; 3337 board_layout_info->is_connector_lengths_valid = 1; 3338 3339 return BP_RESULT_OK; 3340 } 3341 3342 3343 static uint16_t bios_parser_pack_data_tables( 3344 struct dc_bios *dcb, 3345 void *dst) 3346 { 3347 // TODO: There is data bytes alignment issue, disable it for now. 3348 return 0; 3349 } 3350 3351 static struct atom_dc_golden_table_v1 *bios_get_golden_table( 3352 struct bios_parser *bp, 3353 uint32_t rev_major, 3354 uint32_t rev_minor, 3355 uint16_t *dc_golden_table_ver) 3356 { 3357 struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL; 3358 uint32_t dc_golden_offset = 0; 3359 *dc_golden_table_ver = 0; 3360 3361 if (!DATA_TABLES(dce_info)) 3362 return NULL; 3363 3364 /* ver.4.4 or higher */ 3365 switch (rev_major) { 3366 case 4: 3367 switch (rev_minor) { 3368 case 4: 3369 disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4, 3370 DATA_TABLES(dce_info)); 3371 if (!disp_cntl_tbl_4_4) 3372 return NULL; 3373 dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset; 3374 *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver; 3375 break; 3376 case 5: 3377 default: 3378 /* For atom_display_controller_info_v4_5 there is no need to get golden table from 3379 * dc_golden_table_offset as all these fields previously in golden table used for AUX 3380 * pre-charge settings are now available directly in atom_display_controller_info_v4_5. 3381 */ 3382 break; 3383 } 3384 break; 3385 } 3386 3387 if (!dc_golden_offset) 3388 return NULL; 3389 3390 if (*dc_golden_table_ver != 1) 3391 return NULL; 3392 3393 return GET_IMAGE(struct atom_dc_golden_table_v1, 3394 dc_golden_offset); 3395 } 3396 3397 static enum bp_result bios_get_atom_dc_golden_table( 3398 struct dc_bios *dcb) 3399 { 3400 struct bios_parser *bp = BP_FROM_DCB(dcb); 3401 enum bp_result result = BP_RESULT_OK; 3402 struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL; 3403 struct atom_common_table_header *header; 3404 struct atom_data_revision tbl_revision; 3405 uint16_t dc_golden_table_ver = 0; 3406 3407 header = GET_IMAGE(struct atom_common_table_header, 3408 DATA_TABLES(dce_info)); 3409 if (!header) 3410 return BP_RESULT_UNSUPPORTED; 3411 3412 get_atom_data_table_revision(header, &tbl_revision); 3413 3414 atom_dc_golden_table = bios_get_golden_table(bp, 3415 tbl_revision.major, 3416 tbl_revision.minor, 3417 &dc_golden_table_ver); 3418 3419 if (!atom_dc_golden_table) 3420 return BP_RESULT_UNSUPPORTED; 3421 3422 dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver; 3423 dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val; 3424 dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val; 3425 dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val; 3426 dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val; 3427 dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val; 3428 dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val; 3429 dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val; 3430 dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val; 3431 dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val; 3432 3433 return result; 3434 } 3435 3436 3437 static const struct dc_vbios_funcs vbios_funcs = { 3438 .get_connectors_number = bios_parser_get_connectors_number, 3439 3440 .get_connector_id = bios_parser_get_connector_id, 3441 3442 .get_src_obj = bios_parser_get_src_obj, 3443 3444 .get_i2c_info = bios_parser_get_i2c_info, 3445 3446 .get_hpd_info = bios_parser_get_hpd_info, 3447 3448 .get_device_tag = bios_parser_get_device_tag, 3449 3450 .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, 3451 3452 .get_ss_entry_number = bios_parser_get_ss_entry_number, 3453 3454 .get_embedded_panel_info = bios_parser_get_embedded_panel_info, 3455 3456 .get_gpio_pin_info = bios_parser_get_gpio_pin_info, 3457 3458 .get_encoder_cap_info = bios_parser_get_encoder_cap_info, 3459 3460 .is_device_id_supported = bios_parser_is_device_id_supported, 3461 3462 .is_accelerated_mode = bios_parser_is_accelerated_mode, 3463 3464 .set_scratch_critical_state = bios_parser_set_scratch_critical_state, 3465 3466 3467 /* COMMANDS */ 3468 .encoder_control = bios_parser_encoder_control, 3469 3470 .transmitter_control = bios_parser_transmitter_control, 3471 3472 .enable_crtc = bios_parser_enable_crtc, 3473 3474 .set_pixel_clock = bios_parser_set_pixel_clock, 3475 3476 .set_dce_clock = bios_parser_set_dce_clock, 3477 3478 .program_crtc_timing = bios_parser_program_crtc_timing, 3479 3480 .enable_disp_power_gating = bios_parser_enable_disp_power_gating, 3481 3482 .bios_parser_destroy = firmware_parser_destroy, 3483 3484 .get_board_layout_info = bios_get_board_layout_info, 3485 /* TODO: use this fn in hw init?*/ 3486 .pack_data_tables = bios_parser_pack_data_tables, 3487 3488 .get_atom_dc_golden_table = bios_get_atom_dc_golden_table, 3489 3490 .enable_lvtma_control = bios_parser_enable_lvtma_control, 3491 3492 .get_soc_bb_info = bios_parser_get_soc_bb_info, 3493 3494 .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info, 3495 3496 .get_lttpr_caps = bios_parser_get_lttpr_caps, 3497 3498 .get_lttpr_interop = bios_parser_get_lttpr_interop, 3499 3500 .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info, 3501 }; 3502 3503 static bool bios_parser2_construct( 3504 struct bios_parser *bp, 3505 struct bp_init_data *init, 3506 enum dce_version dce_version) 3507 { 3508 uint16_t *rom_header_offset = NULL; 3509 struct atom_rom_header_v2_2 *rom_header = NULL; 3510 struct display_object_info_table_v1_4 *object_info_tbl; 3511 struct atom_data_revision tbl_rev = {0}; 3512 3513 if (!init) 3514 return false; 3515 3516 if (!init->bios) 3517 return false; 3518 3519 bp->base.funcs = &vbios_funcs; 3520 bp->base.bios = init->bios; 3521 bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT; 3522 3523 bp->base.ctx = init->ctx; 3524 3525 bp->base.bios_local_image = NULL; 3526 3527 rom_header_offset = 3528 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER); 3529 3530 if (!rom_header_offset) 3531 return false; 3532 3533 rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset); 3534 3535 if (!rom_header) 3536 return false; 3537 3538 get_atom_data_table_revision(&rom_header->table_header, &tbl_rev); 3539 if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2)) 3540 return false; 3541 3542 bp->master_data_tbl = 3543 GET_IMAGE(struct atom_master_data_table_v2_1, 3544 rom_header->masterdatatable_offset); 3545 3546 if (!bp->master_data_tbl) 3547 return false; 3548 3549 bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo); 3550 3551 if (!bp->object_info_tbl_offset) 3552 return false; 3553 3554 object_info_tbl = 3555 GET_IMAGE(struct display_object_info_table_v1_4, 3556 bp->object_info_tbl_offset); 3557 3558 if (!object_info_tbl) 3559 return false; 3560 3561 get_atom_data_table_revision(&object_info_tbl->table_header, 3562 &bp->object_info_tbl.revision); 3563 3564 if (bp->object_info_tbl.revision.major == 1 3565 && bp->object_info_tbl.revision.minor == 4) { 3566 struct display_object_info_table_v1_4 *tbl_v1_4; 3567 3568 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4, 3569 bp->object_info_tbl_offset); 3570 if (!tbl_v1_4) 3571 return false; 3572 3573 bp->object_info_tbl.v1_4 = tbl_v1_4; 3574 } else if (bp->object_info_tbl.revision.major == 1 3575 && bp->object_info_tbl.revision.minor == 5) { 3576 struct display_object_info_table_v1_5 *tbl_v1_5; 3577 3578 tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5, 3579 bp->object_info_tbl_offset); 3580 if (!tbl_v1_5) 3581 return false; 3582 3583 bp->object_info_tbl.v1_5 = tbl_v1_5; 3584 } else { 3585 ASSERT(0); 3586 return false; 3587 } 3588 3589 dal_firmware_parser_init_cmd_tbl(bp); 3590 dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); 3591 3592 bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); 3593 bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK; 3594 bios_parser_get_vram_info(&bp->base, &bp->base.vram_info); 3595 3596 return true; 3597 } 3598 3599 struct dc_bios *firmware_parser_create( 3600 struct bp_init_data *init, 3601 enum dce_version dce_version) 3602 { 3603 struct bios_parser *bp = NULL; 3604 3605 bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); 3606 if (!bp) 3607 return NULL; 3608 3609 if (bios_parser2_construct(bp, init, dce_version)) 3610 return &bp->base; 3611 3612 kfree(bp); 3613 return NULL; 3614 } 3615 3616 3617