2 * Copyright 2012-15 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include "dm_services.h"
29 #include "atomfirmware.h"
31 #include "dc_bios_types.h"
32 #include "include/grph_object_ctrl_defs.h"
33 #include "include/bios_parser_interface.h"
34 #include "include/i2caux_interface.h"
35 #include "include/logger_interface.h"
37 #include "command_table2.h"
39 #include "bios_parser_helper.h"
40 #include "command_table_helper2.h"
41 #include "bios_parser2.h"
42 #include "bios_parser_types_internal2.h"
43 #include "bios_parser_interface.h"
45 #include "bios_parser_common.h"
47 /* Temporarily add in defines until ObjectID.h patch is updated in a few days */
48 #ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
49 #define GENERIC_OBJECT_ID_BRACKET_LAYOUT 0x05
50 #endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */
52 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
53 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 \
54 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
55 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
56 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
57 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */
59 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
60 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 \
61 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
62 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
63 GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
64 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */
69 #define LAST_RECORD_TYPE 0xff
70 #define SMU9_SYSPLL0_ID 0
72 struct i2c_id_config_access {
73 uint8_t bfI2C_LineMux:4;
74 uint8_t bfHW_EngineID:3;
75 uint8_t bfHW_Capable:1;
79 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
80 struct atom_i2c_record *record,
81 struct graphics_object_i2c_info *info);
83 static enum bp_result bios_parser_get_firmware_info(
85 struct dc_firmware_info *info);
87 static enum bp_result bios_parser_get_encoder_cap_info(
89 struct graphics_object_id object_id,
90 struct bp_encoder_cap_info *info);
92 static enum bp_result get_firmware_info_v3_1(
93 struct bios_parser *bp,
94 struct dc_firmware_info *info);
96 static enum bp_result get_firmware_info_v3_2(
97 struct bios_parser *bp,
98 struct dc_firmware_info *info);
100 static enum bp_result get_firmware_info_v3_4(
101 struct bios_parser *bp,
102 struct dc_firmware_info *info);
104 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
105 struct atom_display_object_path_v2 *object);
107 static struct atom_encoder_caps_record *get_encoder_cap_record(
108 struct bios_parser *bp,
109 struct atom_display_object_path_v2 *object);
111 #define BIOS_IMAGE_SIZE_OFFSET 2
112 #define BIOS_IMAGE_SIZE_UNIT 512
114 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
116 static void bios_parser2_destruct(struct bios_parser *bp)
118 kfree(bp->base.bios_local_image);
119 kfree(bp->base.integrated_info);
122 static void firmware_parser_destroy(struct dc_bios **dcb)
124 struct bios_parser *bp = BP_FROM_DCB(*dcb);
131 bios_parser2_destruct(bp);
137 static void get_atom_data_table_revision(
138 struct atom_common_table_header *atom_data_tbl,
139 struct atom_data_revision *tbl_revision)
144 /* initialize the revision to 0 which is invalid revision */
145 tbl_revision->major = 0;
146 tbl_revision->minor = 0;
151 tbl_revision->major =
152 (uint32_t) atom_data_tbl->format_revision & 0x3f;
153 tbl_revision->minor =
154 (uint32_t) atom_data_tbl->content_revision & 0x3f;
157 /* BIOS oject table displaypath is per connector.
158 * There is extra path not for connector. BIOS fill its encoderid as 0
160 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
162 struct bios_parser *bp = BP_FROM_DCB(dcb);
163 unsigned int count = 0;
166 switch (bp->object_info_tbl.revision.minor) {
169 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++)
170 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
176 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++)
177 if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0)
185 static struct graphics_object_id bios_parser_get_connector_id(
189 struct bios_parser *bp = BP_FROM_DCB(dcb);
190 struct graphics_object_id object_id = dal_graphics_object_id_init(
191 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
192 struct object_info_table *tbl = &bp->object_info_tbl;
193 struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
195 struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5;
197 switch (bp->object_info_tbl.revision.minor) {
200 if (v1_4->number_of_path > i) {
201 /* If display_objid is generic object id, the encoderObj
202 * /extencoderobjId should be 0
204 if (v1_4->display_path[i].encoderobjid != 0 &&
205 v1_4->display_path[i].display_objid != 0)
206 object_id = object_id_from_bios_object_id(
207 v1_4->display_path[i].display_objid);
212 if (v1_5->number_of_path > i) {
213 /* If display_objid is generic object id, the encoderObjId
216 if (v1_5->display_path[i].encoderobjid != 0 &&
217 v1_5->display_path[i].display_objid != 0)
218 object_id = object_id_from_bios_object_id(
219 v1_5->display_path[i].display_objid);
226 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
227 struct graphics_object_id object_id, uint32_t index,
228 struct graphics_object_id *src_object_id)
230 struct bios_parser *bp = BP_FROM_DCB(dcb);
232 enum bp_result bp_result = BP_RESULT_BADINPUT;
233 struct graphics_object_id obj_id = { 0 };
234 struct object_info_table *tbl = &bp->object_info_tbl;
239 switch (object_id.type) {
240 /* Encoder's Source is GPU. BIOS does not provide GPU, since all
241 * displaypaths point to same GPU (0x1100). Hardcode GPU object type
243 case OBJECT_TYPE_ENCODER:
244 /* TODO: since num of src must be less than 2.
245 * If found in for loop, should break.
246 * DAL2 implementation may be changed too
248 switch (bp->object_info_tbl.revision.minor) {
251 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
252 obj_id = object_id_from_bios_object_id(
253 tbl->v1_4->display_path[i].encoderobjid);
254 if (object_id.type == obj_id.type &&
255 object_id.id == obj_id.id &&
256 object_id.enum_id == obj_id.enum_id) {
258 object_id_from_bios_object_id(
263 bp_result = BP_RESULT_OK;
267 for (i = 0; i < tbl->v1_5->number_of_path; i++) {
268 obj_id = object_id_from_bios_object_id(
269 tbl->v1_5->display_path[i].encoderobjid);
270 if (object_id.type == obj_id.type &&
271 object_id.id == obj_id.id &&
272 object_id.enum_id == obj_id.enum_id) {
274 object_id_from_bios_object_id(
279 bp_result = BP_RESULT_OK;
283 case OBJECT_TYPE_CONNECTOR:
284 switch (bp->object_info_tbl.revision.minor) {
287 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
288 obj_id = object_id_from_bios_object_id(
289 tbl->v1_4->display_path[i]
292 if (object_id.type == obj_id.type &&
293 object_id.id == obj_id.id &&
294 object_id.enum_id == obj_id.enum_id) {
296 object_id_from_bios_object_id(
303 bp_result = BP_RESULT_OK;
306 bp_result = BP_RESULT_OK;
309 for (i = 0; i < tbl->v1_5->number_of_path; i++) {
310 obj_id = object_id_from_bios_object_id(
311 tbl->v1_5->display_path[i].display_objid);
313 if (object_id.type == obj_id.type &&
314 object_id.id == obj_id.id &&
315 object_id.enum_id == obj_id.enum_id) {
316 *src_object_id = object_id_from_bios_object_id(
317 tbl->v1_5->display_path[i].encoderobjid);
321 bp_result = BP_RESULT_OK;
325 bp_result = BP_RESULT_OK;
332 /* from graphics_object_id, find display path which includes the object_id */
333 static struct atom_display_object_path_v2 *get_bios_object(
334 struct bios_parser *bp,
335 struct graphics_object_id id)
338 struct graphics_object_id obj_id = {0};
341 case OBJECT_TYPE_ENCODER:
342 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
343 obj_id = object_id_from_bios_object_id(
344 bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
345 if (id.type == obj_id.type && id.id == obj_id.id
346 && id.enum_id == obj_id.enum_id)
347 return &bp->object_info_tbl.v1_4->display_path[i];
350 case OBJECT_TYPE_CONNECTOR:
351 case OBJECT_TYPE_GENERIC:
352 /* Both Generic and Connector Object ID
353 * will be stored on display_objid
355 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
356 obj_id = object_id_from_bios_object_id(
357 bp->object_info_tbl.v1_4->display_path[i].display_objid);
358 if (id.type == obj_id.type && id.id == obj_id.id
359 && id.enum_id == obj_id.enum_id)
360 return &bp->object_info_tbl.v1_4->display_path[i];
368 /* from graphics_object_id, find display path which includes the object_id */
369 static struct atom_display_object_path_v3 *get_bios_object_from_path_v3(
370 struct bios_parser *bp,
371 struct graphics_object_id id)
374 struct graphics_object_id obj_id = {0};
377 case OBJECT_TYPE_ENCODER:
378 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
379 obj_id = object_id_from_bios_object_id(
380 bp->object_info_tbl.v1_5->display_path[i].encoderobjid);
381 if (id.type == obj_id.type && id.id == obj_id.id
382 && id.enum_id == obj_id.enum_id)
383 return &bp->object_info_tbl.v1_5->display_path[i];
387 case OBJECT_TYPE_CONNECTOR:
388 case OBJECT_TYPE_GENERIC:
389 /* Both Generic and Connector Object ID
390 * will be stored on display_objid
392 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
393 obj_id = object_id_from_bios_object_id(
394 bp->object_info_tbl.v1_5->display_path[i].display_objid);
395 if (id.type == obj_id.type && id.id == obj_id.id
396 && id.enum_id == obj_id.enum_id)
397 return &bp->object_info_tbl.v1_5->display_path[i];
408 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
409 struct graphics_object_id id,
410 struct graphics_object_i2c_info *info)
413 struct atom_display_object_path_v2 *object;
415 struct atom_display_object_path_v3 *object_path_v3;
417 struct atom_common_record_header *header;
418 struct atom_i2c_record *record;
419 struct atom_i2c_record dummy_record = {0};
420 struct bios_parser *bp = BP_FROM_DCB(dcb);
423 return BP_RESULT_BADINPUT;
425 if (id.type == OBJECT_TYPE_GENERIC) {
426 dummy_record.i2c_id = id.id;
428 if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
431 return BP_RESULT_NORECORD;
434 switch (bp->object_info_tbl.revision.minor) {
437 object = get_bios_object(bp, id);
440 return BP_RESULT_BADINPUT;
442 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
445 object_path_v3 = get_bios_object_from_path_v3(bp, id);
448 return BP_RESULT_BADINPUT;
450 offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset;
455 header = GET_IMAGE(struct atom_common_record_header, offset);
458 return BP_RESULT_BADBIOSTABLE;
460 if (header->record_type == LAST_RECORD_TYPE ||
461 !header->record_size)
464 if (header->record_type == ATOM_I2C_RECORD_TYPE
465 && sizeof(struct atom_i2c_record) <=
466 header->record_size) {
467 /* get the I2C info */
468 record = (struct atom_i2c_record *) header;
470 if (get_gpio_i2c_info(bp, record, info) ==
475 offset += header->record_size;
478 return BP_RESULT_NORECORD;
481 static enum bp_result get_gpio_i2c_info(
482 struct bios_parser *bp,
483 struct atom_i2c_record *record,
484 struct graphics_object_i2c_info *info)
486 struct atom_gpio_pin_lut_v2_1 *header;
488 unsigned int table_index = 0;
489 bool find_valid = false;
492 return BP_RESULT_BADINPUT;
494 /* get the GPIO_I2C info */
495 if (!DATA_TABLES(gpio_pin_lut))
496 return BP_RESULT_BADBIOSTABLE;
498 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
499 DATA_TABLES(gpio_pin_lut));
501 return BP_RESULT_BADBIOSTABLE;
503 if (sizeof(struct atom_common_table_header) +
504 sizeof(struct atom_gpio_pin_assignment) >
505 le16_to_cpu(header->table_header.structuresize))
506 return BP_RESULT_BADBIOSTABLE;
508 /* TODO: is version change? */
509 if (header->table_header.content_revision != 1)
510 return BP_RESULT_UNSUPPORTED;
513 count = (le16_to_cpu(header->table_header.structuresize)
514 - sizeof(struct atom_common_table_header))
515 / sizeof(struct atom_gpio_pin_assignment);
517 for (table_index = 0; table_index < count; table_index++) {
518 if (((record->i2c_id & I2C_HW_CAP) == (
519 header->gpio_pin[table_index].gpio_id &
521 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
522 (header->gpio_pin[table_index].gpio_id &
523 I2C_HW_ENGINE_ID_MASK)) &&
524 ((record->i2c_id & I2C_HW_LANE_MUX) ==
525 (header->gpio_pin[table_index].gpio_id &
533 /* If we don't find the entry that we are looking for then
534 * we will return BP_Result_BadBiosTable.
536 if (find_valid == false)
537 return BP_RESULT_BADBIOSTABLE;
539 /* get the GPIO_I2C_INFO */
540 info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
541 info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
542 info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
543 info->i2c_slave_address = record->i2c_slave_addr;
545 /* TODO: check how to get register offset for en, Y, etc. */
546 info->gpio_info.clk_a_register_index =
548 header->gpio_pin[table_index].data_a_reg_index);
549 info->gpio_info.clk_a_shift =
550 header->gpio_pin[table_index].gpio_bitshift;
555 static struct atom_hpd_int_record *get_hpd_record_for_path_v3(
556 struct bios_parser *bp,
557 struct atom_display_object_path_v3 *object)
559 struct atom_common_record_header *header;
563 BREAK_TO_DEBUGGER(); /* Invalid object */
567 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
570 header = GET_IMAGE(struct atom_common_record_header, offset);
575 if (header->record_type == ATOM_RECORD_END_TYPE ||
576 !header->record_size)
579 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
580 && sizeof(struct atom_hpd_int_record) <=
582 return (struct atom_hpd_int_record *) header;
584 offset += header->record_size;
590 static enum bp_result bios_parser_get_hpd_info(
592 struct graphics_object_id id,
593 struct graphics_object_hpd_info *info)
595 struct bios_parser *bp = BP_FROM_DCB(dcb);
596 struct atom_display_object_path_v2 *object;
597 struct atom_display_object_path_v3 *object_path_v3;
598 struct atom_hpd_int_record *record = NULL;
601 return BP_RESULT_BADINPUT;
603 switch (bp->object_info_tbl.revision.minor) {
606 object = get_bios_object(bp, id);
609 return BP_RESULT_BADINPUT;
611 record = get_hpd_record(bp, object);
615 object_path_v3 = get_bios_object_from_path_v3(bp, id);
618 return BP_RESULT_BADINPUT;
620 record = get_hpd_record_for_path_v3(bp, object_path_v3);
624 if (record != NULL) {
625 info->hpd_int_gpio_uid = record->pin_id;
626 info->hpd_active = record->plugin_pin_state;
630 return BP_RESULT_NORECORD;
633 static struct atom_hpd_int_record *get_hpd_record(
634 struct bios_parser *bp,
635 struct atom_display_object_path_v2 *object)
637 struct atom_common_record_header *header;
641 BREAK_TO_DEBUGGER(); /* Invalid object */
645 offset = le16_to_cpu(object->disp_recordoffset)
646 + bp->object_info_tbl_offset;
649 header = GET_IMAGE(struct atom_common_record_header, offset);
654 if (header->record_type == LAST_RECORD_TYPE ||
655 !header->record_size)
658 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
659 && sizeof(struct atom_hpd_int_record) <=
661 return (struct atom_hpd_int_record *) header;
663 offset += header->record_size;
670 * bios_parser_get_gpio_pin_info
671 * Get GpioPin information of input gpio id
673 * @dcb: pointer to the DC BIOS
675 * @info: GpioPin information structure
676 * return: Bios parser result code
678 * to get the GPIO PIN INFO, we need:
679 * 1. get the GPIO_ID from other object table, see GetHPDInfo()
680 * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
681 * to get the registerA offset/mask
683 static enum bp_result bios_parser_get_gpio_pin_info(
686 struct gpio_pin_info *info)
688 struct bios_parser *bp = BP_FROM_DCB(dcb);
689 struct atom_gpio_pin_lut_v2_1 *header;
693 if (!DATA_TABLES(gpio_pin_lut))
694 return BP_RESULT_BADBIOSTABLE;
696 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
697 DATA_TABLES(gpio_pin_lut));
699 return BP_RESULT_BADBIOSTABLE;
701 if (sizeof(struct atom_common_table_header) +
702 sizeof(struct atom_gpio_pin_assignment)
703 > le16_to_cpu(header->table_header.structuresize))
704 return BP_RESULT_BADBIOSTABLE;
706 if (header->table_header.content_revision != 1)
707 return BP_RESULT_UNSUPPORTED;
709 /* Temporary hard code gpio pin info */
710 count = (le16_to_cpu(header->table_header.structuresize)
711 - sizeof(struct atom_common_table_header))
712 / sizeof(struct atom_gpio_pin_assignment);
713 for (i = 0; i < count; ++i) {
714 if (header->gpio_pin[i].gpio_id != gpio_id)
718 (uint32_t) le16_to_cpu(
719 header->gpio_pin[i].data_a_reg_index);
720 info->offset_y = info->offset + 2;
721 info->offset_en = info->offset + 1;
722 info->offset_mask = info->offset - 1;
724 info->mask = (uint32_t) (1 <<
725 header->gpio_pin[i].gpio_bitshift);
726 info->mask_y = info->mask + 2;
727 info->mask_en = info->mask + 1;
728 info->mask_mask = info->mask - 1;
733 return BP_RESULT_NORECORD;
736 static struct device_id device_type_from_device_id(uint16_t device_id)
739 struct device_id result_device_id;
741 result_device_id.raw_device_tag = device_id;
744 case ATOM_DISPLAY_LCD1_SUPPORT:
745 result_device_id.device_type = DEVICE_TYPE_LCD;
746 result_device_id.enum_id = 1;
749 case ATOM_DISPLAY_LCD2_SUPPORT:
750 result_device_id.device_type = DEVICE_TYPE_LCD;
751 result_device_id.enum_id = 2;
754 case ATOM_DISPLAY_DFP1_SUPPORT:
755 result_device_id.device_type = DEVICE_TYPE_DFP;
756 result_device_id.enum_id = 1;
759 case ATOM_DISPLAY_DFP2_SUPPORT:
760 result_device_id.device_type = DEVICE_TYPE_DFP;
761 result_device_id.enum_id = 2;
764 case ATOM_DISPLAY_DFP3_SUPPORT:
765 result_device_id.device_type = DEVICE_TYPE_DFP;
766 result_device_id.enum_id = 3;
769 case ATOM_DISPLAY_DFP4_SUPPORT:
770 result_device_id.device_type = DEVICE_TYPE_DFP;
771 result_device_id.enum_id = 4;
774 case ATOM_DISPLAY_DFP5_SUPPORT:
775 result_device_id.device_type = DEVICE_TYPE_DFP;
776 result_device_id.enum_id = 5;
779 case ATOM_DISPLAY_DFP6_SUPPORT:
780 result_device_id.device_type = DEVICE_TYPE_DFP;
781 result_device_id.enum_id = 6;
785 BREAK_TO_DEBUGGER(); /* Invalid device Id */
786 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
787 result_device_id.enum_id = 0;
789 return result_device_id;
792 static enum bp_result bios_parser_get_device_tag(
794 struct graphics_object_id connector_object_id,
795 uint32_t device_tag_index,
796 struct connector_device_tag_info *info)
798 struct bios_parser *bp = BP_FROM_DCB(dcb);
799 struct atom_display_object_path_v2 *object;
801 struct atom_display_object_path_v3 *object_path_v3;
805 return BP_RESULT_BADINPUT;
807 switch (bp->object_info_tbl.revision.minor) {
810 /* getBiosObject will return MXM object */
811 object = get_bios_object(bp, connector_object_id);
814 BREAK_TO_DEBUGGER(); /* Invalid object id */
815 return BP_RESULT_BADINPUT;
818 info->acpi_device = 0; /* BIOS no longer provides this */
819 info->dev_id = device_type_from_device_id(object->device_tag);
822 object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id);
824 if (!object_path_v3) {
825 BREAK_TO_DEBUGGER(); /* Invalid object id */
826 return BP_RESULT_BADINPUT;
828 info->acpi_device = 0; /* BIOS no longer provides this */
829 info->dev_id = device_type_from_device_id(object_path_v3->device_tag);
836 static enum bp_result get_ss_info_v4_1(
837 struct bios_parser *bp,
840 struct spread_spectrum_info *ss_info)
842 enum bp_result result = BP_RESULT_OK;
843 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
844 struct atom_smu_info_v3_3 *smu_info = NULL;
847 return BP_RESULT_BADINPUT;
849 if (!DATA_TABLES(dce_info))
850 return BP_RESULT_BADBIOSTABLE;
852 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
853 DATA_TABLES(dce_info));
855 return BP_RESULT_BADBIOSTABLE;
858 ss_info->type.STEP_AND_DELAY_INFO = false;
859 ss_info->spread_percentage_divider = 1000;
860 /* BIOS no longer uses target clock. Always enable for now */
861 ss_info->target_clock_range = 0xffffffff;
864 case AS_SIGNAL_TYPE_DVI:
865 ss_info->spread_spectrum_percentage =
866 disp_cntl_tbl->dvi_ss_percentage;
867 ss_info->spread_spectrum_range =
868 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
869 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
870 ss_info->type.CENTER_MODE = true;
872 case AS_SIGNAL_TYPE_HDMI:
873 ss_info->spread_spectrum_percentage =
874 disp_cntl_tbl->hdmi_ss_percentage;
875 ss_info->spread_spectrum_range =
876 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
877 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
878 ss_info->type.CENTER_MODE = true;
880 /* TODO LVDS not support anymore? */
881 case AS_SIGNAL_TYPE_DISPLAY_PORT:
882 ss_info->spread_spectrum_percentage =
883 disp_cntl_tbl->dp_ss_percentage;
884 ss_info->spread_spectrum_range =
885 disp_cntl_tbl->dp_ss_rate_10hz * 10;
886 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
887 ss_info->type.CENTER_MODE = true;
889 case AS_SIGNAL_TYPE_GPU_PLL:
890 /* atom_firmware: DAL only get data from dce_info table.
891 * if data within smu_info is needed for DAL, VBIOS should
892 * copy it into dce_info
894 result = BP_RESULT_UNSUPPORTED;
896 case AS_SIGNAL_TYPE_XGMI:
897 smu_info = GET_IMAGE(struct atom_smu_info_v3_3,
898 DATA_TABLES(smu_info));
900 return BP_RESULT_BADBIOSTABLE;
902 ss_info->spread_spectrum_percentage =
903 smu_info->waflclk_ss_percentage;
904 ss_info->spread_spectrum_range =
905 smu_info->gpuclk_ss_rate_10hz * 10;
906 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
907 ss_info->type.CENTER_MODE = true;
910 result = BP_RESULT_UNSUPPORTED;
916 static enum bp_result get_ss_info_v4_2(
917 struct bios_parser *bp,
920 struct spread_spectrum_info *ss_info)
922 enum bp_result result = BP_RESULT_OK;
923 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
924 struct atom_smu_info_v3_1 *smu_info = NULL;
927 return BP_RESULT_BADINPUT;
929 if (!DATA_TABLES(dce_info))
930 return BP_RESULT_BADBIOSTABLE;
932 if (!DATA_TABLES(smu_info))
933 return BP_RESULT_BADBIOSTABLE;
935 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
936 DATA_TABLES(dce_info));
938 return BP_RESULT_BADBIOSTABLE;
940 smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
942 return BP_RESULT_BADBIOSTABLE;
944 ss_info->type.STEP_AND_DELAY_INFO = false;
945 ss_info->spread_percentage_divider = 1000;
946 /* BIOS no longer uses target clock. Always enable for now */
947 ss_info->target_clock_range = 0xffffffff;
950 case AS_SIGNAL_TYPE_DVI:
951 ss_info->spread_spectrum_percentage =
952 disp_cntl_tbl->dvi_ss_percentage;
953 ss_info->spread_spectrum_range =
954 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
955 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
956 ss_info->type.CENTER_MODE = true;
958 case AS_SIGNAL_TYPE_HDMI:
959 ss_info->spread_spectrum_percentage =
960 disp_cntl_tbl->hdmi_ss_percentage;
961 ss_info->spread_spectrum_range =
962 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
963 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
964 ss_info->type.CENTER_MODE = true;
966 /* TODO LVDS not support anymore? */
967 case AS_SIGNAL_TYPE_DISPLAY_PORT:
968 ss_info->spread_spectrum_percentage =
969 smu_info->gpuclk_ss_percentage;
970 ss_info->spread_spectrum_range =
971 smu_info->gpuclk_ss_rate_10hz * 10;
972 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
973 ss_info->type.CENTER_MODE = true;
975 case AS_SIGNAL_TYPE_GPU_PLL:
976 /* atom_firmware: DAL only get data from dce_info table.
977 * if data within smu_info is needed for DAL, VBIOS should
978 * copy it into dce_info
980 result = BP_RESULT_UNSUPPORTED;
983 result = BP_RESULT_UNSUPPORTED;
989 static enum bp_result get_ss_info_v4_5(
990 struct bios_parser *bp,
993 struct spread_spectrum_info *ss_info)
995 enum bp_result result = BP_RESULT_OK;
996 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
999 return BP_RESULT_BADINPUT;
1001 if (!DATA_TABLES(dce_info))
1002 return BP_RESULT_BADBIOSTABLE;
1004 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1005 DATA_TABLES(dce_info));
1007 return BP_RESULT_BADBIOSTABLE;
1009 ss_info->type.STEP_AND_DELAY_INFO = false;
1010 ss_info->spread_percentage_divider = 1000;
1011 /* BIOS no longer uses target clock. Always enable for now */
1012 ss_info->target_clock_range = 0xffffffff;
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;
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;
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;
1039 case AS_SIGNAL_TYPE_GPU_PLL:
1040 /* atom_smu_info_v4_0 does not have fields for SS for SMU Display PLL anymore.
1041 * SMU Display PLL supposed to be without spread.
1042 * Better place for it would be in atom_display_controller_info_v4_5 table.
1044 result = BP_RESULT_UNSUPPORTED;
1047 result = BP_RESULT_UNSUPPORTED;
1055 * bios_parser_get_spread_spectrum_info
1056 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
1057 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
1058 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
1060 * there is only one entry for each signal /ss id. However, there is
1061 * no planning of supporting multiple spread Sprectum entry for EverGreen
1062 * @dcb: pointer to the DC BIOS
1063 * @signal: ASSignalType to be converted to info index
1064 * @index: number of entries that match the converted info index
1065 * @ss_info: sprectrum information structure,
1066 * return: Bios parser result code
1068 static enum bp_result bios_parser_get_spread_spectrum_info(
1069 struct dc_bios *dcb,
1070 enum as_signal_type signal,
1072 struct spread_spectrum_info *ss_info)
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;
1079 if (!ss_info) /* check for bad input */
1080 return BP_RESULT_BADINPUT;
1082 if (!DATA_TABLES(dce_info))
1083 return BP_RESULT_UNSUPPORTED;
1085 header = GET_IMAGE(struct atom_common_table_header,
1086 DATA_TABLES(dce_info));
1087 get_atom_data_table_revision(header, &tbl_revision);
1089 switch (tbl_revision.major) {
1091 switch (tbl_revision.minor) {
1093 return get_ss_info_v4_1(bp, signal, index, ss_info);
1097 return get_ss_info_v4_2(bp, signal, index, ss_info);
1099 return get_ss_info_v4_5(bp, signal, index, ss_info);
1109 /* there can not be more then one entry for SS Info table */
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)
1117 enum bp_result result = BP_RESULT_OK;
1118 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1121 return BP_RESULT_BADINPUT;
1123 if (!DATA_TABLES(dce_info))
1124 return BP_RESULT_BADBIOSTABLE;
1126 if (!DATA_TABLES(smu_info))
1127 return BP_RESULT_BADBIOSTABLE;
1129 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1130 DATA_TABLES(dce_info));
1132 return BP_RESULT_BADBIOSTABLE;
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;
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)
1145 enum bp_result result = BP_RESULT_OK;
1146 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1149 return BP_RESULT_BADINPUT;
1151 if (!DATA_TABLES(dce_info))
1152 return BP_RESULT_BADBIOSTABLE;
1154 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1155 DATA_TABLES(dce_info));
1157 return BP_RESULT_BADBIOSTABLE;
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;
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)
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;
1175 if (!soc_bb_info) /* check for bad input */
1176 return BP_RESULT_BADINPUT;
1178 if (!DATA_TABLES(dce_info))
1179 return BP_RESULT_UNSUPPORTED;
1181 header = GET_IMAGE(struct atom_common_table_header,
1182 DATA_TABLES(dce_info));
1183 get_atom_data_table_revision(header, &tbl_revision);
1185 switch (tbl_revision.major) {
1187 switch (tbl_revision.minor) {
1193 result = get_soc_bb_info_v4_4(bp, soc_bb_info);
1196 result = get_soc_bb_info_v4_5(bp, soc_bb_info);
1209 static enum bp_result get_disp_caps_v4_1(
1210 struct bios_parser *bp,
1213 enum bp_result result = BP_RESULT_OK;
1214 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
1217 return BP_RESULT_BADINPUT;
1219 if (!DATA_TABLES(dce_info))
1220 return BP_RESULT_BADBIOSTABLE;
1222 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
1223 DATA_TABLES(dce_info));
1226 return BP_RESULT_BADBIOSTABLE;
1228 *dce_caps = disp_cntl_tbl->display_caps;
1233 static enum bp_result get_disp_caps_v4_2(
1234 struct bios_parser *bp,
1237 enum bp_result result = BP_RESULT_OK;
1238 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
1241 return BP_RESULT_BADINPUT;
1243 if (!DATA_TABLES(dce_info))
1244 return BP_RESULT_BADBIOSTABLE;
1246 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
1247 DATA_TABLES(dce_info));
1250 return BP_RESULT_BADBIOSTABLE;
1252 *dce_caps = disp_cntl_tbl->display_caps;
1257 static enum bp_result get_disp_caps_v4_3(
1258 struct bios_parser *bp,
1261 enum bp_result result = BP_RESULT_OK;
1262 struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL;
1265 return BP_RESULT_BADINPUT;
1267 if (!DATA_TABLES(dce_info))
1268 return BP_RESULT_BADBIOSTABLE;
1270 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3,
1271 DATA_TABLES(dce_info));
1274 return BP_RESULT_BADBIOSTABLE;
1276 *dce_caps = disp_cntl_tbl->display_caps;
1281 static enum bp_result get_disp_caps_v4_4(
1282 struct bios_parser *bp,
1285 enum bp_result result = BP_RESULT_OK;
1286 struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1289 return BP_RESULT_BADINPUT;
1291 if (!DATA_TABLES(dce_info))
1292 return BP_RESULT_BADBIOSTABLE;
1294 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1295 DATA_TABLES(dce_info));
1298 return BP_RESULT_BADBIOSTABLE;
1300 *dce_caps = disp_cntl_tbl->display_caps;
1305 static enum bp_result get_disp_caps_v4_5(
1306 struct bios_parser *bp,
1309 enum bp_result result = BP_RESULT_OK;
1310 struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1313 return BP_RESULT_BADINPUT;
1315 if (!DATA_TABLES(dce_info))
1316 return BP_RESULT_BADBIOSTABLE;
1318 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1319 DATA_TABLES(dce_info));
1322 return BP_RESULT_BADBIOSTABLE;
1324 *dce_caps = disp_cntl_tbl->display_caps;
1329 static enum bp_result bios_parser_get_lttpr_interop(
1330 struct dc_bios *dcb,
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;
1338 if (!DATA_TABLES(dce_info))
1339 return BP_RESULT_UNSUPPORTED;
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) {
1346 switch (tbl_revision.minor) {
1348 result = get_disp_caps_v4_1(bp, dce_caps);
1349 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1352 result = get_disp_caps_v4_2(bp, dce_caps);
1353 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1356 result = get_disp_caps_v4_3(bp, dce_caps);
1357 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1360 result = get_disp_caps_v4_4(bp, dce_caps);
1361 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1364 result = get_disp_caps_v4_5(bp, dce_caps);
1365 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1379 static enum bp_result bios_parser_get_lttpr_caps(
1380 struct dc_bios *dcb,
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;
1388 if (!DATA_TABLES(dce_info))
1389 return BP_RESULT_UNSUPPORTED;
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) {
1396 switch (tbl_revision.minor) {
1398 result = get_disp_caps_v4_1(bp, dce_caps);
1399 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1402 result = get_disp_caps_v4_2(bp, dce_caps);
1403 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1406 result = get_disp_caps_v4_3(bp, dce_caps);
1407 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1410 result = get_disp_caps_v4_4(bp, dce_caps);
1411 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1414 result = get_disp_caps_v4_5(bp, dce_caps);
1415 *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1428 static enum bp_result get_embedded_panel_info_v2_1(
1429 struct bios_parser *bp,
1430 struct embedded_panel_info *info)
1432 struct lcd_info_v2_1 *lvds;
1435 return BP_RESULT_BADINPUT;
1437 if (!DATA_TABLES(lcd_info))
1438 return BP_RESULT_UNSUPPORTED;
1440 lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
1443 return BP_RESULT_BADBIOSTABLE;
1445 /* TODO: previous vv1_3, should v2_1 */
1446 if (!((lvds->table_header.format_revision == 2)
1447 && (lvds->table_header.content_revision >= 1)))
1448 return BP_RESULT_UNSUPPORTED;
1450 memset(info, 0, sizeof(struct embedded_panel_info));
1452 /* We need to convert from 10KHz units into KHz units */
1453 info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
1454 /* usHActive does not include borders, according to VBIOS team */
1455 info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
1456 /* usHBlanking_Time includes borders, so we should really be
1457 * subtractingborders duing this translation, but LVDS generally
1458 * doesn't have borders, so we should be okay leaving this as is for
1459 * now. May need to revisit if we ever have LVDS with borders
1461 info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
1462 /* usVActive does not include borders, according to VBIOS team*/
1463 info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
1464 /* usVBlanking_Time includes borders, so we should really be
1465 * subtracting borders duing this translation, but LVDS generally
1466 * doesn't have borders, so we should be okay leaving this as is for
1467 * now. May need to revisit if we ever have LVDS with borders
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;
1477 /* not provided by VBIOS */
1478 info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
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);
1485 /* not provided by VBIOS */
1486 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
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);
1496 /* not provided by VBIOS*/
1497 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
1498 /* not provided by VBIOS*/
1501 info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1503 return BP_RESULT_OK;
1506 static enum bp_result bios_parser_get_embedded_panel_info(
1507 struct dc_bios *dcb,
1508 struct embedded_panel_info *info)
1511 *bp = BP_FROM_DCB(dcb);
1512 struct atom_common_table_header *header;
1513 struct atom_data_revision tbl_revision;
1515 if (!DATA_TABLES(lcd_info))
1516 return BP_RESULT_FAILURE;
1518 header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
1521 return BP_RESULT_BADBIOSTABLE;
1523 get_atom_data_table_revision(header, &tbl_revision);
1525 switch (tbl_revision.major) {
1527 switch (tbl_revision.minor) {
1529 return get_embedded_panel_info_v2_1(bp, info);
1538 return BP_RESULT_FAILURE;
1541 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
1543 enum dal_device_type device_type = device_id.device_type;
1544 uint32_t enum_id = device_id.enum_id;
1546 switch (device_type) {
1547 case DEVICE_TYPE_LCD:
1550 return ATOM_DISPLAY_LCD1_SUPPORT;
1555 case DEVICE_TYPE_DFP:
1558 return ATOM_DISPLAY_DFP1_SUPPORT;
1560 return ATOM_DISPLAY_DFP2_SUPPORT;
1562 return ATOM_DISPLAY_DFP3_SUPPORT;
1564 return ATOM_DISPLAY_DFP4_SUPPORT;
1566 return ATOM_DISPLAY_DFP5_SUPPORT;
1568 return ATOM_DISPLAY_DFP6_SUPPORT;
1577 /* Unidentified device ID, return empty support mask. */
1581 static bool bios_parser_is_device_id_supported(
1582 struct dc_bios *dcb,
1583 struct device_id id)
1585 struct bios_parser *bp = BP_FROM_DCB(dcb);
1587 uint32_t mask = get_support_mask_for_device_id(id);
1589 switch (bp->object_info_tbl.revision.minor) {
1592 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0;
1595 return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0;
1602 static uint32_t bios_parser_get_ss_entry_number(
1603 struct dc_bios *dcb,
1604 enum as_signal_type signal)
1606 /* TODO: DAL2 atomfirmware implementation does not need this.
1607 * why DAL3 need this?
1612 static enum bp_result bios_parser_transmitter_control(
1613 struct dc_bios *dcb,
1614 struct bp_transmitter_control *cntl)
1616 struct bios_parser *bp = BP_FROM_DCB(dcb);
1618 if (!bp->cmd_tbl.transmitter_control)
1619 return BP_RESULT_FAILURE;
1621 return bp->cmd_tbl.transmitter_control(bp, cntl);
1624 static enum bp_result bios_parser_encoder_control(
1625 struct dc_bios *dcb,
1626 struct bp_encoder_control *cntl)
1628 struct bios_parser *bp = BP_FROM_DCB(dcb);
1630 if (!bp->cmd_tbl.dig_encoder_control)
1631 return BP_RESULT_FAILURE;
1633 return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1636 static enum bp_result bios_parser_set_pixel_clock(
1637 struct dc_bios *dcb,
1638 struct bp_pixel_clock_parameters *bp_params)
1640 struct bios_parser *bp = BP_FROM_DCB(dcb);
1642 if (!bp->cmd_tbl.set_pixel_clock)
1643 return BP_RESULT_FAILURE;
1645 return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1648 static enum bp_result bios_parser_set_dce_clock(
1649 struct dc_bios *dcb,
1650 struct bp_set_dce_clock_parameters *bp_params)
1652 struct bios_parser *bp = BP_FROM_DCB(dcb);
1654 if (!bp->cmd_tbl.set_dce_clock)
1655 return BP_RESULT_FAILURE;
1657 return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1660 static enum bp_result bios_parser_program_crtc_timing(
1661 struct dc_bios *dcb,
1662 struct bp_hw_crtc_timing_parameters *bp_params)
1664 struct bios_parser *bp = BP_FROM_DCB(dcb);
1666 if (!bp->cmd_tbl.set_crtc_timing)
1667 return BP_RESULT_FAILURE;
1669 return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1672 static enum bp_result bios_parser_enable_crtc(
1673 struct dc_bios *dcb,
1674 enum controller_id id,
1677 struct bios_parser *bp = BP_FROM_DCB(dcb);
1679 if (!bp->cmd_tbl.enable_crtc)
1680 return BP_RESULT_FAILURE;
1682 return bp->cmd_tbl.enable_crtc(bp, id, enable);
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)
1690 struct bios_parser *bp = BP_FROM_DCB(dcb);
1692 if (!bp->cmd_tbl.enable_disp_power_gating)
1693 return BP_RESULT_FAILURE;
1695 return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1699 static enum bp_result bios_parser_enable_lvtma_control(
1700 struct dc_bios *dcb,
1702 uint8_t panel_instance)
1704 struct bios_parser *bp = BP_FROM_DCB(dcb);
1706 if (!bp->cmd_tbl.enable_lvtma_control)
1707 return BP_RESULT_FAILURE;
1709 return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance);
1712 static bool bios_parser_is_accelerated_mode(
1713 struct dc_bios *dcb)
1715 return bios_is_accelerated_mode(dcb);
1719 * bios_parser_set_scratch_critical_state - update critical state bit
1720 * in VBIOS scratch register
1722 * @dcb: pointer to the DC BIO
1723 * @state: set or reset state
1725 static void bios_parser_set_scratch_critical_state(
1726 struct dc_bios *dcb,
1729 bios_set_scratch_critical_state(dcb, state);
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;
1741 static enum bp_result bios_parser_get_firmware_info(
1742 struct dc_bios *dcb,
1743 struct dc_firmware_info *info)
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;
1749 struct atom_data_revision revision;
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) {
1757 switch (revision.minor) {
1759 result = get_firmware_info_v3_1(bp, info);
1763 result = get_firmware_info_v3_2(bp, info);
1766 result = get_firmware_info_v3_4(bp, info);
1780 static enum bp_result get_firmware_info_v3_1(
1781 struct bios_parser *bp,
1782 struct dc_firmware_info *info)
1784 struct atom_firmware_info_v3_1 *firmware_info;
1785 struct atom_display_controller_info_v4_1 *dce_info = NULL;
1788 return BP_RESULT_BADINPUT;
1790 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1791 DATA_TABLES(firmwareinfo));
1793 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1794 DATA_TABLES(dce_info));
1796 if (!firmware_info || !dce_info)
1797 return BP_RESULT_BADBIOSTABLE;
1799 memset(info, 0, sizeof(*info));
1801 /* Pixel clock pll information. */
1802 /* We need to convert from 10KHz units into KHz units */
1803 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1804 info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1806 /* 27MHz for Vega10: */
1807 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1809 /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1810 if (info->pll_info.crystal_frequency == 0)
1811 info->pll_info.crystal_frequency = 27000;
1812 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
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;
1816 /* Get GPU PLL VCO Clock */
1818 if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1819 /* VBIOS gives in 10KHz */
1820 info->smu_gpu_pll_output_freq =
1821 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1824 info->oem_i2c_present = false;
1826 return BP_RESULT_OK;
1829 static enum bp_result get_firmware_info_v3_2(
1830 struct bios_parser *bp,
1831 struct dc_firmware_info *info)
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;
1841 return BP_RESULT_BADINPUT;
1843 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1844 DATA_TABLES(firmwareinfo));
1846 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1847 DATA_TABLES(dce_info));
1849 if (!firmware_info || !dce_info)
1850 return BP_RESULT_BADBIOSTABLE;
1852 memset(info, 0, sizeof(*info));
1854 header = GET_IMAGE(struct atom_common_table_header,
1855 DATA_TABLES(smu_info));
1856 get_atom_data_table_revision(header, &revision);
1858 if (revision.minor == 2) {
1860 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1861 DATA_TABLES(smu_info));
1864 return BP_RESULT_BADBIOSTABLE;
1866 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1867 } else if (revision.minor == 3) {
1869 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1870 DATA_TABLES(smu_info));
1873 return BP_RESULT_BADBIOSTABLE;
1875 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1878 // We need to convert from 10KHz units into KHz units.
1879 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1881 /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1882 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1883 /* Hardcode frequency if BIOS gives no DCE Ref Clk */
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;
1890 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
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;
1894 /* Get GPU PLL VCO Clock */
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;
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;
1908 info->oem_i2c_present = false;
1911 return BP_RESULT_OK;
1914 static enum bp_result get_firmware_info_v3_4(
1915 struct bios_parser *bp,
1916 struct dc_firmware_info *info)
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;
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;
1929 return BP_RESULT_BADINPUT;
1931 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4,
1932 DATA_TABLES(firmwareinfo));
1935 return BP_RESULT_BADBIOSTABLE;
1937 memset(info, 0, sizeof(*info));
1939 header = GET_IMAGE(struct atom_common_table_header,
1940 DATA_TABLES(dce_info));
1942 get_atom_data_table_revision(header, &revision);
1944 switch (revision.major) {
1946 switch (revision.minor) {
1948 dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
1949 DATA_TABLES(dce_info));
1952 return BP_RESULT_BADBIOSTABLE;
1954 /* 100MHz expected */
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 /* 50MHz expected */
1958 info->i2c_engine_ref_clk = dce_info_v4_5->i2c_engine_refclk_10khz * 10;
1960 /* For DCN32/321 Display PLL VCO Frequency from dce_info_v4_5 may not be reliable */
1964 dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
1965 DATA_TABLES(dce_info));
1968 return BP_RESULT_BADBIOSTABLE;
1970 /* 100MHz expected */
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 /* 50MHz expected */
1974 info->i2c_engine_ref_clk = dce_info_v4_4->i2c_engine_refclk_10khz * 10;
1976 /* Get SMU Display PLL VCO Frequency in KHz*/
1977 info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10;
1981 /* should not come here, keep as backup, as was before */
1982 dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1,
1983 DATA_TABLES(dce_info));
1986 return BP_RESULT_BADBIOSTABLE;
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;
2000 header = GET_IMAGE(struct atom_common_table_header,
2001 DATA_TABLES(smu_info));
2002 get_atom_data_table_revision(header, &revision);
2004 switch (revision.major) {
2006 switch (revision.minor) {
2008 smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5,
2009 DATA_TABLES(smu_info));
2012 return BP_RESULT_BADBIOSTABLE;
2014 info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10;
2023 switch (revision.minor) {
2025 smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0,
2026 DATA_TABLES(smu_info));
2029 return BP_RESULT_BADBIOSTABLE;
2031 /* For DCN32/321 bootup DCFCLK from smu_info_v4_0 may not be reliable */
2043 // We need to convert from 10KHz units into KHz units.
2044 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
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;
2050 info->oem_i2c_present = false;
2053 return BP_RESULT_OK;
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)
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;
2066 return BP_RESULT_BADINPUT;
2068 #if defined(CONFIG_DRM_AMD_DC_DCN)
2069 /* encoder cap record not available in v1_5 */
2070 if (bp->object_info_tbl.revision.minor == 5)
2071 return BP_RESULT_NORECORD;
2074 object = get_bios_object(bp, object_id);
2077 return BP_RESULT_BADINPUT;
2079 record = get_encoder_cap_record(bp, object);
2081 return BP_RESULT_NORECORD;
2082 DC_LOG_BIOS("record->encodercaps 0x%x for object_id 0x%x", record->encodercaps, object_id.id);
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);
2104 return BP_RESULT_OK;
2108 static struct atom_encoder_caps_record *get_encoder_cap_record(
2109 struct bios_parser *bp,
2110 struct atom_display_object_path_v2 *object)
2112 struct atom_common_record_header *header;
2116 BREAK_TO_DEBUGGER(); /* Invalid object */
2120 offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
2123 header = GET_IMAGE(struct atom_common_record_header, offset);
2128 offset += header->record_size;
2130 if (header->record_type == LAST_RECORD_TYPE ||
2131 !header->record_size)
2134 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
2137 if (sizeof(struct atom_encoder_caps_record) <=
2138 header->record_size)
2139 return (struct atom_encoder_caps_record *)header;
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)
2149 struct atom_common_record_header *header;
2153 BREAK_TO_DEBUGGER(); /* Invalid object */
2157 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2160 header = GET_IMAGE(struct atom_common_record_header, offset);
2165 offset += header->record_size;
2167 if (header->record_type == LAST_RECORD_TYPE ||
2168 !header->record_size)
2171 if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE)
2174 if (sizeof(struct atom_disp_connector_caps_record) <=
2175 header->record_size)
2176 return (struct atom_disp_connector_caps_record *)header;
2182 static struct atom_connector_caps_record *get_connector_caps_record(
2183 struct bios_parser *bp,
2184 struct atom_display_object_path_v3 *object)
2186 struct atom_common_record_header *header;
2190 BREAK_TO_DEBUGGER(); /* Invalid object */
2194 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2197 header = GET_IMAGE(struct atom_common_record_header, offset);
2202 offset += header->record_size;
2204 if (header->record_type == ATOM_RECORD_END_TYPE ||
2205 !header->record_size)
2208 if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE)
2211 if (sizeof(struct atom_connector_caps_record) <= header->record_size)
2212 return (struct atom_connector_caps_record *)header;
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)
2223 struct bios_parser *bp = BP_FROM_DCB(dcb);
2224 struct atom_display_object_path_v2 *object;
2226 struct atom_display_object_path_v3 *object_path_v3;
2227 struct atom_connector_caps_record *record_path_v3;
2229 struct atom_disp_connector_caps_record *record = NULL;
2232 return BP_RESULT_BADINPUT;
2234 switch (bp->object_info_tbl.revision.minor) {
2237 object = get_bios_object(bp, object_id);
2240 return BP_RESULT_BADINPUT;
2242 record = get_disp_connector_caps_record(bp, object);
2244 return BP_RESULT_NORECORD;
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;
2252 object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2254 if (!object_path_v3)
2255 return BP_RESULT_BADINPUT;
2257 record_path_v3 = get_connector_caps_record(bp, object_path_v3);
2258 if (!record_path_v3)
2259 return BP_RESULT_NORECORD;
2261 info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
2263 info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
2268 return BP_RESULT_OK;
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)
2275 struct atom_common_record_header *header;
2279 BREAK_TO_DEBUGGER(); /* Invalid object */
2283 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2286 header = GET_IMAGE(struct atom_common_record_header, offset);
2291 offset += header->record_size;
2293 if (header->record_type == ATOM_RECORD_END_TYPE ||
2294 !header->record_size)
2297 if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO)
2300 if (sizeof(struct atom_connector_speed_record) <= header->record_size)
2301 return (struct atom_connector_speed_record *)header;
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)
2312 struct bios_parser *bp = BP_FROM_DCB(dcb);
2313 struct atom_display_object_path_v3 *object_path_v3;
2314 //struct atom_connector_speed_record *record = NULL;
2315 struct atom_connector_speed_record *record;
2318 return BP_RESULT_BADINPUT;
2320 object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2322 if (!object_path_v3)
2323 return BP_RESULT_BADINPUT;
2325 record = get_connector_speed_cap_record(bp, object_path_v3);
2327 return BP_RESULT_NORECORD;
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;
2338 static enum bp_result get_vram_info_v23(
2339 struct bios_parser *bp,
2340 struct dc_vram_info *info)
2342 struct atom_vram_info_header_v2_3 *info_v23;
2343 static enum bp_result result = BP_RESULT_OK;
2345 info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
2346 DATA_TABLES(vram_info));
2348 if (info_v23 == NULL)
2349 return BP_RESULT_BADBIOSTABLE;
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;
2357 static enum bp_result get_vram_info_v24(
2358 struct bios_parser *bp,
2359 struct dc_vram_info *info)
2361 struct atom_vram_info_header_v2_4 *info_v24;
2362 static enum bp_result result = BP_RESULT_OK;
2364 info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
2365 DATA_TABLES(vram_info));
2367 if (info_v24 == NULL)
2368 return BP_RESULT_BADBIOSTABLE;
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;
2376 static enum bp_result get_vram_info_v25(
2377 struct bios_parser *bp,
2378 struct dc_vram_info *info)
2380 struct atom_vram_info_header_v2_5 *info_v25;
2381 static enum bp_result result = BP_RESULT_OK;
2383 info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
2384 DATA_TABLES(vram_info));
2386 if (info_v25 == NULL)
2387 return BP_RESULT_BADBIOSTABLE;
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;
2396 * get_integrated_info_v11
2399 * Get V8 integrated BIOS information
2402 * bios_parser *bp - [in]BIOS parser handler to get master data table
2403 * integrated_info *info - [out] store and output integrated info
2406 * static enum bp_result - BP_RESULT_OK if information is available,
2407 * BP_RESULT_BADBIOSTABLE otherwise.
2409 static enum bp_result get_integrated_info_v11(
2410 struct bios_parser *bp,
2411 struct integrated_info *info)
2413 struct atom_integrated_system_info_v1_11 *info_v11;
2416 info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
2417 DATA_TABLES(integratedsysteminfo));
2419 if (info_v11 == NULL)
2420 return BP_RESULT_BADBIOSTABLE;
2422 info->gpu_cap_info =
2423 le32_to_cpu(info_v11->gpucapinfo);
2425 * system_config: Bit[0] = 0 : PCIE power gating disabled
2426 * = 1 : PCIE power gating enabled
2427 * Bit[1] = 0 : DDR-PLL shut down disabled
2428 * = 1 : DDR-PLL shut down enabled
2429 * Bit[2] = 0 : DDR-PLL power down disabled
2430 * = 1 : DDR-PLL power down enabled
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];
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));
2461 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2462 object_id_from_bios_object_id(
2464 info_v11->extdispconninfo.path[i].ext_encoder_objid));
2466 info->ext_disp_conn_info.path[i].device_tag =
2468 info_v11->extdispconninfo.path[i].device_tag);
2469 info->ext_disp_conn_info.path[i].device_acpi_enum =
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);
2481 info->ext_disp_conn_info.checksum =
2482 info_v11->extdispconninfo.checksum;
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;
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;
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;
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;
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;
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;
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;
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;
2549 /** TODO - review **/
2551 info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
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;
2556 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
2557 /* Convert [10KHz] into [KHz] */
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);
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]);
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);
2609 for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
2610 /* Convert [10KHz] into [KHz] */
2611 info->avail_s_clk[i].supported_s_clk =
2612 le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
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);
2621 return BP_RESULT_OK;
2624 static enum bp_result get_integrated_info_v2_1(
2625 struct bios_parser *bp,
2626 struct integrated_info *info)
2628 struct atom_integrated_system_info_v2_1 *info_v2_1;
2631 info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1,
2632 DATA_TABLES(integratedsysteminfo));
2634 if (info_v2_1 == NULL)
2635 return BP_RESULT_BADBIOSTABLE;
2637 info->gpu_cap_info =
2638 le32_to_cpu(info_v2_1->gpucapinfo);
2640 * system_config: Bit[0] = 0 : PCIE power gating disabled
2641 * = 1 : PCIE power gating enabled
2642 * Bit[1] = 0 : DDR-PLL shut down disabled
2643 * = 1 : DDR-PLL shut down enabled
2644 * Bit[2] = 0 : DDR-PLL power down disabled
2645 * = 1 : DDR-PLL power down enabled
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);
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];
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));
2664 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2665 object_id_from_bios_object_id(
2667 info_v2_1->extdispconninfo.path[i].ext_encoder_objid));
2669 info->ext_disp_conn_info.path[i].device_tag =
2671 info_v2_1->extdispconninfo.path[i].device_tag);
2672 info->ext_disp_conn_info.path[i].device_acpi_enum =
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);
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
2781 return BP_RESULT_OK;
2784 static enum bp_result get_integrated_info_v2_2(
2785 struct bios_parser *bp,
2786 struct integrated_info *info)
2788 struct atom_integrated_system_info_v2_2 *info_v2_2;
2791 info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2,
2792 DATA_TABLES(integratedsysteminfo));
2794 if (info_v2_2 == NULL)
2795 return BP_RESULT_BADBIOSTABLE;
2797 info->gpu_cap_info =
2798 le32_to_cpu(info_v2_2->gpucapinfo);
2800 * system_config: Bit[0] = 0 : PCIE power gating disabled
2801 * = 1 : PCIE power gating enabled
2802 * Bit[1] = 0 : DDR-PLL shut down disabled
2803 * = 1 : DDR-PLL shut down enabled
2804 * Bit[2] = 0 : DDR-PLL power down disabled
2805 * = 1 : DDR-PLL power down enabled
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);
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];
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));
2824 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2825 object_id_from_bios_object_id(
2827 info_v2_2->extdispconninfo.path[i].ext_encoder_objid));
2829 info->ext_disp_conn_info.path[i].device_tag =
2831 info_v2_2->extdispconninfo.path[i].device_tag);
2832 info->ext_disp_conn_info.path[i].device_acpi_enum =
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);
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;
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 =
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;
2883 return BP_RESULT_OK;
2887 * construct_integrated_info
2890 * Get integrated BIOS information based on table revision
2893 * bios_parser *bp - [in]BIOS parser handler to get master data table
2894 * integrated_info *info - [out] store and output integrated info
2897 * static enum bp_result - BP_RESULT_OK if information is available,
2898 * BP_RESULT_BADBIOSTABLE otherwise.
2900 static enum bp_result construct_integrated_info(
2901 struct bios_parser *bp,
2902 struct integrated_info *info)
2904 static enum bp_result result = BP_RESULT_BADBIOSTABLE;
2906 struct atom_common_table_header *header;
2907 struct atom_data_revision revision;
2909 struct clock_voltage_caps temp = {0, 0};
2913 if (info && DATA_TABLES(integratedsysteminfo)) {
2914 header = GET_IMAGE(struct atom_common_table_header,
2915 DATA_TABLES(integratedsysteminfo));
2917 get_atom_data_table_revision(header, &revision);
2919 switch (revision.major) {
2921 switch (revision.minor) {
2924 result = get_integrated_info_v11(bp, info);
2931 switch (revision.minor) {
2933 result = get_integrated_info_v2_1(bp, info);
2936 result = get_integrated_info_v2_2(bp, info);
2947 if (result != BP_RESULT_OK)
2950 // Log each external path
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",
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
2972 // Log the Checksum and Voltage Swing
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);
2978 /* Sort voltage table from low to high*/
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
2984 /* swap j and j - 1*/
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;
2996 static enum bp_result bios_parser_get_vram_info(
2997 struct dc_bios *dcb,
2998 struct dc_vram_info *info)
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;
3005 if (info && DATA_TABLES(vram_info)) {
3006 header = GET_IMAGE(struct atom_common_table_header,
3007 DATA_TABLES(vram_info));
3009 get_atom_data_table_revision(header, &revision);
3011 switch (revision.major) {
3013 switch (revision.minor) {
3015 result = get_vram_info_v23(bp, info);
3018 result = get_vram_info_v24(bp, info);
3021 result = get_vram_info_v25(bp, info);
3036 static struct integrated_info *bios_parser_create_integrated_info(
3037 struct dc_bios *dcb)
3039 struct bios_parser *bp = BP_FROM_DCB(dcb);
3040 struct integrated_info *info = NULL;
3042 info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
3049 if (construct_integrated_info(bp, info) == BP_RESULT_OK)
3057 static enum bp_result update_slot_layout_info(
3058 struct dc_bios *dcb,
3060 struct slot_layout_info *slot_layout_info)
3062 unsigned int record_offset;
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;
3073 record_header = NULL;
3074 result = BP_RESULT_NORECORD;
3076 bp = BP_FROM_DCB(dcb);
3077 tbl = &bp->object_info_tbl;
3080 object = &v1_4->display_path[i];
3081 record_offset = (unsigned int)
3082 (object->disp_recordoffset) +
3083 (unsigned int)(bp->object_info_tbl_offset);
3087 record_header = (struct atom_common_record_header *)
3088 GET_IMAGE(struct atom_common_record_header,
3090 if (record_header == NULL) {
3091 result = BP_RESULT_BADBIOSTABLE;
3095 /* the end of the list */
3096 if (record_header->record_type == 0xff ||
3097 record_header->record_size == 0) {
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 *)
3107 result = BP_RESULT_OK;
3111 record_offset += record_header->record_size;
3114 /* return if the record not found */
3115 if (result != BP_RESULT_OK)
3118 /* get slot sizes */
3119 slot_layout_info->length = record->bracketlen;
3120 slot_layout_info->width = record->bracketwidth;
3122 /* get info for each connector in the slot */
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 =
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;
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 =
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;
3158 slot_layout_info->connectors[j].connector_type =
3159 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3160 slot_layout_info->connectors[j].length =
3161 CONNECTOR_SIZE_UNKNOWN;
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);
3173 static enum bp_result update_slot_layout_info_v2(
3174 struct dc_bios *dcb,
3176 struct slot_layout_info *slot_layout_info)
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;
3189 record_header = NULL;
3190 result = BP_RESULT_NORECORD;
3192 bp = BP_FROM_DCB(dcb);
3193 tbl = &bp->object_info_tbl;
3196 object = &v1_5->display_path[i];
3197 record_offset = (unsigned int)
3198 (object->disp_recordoffset) +
3199 (unsigned int)(bp->object_info_tbl_offset);
3203 record_header = (struct atom_common_record_header *)
3204 GET_IMAGE(struct atom_common_record_header,
3206 if (record_header == NULL) {
3207 result = BP_RESULT_BADBIOSTABLE;
3211 /* the end of the list */
3212 if (record_header->record_type == ATOM_RECORD_END_TYPE ||
3213 record_header->record_size == 0) {
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 *)
3223 result = BP_RESULT_OK;
3227 record_offset += record_header->record_size;
3230 /* return if the record not found */
3231 if (result != BP_RESULT_OK)
3234 /* get slot sizes */
3235 connector_id = object_id_from_bios_object_id(object->display_objid);
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;
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;
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;
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;
3261 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP;
3262 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP;
3267 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3268 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN;
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)
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;
3285 if (slot_layout_info == NULL) {
3286 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
3287 return BP_RESULT_BADINPUT;
3289 tbl = &bp->object_info_tbl;
3293 result = BP_RESULT_NORECORD;
3294 switch (bp->object_info_tbl.revision.minor) {
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);
3306 for (i = 0; i < v1_5->number_of_path; ++i)
3307 result = update_slot_layout_info_v2(dcb, i, slot_layout_info);
3313 static enum bp_result bios_get_board_layout_info(
3314 struct dc_bios *dcb,
3315 struct board_layout_info *board_layout_info)
3319 struct bios_parser *bp;
3321 static enum bp_result record_result;
3323 const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
3324 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
3325 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
3330 bp = BP_FROM_DCB(dcb);
3332 if (board_layout_info == NULL) {
3333 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
3334 return BP_RESULT_BADINPUT;
3337 board_layout_info->num_of_slots = 0;
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]);
3344 if (record_result == BP_RESULT_NORECORD && i > 0)
3345 break; /* no more slots present in bios */
3346 else if (record_result != BP_RESULT_OK)
3347 return record_result; /* fail */
3349 ++board_layout_info->num_of_slots;
3352 /* all data is valid */
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;
3358 return BP_RESULT_OK;
3362 static uint16_t bios_parser_pack_data_tables(
3363 struct dc_bios *dcb,
3366 // TODO: There is data bytes alignment issue, disable it for now.
3370 static struct atom_dc_golden_table_v1 *bios_get_golden_table(
3371 struct bios_parser *bp,
3374 uint16_t *dc_golden_table_ver)
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;
3380 if (!DATA_TABLES(dce_info))
3383 /* ver.4.4 or higher */
3384 switch (rev_major) {
3386 switch (rev_minor) {
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)
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;
3397 /* For atom_display_controller_info_v4_5 there is no need to get golden table from
3398 * dc_golden_table_offset as all these fields previously in golden table used for AUX
3399 * pre-charge settings are now available directly in atom_display_controller_info_v4_5.
3406 if (!dc_golden_offset)
3409 if (*dc_golden_table_ver != 1)
3412 return GET_IMAGE(struct atom_dc_golden_table_v1,
3416 static enum bp_result bios_get_atom_dc_golden_table(
3417 struct dc_bios *dcb)
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;
3426 header = GET_IMAGE(struct atom_common_table_header,
3427 DATA_TABLES(dce_info));
3429 return BP_RESULT_UNSUPPORTED;
3431 get_atom_data_table_revision(header, &tbl_revision);
3433 atom_dc_golden_table = bios_get_golden_table(bp,
3436 &dc_golden_table_ver);
3438 if (!atom_dc_golden_table)
3439 return BP_RESULT_UNSUPPORTED;
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;
3456 static const struct dc_vbios_funcs vbios_funcs = {
3457 .get_connectors_number = bios_parser_get_connectors_number,
3459 .get_connector_id = bios_parser_get_connector_id,
3461 .get_src_obj = bios_parser_get_src_obj,
3463 .get_i2c_info = bios_parser_get_i2c_info,
3465 .get_hpd_info = bios_parser_get_hpd_info,
3467 .get_device_tag = bios_parser_get_device_tag,
3469 .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
3471 .get_ss_entry_number = bios_parser_get_ss_entry_number,
3473 .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
3475 .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
3477 .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
3479 .is_device_id_supported = bios_parser_is_device_id_supported,
3481 .is_accelerated_mode = bios_parser_is_accelerated_mode,
3483 .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
3487 .encoder_control = bios_parser_encoder_control,
3489 .transmitter_control = bios_parser_transmitter_control,
3491 .enable_crtc = bios_parser_enable_crtc,
3493 .set_pixel_clock = bios_parser_set_pixel_clock,
3495 .set_dce_clock = bios_parser_set_dce_clock,
3497 .program_crtc_timing = bios_parser_program_crtc_timing,
3499 .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
3501 .bios_parser_destroy = firmware_parser_destroy,
3503 .get_board_layout_info = bios_get_board_layout_info,
3504 /* TODO: use this fn in hw init?*/
3505 .pack_data_tables = bios_parser_pack_data_tables,
3507 .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
3509 .enable_lvtma_control = bios_parser_enable_lvtma_control,
3511 .get_soc_bb_info = bios_parser_get_soc_bb_info,
3513 .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info,
3515 .get_lttpr_caps = bios_parser_get_lttpr_caps,
3517 .get_lttpr_interop = bios_parser_get_lttpr_interop,
3519 .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info,
3522 static bool bios_parser2_construct(
3523 struct bios_parser *bp,
3524 struct bp_init_data *init,
3525 enum dce_version dce_version)
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};
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;
3542 bp->base.ctx = init->ctx;
3544 bp->base.bios_local_image = NULL;
3547 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
3549 if (!rom_header_offset)
3552 rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
3557 get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
3558 if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
3561 bp->master_data_tbl =
3562 GET_IMAGE(struct atom_master_data_table_v2_1,
3563 rom_header->masterdatatable_offset);
3565 if (!bp->master_data_tbl)
3568 bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
3570 if (!bp->object_info_tbl_offset)
3574 GET_IMAGE(struct display_object_info_table_v1_4,
3575 bp->object_info_tbl_offset);
3577 if (!object_info_tbl)
3580 get_atom_data_table_revision(&object_info_tbl->table_header,
3581 &bp->object_info_tbl.revision);
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;
3587 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
3588 bp->object_info_tbl_offset);
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;
3597 tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5,
3598 bp->object_info_tbl_offset);
3602 bp->object_info_tbl.v1_5 = tbl_v1_5;
3608 dal_firmware_parser_init_cmd_tbl(bp);
3609 dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
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);
3618 struct dc_bios *firmware_parser_create(
3619 struct bp_init_data *init,
3620 enum dce_version dce_version)
3622 struct bios_parser *bp = NULL;
3624 bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
3628 if (bios_parser2_construct(bp, init, dce_version))