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