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