0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dm_services.h"
0027
0028 #include "ObjectID.h"
0029 #include "atomfirmware.h"
0030
0031 #include "dc_bios_types.h"
0032 #include "include/grph_object_ctrl_defs.h"
0033 #include "include/bios_parser_interface.h"
0034 #include "include/i2caux_interface.h"
0035 #include "include/logger_interface.h"
0036
0037 #include "command_table2.h"
0038
0039 #include "bios_parser_helper.h"
0040 #include "command_table_helper2.h"
0041 #include "bios_parser2.h"
0042 #include "bios_parser_types_internal2.h"
0043 #include "bios_parser_interface.h"
0044
0045 #include "bios_parser_common.h"
0046
0047
0048 #ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
0049 #define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05
0050 #endif
0051
0052 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
0053 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \
0054 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
0055 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
0056 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
0057 #endif
0058
0059 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
0060 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \
0061 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
0062 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
0063 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
0064 #endif
0065
0066 #define DC_LOGGER \
0067 bp->base.ctx->logger
0068
0069 #define LAST_RECORD_TYPE 0xff
0070 #define SMU9_SYSPLL0_ID 0
0071
0072 struct i2c_id_config_access {
0073 uint8_t bfI2C_LineMux:4;
0074 uint8_t bfHW_EngineID:3;
0075 uint8_t bfHW_Capable:1;
0076 uint8_t ucAccess;
0077 };
0078
0079 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
0080 struct atom_i2c_record *record,
0081 struct graphics_object_i2c_info *info);
0082
0083 static enum bp_result bios_parser_get_firmware_info(
0084 struct dc_bios *dcb,
0085 struct dc_firmware_info *info);
0086
0087 static enum bp_result bios_parser_get_encoder_cap_info(
0088 struct dc_bios *dcb,
0089 struct graphics_object_id object_id,
0090 struct bp_encoder_cap_info *info);
0091
0092 static enum bp_result get_firmware_info_v3_1(
0093 struct bios_parser *bp,
0094 struct dc_firmware_info *info);
0095
0096 static enum bp_result get_firmware_info_v3_2(
0097 struct bios_parser *bp,
0098 struct dc_firmware_info *info);
0099
0100 static enum bp_result get_firmware_info_v3_4(
0101 struct bios_parser *bp,
0102 struct dc_firmware_info *info);
0103
0104 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
0105 struct atom_display_object_path_v2 *object);
0106
0107 static struct atom_encoder_caps_record *get_encoder_cap_record(
0108 struct bios_parser *bp,
0109 struct atom_display_object_path_v2 *object);
0110
0111 #define BIOS_IMAGE_SIZE_OFFSET 2
0112 #define BIOS_IMAGE_SIZE_UNIT 512
0113
0114 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
0115
0116 static void bios_parser2_destruct(struct bios_parser *bp)
0117 {
0118 kfree(bp->base.bios_local_image);
0119 kfree(bp->base.integrated_info);
0120 }
0121
0122 static void firmware_parser_destroy(struct dc_bios **dcb)
0123 {
0124 struct bios_parser *bp = BP_FROM_DCB(*dcb);
0125
0126 if (!bp) {
0127 BREAK_TO_DEBUGGER();
0128 return;
0129 }
0130
0131 bios_parser2_destruct(bp);
0132
0133 kfree(bp);
0134 *dcb = NULL;
0135 }
0136
0137 static void get_atom_data_table_revision(
0138 struct atom_common_table_header *atom_data_tbl,
0139 struct atom_data_revision *tbl_revision)
0140 {
0141 if (!tbl_revision)
0142 return;
0143
0144
0145 tbl_revision->major = 0;
0146 tbl_revision->minor = 0;
0147
0148 if (!atom_data_tbl)
0149 return;
0150
0151 tbl_revision->major =
0152 (uint32_t) atom_data_tbl->format_revision & 0x3f;
0153 tbl_revision->minor =
0154 (uint32_t) atom_data_tbl->content_revision & 0x3f;
0155 }
0156
0157
0158
0159
0160 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
0161 {
0162 struct bios_parser *bp = BP_FROM_DCB(dcb);
0163 unsigned int count = 0;
0164 unsigned int i;
0165
0166 switch (bp->object_info_tbl.revision.minor) {
0167 default:
0168 case 4:
0169 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++)
0170 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
0171 count++;
0172
0173 break;
0174
0175 case 5:
0176 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++)
0177 if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0)
0178 count++;
0179
0180 break;
0181 }
0182 return count;
0183 }
0184
0185 static struct graphics_object_id bios_parser_get_connector_id(
0186 struct dc_bios *dcb,
0187 uint8_t i)
0188 {
0189 struct bios_parser *bp = BP_FROM_DCB(dcb);
0190 struct graphics_object_id object_id = dal_graphics_object_id_init(
0191 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
0192 struct object_info_table *tbl = &bp->object_info_tbl;
0193 struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
0194
0195 struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5;
0196
0197 switch (bp->object_info_tbl.revision.minor) {
0198 default:
0199 case 4:
0200 if (v1_4->number_of_path > i) {
0201
0202
0203
0204 if (v1_4->display_path[i].encoderobjid != 0 &&
0205 v1_4->display_path[i].display_objid != 0)
0206 object_id = object_id_from_bios_object_id(
0207 v1_4->display_path[i].display_objid);
0208 }
0209 break;
0210
0211 case 5:
0212 if (v1_5->number_of_path > i) {
0213
0214
0215
0216 if (v1_5->display_path[i].encoderobjid != 0 &&
0217 v1_5->display_path[i].display_objid != 0)
0218 object_id = object_id_from_bios_object_id(
0219 v1_5->display_path[i].display_objid);
0220 }
0221 break;
0222 }
0223 return object_id;
0224 }
0225
0226 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
0227 struct graphics_object_id object_id, uint32_t index,
0228 struct graphics_object_id *src_object_id)
0229 {
0230 struct bios_parser *bp = BP_FROM_DCB(dcb);
0231 unsigned int i;
0232 enum bp_result bp_result = BP_RESULT_BADINPUT;
0233 struct graphics_object_id obj_id = { 0 };
0234 struct object_info_table *tbl = &bp->object_info_tbl;
0235
0236 if (!src_object_id)
0237 return bp_result;
0238
0239 switch (object_id.type) {
0240
0241
0242
0243 case OBJECT_TYPE_ENCODER:
0244
0245
0246
0247
0248 switch (bp->object_info_tbl.revision.minor) {
0249 default:
0250 case 4:
0251 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
0252 obj_id = object_id_from_bios_object_id(
0253 tbl->v1_4->display_path[i].encoderobjid);
0254 if (object_id.type == obj_id.type &&
0255 object_id.id == obj_id.id &&
0256 object_id.enum_id == obj_id.enum_id) {
0257 *src_object_id =
0258 object_id_from_bios_object_id(
0259 0x1100);
0260
0261 }
0262 }
0263 bp_result = BP_RESULT_OK;
0264 break;
0265
0266 case 5:
0267 for (i = 0; i < tbl->v1_5->number_of_path; i++) {
0268 obj_id = object_id_from_bios_object_id(
0269 tbl->v1_5->display_path[i].encoderobjid);
0270 if (object_id.type == obj_id.type &&
0271 object_id.id == obj_id.id &&
0272 object_id.enum_id == obj_id.enum_id) {
0273 *src_object_id =
0274 object_id_from_bios_object_id(
0275 0x1100);
0276
0277 }
0278 }
0279 bp_result = BP_RESULT_OK;
0280 break;
0281 }
0282 break;
0283 case OBJECT_TYPE_CONNECTOR:
0284 switch (bp->object_info_tbl.revision.minor) {
0285 default:
0286 case 4:
0287 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
0288 obj_id = object_id_from_bios_object_id(
0289 tbl->v1_4->display_path[i]
0290 .display_objid);
0291
0292 if (object_id.type == obj_id.type &&
0293 object_id.id == obj_id.id &&
0294 object_id.enum_id == obj_id.enum_id) {
0295 *src_object_id =
0296 object_id_from_bios_object_id(
0297 tbl->v1_4
0298 ->display_path[i]
0299 .encoderobjid);
0300
0301 }
0302 }
0303 bp_result = BP_RESULT_OK;
0304 break;
0305 }
0306 bp_result = BP_RESULT_OK;
0307 break;
0308 case 5:
0309 for (i = 0; i < tbl->v1_5->number_of_path; i++) {
0310 obj_id = object_id_from_bios_object_id(
0311 tbl->v1_5->display_path[i].display_objid);
0312
0313 if (object_id.type == obj_id.type &&
0314 object_id.id == obj_id.id &&
0315 object_id.enum_id == obj_id.enum_id) {
0316 *src_object_id = object_id_from_bios_object_id(
0317 tbl->v1_5->display_path[i].encoderobjid);
0318
0319 }
0320 }
0321 bp_result = BP_RESULT_OK;
0322 break;
0323
0324 default:
0325 bp_result = BP_RESULT_OK;
0326 break;
0327 }
0328
0329 return bp_result;
0330 }
0331
0332
0333 static struct atom_display_object_path_v2 *get_bios_object(
0334 struct bios_parser *bp,
0335 struct graphics_object_id id)
0336 {
0337 unsigned int i;
0338 struct graphics_object_id obj_id = {0};
0339
0340 switch (id.type) {
0341 case OBJECT_TYPE_ENCODER:
0342 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
0343 obj_id = object_id_from_bios_object_id(
0344 bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
0345 if (id.type == obj_id.type && id.id == obj_id.id
0346 && id.enum_id == obj_id.enum_id)
0347 return &bp->object_info_tbl.v1_4->display_path[i];
0348 }
0349 fallthrough;
0350 case OBJECT_TYPE_CONNECTOR:
0351 case OBJECT_TYPE_GENERIC:
0352
0353
0354
0355 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
0356 obj_id = object_id_from_bios_object_id(
0357 bp->object_info_tbl.v1_4->display_path[i].display_objid);
0358 if (id.type == obj_id.type && id.id == obj_id.id
0359 && id.enum_id == obj_id.enum_id)
0360 return &bp->object_info_tbl.v1_4->display_path[i];
0361 }
0362 fallthrough;
0363 default:
0364 return NULL;
0365 }
0366 }
0367
0368
0369 static struct atom_display_object_path_v3 *get_bios_object_from_path_v3(
0370 struct bios_parser *bp,
0371 struct graphics_object_id id)
0372 {
0373 unsigned int i;
0374 struct graphics_object_id obj_id = {0};
0375
0376 switch (id.type) {
0377 case OBJECT_TYPE_ENCODER:
0378 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
0379 obj_id = object_id_from_bios_object_id(
0380 bp->object_info_tbl.v1_5->display_path[i].encoderobjid);
0381 if (id.type == obj_id.type && id.id == obj_id.id
0382 && id.enum_id == obj_id.enum_id)
0383 return &bp->object_info_tbl.v1_5->display_path[i];
0384 }
0385 break;
0386
0387 case OBJECT_TYPE_CONNECTOR:
0388 case OBJECT_TYPE_GENERIC:
0389
0390
0391
0392 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
0393 obj_id = object_id_from_bios_object_id(
0394 bp->object_info_tbl.v1_5->display_path[i].display_objid);
0395 if (id.type == obj_id.type && id.id == obj_id.id
0396 && id.enum_id == obj_id.enum_id)
0397 return &bp->object_info_tbl.v1_5->display_path[i];
0398 }
0399 break;
0400
0401 default:
0402 return NULL;
0403 }
0404
0405 return NULL;
0406 }
0407
0408 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
0409 struct graphics_object_id id,
0410 struct graphics_object_i2c_info *info)
0411 {
0412 uint32_t offset;
0413 struct atom_display_object_path_v2 *object;
0414
0415 struct atom_display_object_path_v3 *object_path_v3;
0416
0417 struct atom_common_record_header *header;
0418 struct atom_i2c_record *record;
0419 struct atom_i2c_record dummy_record = {0};
0420 struct bios_parser *bp = BP_FROM_DCB(dcb);
0421
0422 if (!info)
0423 return BP_RESULT_BADINPUT;
0424
0425 if (id.type == OBJECT_TYPE_GENERIC) {
0426 dummy_record.i2c_id = id.id;
0427
0428 if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
0429 return BP_RESULT_OK;
0430 else
0431 return BP_RESULT_NORECORD;
0432 }
0433
0434 switch (bp->object_info_tbl.revision.minor) {
0435 case 4:
0436 default:
0437 object = get_bios_object(bp, id);
0438
0439 if (!object)
0440 return BP_RESULT_BADINPUT;
0441
0442 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
0443 break;
0444 case 5:
0445 object_path_v3 = get_bios_object_from_path_v3(bp, id);
0446
0447 if (!object_path_v3)
0448 return BP_RESULT_BADINPUT;
0449
0450 offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset;
0451 break;
0452 }
0453
0454 for (;;) {
0455 header = GET_IMAGE(struct atom_common_record_header, offset);
0456
0457 if (!header)
0458 return BP_RESULT_BADBIOSTABLE;
0459
0460 if (header->record_type == LAST_RECORD_TYPE ||
0461 !header->record_size)
0462 break;
0463
0464 if (header->record_type == ATOM_I2C_RECORD_TYPE
0465 && sizeof(struct atom_i2c_record) <=
0466 header->record_size) {
0467
0468 record = (struct atom_i2c_record *) header;
0469
0470 if (get_gpio_i2c_info(bp, record, info) ==
0471 BP_RESULT_OK)
0472 return BP_RESULT_OK;
0473 }
0474
0475 offset += header->record_size;
0476 }
0477
0478 return BP_RESULT_NORECORD;
0479 }
0480
0481 static enum bp_result get_gpio_i2c_info(
0482 struct bios_parser *bp,
0483 struct atom_i2c_record *record,
0484 struct graphics_object_i2c_info *info)
0485 {
0486 struct atom_gpio_pin_lut_v2_1 *header;
0487 uint32_t count = 0;
0488 unsigned int table_index = 0;
0489 bool find_valid = false;
0490
0491 if (!info)
0492 return BP_RESULT_BADINPUT;
0493
0494
0495 if (!DATA_TABLES(gpio_pin_lut))
0496 return BP_RESULT_BADBIOSTABLE;
0497
0498 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
0499 DATA_TABLES(gpio_pin_lut));
0500 if (!header)
0501 return BP_RESULT_BADBIOSTABLE;
0502
0503 if (sizeof(struct atom_common_table_header) +
0504 sizeof(struct atom_gpio_pin_assignment) >
0505 le16_to_cpu(header->table_header.structuresize))
0506 return BP_RESULT_BADBIOSTABLE;
0507
0508
0509 if (header->table_header.content_revision != 1)
0510 return BP_RESULT_UNSUPPORTED;
0511
0512
0513 count = (le16_to_cpu(header->table_header.structuresize)
0514 - sizeof(struct atom_common_table_header))
0515 / sizeof(struct atom_gpio_pin_assignment);
0516
0517 for (table_index = 0; table_index < count; table_index++) {
0518 if (((record->i2c_id & I2C_HW_CAP) == (
0519 header->gpio_pin[table_index].gpio_id &
0520 I2C_HW_CAP)) &&
0521 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
0522 (header->gpio_pin[table_index].gpio_id &
0523 I2C_HW_ENGINE_ID_MASK)) &&
0524 ((record->i2c_id & I2C_HW_LANE_MUX) ==
0525 (header->gpio_pin[table_index].gpio_id &
0526 I2C_HW_LANE_MUX))) {
0527
0528 find_valid = true;
0529 break;
0530 }
0531 }
0532
0533
0534
0535
0536 if (find_valid == false)
0537 return BP_RESULT_BADBIOSTABLE;
0538
0539
0540 info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
0541 info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
0542 info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
0543 info->i2c_slave_address = record->i2c_slave_addr;
0544
0545
0546 info->gpio_info.clk_a_register_index =
0547 le16_to_cpu(
0548 header->gpio_pin[table_index].data_a_reg_index);
0549 info->gpio_info.clk_a_shift =
0550 header->gpio_pin[table_index].gpio_bitshift;
0551
0552 return BP_RESULT_OK;
0553 }
0554
0555 static struct atom_hpd_int_record *get_hpd_record_for_path_v3(
0556 struct bios_parser *bp,
0557 struct atom_display_object_path_v3 *object)
0558 {
0559 struct atom_common_record_header *header;
0560 uint32_t offset;
0561
0562 if (!object) {
0563 BREAK_TO_DEBUGGER();
0564 return NULL;
0565 }
0566
0567 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
0568
0569 for (;;) {
0570 header = GET_IMAGE(struct atom_common_record_header, offset);
0571
0572 if (!header)
0573 return NULL;
0574
0575 if (header->record_type == ATOM_RECORD_END_TYPE ||
0576 !header->record_size)
0577 break;
0578
0579 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
0580 && sizeof(struct atom_hpd_int_record) <=
0581 header->record_size)
0582 return (struct atom_hpd_int_record *) header;
0583
0584 offset += header->record_size;
0585 }
0586
0587 return NULL;
0588 }
0589
0590 static enum bp_result bios_parser_get_hpd_info(
0591 struct dc_bios *dcb,
0592 struct graphics_object_id id,
0593 struct graphics_object_hpd_info *info)
0594 {
0595 struct bios_parser *bp = BP_FROM_DCB(dcb);
0596 struct atom_display_object_path_v2 *object;
0597 struct atom_display_object_path_v3 *object_path_v3;
0598 struct atom_hpd_int_record *record = NULL;
0599
0600 if (!info)
0601 return BP_RESULT_BADINPUT;
0602
0603 switch (bp->object_info_tbl.revision.minor) {
0604 case 4:
0605 default:
0606 object = get_bios_object(bp, id);
0607
0608 if (!object)
0609 return BP_RESULT_BADINPUT;
0610
0611 record = get_hpd_record(bp, object);
0612
0613 break;
0614 case 5:
0615 object_path_v3 = get_bios_object_from_path_v3(bp, id);
0616
0617 if (!object_path_v3)
0618 return BP_RESULT_BADINPUT;
0619
0620 record = get_hpd_record_for_path_v3(bp, object_path_v3);
0621 break;
0622 }
0623
0624 if (record != NULL) {
0625 info->hpd_int_gpio_uid = record->pin_id;
0626 info->hpd_active = record->plugin_pin_state;
0627 return BP_RESULT_OK;
0628 }
0629
0630 return BP_RESULT_NORECORD;
0631 }
0632
0633 static struct atom_hpd_int_record *get_hpd_record(
0634 struct bios_parser *bp,
0635 struct atom_display_object_path_v2 *object)
0636 {
0637 struct atom_common_record_header *header;
0638 uint32_t offset;
0639
0640 if (!object) {
0641 BREAK_TO_DEBUGGER();
0642 return NULL;
0643 }
0644
0645 offset = le16_to_cpu(object->disp_recordoffset)
0646 + bp->object_info_tbl_offset;
0647
0648 for (;;) {
0649 header = GET_IMAGE(struct atom_common_record_header, offset);
0650
0651 if (!header)
0652 return NULL;
0653
0654 if (header->record_type == LAST_RECORD_TYPE ||
0655 !header->record_size)
0656 break;
0657
0658 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
0659 && sizeof(struct atom_hpd_int_record) <=
0660 header->record_size)
0661 return (struct atom_hpd_int_record *) header;
0662
0663 offset += header->record_size;
0664 }
0665
0666 return NULL;
0667 }
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683 static enum bp_result bios_parser_get_gpio_pin_info(
0684 struct dc_bios *dcb,
0685 uint32_t gpio_id,
0686 struct gpio_pin_info *info)
0687 {
0688 struct bios_parser *bp = BP_FROM_DCB(dcb);
0689 struct atom_gpio_pin_lut_v2_1 *header;
0690 uint32_t count = 0;
0691 uint32_t i = 0;
0692
0693 if (!DATA_TABLES(gpio_pin_lut))
0694 return BP_RESULT_BADBIOSTABLE;
0695
0696 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
0697 DATA_TABLES(gpio_pin_lut));
0698 if (!header)
0699 return BP_RESULT_BADBIOSTABLE;
0700
0701 if (sizeof(struct atom_common_table_header) +
0702 sizeof(struct atom_gpio_pin_assignment)
0703 > le16_to_cpu(header->table_header.structuresize))
0704 return BP_RESULT_BADBIOSTABLE;
0705
0706 if (header->table_header.content_revision != 1)
0707 return BP_RESULT_UNSUPPORTED;
0708
0709
0710 count = (le16_to_cpu(header->table_header.structuresize)
0711 - sizeof(struct atom_common_table_header))
0712 / sizeof(struct atom_gpio_pin_assignment);
0713 for (i = 0; i < count; ++i) {
0714 if (header->gpio_pin[i].gpio_id != gpio_id)
0715 continue;
0716
0717 info->offset =
0718 (uint32_t) le16_to_cpu(
0719 header->gpio_pin[i].data_a_reg_index);
0720 info->offset_y = info->offset + 2;
0721 info->offset_en = info->offset + 1;
0722 info->offset_mask = info->offset - 1;
0723
0724 info->mask = (uint32_t) (1 <<
0725 header->gpio_pin[i].gpio_bitshift);
0726 info->mask_y = info->mask + 2;
0727 info->mask_en = info->mask + 1;
0728 info->mask_mask = info->mask - 1;
0729
0730 return BP_RESULT_OK;
0731 }
0732
0733 return BP_RESULT_NORECORD;
0734 }
0735
0736 static struct device_id device_type_from_device_id(uint16_t device_id)
0737 {
0738
0739 struct device_id result_device_id;
0740
0741 result_device_id.raw_device_tag = device_id;
0742
0743 switch (device_id) {
0744 case ATOM_DISPLAY_LCD1_SUPPORT:
0745 result_device_id.device_type = DEVICE_TYPE_LCD;
0746 result_device_id.enum_id = 1;
0747 break;
0748
0749 case ATOM_DISPLAY_LCD2_SUPPORT:
0750 result_device_id.device_type = DEVICE_TYPE_LCD;
0751 result_device_id.enum_id = 2;
0752 break;
0753
0754 case ATOM_DISPLAY_DFP1_SUPPORT:
0755 result_device_id.device_type = DEVICE_TYPE_DFP;
0756 result_device_id.enum_id = 1;
0757 break;
0758
0759 case ATOM_DISPLAY_DFP2_SUPPORT:
0760 result_device_id.device_type = DEVICE_TYPE_DFP;
0761 result_device_id.enum_id = 2;
0762 break;
0763
0764 case ATOM_DISPLAY_DFP3_SUPPORT:
0765 result_device_id.device_type = DEVICE_TYPE_DFP;
0766 result_device_id.enum_id = 3;
0767 break;
0768
0769 case ATOM_DISPLAY_DFP4_SUPPORT:
0770 result_device_id.device_type = DEVICE_TYPE_DFP;
0771 result_device_id.enum_id = 4;
0772 break;
0773
0774 case ATOM_DISPLAY_DFP5_SUPPORT:
0775 result_device_id.device_type = DEVICE_TYPE_DFP;
0776 result_device_id.enum_id = 5;
0777 break;
0778
0779 case ATOM_DISPLAY_DFP6_SUPPORT:
0780 result_device_id.device_type = DEVICE_TYPE_DFP;
0781 result_device_id.enum_id = 6;
0782 break;
0783
0784 default:
0785 BREAK_TO_DEBUGGER();
0786 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
0787 result_device_id.enum_id = 0;
0788 }
0789 return result_device_id;
0790 }
0791
0792 static enum bp_result bios_parser_get_device_tag(
0793 struct dc_bios *dcb,
0794 struct graphics_object_id connector_object_id,
0795 uint32_t device_tag_index,
0796 struct connector_device_tag_info *info)
0797 {
0798 struct bios_parser *bp = BP_FROM_DCB(dcb);
0799 struct atom_display_object_path_v2 *object;
0800
0801 struct atom_display_object_path_v3 *object_path_v3;
0802
0803
0804 if (!info)
0805 return BP_RESULT_BADINPUT;
0806
0807 switch (bp->object_info_tbl.revision.minor) {
0808 case 4:
0809 default:
0810
0811 object = get_bios_object(bp, connector_object_id);
0812
0813 if (!object) {
0814 BREAK_TO_DEBUGGER();
0815 return BP_RESULT_BADINPUT;
0816 }
0817
0818 info->acpi_device = 0;
0819 info->dev_id = device_type_from_device_id(object->device_tag);
0820 break;
0821 case 5:
0822 object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id);
0823
0824 if (!object_path_v3) {
0825 BREAK_TO_DEBUGGER();
0826 return BP_RESULT_BADINPUT;
0827 }
0828 info->acpi_device = 0;
0829 info->dev_id = device_type_from_device_id(object_path_v3->device_tag);
0830 break;
0831 }
0832
0833 return BP_RESULT_OK;
0834 }
0835
0836 static enum bp_result get_ss_info_v4_1(
0837 struct bios_parser *bp,
0838 uint32_t id,
0839 uint32_t index,
0840 struct spread_spectrum_info *ss_info)
0841 {
0842 enum bp_result result = BP_RESULT_OK;
0843 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
0844 struct atom_smu_info_v3_3 *smu_info = NULL;
0845
0846 if (!ss_info)
0847 return BP_RESULT_BADINPUT;
0848
0849 if (!DATA_TABLES(dce_info))
0850 return BP_RESULT_BADBIOSTABLE;
0851
0852 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
0853 DATA_TABLES(dce_info));
0854 if (!disp_cntl_tbl)
0855 return BP_RESULT_BADBIOSTABLE;
0856
0857
0858 ss_info->type.STEP_AND_DELAY_INFO = false;
0859 ss_info->spread_percentage_divider = 1000;
0860
0861 ss_info->target_clock_range = 0xffffffff;
0862
0863 switch (id) {
0864 case AS_SIGNAL_TYPE_DVI:
0865 ss_info->spread_spectrum_percentage =
0866 disp_cntl_tbl->dvi_ss_percentage;
0867 ss_info->spread_spectrum_range =
0868 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
0869 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0870 ss_info->type.CENTER_MODE = true;
0871 break;
0872 case AS_SIGNAL_TYPE_HDMI:
0873 ss_info->spread_spectrum_percentage =
0874 disp_cntl_tbl->hdmi_ss_percentage;
0875 ss_info->spread_spectrum_range =
0876 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
0877 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0878 ss_info->type.CENTER_MODE = true;
0879 break;
0880
0881 case AS_SIGNAL_TYPE_DISPLAY_PORT:
0882 ss_info->spread_spectrum_percentage =
0883 disp_cntl_tbl->dp_ss_percentage;
0884 ss_info->spread_spectrum_range =
0885 disp_cntl_tbl->dp_ss_rate_10hz * 10;
0886 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0887 ss_info->type.CENTER_MODE = true;
0888 break;
0889 case AS_SIGNAL_TYPE_GPU_PLL:
0890
0891
0892
0893
0894 result = BP_RESULT_UNSUPPORTED;
0895 break;
0896 case AS_SIGNAL_TYPE_XGMI:
0897 smu_info = GET_IMAGE(struct atom_smu_info_v3_3,
0898 DATA_TABLES(smu_info));
0899 if (!smu_info)
0900 return BP_RESULT_BADBIOSTABLE;
0901
0902 ss_info->spread_spectrum_percentage =
0903 smu_info->waflclk_ss_percentage;
0904 ss_info->spread_spectrum_range =
0905 smu_info->gpuclk_ss_rate_10hz * 10;
0906 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0907 ss_info->type.CENTER_MODE = true;
0908 break;
0909 default:
0910 result = BP_RESULT_UNSUPPORTED;
0911 }
0912
0913 return result;
0914 }
0915
0916 static enum bp_result get_ss_info_v4_2(
0917 struct bios_parser *bp,
0918 uint32_t id,
0919 uint32_t index,
0920 struct spread_spectrum_info *ss_info)
0921 {
0922 enum bp_result result = BP_RESULT_OK;
0923 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
0924 struct atom_smu_info_v3_1 *smu_info = NULL;
0925
0926 if (!ss_info)
0927 return BP_RESULT_BADINPUT;
0928
0929 if (!DATA_TABLES(dce_info))
0930 return BP_RESULT_BADBIOSTABLE;
0931
0932 if (!DATA_TABLES(smu_info))
0933 return BP_RESULT_BADBIOSTABLE;
0934
0935 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
0936 DATA_TABLES(dce_info));
0937 if (!disp_cntl_tbl)
0938 return BP_RESULT_BADBIOSTABLE;
0939
0940 smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
0941 if (!smu_info)
0942 return BP_RESULT_BADBIOSTABLE;
0943
0944 ss_info->type.STEP_AND_DELAY_INFO = false;
0945 ss_info->spread_percentage_divider = 1000;
0946
0947 ss_info->target_clock_range = 0xffffffff;
0948
0949 switch (id) {
0950 case AS_SIGNAL_TYPE_DVI:
0951 ss_info->spread_spectrum_percentage =
0952 disp_cntl_tbl->dvi_ss_percentage;
0953 ss_info->spread_spectrum_range =
0954 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
0955 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0956 ss_info->type.CENTER_MODE = true;
0957 break;
0958 case AS_SIGNAL_TYPE_HDMI:
0959 ss_info->spread_spectrum_percentage =
0960 disp_cntl_tbl->hdmi_ss_percentage;
0961 ss_info->spread_spectrum_range =
0962 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
0963 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0964 ss_info->type.CENTER_MODE = true;
0965 break;
0966
0967 case AS_SIGNAL_TYPE_DISPLAY_PORT:
0968 ss_info->spread_spectrum_percentage =
0969 smu_info->gpuclk_ss_percentage;
0970 ss_info->spread_spectrum_range =
0971 smu_info->gpuclk_ss_rate_10hz * 10;
0972 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
0973 ss_info->type.CENTER_MODE = true;
0974 break;
0975 case AS_SIGNAL_TYPE_GPU_PLL:
0976
0977
0978
0979
0980 result = BP_RESULT_UNSUPPORTED;
0981 break;
0982 default:
0983 result = BP_RESULT_UNSUPPORTED;
0984 }
0985
0986 return result;
0987 }
0988
0989 static enum bp_result get_ss_info_v4_5(
0990 struct bios_parser *bp,
0991 uint32_t id,
0992 uint32_t index,
0993 struct spread_spectrum_info *ss_info)
0994 {
0995 enum bp_result result = BP_RESULT_OK;
0996 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
0997
0998 if (!ss_info)
0999 return BP_RESULT_BADINPUT;
1000
1001 if (!DATA_TABLES(dce_info))
1002 return BP_RESULT_BADBIOSTABLE;
1003
1004 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1005 DATA_TABLES(dce_info));
1006 if (!disp_cntl_tbl)
1007 return BP_RESULT_BADBIOSTABLE;
1008
1009 ss_info->type.STEP_AND_DELAY_INFO = false;
1010 ss_info->spread_percentage_divider = 1000;
1011
1012 ss_info->target_clock_range = 0xffffffff;
1013
1014 switch (id) {
1015 case AS_SIGNAL_TYPE_DVI:
1016 ss_info->spread_spectrum_percentage =
1017 disp_cntl_tbl->dvi_ss_percentage;
1018 ss_info->spread_spectrum_range =
1019 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
1020 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1021 ss_info->type.CENTER_MODE = true;
1022 break;
1023 case AS_SIGNAL_TYPE_HDMI:
1024 ss_info->spread_spectrum_percentage =
1025 disp_cntl_tbl->hdmi_ss_percentage;
1026 ss_info->spread_spectrum_range =
1027 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
1028 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1029 ss_info->type.CENTER_MODE = true;
1030 break;
1031 case AS_SIGNAL_TYPE_DISPLAY_PORT:
1032 ss_info->spread_spectrum_percentage =
1033 disp_cntl_tbl->dp_ss_percentage;
1034 ss_info->spread_spectrum_range =
1035 disp_cntl_tbl->dp_ss_rate_10hz * 10;
1036 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1037 ss_info->type.CENTER_MODE = true;
1038 break;
1039 case AS_SIGNAL_TYPE_GPU_PLL:
1040
1041
1042
1043
1044 result = BP_RESULT_UNSUPPORTED;
1045 break;
1046 default:
1047 result = BP_RESULT_UNSUPPORTED;
1048 break;
1049 }
1050
1051 return result;
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068 static enum bp_result bios_parser_get_spread_spectrum_info(
1069 struct dc_bios *dcb,
1070 enum as_signal_type signal,
1071 uint32_t index,
1072 struct spread_spectrum_info *ss_info)
1073 {
1074 struct bios_parser *bp = BP_FROM_DCB(dcb);
1075 enum bp_result result = BP_RESULT_UNSUPPORTED;
1076 struct atom_common_table_header *header;
1077 struct atom_data_revision tbl_revision;
1078
1079 if (!ss_info)
1080 return BP_RESULT_BADINPUT;
1081
1082 if (!DATA_TABLES(dce_info))
1083 return BP_RESULT_UNSUPPORTED;
1084
1085 header = GET_IMAGE(struct atom_common_table_header,
1086 DATA_TABLES(dce_info));
1087 get_atom_data_table_revision(header, &tbl_revision);
1088
1089 switch (tbl_revision.major) {
1090 case 4:
1091 switch (tbl_revision.minor) {
1092 case 1:
1093 return get_ss_info_v4_1(bp, signal, index, ss_info);
1094 case 2:
1095 case 3:
1096 case 4:
1097 return get_ss_info_v4_2(bp, signal, index, ss_info);
1098 case 5:
1099 return get_ss_info_v4_5(bp, signal, index, ss_info);
1100
1101 default:
1102 ASSERT(0);
1103 break;
1104 }
1105 break;
1106 default:
1107 break;
1108 }
1109
1110 return result;
1111 }
1112
1113 static enum bp_result get_soc_bb_info_v4_4(
1114 struct bios_parser *bp,
1115 struct bp_soc_bb_info *soc_bb_info)
1116 {
1117 enum bp_result result = BP_RESULT_OK;
1118 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1119
1120 if (!soc_bb_info)
1121 return BP_RESULT_BADINPUT;
1122
1123 if (!DATA_TABLES(dce_info))
1124 return BP_RESULT_BADBIOSTABLE;
1125
1126 if (!DATA_TABLES(smu_info))
1127 return BP_RESULT_BADBIOSTABLE;
1128
1129 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1130 DATA_TABLES(dce_info));
1131 if (!disp_cntl_tbl)
1132 return BP_RESULT_BADBIOSTABLE;
1133
1134 soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
1135 soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
1136 soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
1137
1138 return result;
1139 }
1140
1141 static enum bp_result get_soc_bb_info_v4_5(
1142 struct bios_parser *bp,
1143 struct bp_soc_bb_info *soc_bb_info)
1144 {
1145 enum bp_result result = BP_RESULT_OK;
1146 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1147
1148 if (!soc_bb_info)
1149 return BP_RESULT_BADINPUT;
1150
1151 if (!DATA_TABLES(dce_info))
1152 return BP_RESULT_BADBIOSTABLE;
1153
1154 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1155 DATA_TABLES(dce_info));
1156 if (!disp_cntl_tbl)
1157 return BP_RESULT_BADBIOSTABLE;
1158
1159 soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
1160 soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
1161 soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
1162
1163 return result;
1164 }
1165
1166 static enum bp_result bios_parser_get_soc_bb_info(
1167 struct dc_bios *dcb,
1168 struct bp_soc_bb_info *soc_bb_info)
1169 {
1170 struct bios_parser *bp = BP_FROM_DCB(dcb);
1171 enum bp_result result = BP_RESULT_UNSUPPORTED;
1172 struct atom_common_table_header *header;
1173 struct atom_data_revision tbl_revision;
1174
1175 if (!soc_bb_info)
1176 return BP_RESULT_BADINPUT;
1177
1178 if (!DATA_TABLES(dce_info))
1179 return BP_RESULT_UNSUPPORTED;
1180
1181 header = GET_IMAGE(struct atom_common_table_header,
1182 DATA_TABLES(dce_info));
1183 get_atom_data_table_revision(header, &tbl_revision);
1184
1185 switch (tbl_revision.major) {
1186 case 4:
1187 switch (tbl_revision.minor) {
1188 case 1:
1189 case 2:
1190 case 3:
1191 break;
1192 case 4:
1193 result = get_soc_bb_info_v4_4(bp, soc_bb_info);
1194 break;
1195 case 5:
1196 result = get_soc_bb_info_v4_5(bp, soc_bb_info);
1197 break;
1198 default:
1199 break;
1200 }
1201 break;
1202 default:
1203 break;
1204 }
1205
1206 return result;
1207 }
1208
1209 static enum bp_result get_disp_caps_v4_1(
1210 struct bios_parser *bp,
1211 uint8_t *dce_caps)
1212 {
1213 enum bp_result result = BP_RESULT_OK;
1214 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
1215
1216 if (!dce_caps)
1217 return BP_RESULT_BADINPUT;
1218
1219 if (!DATA_TABLES(dce_info))
1220 return BP_RESULT_BADBIOSTABLE;
1221
1222 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
1223 DATA_TABLES(dce_info));
1224
1225 if (!disp_cntl_tbl)
1226 return BP_RESULT_BADBIOSTABLE;
1227
1228 *dce_caps = disp_cntl_tbl->display_caps;
1229
1230 return result;
1231 }
1232
1233 static enum bp_result get_disp_caps_v4_2(
1234 struct bios_parser *bp,
1235 uint8_t *dce_caps)
1236 {
1237 enum bp_result result = BP_RESULT_OK;
1238 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
1239
1240 if (!dce_caps)
1241 return BP_RESULT_BADINPUT;
1242
1243 if (!DATA_TABLES(dce_info))
1244 return BP_RESULT_BADBIOSTABLE;
1245
1246 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
1247 DATA_TABLES(dce_info));
1248
1249 if (!disp_cntl_tbl)
1250 return BP_RESULT_BADBIOSTABLE;
1251
1252 *dce_caps = disp_cntl_tbl->display_caps;
1253
1254 return result;
1255 }
1256
1257 static enum bp_result get_disp_caps_v4_3(
1258 struct bios_parser *bp,
1259 uint8_t *dce_caps)
1260 {
1261 enum bp_result result = BP_RESULT_OK;
1262 struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL;
1263
1264 if (!dce_caps)
1265 return BP_RESULT_BADINPUT;
1266
1267 if (!DATA_TABLES(dce_info))
1268 return BP_RESULT_BADBIOSTABLE;
1269
1270 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3,
1271 DATA_TABLES(dce_info));
1272
1273 if (!disp_cntl_tbl)
1274 return BP_RESULT_BADBIOSTABLE;
1275
1276 *dce_caps = disp_cntl_tbl->display_caps;
1277
1278 return result;
1279 }
1280
1281 static enum bp_result get_disp_caps_v4_4(
1282 struct bios_parser *bp,
1283 uint8_t *dce_caps)
1284 {
1285 enum bp_result result = BP_RESULT_OK;
1286 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1287
1288 if (!dce_caps)
1289 return BP_RESULT_BADINPUT;
1290
1291 if (!DATA_TABLES(dce_info))
1292 return BP_RESULT_BADBIOSTABLE;
1293
1294 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1295 DATA_TABLES(dce_info));
1296
1297 if (!disp_cntl_tbl)
1298 return BP_RESULT_BADBIOSTABLE;
1299
1300 *dce_caps = disp_cntl_tbl->display_caps;
1301
1302 return result;
1303 }
1304
1305 static enum bp_result get_disp_caps_v4_5(
1306 struct bios_parser *bp,
1307 uint8_t *dce_caps)
1308 {
1309 enum bp_result result = BP_RESULT_OK;
1310 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1311
1312 if (!dce_caps)
1313 return BP_RESULT_BADINPUT;
1314
1315 if (!DATA_TABLES(dce_info))
1316 return BP_RESULT_BADBIOSTABLE;
1317
1318 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1319 DATA_TABLES(dce_info));
1320
1321 if (!disp_cntl_tbl)
1322 return BP_RESULT_BADBIOSTABLE;
1323
1324 *dce_caps = disp_cntl_tbl->display_caps;
1325
1326 return result;
1327 }
1328
1329 static enum bp_result bios_parser_get_lttpr_interop(
1330 struct dc_bios *dcb,
1331 uint8_t *dce_caps)
1332 {
1333 struct bios_parser *bp = BP_FROM_DCB(dcb);
1334 enum bp_result result = BP_RESULT_UNSUPPORTED;
1335 struct atom_common_table_header *header;
1336 struct atom_data_revision tbl_revision;
1337
1338 if (!DATA_TABLES(dce_info))
1339 return BP_RESULT_UNSUPPORTED;
1340
1341 header = GET_IMAGE(struct atom_common_table_header,
1342 DATA_TABLES(dce_info));
1343 get_atom_data_table_revision(header, &tbl_revision);
1344 switch (tbl_revision.major) {
1345 case 4:
1346 switch (tbl_revision.minor) {
1347 case 1:
1348 result = get_disp_caps_v4_1(bp, dce_caps);
1349 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1350 break;
1351 case 2:
1352 result = get_disp_caps_v4_2(bp, dce_caps);
1353 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1354 break;
1355 case 3:
1356 result = get_disp_caps_v4_3(bp, dce_caps);
1357 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1358 break;
1359 case 4:
1360 result = get_disp_caps_v4_4(bp, dce_caps);
1361 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1362 break;
1363 case 5:
1364 result = get_disp_caps_v4_5(bp, dce_caps);
1365 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1366 break;
1367
1368 default:
1369 break;
1370 }
1371 break;
1372 default:
1373 break;
1374 }
1375
1376 return result;
1377 }
1378
1379 static enum bp_result bios_parser_get_lttpr_caps(
1380 struct dc_bios *dcb,
1381 uint8_t *dce_caps)
1382 {
1383 struct bios_parser *bp = BP_FROM_DCB(dcb);
1384 enum bp_result result = BP_RESULT_UNSUPPORTED;
1385 struct atom_common_table_header *header;
1386 struct atom_data_revision tbl_revision;
1387
1388 if (!DATA_TABLES(dce_info))
1389 return BP_RESULT_UNSUPPORTED;
1390
1391 header = GET_IMAGE(struct atom_common_table_header,
1392 DATA_TABLES(dce_info));
1393 get_atom_data_table_revision(header, &tbl_revision);
1394 switch (tbl_revision.major) {
1395 case 4:
1396 switch (tbl_revision.minor) {
1397 case 1:
1398 result = get_disp_caps_v4_1(bp, dce_caps);
1399 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1400 break;
1401 case 2:
1402 result = get_disp_caps_v4_2(bp, dce_caps);
1403 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1404 break;
1405 case 3:
1406 result = get_disp_caps_v4_3(bp, dce_caps);
1407 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1408 break;
1409 case 4:
1410 result = get_disp_caps_v4_4(bp, dce_caps);
1411 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1412 break;
1413 case 5:
1414 result = get_disp_caps_v4_5(bp, dce_caps);
1415 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1416 break;
1417 default:
1418 break;
1419 }
1420 break;
1421 default:
1422 break;
1423 }
1424
1425 return result;
1426 }
1427
1428 static enum bp_result get_embedded_panel_info_v2_1(
1429 struct bios_parser *bp,
1430 struct embedded_panel_info *info)
1431 {
1432 struct lcd_info_v2_1 *lvds;
1433
1434 if (!info)
1435 return BP_RESULT_BADINPUT;
1436
1437 if (!DATA_TABLES(lcd_info))
1438 return BP_RESULT_UNSUPPORTED;
1439
1440 lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
1441
1442 if (!lvds)
1443 return BP_RESULT_BADBIOSTABLE;
1444
1445
1446 if (!((lvds->table_header.format_revision == 2)
1447 && (lvds->table_header.content_revision >= 1)))
1448 return BP_RESULT_UNSUPPORTED;
1449
1450 memset(info, 0, sizeof(struct embedded_panel_info));
1451
1452
1453 info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
1454
1455 info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
1456
1457
1458
1459
1460
1461 info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
1462
1463 info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
1464
1465
1466
1467
1468
1469 info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time);
1470 info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset);
1471 info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width);
1472 info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset);
1473 info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth);
1474 info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
1475 info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
1476
1477
1478 info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
1479
1480 info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1481 & ATOM_HSYNC_POLARITY);
1482 info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1483 & ATOM_VSYNC_POLARITY);
1484
1485
1486 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
1487
1488 info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1489 & ATOM_H_REPLICATIONBY2);
1490 info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1491 & ATOM_V_REPLICATIONBY2);
1492 info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo
1493 & ATOM_COMPOSITESYNC);
1494 info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
1495
1496
1497 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
1498
1499 info->ss_id = 0;
1500
1501 info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1502
1503 return BP_RESULT_OK;
1504 }
1505
1506 static enum bp_result bios_parser_get_embedded_panel_info(
1507 struct dc_bios *dcb,
1508 struct embedded_panel_info *info)
1509 {
1510 struct bios_parser
1511 *bp = BP_FROM_DCB(dcb);
1512 struct atom_common_table_header *header;
1513 struct atom_data_revision tbl_revision;
1514
1515 if (!DATA_TABLES(lcd_info))
1516 return BP_RESULT_FAILURE;
1517
1518 header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
1519
1520 if (!header)
1521 return BP_RESULT_BADBIOSTABLE;
1522
1523 get_atom_data_table_revision(header, &tbl_revision);
1524
1525 switch (tbl_revision.major) {
1526 case 2:
1527 switch (tbl_revision.minor) {
1528 case 1:
1529 return get_embedded_panel_info_v2_1(bp, info);
1530 default:
1531 break;
1532 }
1533 break;
1534 default:
1535 break;
1536 }
1537
1538 return BP_RESULT_FAILURE;
1539 }
1540
1541 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
1542 {
1543 enum dal_device_type device_type = device_id.device_type;
1544 uint32_t enum_id = device_id.enum_id;
1545
1546 switch (device_type) {
1547 case DEVICE_TYPE_LCD:
1548 switch (enum_id) {
1549 case 1:
1550 return ATOM_DISPLAY_LCD1_SUPPORT;
1551 default:
1552 break;
1553 }
1554 break;
1555 case DEVICE_TYPE_DFP:
1556 switch (enum_id) {
1557 case 1:
1558 return ATOM_DISPLAY_DFP1_SUPPORT;
1559 case 2:
1560 return ATOM_DISPLAY_DFP2_SUPPORT;
1561 case 3:
1562 return ATOM_DISPLAY_DFP3_SUPPORT;
1563 case 4:
1564 return ATOM_DISPLAY_DFP4_SUPPORT;
1565 case 5:
1566 return ATOM_DISPLAY_DFP5_SUPPORT;
1567 case 6:
1568 return ATOM_DISPLAY_DFP6_SUPPORT;
1569 default:
1570 break;
1571 }
1572 break;
1573 default:
1574 break;
1575 }
1576
1577
1578 return 0;
1579 }
1580
1581 static bool bios_parser_is_device_id_supported(
1582 struct dc_bios *dcb,
1583 struct device_id id)
1584 {
1585 struct bios_parser *bp = BP_FROM_DCB(dcb);
1586
1587 uint32_t mask = get_support_mask_for_device_id(id);
1588
1589 switch (bp->object_info_tbl.revision.minor) {
1590 case 4:
1591 default:
1592 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0;
1593 break;
1594 case 5:
1595 return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0;
1596 break;
1597 }
1598
1599 return false;
1600 }
1601
1602 static uint32_t bios_parser_get_ss_entry_number(
1603 struct dc_bios *dcb,
1604 enum as_signal_type signal)
1605 {
1606
1607
1608
1609 return 1;
1610 }
1611
1612 static enum bp_result bios_parser_transmitter_control(
1613 struct dc_bios *dcb,
1614 struct bp_transmitter_control *cntl)
1615 {
1616 struct bios_parser *bp = BP_FROM_DCB(dcb);
1617
1618 if (!bp->cmd_tbl.transmitter_control)
1619 return BP_RESULT_FAILURE;
1620
1621 return bp->cmd_tbl.transmitter_control(bp, cntl);
1622 }
1623
1624 static enum bp_result bios_parser_encoder_control(
1625 struct dc_bios *dcb,
1626 struct bp_encoder_control *cntl)
1627 {
1628 struct bios_parser *bp = BP_FROM_DCB(dcb);
1629
1630 if (!bp->cmd_tbl.dig_encoder_control)
1631 return BP_RESULT_FAILURE;
1632
1633 return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1634 }
1635
1636 static enum bp_result bios_parser_set_pixel_clock(
1637 struct dc_bios *dcb,
1638 struct bp_pixel_clock_parameters *bp_params)
1639 {
1640 struct bios_parser *bp = BP_FROM_DCB(dcb);
1641
1642 if (!bp->cmd_tbl.set_pixel_clock)
1643 return BP_RESULT_FAILURE;
1644
1645 return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1646 }
1647
1648 static enum bp_result bios_parser_set_dce_clock(
1649 struct dc_bios *dcb,
1650 struct bp_set_dce_clock_parameters *bp_params)
1651 {
1652 struct bios_parser *bp = BP_FROM_DCB(dcb);
1653
1654 if (!bp->cmd_tbl.set_dce_clock)
1655 return BP_RESULT_FAILURE;
1656
1657 return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1658 }
1659
1660 static enum bp_result bios_parser_program_crtc_timing(
1661 struct dc_bios *dcb,
1662 struct bp_hw_crtc_timing_parameters *bp_params)
1663 {
1664 struct bios_parser *bp = BP_FROM_DCB(dcb);
1665
1666 if (!bp->cmd_tbl.set_crtc_timing)
1667 return BP_RESULT_FAILURE;
1668
1669 return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1670 }
1671
1672 static enum bp_result bios_parser_enable_crtc(
1673 struct dc_bios *dcb,
1674 enum controller_id id,
1675 bool enable)
1676 {
1677 struct bios_parser *bp = BP_FROM_DCB(dcb);
1678
1679 if (!bp->cmd_tbl.enable_crtc)
1680 return BP_RESULT_FAILURE;
1681
1682 return bp->cmd_tbl.enable_crtc(bp, id, enable);
1683 }
1684
1685 static enum bp_result bios_parser_enable_disp_power_gating(
1686 struct dc_bios *dcb,
1687 enum controller_id controller_id,
1688 enum bp_pipe_control_action action)
1689 {
1690 struct bios_parser *bp = BP_FROM_DCB(dcb);
1691
1692 if (!bp->cmd_tbl.enable_disp_power_gating)
1693 return BP_RESULT_FAILURE;
1694
1695 return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1696 action);
1697 }
1698
1699 static enum bp_result bios_parser_enable_lvtma_control(
1700 struct dc_bios *dcb,
1701 uint8_t uc_pwr_on,
1702 uint8_t panel_instance)
1703 {
1704 struct bios_parser *bp = BP_FROM_DCB(dcb);
1705
1706 if (!bp->cmd_tbl.enable_lvtma_control)
1707 return BP_RESULT_FAILURE;
1708
1709 return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance);
1710 }
1711
1712 static bool bios_parser_is_accelerated_mode(
1713 struct dc_bios *dcb)
1714 {
1715 return bios_is_accelerated_mode(dcb);
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725 static void bios_parser_set_scratch_critical_state(
1726 struct dc_bios *dcb,
1727 bool state)
1728 {
1729 bios_set_scratch_critical_state(dcb, state);
1730 }
1731
1732 struct atom_dig_transmitter_info_header_v5_3 {
1733 struct atom_common_table_header table_header;
1734 uint16_t dpphy_hdmi_settings_offset;
1735 uint16_t dpphy_dvi_settings_offset;
1736 uint16_t dpphy_dp_setting_table_offset;
1737 uint16_t uniphy_xbar_settings_v2_table_offset;
1738 uint16_t dpphy_internal_reg_overide_offset;
1739 };
1740
1741 static enum bp_result bios_parser_get_firmware_info(
1742 struct dc_bios *dcb,
1743 struct dc_firmware_info *info)
1744 {
1745 struct bios_parser *bp = BP_FROM_DCB(dcb);
1746 static enum bp_result result = BP_RESULT_BADBIOSTABLE;
1747 struct atom_common_table_header *header;
1748
1749 struct atom_data_revision revision;
1750
1751 if (info && DATA_TABLES(firmwareinfo)) {
1752 header = GET_IMAGE(struct atom_common_table_header,
1753 DATA_TABLES(firmwareinfo));
1754 get_atom_data_table_revision(header, &revision);
1755 switch (revision.major) {
1756 case 3:
1757 switch (revision.minor) {
1758 case 1:
1759 result = get_firmware_info_v3_1(bp, info);
1760 break;
1761 case 2:
1762 case 3:
1763 result = get_firmware_info_v3_2(bp, info);
1764 break;
1765 case 4:
1766 result = get_firmware_info_v3_4(bp, info);
1767 break;
1768 default:
1769 break;
1770 }
1771 break;
1772 default:
1773 break;
1774 }
1775 }
1776
1777 return result;
1778 }
1779
1780 static enum bp_result get_firmware_info_v3_1(
1781 struct bios_parser *bp,
1782 struct dc_firmware_info *info)
1783 {
1784 struct atom_firmware_info_v3_1 *firmware_info;
1785 struct atom_display_controller_info_v4_1 *dce_info = NULL;
1786
1787 if (!info)
1788 return BP_RESULT_BADINPUT;
1789
1790 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1791 DATA_TABLES(firmwareinfo));
1792
1793 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1794 DATA_TABLES(dce_info));
1795
1796 if (!firmware_info || !dce_info)
1797 return BP_RESULT_BADBIOSTABLE;
1798
1799 memset(info, 0, sizeof(*info));
1800
1801
1802
1803 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1804 info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1805
1806
1807 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1808
1809
1810 if (info->pll_info.crystal_frequency == 0)
1811 info->pll_info.crystal_frequency = 27000;
1812
1813 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
1814 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1815
1816
1817
1818 if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1819
1820 info->smu_gpu_pll_output_freq =
1821 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1822 }
1823
1824 info->oem_i2c_present = false;
1825
1826 return BP_RESULT_OK;
1827 }
1828
1829 static enum bp_result get_firmware_info_v3_2(
1830 struct bios_parser *bp,
1831 struct dc_firmware_info *info)
1832 {
1833 struct atom_firmware_info_v3_2 *firmware_info;
1834 struct atom_display_controller_info_v4_1 *dce_info = NULL;
1835 struct atom_common_table_header *header;
1836 struct atom_data_revision revision;
1837 struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1838 struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1839
1840 if (!info)
1841 return BP_RESULT_BADINPUT;
1842
1843 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1844 DATA_TABLES(firmwareinfo));
1845
1846 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1847 DATA_TABLES(dce_info));
1848
1849 if (!firmware_info || !dce_info)
1850 return BP_RESULT_BADBIOSTABLE;
1851
1852 memset(info, 0, sizeof(*info));
1853
1854 header = GET_IMAGE(struct atom_common_table_header,
1855 DATA_TABLES(smu_info));
1856 get_atom_data_table_revision(header, &revision);
1857
1858 if (revision.minor == 2) {
1859
1860 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1861 DATA_TABLES(smu_info));
1862
1863 if (!smu_info_v3_2)
1864 return BP_RESULT_BADBIOSTABLE;
1865
1866 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1867 } else if (revision.minor == 3) {
1868
1869 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1870 DATA_TABLES(smu_info));
1871
1872 if (!smu_info_v3_3)
1873 return BP_RESULT_BADBIOSTABLE;
1874
1875 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1876 }
1877
1878
1879 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1880
1881
1882 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1883
1884 if (info->pll_info.crystal_frequency == 0) {
1885 if (revision.minor == 2)
1886 info->pll_info.crystal_frequency = 27000;
1887 else if (revision.minor == 3)
1888 info->pll_info.crystal_frequency = 100000;
1889 }
1890
1891 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
1892 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1893
1894
1895 if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1896 if (revision.minor == 2)
1897 info->smu_gpu_pll_output_freq =
1898 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1899 else if (revision.minor == 3)
1900 info->smu_gpu_pll_output_freq =
1901 bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1902 }
1903
1904 if (firmware_info->board_i2c_feature_id == 0x2) {
1905 info->oem_i2c_present = true;
1906 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
1907 } else {
1908 info->oem_i2c_present = false;
1909 }
1910
1911 return BP_RESULT_OK;
1912 }
1913
1914 static enum bp_result get_firmware_info_v3_4(
1915 struct bios_parser *bp,
1916 struct dc_firmware_info *info)
1917 {
1918 struct atom_firmware_info_v3_4 *firmware_info;
1919 struct atom_common_table_header *header;
1920 struct atom_data_revision revision;
1921 struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL;
1922 struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL;
1923
1924 struct atom_smu_info_v3_5 *smu_info_v3_5 = NULL;
1925 struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL;
1926 struct atom_smu_info_v4_0 *smu_info_v4_0 = NULL;
1927
1928 if (!info)
1929 return BP_RESULT_BADINPUT;
1930
1931 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4,
1932 DATA_TABLES(firmwareinfo));
1933
1934 if (!firmware_info)
1935 return BP_RESULT_BADBIOSTABLE;
1936
1937 memset(info, 0, sizeof(*info));
1938
1939 header = GET_IMAGE(struct atom_common_table_header,
1940 DATA_TABLES(dce_info));
1941
1942 get_atom_data_table_revision(header, &revision);
1943
1944 switch (revision.major) {
1945 case 4:
1946 switch (revision.minor) {
1947 case 5:
1948 dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
1949 DATA_TABLES(dce_info));
1950
1951 if (!dce_info_v4_5)
1952 return BP_RESULT_BADBIOSTABLE;
1953
1954
1955 info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10;
1956 info->dp_phy_ref_clk = dce_info_v4_5->dpphy_refclk_10khz * 10;
1957
1958 info->i2c_engine_ref_clk = dce_info_v4_5->i2c_engine_refclk_10khz * 10;
1959
1960
1961 break;
1962
1963 case 4:
1964 dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
1965 DATA_TABLES(dce_info));
1966
1967 if (!dce_info_v4_4)
1968 return BP_RESULT_BADBIOSTABLE;
1969
1970
1971 info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10;
1972 info->dp_phy_ref_clk = dce_info_v4_4->dpphy_refclk_10khz * 10;
1973
1974 info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10;
1975
1976
1977 info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10;
1978 break;
1979
1980 default:
1981
1982 dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1,
1983 DATA_TABLES(dce_info));
1984
1985 if (!dce_info_v4_1)
1986 return BP_RESULT_BADBIOSTABLE;
1987
1988 info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10;
1989 info->dp_phy_ref_clk = dce_info_v4_1->dpphy_refclk_10khz * 10;
1990 info->i2c_engine_ref_clk = dce_info_v4_1->i2c_engine_refclk_10khz * 10;
1991 break;
1992 }
1993 break;
1994
1995 default:
1996 ASSERT(0);
1997 break;
1998 }
1999
2000 header = GET_IMAGE(struct atom_common_table_header,
2001 DATA_TABLES(smu_info));
2002 get_atom_data_table_revision(header, &revision);
2003
2004 switch (revision.major) {
2005 case 3:
2006 switch (revision.minor) {
2007 case 5:
2008 smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5,
2009 DATA_TABLES(smu_info));
2010
2011 if (!smu_info_v3_5)
2012 return BP_RESULT_BADBIOSTABLE;
2013
2014 info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10;
2015 break;
2016
2017 default:
2018 break;
2019 }
2020 break;
2021
2022 case 4:
2023 switch (revision.minor) {
2024 case 0:
2025 smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0,
2026 DATA_TABLES(smu_info));
2027
2028 if (!smu_info_v4_0)
2029 return BP_RESULT_BADBIOSTABLE;
2030
2031
2032 break;
2033
2034 default:
2035 break;
2036 }
2037 break;
2038
2039 default:
2040 break;
2041 }
2042
2043
2044 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
2045
2046 if (firmware_info->board_i2c_feature_id == 0x2) {
2047 info->oem_i2c_present = true;
2048 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
2049 } else {
2050 info->oem_i2c_present = false;
2051 }
2052
2053 return BP_RESULT_OK;
2054 }
2055
2056 static enum bp_result bios_parser_get_encoder_cap_info(
2057 struct dc_bios *dcb,
2058 struct graphics_object_id object_id,
2059 struct bp_encoder_cap_info *info)
2060 {
2061 struct bios_parser *bp = BP_FROM_DCB(dcb);
2062 struct atom_display_object_path_v2 *object;
2063 struct atom_encoder_caps_record *record = NULL;
2064
2065 if (!info)
2066 return BP_RESULT_BADINPUT;
2067
2068 #if defined(CONFIG_DRM_AMD_DC_DCN)
2069
2070 if (bp->object_info_tbl.revision.minor == 5)
2071 return BP_RESULT_NORECORD;
2072 #endif
2073
2074 object = get_bios_object(bp, object_id);
2075
2076 if (!object)
2077 return BP_RESULT_BADINPUT;
2078
2079 record = get_encoder_cap_record(bp, object);
2080 if (!record)
2081 return BP_RESULT_NORECORD;
2082 DC_LOG_BIOS("record->encodercaps 0x%x for object_id 0x%x", record->encodercaps, object_id.id);
2083
2084 info->DP_HBR2_CAP = (record->encodercaps &
2085 ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
2086 info->DP_HBR2_EN = (record->encodercaps &
2087 ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
2088 info->DP_HBR3_EN = (record->encodercaps &
2089 ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
2090 info->HDMI_6GB_EN = (record->encodercaps &
2091 ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
2092 info->IS_DP2_CAPABLE = (record->encodercaps &
2093 ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0;
2094 info->DP_UHBR10_EN = (record->encodercaps &
2095 ATOM_ENCODER_CAP_RECORD_UHBR10_EN) ? 1 : 0;
2096 info->DP_UHBR13_5_EN = (record->encodercaps &
2097 ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0;
2098 info->DP_UHBR20_EN = (record->encodercaps &
2099 ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0;
2100 info->DP_IS_USB_C = (record->encodercaps &
2101 ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
2102 DC_LOG_BIOS("\t info->DP_IS_USB_C %d", info->DP_IS_USB_C);
2103
2104 return BP_RESULT_OK;
2105 }
2106
2107
2108 static struct atom_encoder_caps_record *get_encoder_cap_record(
2109 struct bios_parser *bp,
2110 struct atom_display_object_path_v2 *object)
2111 {
2112 struct atom_common_record_header *header;
2113 uint32_t offset;
2114
2115 if (!object) {
2116 BREAK_TO_DEBUGGER();
2117 return NULL;
2118 }
2119
2120 offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
2121
2122 for (;;) {
2123 header = GET_IMAGE(struct atom_common_record_header, offset);
2124
2125 if (!header)
2126 return NULL;
2127
2128 offset += header->record_size;
2129
2130 if (header->record_type == LAST_RECORD_TYPE ||
2131 !header->record_size)
2132 break;
2133
2134 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
2135 continue;
2136
2137 if (sizeof(struct atom_encoder_caps_record) <=
2138 header->record_size)
2139 return (struct atom_encoder_caps_record *)header;
2140 }
2141
2142 return NULL;
2143 }
2144
2145 static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
2146 struct bios_parser *bp,
2147 struct atom_display_object_path_v2 *object)
2148 {
2149 struct atom_common_record_header *header;
2150 uint32_t offset;
2151
2152 if (!object) {
2153 BREAK_TO_DEBUGGER();
2154 return NULL;
2155 }
2156
2157 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2158
2159 for (;;) {
2160 header = GET_IMAGE(struct atom_common_record_header, offset);
2161
2162 if (!header)
2163 return NULL;
2164
2165 offset += header->record_size;
2166
2167 if (header->record_type == LAST_RECORD_TYPE ||
2168 !header->record_size)
2169 break;
2170
2171 if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE)
2172 continue;
2173
2174 if (sizeof(struct atom_disp_connector_caps_record) <=
2175 header->record_size)
2176 return (struct atom_disp_connector_caps_record *)header;
2177 }
2178
2179 return NULL;
2180 }
2181
2182 static struct atom_connector_caps_record *get_connector_caps_record(
2183 struct bios_parser *bp,
2184 struct atom_display_object_path_v3 *object)
2185 {
2186 struct atom_common_record_header *header;
2187 uint32_t offset;
2188
2189 if (!object) {
2190 BREAK_TO_DEBUGGER();
2191 return NULL;
2192 }
2193
2194 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2195
2196 for (;;) {
2197 header = GET_IMAGE(struct atom_common_record_header, offset);
2198
2199 if (!header)
2200 return NULL;
2201
2202 offset += header->record_size;
2203
2204 if (header->record_type == ATOM_RECORD_END_TYPE ||
2205 !header->record_size)
2206 break;
2207
2208 if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE)
2209 continue;
2210
2211 if (sizeof(struct atom_connector_caps_record) <= header->record_size)
2212 return (struct atom_connector_caps_record *)header;
2213 }
2214
2215 return NULL;
2216 }
2217
2218 static enum bp_result bios_parser_get_disp_connector_caps_info(
2219 struct dc_bios *dcb,
2220 struct graphics_object_id object_id,
2221 struct bp_disp_connector_caps_info *info)
2222 {
2223 struct bios_parser *bp = BP_FROM_DCB(dcb);
2224 struct atom_display_object_path_v2 *object;
2225
2226 struct atom_display_object_path_v3 *object_path_v3;
2227 struct atom_connector_caps_record *record_path_v3;
2228
2229 struct atom_disp_connector_caps_record *record = NULL;
2230
2231 if (!info)
2232 return BP_RESULT_BADINPUT;
2233
2234 switch (bp->object_info_tbl.revision.minor) {
2235 case 4:
2236 default:
2237 object = get_bios_object(bp, object_id);
2238
2239 if (!object)
2240 return BP_RESULT_BADINPUT;
2241
2242 record = get_disp_connector_caps_record(bp, object);
2243 if (!record)
2244 return BP_RESULT_NORECORD;
2245
2246 info->INTERNAL_DISPLAY =
2247 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) ? 1 : 0;
2248 info->INTERNAL_DISPLAY_BL =
2249 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) ? 1 : 0;
2250 break;
2251 case 5:
2252 object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2253
2254 if (!object_path_v3)
2255 return BP_RESULT_BADINPUT;
2256
2257 record_path_v3 = get_connector_caps_record(bp, object_path_v3);
2258 if (!record_path_v3)
2259 return BP_RESULT_NORECORD;
2260
2261 info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
2262 ? 1 : 0;
2263 info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
2264 ? 1 : 0;
2265 break;
2266 }
2267
2268 return BP_RESULT_OK;
2269 }
2270
2271 static struct atom_connector_speed_record *get_connector_speed_cap_record(
2272 struct bios_parser *bp,
2273 struct atom_display_object_path_v3 *object)
2274 {
2275 struct atom_common_record_header *header;
2276 uint32_t offset;
2277
2278 if (!object) {
2279 BREAK_TO_DEBUGGER();
2280 return NULL;
2281 }
2282
2283 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2284
2285 for (;;) {
2286 header = GET_IMAGE(struct atom_common_record_header, offset);
2287
2288 if (!header)
2289 return NULL;
2290
2291 offset += header->record_size;
2292
2293 if (header->record_type == ATOM_RECORD_END_TYPE ||
2294 !header->record_size)
2295 break;
2296
2297 if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO)
2298 continue;
2299
2300 if (sizeof(struct atom_connector_speed_record) <= header->record_size)
2301 return (struct atom_connector_speed_record *)header;
2302 }
2303
2304 return NULL;
2305 }
2306
2307 static enum bp_result bios_parser_get_connector_speed_cap_info(
2308 struct dc_bios *dcb,
2309 struct graphics_object_id object_id,
2310 struct bp_connector_speed_cap_info *info)
2311 {
2312 struct bios_parser *bp = BP_FROM_DCB(dcb);
2313 struct atom_display_object_path_v3 *object_path_v3;
2314
2315 struct atom_connector_speed_record *record;
2316
2317 if (!info)
2318 return BP_RESULT_BADINPUT;
2319
2320 object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2321
2322 if (!object_path_v3)
2323 return BP_RESULT_BADINPUT;
2324
2325 record = get_connector_speed_cap_record(bp, object_path_v3);
2326 if (!record)
2327 return BP_RESULT_NORECORD;
2328
2329 info->DP_HBR2_EN = (record->connector_max_speed >= 5400) ? 1 : 0;
2330 info->DP_HBR3_EN = (record->connector_max_speed >= 8100) ? 1 : 0;
2331 info->HDMI_6GB_EN = (record->connector_max_speed >= 5940) ? 1 : 0;
2332 info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0;
2333 info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0;
2334 info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0;
2335 return BP_RESULT_OK;
2336 }
2337
2338 static enum bp_result get_vram_info_v23(
2339 struct bios_parser *bp,
2340 struct dc_vram_info *info)
2341 {
2342 struct atom_vram_info_header_v2_3 *info_v23;
2343 static enum bp_result result = BP_RESULT_OK;
2344
2345 info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
2346 DATA_TABLES(vram_info));
2347
2348 if (info_v23 == NULL)
2349 return BP_RESULT_BADBIOSTABLE;
2350
2351 info->num_chans = info_v23->vram_module[0].channel_num;
2352 info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8;
2353
2354 return result;
2355 }
2356
2357 static enum bp_result get_vram_info_v24(
2358 struct bios_parser *bp,
2359 struct dc_vram_info *info)
2360 {
2361 struct atom_vram_info_header_v2_4 *info_v24;
2362 static enum bp_result result = BP_RESULT_OK;
2363
2364 info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
2365 DATA_TABLES(vram_info));
2366
2367 if (info_v24 == NULL)
2368 return BP_RESULT_BADBIOSTABLE;
2369
2370 info->num_chans = info_v24->vram_module[0].channel_num;
2371 info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8;
2372
2373 return result;
2374 }
2375
2376 static enum bp_result get_vram_info_v25(
2377 struct bios_parser *bp,
2378 struct dc_vram_info *info)
2379 {
2380 struct atom_vram_info_header_v2_5 *info_v25;
2381 static enum bp_result result = BP_RESULT_OK;
2382
2383 info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
2384 DATA_TABLES(vram_info));
2385
2386 if (info_v25 == NULL)
2387 return BP_RESULT_BADBIOSTABLE;
2388
2389 info->num_chans = info_v25->vram_module[0].channel_num;
2390 info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8;
2391
2392 return result;
2393 }
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409 static enum bp_result get_integrated_info_v11(
2410 struct bios_parser *bp,
2411 struct integrated_info *info)
2412 {
2413 struct atom_integrated_system_info_v1_11 *info_v11;
2414 uint32_t i;
2415
2416 info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
2417 DATA_TABLES(integratedsysteminfo));
2418
2419 if (info_v11 == NULL)
2420 return BP_RESULT_BADBIOSTABLE;
2421
2422 info->gpu_cap_info =
2423 le32_to_cpu(info_v11->gpucapinfo);
2424
2425
2426
2427
2428
2429
2430
2431
2432 info->system_config = le32_to_cpu(info_v11->system_config);
2433 info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
2434 info->memory_type = info_v11->memorytype;
2435 info->ma_channel_number = info_v11->umachannelnumber;
2436 info->lvds_ss_percentage =
2437 le16_to_cpu(info_v11->lvds_ss_percentage);
2438 info->dp_ss_control =
2439 le16_to_cpu(info_v11->reserved1);
2440 info->lvds_sspread_rate_in_10hz =
2441 le16_to_cpu(info_v11->lvds_ss_rate_10hz);
2442 info->hdmi_ss_percentage =
2443 le16_to_cpu(info_v11->hdmi_ss_percentage);
2444 info->hdmi_sspread_rate_in_10hz =
2445 le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
2446 info->dvi_ss_percentage =
2447 le16_to_cpu(info_v11->dvi_ss_percentage);
2448 info->dvi_sspread_rate_in_10_hz =
2449 le16_to_cpu(info_v11->dvi_ss_rate_10hz);
2450 info->lvds_misc = info_v11->lvds_misc;
2451 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2452 info->ext_disp_conn_info.gu_id[i] =
2453 info_v11->extdispconninfo.guid[i];
2454 }
2455
2456 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2457 info->ext_disp_conn_info.path[i].device_connector_id =
2458 object_id_from_bios_object_id(
2459 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
2460
2461 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2462 object_id_from_bios_object_id(
2463 le16_to_cpu(
2464 info_v11->extdispconninfo.path[i].ext_encoder_objid));
2465
2466 info->ext_disp_conn_info.path[i].device_tag =
2467 le16_to_cpu(
2468 info_v11->extdispconninfo.path[i].device_tag);
2469 info->ext_disp_conn_info.path[i].device_acpi_enum =
2470 le16_to_cpu(
2471 info_v11->extdispconninfo.path[i].device_acpi_enum);
2472 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2473 info_v11->extdispconninfo.path[i].auxddclut_index;
2474 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2475 info_v11->extdispconninfo.path[i].hpdlut_index;
2476 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2477 info_v11->extdispconninfo.path[i].channelmapping;
2478 info->ext_disp_conn_info.path[i].caps =
2479 le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
2480 }
2481 info->ext_disp_conn_info.checksum =
2482 info_v11->extdispconninfo.checksum;
2483
2484 info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
2485 info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
2486 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
2487 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
2488 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2489 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
2490 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2491 }
2492 info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
2493 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
2494 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2495 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2496 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2497 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2498 }
2499
2500 info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
2501 info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
2502 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
2503 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
2504 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2505 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
2506 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2507 }
2508 info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
2509 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
2510 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2511 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2512 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2513 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2514 }
2515
2516 info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
2517 info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
2518 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
2519 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
2520 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2521 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
2522 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2523 }
2524 info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
2525 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
2526 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2527 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2528 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2529 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2530 }
2531
2532 info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
2533 info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
2534 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
2535 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
2536 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2537 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
2538 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2539 }
2540 info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
2541 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
2542 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2543 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2544 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2545 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2546 }
2547
2548
2549
2550 #if 0
2551 info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
2552 * 10;
2553 info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
2554 info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
2555
2556 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
2557
2558 info->disp_clk_voltage[i].max_supported_clk =
2559 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
2560 ulMaximumSupportedCLK) * 10;
2561 info->disp_clk_voltage[i].voltage_index =
2562 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
2563 }
2564
2565 info->boot_up_req_display_vector =
2566 le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
2567 info->boot_up_nb_voltage =
2568 le16_to_cpu(info_v11->usBootUpNBVoltage);
2569 info->ext_disp_conn_info_offset =
2570 le16_to_cpu(info_v11->usExtDispConnInfoOffset);
2571 info->gmc_restore_reset_time =
2572 le32_to_cpu(info_v11->ulGMCRestoreResetTime);
2573 info->minimum_n_clk =
2574 le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
2575 for (i = 1; i < 4; ++i)
2576 info->minimum_n_clk =
2577 info->minimum_n_clk <
2578 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
2579 info->minimum_n_clk : le32_to_cpu(
2580 info_v11->ulNbpStateNClkFreq[i]);
2581
2582 info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
2583 info->ddr_dll_power_up_time =
2584 le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
2585 info->ddr_pll_power_up_time =
2586 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
2587 info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
2588 info->max_lvds_pclk_freq_in_single_link =
2589 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
2590 info->max_lvds_pclk_freq_in_single_link =
2591 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
2592 info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
2593 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
2594 info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
2595 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
2596 info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
2597 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
2598 info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
2599 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
2600 info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
2601 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
2602 info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
2603 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
2604 info->lvds_off_to_on_delay_in_4ms =
2605 info_v11->ucLVDSOffToOnDelay_in4Ms;
2606 info->lvds_bit_depth_control_val =
2607 le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
2608
2609 for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
2610
2611 info->avail_s_clk[i].supported_s_clk =
2612 le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
2613 * 10;
2614 info->avail_s_clk[i].voltage_index =
2615 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
2616 info->avail_s_clk[i].voltage_id =
2617 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
2618 }
2619 #endif
2620
2621 return BP_RESULT_OK;
2622 }
2623
2624 static enum bp_result get_integrated_info_v2_1(
2625 struct bios_parser *bp,
2626 struct integrated_info *info)
2627 {
2628 struct atom_integrated_system_info_v2_1 *info_v2_1;
2629 uint32_t i;
2630
2631 info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1,
2632 DATA_TABLES(integratedsysteminfo));
2633
2634 if (info_v2_1 == NULL)
2635 return BP_RESULT_BADBIOSTABLE;
2636
2637 info->gpu_cap_info =
2638 le32_to_cpu(info_v2_1->gpucapinfo);
2639
2640
2641
2642
2643
2644
2645
2646
2647 info->system_config = le32_to_cpu(info_v2_1->system_config);
2648 info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo);
2649 info->memory_type = info_v2_1->memorytype;
2650 info->ma_channel_number = info_v2_1->umachannelnumber;
2651 info->dp_ss_control =
2652 le16_to_cpu(info_v2_1->reserved1);
2653
2654 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2655 info->ext_disp_conn_info.gu_id[i] =
2656 info_v2_1->extdispconninfo.guid[i];
2657 }
2658
2659 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2660 info->ext_disp_conn_info.path[i].device_connector_id =
2661 object_id_from_bios_object_id(
2662 le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid));
2663
2664 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2665 object_id_from_bios_object_id(
2666 le16_to_cpu(
2667 info_v2_1->extdispconninfo.path[i].ext_encoder_objid));
2668
2669 info->ext_disp_conn_info.path[i].device_tag =
2670 le16_to_cpu(
2671 info_v2_1->extdispconninfo.path[i].device_tag);
2672 info->ext_disp_conn_info.path[i].device_acpi_enum =
2673 le16_to_cpu(
2674 info_v2_1->extdispconninfo.path[i].device_acpi_enum);
2675 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2676 info_v2_1->extdispconninfo.path[i].auxddclut_index;
2677 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2678 info_v2_1->extdispconninfo.path[i].hpdlut_index;
2679 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2680 info_v2_1->extdispconninfo.path[i].channelmapping;
2681 info->ext_disp_conn_info.path[i].caps =
2682 le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps);
2683 }
2684
2685 info->ext_disp_conn_info.checksum =
2686 info_v2_1->extdispconninfo.checksum;
2687 info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr;
2688 info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum;
2689 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
2690 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
2691 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2692 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
2693 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2694 }
2695 info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum;
2696 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
2697 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2698 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2699 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2700 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2701 }
2702 info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr;
2703 info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum;
2704 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
2705 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
2706 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2707 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
2708 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2709 }
2710 info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum;
2711 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
2712 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2713 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2714 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2715 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2716 }
2717 info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr;
2718 info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum;
2719 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
2720 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
2721 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2722 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
2723 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2724 }
2725 info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum;
2726 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
2727 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2728 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2729 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2730 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2731 }
2732 info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr;
2733 info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum;
2734 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
2735 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
2736 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2737 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
2738 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2739 }
2740 info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum;
2741 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
2742 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2743 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2744 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2745 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2746 }
2747
2748 info->edp1_info.edp_backlight_pwm_hz =
2749 le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz);
2750 info->edp1_info.edp_ss_percentage =
2751 le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage);
2752 info->edp1_info.edp_ss_rate_10hz =
2753 le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz);
2754 info->edp1_info.edp_pwr_on_off_delay =
2755 info_v2_1->edp1_info.edp_pwr_on_off_delay;
2756 info->edp1_info.edp_pwr_on_vary_bl_to_blon =
2757 info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon;
2758 info->edp1_info.edp_pwr_down_bloff_to_vary_bloff =
2759 info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
2760 info->edp1_info.edp_panel_bpc =
2761 info_v2_1->edp1_info.edp_panel_bpc;
2762 info->edp1_info.edp_bootup_bl_level = info_v2_1->edp1_info.edp_bootup_bl_level;
2763
2764 info->edp2_info.edp_backlight_pwm_hz =
2765 le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz);
2766 info->edp2_info.edp_ss_percentage =
2767 le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage);
2768 info->edp2_info.edp_ss_rate_10hz =
2769 le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz);
2770 info->edp2_info.edp_pwr_on_off_delay =
2771 info_v2_1->edp2_info.edp_pwr_on_off_delay;
2772 info->edp2_info.edp_pwr_on_vary_bl_to_blon =
2773 info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon;
2774 info->edp2_info.edp_pwr_down_bloff_to_vary_bloff =
2775 info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff;
2776 info->edp2_info.edp_panel_bpc =
2777 info_v2_1->edp2_info.edp_panel_bpc;
2778 info->edp2_info.edp_bootup_bl_level =
2779 info_v2_1->edp2_info.edp_bootup_bl_level;
2780
2781 return BP_RESULT_OK;
2782 }
2783
2784 static enum bp_result get_integrated_info_v2_2(
2785 struct bios_parser *bp,
2786 struct integrated_info *info)
2787 {
2788 struct atom_integrated_system_info_v2_2 *info_v2_2;
2789 uint32_t i;
2790
2791 info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2,
2792 DATA_TABLES(integratedsysteminfo));
2793
2794 if (info_v2_2 == NULL)
2795 return BP_RESULT_BADBIOSTABLE;
2796
2797 info->gpu_cap_info =
2798 le32_to_cpu(info_v2_2->gpucapinfo);
2799
2800
2801
2802
2803
2804
2805
2806
2807 info->system_config = le32_to_cpu(info_v2_2->system_config);
2808 info->cpu_cap_info = le32_to_cpu(info_v2_2->cpucapinfo);
2809 info->memory_type = info_v2_2->memorytype;
2810 info->ma_channel_number = info_v2_2->umachannelnumber;
2811 info->dp_ss_control =
2812 le16_to_cpu(info_v2_2->reserved1);
2813
2814 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2815 info->ext_disp_conn_info.gu_id[i] =
2816 info_v2_2->extdispconninfo.guid[i];
2817 }
2818
2819 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2820 info->ext_disp_conn_info.path[i].device_connector_id =
2821 object_id_from_bios_object_id(
2822 le16_to_cpu(info_v2_2->extdispconninfo.path[i].connectorobjid));
2823
2824 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2825 object_id_from_bios_object_id(
2826 le16_to_cpu(
2827 info_v2_2->extdispconninfo.path[i].ext_encoder_objid));
2828
2829 info->ext_disp_conn_info.path[i].device_tag =
2830 le16_to_cpu(
2831 info_v2_2->extdispconninfo.path[i].device_tag);
2832 info->ext_disp_conn_info.path[i].device_acpi_enum =
2833 le16_to_cpu(
2834 info_v2_2->extdispconninfo.path[i].device_acpi_enum);
2835 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2836 info_v2_2->extdispconninfo.path[i].auxddclut_index;
2837 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2838 info_v2_2->extdispconninfo.path[i].hpdlut_index;
2839 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2840 info_v2_2->extdispconninfo.path[i].channelmapping;
2841 info->ext_disp_conn_info.path[i].caps =
2842 le16_to_cpu(info_v2_2->extdispconninfo.path[i].caps);
2843 }
2844
2845 info->ext_disp_conn_info.checksum =
2846 info_v2_2->extdispconninfo.checksum;
2847 info->ext_disp_conn_info.fixdpvoltageswing =
2848 info_v2_2->extdispconninfo.fixdpvoltageswing;
2849
2850 info->edp1_info.edp_backlight_pwm_hz =
2851 le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz);
2852 info->edp1_info.edp_ss_percentage =
2853 le16_to_cpu(info_v2_2->edp1_info.edp_ss_percentage);
2854 info->edp1_info.edp_ss_rate_10hz =
2855 le16_to_cpu(info_v2_2->edp1_info.edp_ss_rate_10hz);
2856 info->edp1_info.edp_pwr_on_off_delay =
2857 info_v2_2->edp1_info.edp_pwr_on_off_delay;
2858 info->edp1_info.edp_pwr_on_vary_bl_to_blon =
2859 info_v2_2->edp1_info.edp_pwr_on_vary_bl_to_blon;
2860 info->edp1_info.edp_pwr_down_bloff_to_vary_bloff =
2861 info_v2_2->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
2862 info->edp1_info.edp_panel_bpc =
2863 info_v2_2->edp1_info.edp_panel_bpc;
2864 info->edp1_info.edp_bootup_bl_level =
2865
2866 info->edp2_info.edp_backlight_pwm_hz =
2867 le16_to_cpu(info_v2_2->edp2_info.edp_backlight_pwm_hz);
2868 info->edp2_info.edp_ss_percentage =
2869 le16_to_cpu(info_v2_2->edp2_info.edp_ss_percentage);
2870 info->edp2_info.edp_ss_rate_10hz =
2871 le16_to_cpu(info_v2_2->edp2_info.edp_ss_rate_10hz);
2872 info->edp2_info.edp_pwr_on_off_delay =
2873 info_v2_2->edp2_info.edp_pwr_on_off_delay;
2874 info->edp2_info.edp_pwr_on_vary_bl_to_blon =
2875 info_v2_2->edp2_info.edp_pwr_on_vary_bl_to_blon;
2876 info->edp2_info.edp_pwr_down_bloff_to_vary_bloff =
2877 info_v2_2->edp2_info.edp_pwr_down_bloff_to_vary_bloff;
2878 info->edp2_info.edp_panel_bpc =
2879 info_v2_2->edp2_info.edp_panel_bpc;
2880 info->edp2_info.edp_bootup_bl_level =
2881 info_v2_2->edp2_info.edp_bootup_bl_level;
2882
2883 return BP_RESULT_OK;
2884 }
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900 static enum bp_result construct_integrated_info(
2901 struct bios_parser *bp,
2902 struct integrated_info *info)
2903 {
2904 static enum bp_result result = BP_RESULT_BADBIOSTABLE;
2905
2906 struct atom_common_table_header *header;
2907 struct atom_data_revision revision;
2908
2909 struct clock_voltage_caps temp = {0, 0};
2910 uint32_t i;
2911 uint32_t j;
2912
2913 if (info && DATA_TABLES(integratedsysteminfo)) {
2914 header = GET_IMAGE(struct atom_common_table_header,
2915 DATA_TABLES(integratedsysteminfo));
2916
2917 get_atom_data_table_revision(header, &revision);
2918
2919 switch (revision.major) {
2920 case 1:
2921 switch (revision.minor) {
2922 case 11:
2923 case 12:
2924 result = get_integrated_info_v11(bp, info);
2925 break;
2926 default:
2927 return result;
2928 }
2929 break;
2930 case 2:
2931 switch (revision.minor) {
2932 case 1:
2933 result = get_integrated_info_v2_1(bp, info);
2934 break;
2935 case 2:
2936 result = get_integrated_info_v2_2(bp, info);
2937 break;
2938 default:
2939 return result;
2940 }
2941 break;
2942 default:
2943 return result;
2944 }
2945 }
2946
2947 if (result != BP_RESULT_OK)
2948 return result;
2949 else {
2950
2951 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
2952 if (info->ext_disp_conn_info.path[i].device_tag != 0)
2953 DC_LOG_BIOS("integrated_info:For EXTERNAL DISPLAY PATH %d --------------\n"
2954 "DEVICE_TAG: 0x%x\n"
2955 "DEVICE_ACPI_ENUM: 0x%x\n"
2956 "DEVICE_CONNECTOR_ID: 0x%x\n"
2957 "EXT_AUX_DDC_LUT_INDEX: %d\n"
2958 "EXT_HPD_PIN_LUT_INDEX: %d\n"
2959 "EXT_ENCODER_OBJ_ID: 0x%x\n"
2960 "Encoder CAPS: 0x%x\n",
2961 i,
2962 info->ext_disp_conn_info.path[i].device_tag,
2963 info->ext_disp_conn_info.path[i].device_acpi_enum,
2964 info->ext_disp_conn_info.path[i].device_connector_id.id,
2965 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index,
2966 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index,
2967 info->ext_disp_conn_info.path[i].ext_encoder_obj_id.id,
2968 info->ext_disp_conn_info.path[i].caps
2969 );
2970 }
2971
2972
2973 DC_LOG_BIOS("Integrated info table CHECKSUM: %d\n"
2974 "Integrated info table FIX_DP_VOLTAGE_SWING: %d\n",
2975 info->ext_disp_conn_info.checksum,
2976 info->ext_disp_conn_info.fixdpvoltageswing);
2977 }
2978
2979 for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
2980 for (j = i; j > 0; --j) {
2981 if (info->disp_clk_voltage[j].max_supported_clk <
2982 info->disp_clk_voltage[j-1].max_supported_clk
2983 ) {
2984
2985 temp = info->disp_clk_voltage[j-1];
2986 info->disp_clk_voltage[j-1] =
2987 info->disp_clk_voltage[j];
2988 info->disp_clk_voltage[j] = temp;
2989 }
2990 }
2991 }
2992
2993 return result;
2994 }
2995
2996 static enum bp_result bios_parser_get_vram_info(
2997 struct dc_bios *dcb,
2998 struct dc_vram_info *info)
2999 {
3000 struct bios_parser *bp = BP_FROM_DCB(dcb);
3001 static enum bp_result result = BP_RESULT_BADBIOSTABLE;
3002 struct atom_common_table_header *header;
3003 struct atom_data_revision revision;
3004
3005 if (info && DATA_TABLES(vram_info)) {
3006 header = GET_IMAGE(struct atom_common_table_header,
3007 DATA_TABLES(vram_info));
3008
3009 get_atom_data_table_revision(header, &revision);
3010
3011 switch (revision.major) {
3012 case 2:
3013 switch (revision.minor) {
3014 case 3:
3015 result = get_vram_info_v23(bp, info);
3016 break;
3017 case 4:
3018 result = get_vram_info_v24(bp, info);
3019 break;
3020 case 5:
3021 result = get_vram_info_v25(bp, info);
3022 break;
3023 default:
3024 break;
3025 }
3026 break;
3027
3028 default:
3029 return result;
3030 }
3031
3032 }
3033 return result;
3034 }
3035
3036 static struct integrated_info *bios_parser_create_integrated_info(
3037 struct dc_bios *dcb)
3038 {
3039 struct bios_parser *bp = BP_FROM_DCB(dcb);
3040 struct integrated_info *info = NULL;
3041
3042 info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
3043
3044 if (info == NULL) {
3045 ASSERT_CRITICAL(0);
3046 return NULL;
3047 }
3048
3049 if (construct_integrated_info(bp, info) == BP_RESULT_OK)
3050 return info;
3051
3052 kfree(info);
3053
3054 return NULL;
3055 }
3056
3057 static enum bp_result update_slot_layout_info(
3058 struct dc_bios *dcb,
3059 unsigned int i,
3060 struct slot_layout_info *slot_layout_info)
3061 {
3062 unsigned int record_offset;
3063 unsigned int j;
3064 struct atom_display_object_path_v2 *object;
3065 struct atom_bracket_layout_record *record;
3066 struct atom_common_record_header *record_header;
3067 static enum bp_result result;
3068 struct bios_parser *bp;
3069 struct object_info_table *tbl;
3070 struct display_object_info_table_v1_4 *v1_4;
3071
3072 record = NULL;
3073 record_header = NULL;
3074 result = BP_RESULT_NORECORD;
3075
3076 bp = BP_FROM_DCB(dcb);
3077 tbl = &bp->object_info_tbl;
3078 v1_4 = tbl->v1_4;
3079
3080 object = &v1_4->display_path[i];
3081 record_offset = (unsigned int)
3082 (object->disp_recordoffset) +
3083 (unsigned int)(bp->object_info_tbl_offset);
3084
3085 for (;;) {
3086
3087 record_header = (struct atom_common_record_header *)
3088 GET_IMAGE(struct atom_common_record_header,
3089 record_offset);
3090 if (record_header == NULL) {
3091 result = BP_RESULT_BADBIOSTABLE;
3092 break;
3093 }
3094
3095
3096 if (record_header->record_type == 0xff ||
3097 record_header->record_size == 0) {
3098 break;
3099 }
3100
3101 if (record_header->record_type ==
3102 ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
3103 sizeof(struct atom_bracket_layout_record)
3104 <= record_header->record_size) {
3105 record = (struct atom_bracket_layout_record *)
3106 (record_header);
3107 result = BP_RESULT_OK;
3108 break;
3109 }
3110
3111 record_offset += record_header->record_size;
3112 }
3113
3114
3115 if (result != BP_RESULT_OK)
3116 return result;
3117
3118
3119 slot_layout_info->length = record->bracketlen;
3120 slot_layout_info->width = record->bracketwidth;
3121
3122
3123 slot_layout_info->num_of_connectors = record->conn_num;
3124 for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
3125 slot_layout_info->connectors[j].connector_type =
3126 (enum connector_layout_type)
3127 (record->conn_info[j].connector_type);
3128 switch (record->conn_info[j].connector_type) {
3129 case CONNECTOR_TYPE_DVI_D:
3130 slot_layout_info->connectors[j].connector_type =
3131 CONNECTOR_LAYOUT_TYPE_DVI_D;
3132 slot_layout_info->connectors[j].length =
3133 CONNECTOR_SIZE_DVI;
3134 break;
3135
3136 case CONNECTOR_TYPE_HDMI:
3137 slot_layout_info->connectors[j].connector_type =
3138 CONNECTOR_LAYOUT_TYPE_HDMI;
3139 slot_layout_info->connectors[j].length =
3140 CONNECTOR_SIZE_HDMI;
3141 break;
3142
3143 case CONNECTOR_TYPE_DISPLAY_PORT:
3144 slot_layout_info->connectors[j].connector_type =
3145 CONNECTOR_LAYOUT_TYPE_DP;
3146 slot_layout_info->connectors[j].length =
3147 CONNECTOR_SIZE_DP;
3148 break;
3149
3150 case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
3151 slot_layout_info->connectors[j].connector_type =
3152 CONNECTOR_LAYOUT_TYPE_MINI_DP;
3153 slot_layout_info->connectors[j].length =
3154 CONNECTOR_SIZE_MINI_DP;
3155 break;
3156
3157 default:
3158 slot_layout_info->connectors[j].connector_type =
3159 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3160 slot_layout_info->connectors[j].length =
3161 CONNECTOR_SIZE_UNKNOWN;
3162 }
3163
3164 slot_layout_info->connectors[j].position =
3165 record->conn_info[j].position;
3166 slot_layout_info->connectors[j].connector_id =
3167 object_id_from_bios_object_id(
3168 record->conn_info[j].connectorobjid);
3169 }
3170 return result;
3171 }
3172
3173 static enum bp_result update_slot_layout_info_v2(
3174 struct dc_bios *dcb,
3175 unsigned int i,
3176 struct slot_layout_info *slot_layout_info)
3177 {
3178 unsigned int record_offset;
3179 struct atom_display_object_path_v3 *object;
3180 struct atom_bracket_layout_record_v2 *record;
3181 struct atom_common_record_header *record_header;
3182 static enum bp_result result;
3183 struct bios_parser *bp;
3184 struct object_info_table *tbl;
3185 struct display_object_info_table_v1_5 *v1_5;
3186 struct graphics_object_id connector_id;
3187
3188 record = NULL;
3189 record_header = NULL;
3190 result = BP_RESULT_NORECORD;
3191
3192 bp = BP_FROM_DCB(dcb);
3193 tbl = &bp->object_info_tbl;
3194 v1_5 = tbl->v1_5;
3195
3196 object = &v1_5->display_path[i];
3197 record_offset = (unsigned int)
3198 (object->disp_recordoffset) +
3199 (unsigned int)(bp->object_info_tbl_offset);
3200
3201 for (;;) {
3202
3203 record_header = (struct atom_common_record_header *)
3204 GET_IMAGE(struct atom_common_record_header,
3205 record_offset);
3206 if (record_header == NULL) {
3207 result = BP_RESULT_BADBIOSTABLE;
3208 break;
3209 }
3210
3211
3212 if (record_header->record_type == ATOM_RECORD_END_TYPE ||
3213 record_header->record_size == 0) {
3214 break;
3215 }
3216
3217 if (record_header->record_type ==
3218 ATOM_BRACKET_LAYOUT_V2_RECORD_TYPE &&
3219 sizeof(struct atom_bracket_layout_record_v2)
3220 <= record_header->record_size) {
3221 record = (struct atom_bracket_layout_record_v2 *)
3222 (record_header);
3223 result = BP_RESULT_OK;
3224 break;
3225 }
3226
3227 record_offset += record_header->record_size;
3228 }
3229
3230
3231 if (result != BP_RESULT_OK)
3232 return result;
3233
3234
3235 connector_id = object_id_from_bios_object_id(object->display_objid);
3236
3237 slot_layout_info->length = record->bracketlen;
3238 slot_layout_info->width = record->bracketwidth;
3239 slot_layout_info->num_of_connectors = v1_5->number_of_path;
3240 slot_layout_info->connectors[i].position = record->conn_num;
3241 slot_layout_info->connectors[i].connector_id = connector_id;
3242
3243 switch (connector_id.id) {
3244 case CONNECTOR_ID_SINGLE_LINK_DVID:
3245 case CONNECTOR_ID_DUAL_LINK_DVID:
3246 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DVI_D;
3247 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DVI;
3248 break;
3249
3250 case CONNECTOR_ID_HDMI_TYPE_A:
3251 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_HDMI;
3252 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_HDMI;
3253 break;
3254
3255 case CONNECTOR_ID_DISPLAY_PORT:
3256 case CONNECTOR_ID_USBC:
3257 if (record->mini_type == MINI_TYPE_NORMAL) {
3258 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DP;
3259 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DP;
3260 } else {
3261 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP;
3262 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP;
3263 }
3264 break;
3265
3266 default:
3267 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3268 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN;
3269 }
3270 return result;
3271 }
3272
3273 static enum bp_result get_bracket_layout_record(
3274 struct dc_bios *dcb,
3275 unsigned int bracket_layout_id,
3276 struct slot_layout_info *slot_layout_info)
3277 {
3278 unsigned int i;
3279 struct bios_parser *bp = BP_FROM_DCB(dcb);
3280 static enum bp_result result;
3281 struct object_info_table *tbl;
3282 struct display_object_info_table_v1_4 *v1_4;
3283 struct display_object_info_table_v1_5 *v1_5;
3284
3285 if (slot_layout_info == NULL) {
3286 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
3287 return BP_RESULT_BADINPUT;
3288 }
3289 tbl = &bp->object_info_tbl;
3290 v1_4 = tbl->v1_4;
3291 v1_5 = tbl->v1_5;
3292
3293 result = BP_RESULT_NORECORD;
3294 switch (bp->object_info_tbl.revision.minor) {
3295 case 4:
3296 default:
3297 for (i = 0; i < v1_4->number_of_path; ++i) {
3298 if (bracket_layout_id ==
3299 v1_4->display_path[i].display_objid) {
3300 result = update_slot_layout_info(dcb, i, slot_layout_info);
3301 break;
3302 }
3303 }
3304 break;
3305 case 5:
3306 for (i = 0; i < v1_5->number_of_path; ++i)
3307 result = update_slot_layout_info_v2(dcb, i, slot_layout_info);
3308 break;
3309 }
3310 return result;
3311 }
3312
3313 static enum bp_result bios_get_board_layout_info(
3314 struct dc_bios *dcb,
3315 struct board_layout_info *board_layout_info)
3316 {
3317 unsigned int i;
3318
3319 struct bios_parser *bp;
3320
3321 static enum bp_result record_result;
3322
3323 const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
3324 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
3325 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
3326 0, 0
3327 };
3328
3329
3330 bp = BP_FROM_DCB(dcb);
3331
3332 if (board_layout_info == NULL) {
3333 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
3334 return BP_RESULT_BADINPUT;
3335 }
3336
3337 board_layout_info->num_of_slots = 0;
3338
3339 for (i = 0; i < MAX_BOARD_SLOTS; ++i) {
3340 record_result = get_bracket_layout_record(dcb,
3341 slot_index_to_vbios_id[i],
3342 &board_layout_info->slots[i]);
3343
3344 if (record_result == BP_RESULT_NORECORD && i > 0)
3345 break;
3346 else if (record_result != BP_RESULT_OK)
3347 return record_result;
3348
3349 ++board_layout_info->num_of_slots;
3350 }
3351
3352
3353 board_layout_info->is_number_of_slots_valid = 1;
3354 board_layout_info->is_slots_size_valid = 1;
3355 board_layout_info->is_connector_offsets_valid = 1;
3356 board_layout_info->is_connector_lengths_valid = 1;
3357
3358 return BP_RESULT_OK;
3359 }
3360
3361
3362 static uint16_t bios_parser_pack_data_tables(
3363 struct dc_bios *dcb,
3364 void *dst)
3365 {
3366
3367 return 0;
3368 }
3369
3370 static struct atom_dc_golden_table_v1 *bios_get_golden_table(
3371 struct bios_parser *bp,
3372 uint32_t rev_major,
3373 uint32_t rev_minor,
3374 uint16_t *dc_golden_table_ver)
3375 {
3376 struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL;
3377 uint32_t dc_golden_offset = 0;
3378 *dc_golden_table_ver = 0;
3379
3380 if (!DATA_TABLES(dce_info))
3381 return NULL;
3382
3383
3384 switch (rev_major) {
3385 case 4:
3386 switch (rev_minor) {
3387 case 4:
3388 disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
3389 DATA_TABLES(dce_info));
3390 if (!disp_cntl_tbl_4_4)
3391 return NULL;
3392 dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset;
3393 *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
3394 break;
3395 case 5:
3396 default:
3397
3398
3399
3400
3401 break;
3402 }
3403 break;
3404 }
3405
3406 if (!dc_golden_offset)
3407 return NULL;
3408
3409 if (*dc_golden_table_ver != 1)
3410 return NULL;
3411
3412 return GET_IMAGE(struct atom_dc_golden_table_v1,
3413 dc_golden_offset);
3414 }
3415
3416 static enum bp_result bios_get_atom_dc_golden_table(
3417 struct dc_bios *dcb)
3418 {
3419 struct bios_parser *bp = BP_FROM_DCB(dcb);
3420 enum bp_result result = BP_RESULT_OK;
3421 struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL;
3422 struct atom_common_table_header *header;
3423 struct atom_data_revision tbl_revision;
3424 uint16_t dc_golden_table_ver = 0;
3425
3426 header = GET_IMAGE(struct atom_common_table_header,
3427 DATA_TABLES(dce_info));
3428 if (!header)
3429 return BP_RESULT_UNSUPPORTED;
3430
3431 get_atom_data_table_revision(header, &tbl_revision);
3432
3433 atom_dc_golden_table = bios_get_golden_table(bp,
3434 tbl_revision.major,
3435 tbl_revision.minor,
3436 &dc_golden_table_ver);
3437
3438 if (!atom_dc_golden_table)
3439 return BP_RESULT_UNSUPPORTED;
3440
3441 dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver;
3442 dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val;
3443 dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val;
3444 dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val;
3445 dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val;
3446 dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val;
3447 dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val;
3448 dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val;
3449 dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val;
3450 dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val;
3451
3452 return result;
3453 }
3454
3455
3456 static const struct dc_vbios_funcs vbios_funcs = {
3457 .get_connectors_number = bios_parser_get_connectors_number,
3458
3459 .get_connector_id = bios_parser_get_connector_id,
3460
3461 .get_src_obj = bios_parser_get_src_obj,
3462
3463 .get_i2c_info = bios_parser_get_i2c_info,
3464
3465 .get_hpd_info = bios_parser_get_hpd_info,
3466
3467 .get_device_tag = bios_parser_get_device_tag,
3468
3469 .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
3470
3471 .get_ss_entry_number = bios_parser_get_ss_entry_number,
3472
3473 .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
3474
3475 .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
3476
3477 .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
3478
3479 .is_device_id_supported = bios_parser_is_device_id_supported,
3480
3481 .is_accelerated_mode = bios_parser_is_accelerated_mode,
3482
3483 .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
3484
3485
3486
3487 .encoder_control = bios_parser_encoder_control,
3488
3489 .transmitter_control = bios_parser_transmitter_control,
3490
3491 .enable_crtc = bios_parser_enable_crtc,
3492
3493 .set_pixel_clock = bios_parser_set_pixel_clock,
3494
3495 .set_dce_clock = bios_parser_set_dce_clock,
3496
3497 .program_crtc_timing = bios_parser_program_crtc_timing,
3498
3499 .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
3500
3501 .bios_parser_destroy = firmware_parser_destroy,
3502
3503 .get_board_layout_info = bios_get_board_layout_info,
3504
3505 .pack_data_tables = bios_parser_pack_data_tables,
3506
3507 .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
3508
3509 .enable_lvtma_control = bios_parser_enable_lvtma_control,
3510
3511 .get_soc_bb_info = bios_parser_get_soc_bb_info,
3512
3513 .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info,
3514
3515 .get_lttpr_caps = bios_parser_get_lttpr_caps,
3516
3517 .get_lttpr_interop = bios_parser_get_lttpr_interop,
3518
3519 .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info,
3520 };
3521
3522 static bool bios_parser2_construct(
3523 struct bios_parser *bp,
3524 struct bp_init_data *init,
3525 enum dce_version dce_version)
3526 {
3527 uint16_t *rom_header_offset = NULL;
3528 struct atom_rom_header_v2_2 *rom_header = NULL;
3529 struct display_object_info_table_v1_4 *object_info_tbl;
3530 struct atom_data_revision tbl_rev = {0};
3531
3532 if (!init)
3533 return false;
3534
3535 if (!init->bios)
3536 return false;
3537
3538 bp->base.funcs = &vbios_funcs;
3539 bp->base.bios = init->bios;
3540 bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
3541
3542 bp->base.ctx = init->ctx;
3543
3544 bp->base.bios_local_image = NULL;
3545
3546 rom_header_offset =
3547 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
3548
3549 if (!rom_header_offset)
3550 return false;
3551
3552 rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
3553
3554 if (!rom_header)
3555 return false;
3556
3557 get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
3558 if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
3559 return false;
3560
3561 bp->master_data_tbl =
3562 GET_IMAGE(struct atom_master_data_table_v2_1,
3563 rom_header->masterdatatable_offset);
3564
3565 if (!bp->master_data_tbl)
3566 return false;
3567
3568 bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
3569
3570 if (!bp->object_info_tbl_offset)
3571 return false;
3572
3573 object_info_tbl =
3574 GET_IMAGE(struct display_object_info_table_v1_4,
3575 bp->object_info_tbl_offset);
3576
3577 if (!object_info_tbl)
3578 return false;
3579
3580 get_atom_data_table_revision(&object_info_tbl->table_header,
3581 &bp->object_info_tbl.revision);
3582
3583 if (bp->object_info_tbl.revision.major == 1
3584 && bp->object_info_tbl.revision.minor == 4) {
3585 struct display_object_info_table_v1_4 *tbl_v1_4;
3586
3587 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
3588 bp->object_info_tbl_offset);
3589 if (!tbl_v1_4)
3590 return false;
3591
3592 bp->object_info_tbl.v1_4 = tbl_v1_4;
3593 } else if (bp->object_info_tbl.revision.major == 1
3594 && bp->object_info_tbl.revision.minor == 5) {
3595 struct display_object_info_table_v1_5 *tbl_v1_5;
3596
3597 tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5,
3598 bp->object_info_tbl_offset);
3599 if (!tbl_v1_5)
3600 return false;
3601
3602 bp->object_info_tbl.v1_5 = tbl_v1_5;
3603 } else {
3604 ASSERT(0);
3605 return false;
3606 }
3607
3608 dal_firmware_parser_init_cmd_tbl(bp);
3609 dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
3610
3611 bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
3612 bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
3613 bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);
3614
3615 return true;
3616 }
3617
3618 struct dc_bios *firmware_parser_create(
3619 struct bp_init_data *init,
3620 enum dce_version dce_version)
3621 {
3622 struct bios_parser *bp = NULL;
3623
3624 bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
3625 if (!bp)
3626 return NULL;
3627
3628 if (bios_parser2_construct(bp, init, dce_version))
3629 return &bp->base;
3630
3631 kfree(bp);
3632 return NULL;
3633 }
3634
3635