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 struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
101 struct atom_display_object_path_v2 *object);
103 static struct atom_encoder_caps_record *get_encoder_cap_record(
104 struct bios_parser *bp,
105 struct atom_display_object_path_v2 *object);
107 #define BIOS_IMAGE_SIZE_OFFSET 2
108 #define BIOS_IMAGE_SIZE_UNIT 512
110 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
112 static void destruct(struct bios_parser *bp)
114 kfree(bp->base.bios_local_image);
115 kfree(bp->base.integrated_info);
118 static void firmware_parser_destroy(struct dc_bios **dcb)
120 struct bios_parser *bp = BP_FROM_DCB(*dcb);
133 static void get_atom_data_table_revision(
134 struct atom_common_table_header *atom_data_tbl,
135 struct atom_data_revision *tbl_revision)
140 /* initialize the revision to 0 which is invalid revision */
141 tbl_revision->major = 0;
142 tbl_revision->minor = 0;
147 tbl_revision->major =
148 (uint32_t) atom_data_tbl->format_revision & 0x3f;
149 tbl_revision->minor =
150 (uint32_t) atom_data_tbl->content_revision & 0x3f;
153 /* BIOS oject table displaypath is per connector.
154 * There is extra path not for connector. BIOS fill its encoderid as 0
156 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
158 struct bios_parser *bp = BP_FROM_DCB(dcb);
159 unsigned int count = 0;
162 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
163 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
169 static struct graphics_object_id bios_parser_get_encoder_id(
173 struct bios_parser *bp = BP_FROM_DCB(dcb);
174 struct graphics_object_id object_id = dal_graphics_object_id_init(
175 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
177 if (bp->object_info_tbl.v1_4->number_of_path > i)
178 object_id = object_id_from_bios_object_id(
179 bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
184 static struct graphics_object_id bios_parser_get_connector_id(
188 struct bios_parser *bp = BP_FROM_DCB(dcb);
189 struct graphics_object_id object_id = dal_graphics_object_id_init(
190 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
191 struct object_info_table *tbl = &bp->object_info_tbl;
192 struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
194 if (v1_4->number_of_path > i) {
195 /* If display_objid is generic object id, the encoderObj
196 * /extencoderobjId should be 0
198 if (v1_4->display_path[i].encoderobjid != 0 &&
199 v1_4->display_path[i].display_objid != 0)
200 object_id = object_id_from_bios_object_id(
201 v1_4->display_path[i].display_objid);
208 /* TODO: GetNumberOfSrc*/
210 static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb,
211 struct graphics_object_id id)
213 /* connector has 1 Dest, encoder has 0 Dest */
215 case OBJECT_TYPE_ENCODER:
217 case OBJECT_TYPE_CONNECTOR:
224 /* removed getSrcObjList, getDestObjList*/
227 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
228 struct graphics_object_id object_id, uint32_t index,
229 struct graphics_object_id *src_object_id)
231 struct bios_parser *bp = BP_FROM_DCB(dcb);
233 enum bp_result bp_result = BP_RESULT_BADINPUT;
234 struct graphics_object_id obj_id = {0};
235 struct object_info_table *tbl = &bp->object_info_tbl;
240 switch (object_id.type) {
241 /* Encoder's Source is GPU. BIOS does not provide GPU, since all
242 * displaypaths point to same GPU (0x1100). Hardcode GPU object type
244 case OBJECT_TYPE_ENCODER:
245 /* TODO: since num of src must be less than 2.
246 * If found in for loop, should break.
247 * DAL2 implementation may be changed too
249 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
250 obj_id = object_id_from_bios_object_id(
251 tbl->v1_4->display_path[i].encoderobjid);
252 if (object_id.type == obj_id.type &&
253 object_id.id == obj_id.id &&
257 object_id_from_bios_object_id(0x1100);
261 bp_result = BP_RESULT_OK;
263 case OBJECT_TYPE_CONNECTOR:
264 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
265 obj_id = object_id_from_bios_object_id(
266 tbl->v1_4->display_path[i].display_objid);
268 if (object_id.type == obj_id.type &&
269 object_id.id == obj_id.id &&
270 object_id.enum_id == obj_id.enum_id) {
272 object_id_from_bios_object_id(
273 tbl->v1_4->display_path[i].encoderobjid);
277 bp_result = BP_RESULT_OK;
286 static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb,
287 struct graphics_object_id object_id, uint32_t index,
288 struct graphics_object_id *dest_object_id)
290 struct bios_parser *bp = BP_FROM_DCB(dcb);
292 enum bp_result bp_result = BP_RESULT_BADINPUT;
293 struct graphics_object_id obj_id = {0};
294 struct object_info_table *tbl = &bp->object_info_tbl;
297 return BP_RESULT_BADINPUT;
299 switch (object_id.type) {
300 case OBJECT_TYPE_ENCODER:
301 /* TODO: since num of src must be less than 2.
302 * If found in for loop, should break.
303 * DAL2 implementation may be changed too
305 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
306 obj_id = object_id_from_bios_object_id(
307 tbl->v1_4->display_path[i].encoderobjid);
308 if (object_id.type == obj_id.type &&
309 object_id.id == obj_id.id &&
313 object_id_from_bios_object_id(
314 tbl->v1_4->display_path[i].display_objid);
318 bp_result = BP_RESULT_OK;
328 /* from graphics_object_id, find display path which includes the object_id */
329 static struct atom_display_object_path_v2 *get_bios_object(
330 struct bios_parser *bp,
331 struct graphics_object_id id)
334 struct graphics_object_id obj_id = {0};
337 case OBJECT_TYPE_ENCODER:
338 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
339 obj_id = object_id_from_bios_object_id(
340 bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
341 if (id.type == obj_id.type &&
342 id.id == obj_id.id &&
343 id.enum_id == obj_id.enum_id)
345 &bp->object_info_tbl.v1_4->display_path[i];
347 case OBJECT_TYPE_CONNECTOR:
348 case OBJECT_TYPE_GENERIC:
349 /* Both Generic and Connector Object ID
350 * will be stored on display_objid
352 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
353 obj_id = object_id_from_bios_object_id(
354 bp->object_info_tbl.v1_4->display_path[i].display_objid
356 if (id.type == obj_id.type &&
357 id.id == obj_id.id &&
358 id.enum_id == obj_id.enum_id)
360 &bp->object_info_tbl.v1_4->display_path[i];
367 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
368 struct graphics_object_id id,
369 struct graphics_object_i2c_info *info)
372 struct atom_display_object_path_v2 *object;
373 struct atom_common_record_header *header;
374 struct atom_i2c_record *record;
375 struct bios_parser *bp = BP_FROM_DCB(dcb);
378 return BP_RESULT_BADINPUT;
380 object = get_bios_object(bp, id);
383 return BP_RESULT_BADINPUT;
385 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
388 header = GET_IMAGE(struct atom_common_record_header, offset);
391 return BP_RESULT_BADBIOSTABLE;
393 if (header->record_type == LAST_RECORD_TYPE ||
394 !header->record_size)
397 if (header->record_type == ATOM_I2C_RECORD_TYPE
398 && sizeof(struct atom_i2c_record) <=
399 header->record_size) {
400 /* get the I2C info */
401 record = (struct atom_i2c_record *) header;
403 if (get_gpio_i2c_info(bp, record, info) ==
408 offset += header->record_size;
411 return BP_RESULT_NORECORD;
414 static enum bp_result get_gpio_i2c_info(
415 struct bios_parser *bp,
416 struct atom_i2c_record *record,
417 struct graphics_object_i2c_info *info)
419 struct atom_gpio_pin_lut_v2_1 *header;
421 unsigned int table_index = 0;
424 return BP_RESULT_BADINPUT;
426 /* get the GPIO_I2C info */
427 if (!DATA_TABLES(gpio_pin_lut))
428 return BP_RESULT_BADBIOSTABLE;
430 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
431 DATA_TABLES(gpio_pin_lut));
433 return BP_RESULT_BADBIOSTABLE;
435 if (sizeof(struct atom_common_table_header) +
436 sizeof(struct atom_gpio_pin_assignment) >
437 le16_to_cpu(header->table_header.structuresize))
438 return BP_RESULT_BADBIOSTABLE;
440 /* TODO: is version change? */
441 if (header->table_header.content_revision != 1)
442 return BP_RESULT_UNSUPPORTED;
445 count = (le16_to_cpu(header->table_header.structuresize)
446 - sizeof(struct atom_common_table_header))
447 / sizeof(struct atom_gpio_pin_assignment);
449 table_index = record->i2c_id & I2C_HW_LANE_MUX;
451 if (count < table_index) {
452 bool find_valid = false;
454 for (table_index = 0; table_index < count; table_index++) {
455 if (((record->i2c_id & I2C_HW_CAP) == (
456 header->gpio_pin[table_index].gpio_id &
458 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
459 (header->gpio_pin[table_index].gpio_id &
460 I2C_HW_ENGINE_ID_MASK)) &&
461 ((record->i2c_id & I2C_HW_LANE_MUX) ==
462 (header->gpio_pin[table_index].gpio_id &
469 /* If we don't find the entry that we are looking for then
470 * we will return BP_Result_BadBiosTable.
472 if (find_valid == false)
473 return BP_RESULT_BADBIOSTABLE;
476 /* get the GPIO_I2C_INFO */
477 info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
478 info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
479 info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
480 info->i2c_slave_address = record->i2c_slave_addr;
482 /* TODO: check how to get register offset for en, Y, etc. */
483 info->gpio_info.clk_a_register_index =
485 header->gpio_pin[table_index].data_a_reg_index);
486 info->gpio_info.clk_a_shift =
487 header->gpio_pin[table_index].gpio_bitshift;
492 static enum bp_result get_voltage_ddc_info_v4(
495 struct atom_common_table_header *header,
498 enum bp_result result = BP_RESULT_NORECORD;
499 struct atom_voltage_objects_info_v4_1 *info =
500 (struct atom_voltage_objects_info_v4_1 *) address;
502 uint8_t *voltage_current_object =
503 (uint8_t *) (&(info->voltage_object[0]));
505 while ((address + le16_to_cpu(header->structuresize)) >
506 voltage_current_object) {
507 struct atom_i2c_voltage_object_v4 *object =
508 (struct atom_i2c_voltage_object_v4 *)
509 voltage_current_object;
511 if (object->header.voltage_mode ==
512 ATOM_INIT_VOLTAGE_REGULATOR) {
513 if (object->header.voltage_type == index) {
514 *i2c_line = object->i2c_id ^ 0x90;
515 result = BP_RESULT_OK;
520 voltage_current_object +=
521 le16_to_cpu(object->header.object_size);
526 static enum bp_result bios_parser_get_thermal_ddc_info(
528 uint32_t i2c_channel_id,
529 struct graphics_object_i2c_info *info)
531 struct bios_parser *bp = BP_FROM_DCB(dcb);
532 struct i2c_id_config_access *config;
533 struct atom_i2c_record record;
536 return BP_RESULT_BADINPUT;
538 config = (struct i2c_id_config_access *) &i2c_channel_id;
540 record.i2c_id = config->bfHW_Capable;
541 record.i2c_id |= config->bfI2C_LineMux;
542 record.i2c_id |= config->bfHW_EngineID;
544 return get_gpio_i2c_info(bp, &record, info);
547 static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios *dcb,
549 struct graphics_object_i2c_info *info)
551 uint8_t i2c_line = 0;
552 enum bp_result result = BP_RESULT_NORECORD;
553 uint8_t *voltage_info_address;
554 struct atom_common_table_header *header;
555 struct atom_data_revision revision = {0};
556 struct bios_parser *bp = BP_FROM_DCB(dcb);
558 if (!DATA_TABLES(voltageobject_info))
561 voltage_info_address = bios_get_image(&bp->base,
562 DATA_TABLES(voltageobject_info),
563 sizeof(struct atom_common_table_header));
565 header = (struct atom_common_table_header *) voltage_info_address;
567 get_atom_data_table_revision(header, &revision);
569 switch (revision.major) {
571 if (revision.minor != 1)
573 result = get_voltage_ddc_info_v4(&i2c_line, index, header,
574 voltage_info_address);
578 if (result == BP_RESULT_OK)
579 result = bios_parser_get_thermal_ddc_info(dcb,
585 static enum bp_result bios_parser_get_hpd_info(
587 struct graphics_object_id id,
588 struct graphics_object_hpd_info *info)
590 struct bios_parser *bp = BP_FROM_DCB(dcb);
591 struct atom_display_object_path_v2 *object;
592 struct atom_hpd_int_record *record = NULL;
595 return BP_RESULT_BADINPUT;
597 object = get_bios_object(bp, id);
600 return BP_RESULT_BADINPUT;
602 record = get_hpd_record(bp, object);
604 if (record != NULL) {
605 info->hpd_int_gpio_uid = record->pin_id;
606 info->hpd_active = record->plugin_pin_state;
610 return BP_RESULT_NORECORD;
613 static struct atom_hpd_int_record *get_hpd_record(
614 struct bios_parser *bp,
615 struct atom_display_object_path_v2 *object)
617 struct atom_common_record_header *header;
621 BREAK_TO_DEBUGGER(); /* Invalid object */
625 offset = le16_to_cpu(object->disp_recordoffset)
626 + bp->object_info_tbl_offset;
629 header = GET_IMAGE(struct atom_common_record_header, offset);
634 if (header->record_type == LAST_RECORD_TYPE ||
635 !header->record_size)
638 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
639 && sizeof(struct atom_hpd_int_record) <=
641 return (struct atom_hpd_int_record *) header;
643 offset += header->record_size;
650 * bios_parser_get_gpio_pin_info
651 * Get GpioPin information of input gpio id
653 * @param gpio_id, GPIO ID
654 * @param info, GpioPin information structure
655 * @return Bios parser result code
657 * to get the GPIO PIN INFO, we need:
658 * 1. get the GPIO_ID from other object table, see GetHPDInfo()
659 * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
660 * to get the registerA offset/mask
662 static enum bp_result bios_parser_get_gpio_pin_info(
665 struct gpio_pin_info *info)
667 struct bios_parser *bp = BP_FROM_DCB(dcb);
668 struct atom_gpio_pin_lut_v2_1 *header;
672 if (!DATA_TABLES(gpio_pin_lut))
673 return BP_RESULT_BADBIOSTABLE;
675 header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
676 DATA_TABLES(gpio_pin_lut));
678 return BP_RESULT_BADBIOSTABLE;
680 if (sizeof(struct atom_common_table_header) +
681 sizeof(struct atom_gpio_pin_assignment)
682 > le16_to_cpu(header->table_header.structuresize))
683 return BP_RESULT_BADBIOSTABLE;
685 if (header->table_header.content_revision != 1)
686 return BP_RESULT_UNSUPPORTED;
688 /* Temporary hard code gpio pin info */
689 #if defined(FOR_SIMNOW_BOOT)
691 struct atom_gpio_pin_assignment gpio_pin[8] = {
692 {0x5db5, 0, 0, 1, 0},
693 {0x5db5, 8, 8, 2, 0},
694 {0x5db5, 0x10, 0x10, 3, 0},
695 {0x5db5, 0x18, 0x14, 4, 0},
696 {0x5db5, 0x1A, 0x18, 5, 0},
697 {0x5db5, 0x1C, 0x1C, 6, 0},
701 memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
704 count = (le16_to_cpu(header->table_header.structuresize)
705 - sizeof(struct atom_common_table_header))
706 / sizeof(struct atom_gpio_pin_assignment);
708 for (i = 0; i < count; ++i) {
709 if (header->gpio_pin[i].gpio_id != gpio_id)
713 (uint32_t) le16_to_cpu(
714 header->gpio_pin[i].data_a_reg_index);
715 info->offset_y = info->offset + 2;
716 info->offset_en = info->offset + 1;
717 info->offset_mask = info->offset - 1;
719 info->mask = (uint32_t) (1 <<
720 header->gpio_pin[i].gpio_bitshift);
721 info->mask_y = info->mask + 2;
722 info->mask_en = info->mask + 1;
723 info->mask_mask = info->mask - 1;
728 return BP_RESULT_NORECORD;
731 static struct device_id device_type_from_device_id(uint16_t device_id)
734 struct device_id result_device_id;
736 result_device_id.raw_device_tag = device_id;
739 case ATOM_DISPLAY_LCD1_SUPPORT:
740 result_device_id.device_type = DEVICE_TYPE_LCD;
741 result_device_id.enum_id = 1;
744 case ATOM_DISPLAY_DFP1_SUPPORT:
745 result_device_id.device_type = DEVICE_TYPE_DFP;
746 result_device_id.enum_id = 1;
749 case ATOM_DISPLAY_DFP2_SUPPORT:
750 result_device_id.device_type = DEVICE_TYPE_DFP;
751 result_device_id.enum_id = 2;
754 case ATOM_DISPLAY_DFP3_SUPPORT:
755 result_device_id.device_type = DEVICE_TYPE_DFP;
756 result_device_id.enum_id = 3;
759 case ATOM_DISPLAY_DFP4_SUPPORT:
760 result_device_id.device_type = DEVICE_TYPE_DFP;
761 result_device_id.enum_id = 4;
764 case ATOM_DISPLAY_DFP5_SUPPORT:
765 result_device_id.device_type = DEVICE_TYPE_DFP;
766 result_device_id.enum_id = 5;
769 case ATOM_DISPLAY_DFP6_SUPPORT:
770 result_device_id.device_type = DEVICE_TYPE_DFP;
771 result_device_id.enum_id = 6;
775 BREAK_TO_DEBUGGER(); /* Invalid device Id */
776 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
777 result_device_id.enum_id = 0;
779 return result_device_id;
782 static enum bp_result bios_parser_get_device_tag(
784 struct graphics_object_id connector_object_id,
785 uint32_t device_tag_index,
786 struct connector_device_tag_info *info)
788 struct bios_parser *bp = BP_FROM_DCB(dcb);
789 struct atom_display_object_path_v2 *object;
792 return BP_RESULT_BADINPUT;
794 /* getBiosObject will return MXM object */
795 object = get_bios_object(bp, connector_object_id);
798 BREAK_TO_DEBUGGER(); /* Invalid object id */
799 return BP_RESULT_BADINPUT;
802 info->acpi_device = 0; /* BIOS no longer provides this */
803 info->dev_id = device_type_from_device_id(object->device_tag);
808 static enum bp_result get_ss_info_v4_1(
809 struct bios_parser *bp,
812 struct spread_spectrum_info *ss_info)
814 enum bp_result result = BP_RESULT_OK;
815 struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
818 return BP_RESULT_BADINPUT;
820 if (!DATA_TABLES(dce_info))
821 return BP_RESULT_BADBIOSTABLE;
823 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
824 DATA_TABLES(dce_info));
826 return BP_RESULT_BADBIOSTABLE;
828 ss_info->type.STEP_AND_DELAY_INFO = false;
829 ss_info->spread_percentage_divider = 1000;
830 /* BIOS no longer uses target clock. Always enable for now */
831 ss_info->target_clock_range = 0xffffffff;
834 case AS_SIGNAL_TYPE_DVI:
835 ss_info->spread_spectrum_percentage =
836 disp_cntl_tbl->dvi_ss_percentage;
837 ss_info->spread_spectrum_range =
838 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
839 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
840 ss_info->type.CENTER_MODE = true;
842 case AS_SIGNAL_TYPE_HDMI:
843 ss_info->spread_spectrum_percentage =
844 disp_cntl_tbl->hdmi_ss_percentage;
845 ss_info->spread_spectrum_range =
846 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
847 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
848 ss_info->type.CENTER_MODE = true;
850 /* TODO LVDS not support anymore? */
851 case AS_SIGNAL_TYPE_DISPLAY_PORT:
852 ss_info->spread_spectrum_percentage =
853 disp_cntl_tbl->dp_ss_percentage;
854 ss_info->spread_spectrum_range =
855 disp_cntl_tbl->dp_ss_rate_10hz * 10;
856 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
857 ss_info->type.CENTER_MODE = true;
859 case AS_SIGNAL_TYPE_GPU_PLL:
860 /* atom_firmware: DAL only get data from dce_info table.
861 * if data within smu_info is needed for DAL, VBIOS should
862 * copy it into dce_info
864 result = BP_RESULT_UNSUPPORTED;
867 result = BP_RESULT_UNSUPPORTED;
873 static enum bp_result get_ss_info_v4_2(
874 struct bios_parser *bp,
877 struct spread_spectrum_info *ss_info)
879 enum bp_result result = BP_RESULT_OK;
880 struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
881 struct atom_smu_info_v3_1 *smu_info = NULL;
884 return BP_RESULT_BADINPUT;
886 if (!DATA_TABLES(dce_info))
887 return BP_RESULT_BADBIOSTABLE;
889 if (!DATA_TABLES(smu_info))
890 return BP_RESULT_BADBIOSTABLE;
892 disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
893 DATA_TABLES(dce_info));
895 return BP_RESULT_BADBIOSTABLE;
897 smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
899 return BP_RESULT_BADBIOSTABLE;
901 ss_info->type.STEP_AND_DELAY_INFO = false;
902 ss_info->spread_percentage_divider = 1000;
903 /* BIOS no longer uses target clock. Always enable for now */
904 ss_info->target_clock_range = 0xffffffff;
907 case AS_SIGNAL_TYPE_DVI:
908 ss_info->spread_spectrum_percentage =
909 disp_cntl_tbl->dvi_ss_percentage;
910 ss_info->spread_spectrum_range =
911 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
912 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
913 ss_info->type.CENTER_MODE = true;
915 case AS_SIGNAL_TYPE_HDMI:
916 ss_info->spread_spectrum_percentage =
917 disp_cntl_tbl->hdmi_ss_percentage;
918 ss_info->spread_spectrum_range =
919 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
920 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
921 ss_info->type.CENTER_MODE = true;
923 /* TODO LVDS not support anymore? */
924 case AS_SIGNAL_TYPE_DISPLAY_PORT:
925 ss_info->spread_spectrum_percentage =
926 smu_info->gpuclk_ss_percentage;
927 ss_info->spread_spectrum_range =
928 smu_info->gpuclk_ss_rate_10hz * 10;
929 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
930 ss_info->type.CENTER_MODE = true;
932 case AS_SIGNAL_TYPE_GPU_PLL:
933 /* atom_firmware: DAL only get data from dce_info table.
934 * if data within smu_info is needed for DAL, VBIOS should
935 * copy it into dce_info
937 result = BP_RESULT_UNSUPPORTED;
940 result = BP_RESULT_UNSUPPORTED;
947 * bios_parser_get_spread_spectrum_info
948 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
949 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
950 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
952 * there is only one entry for each signal /ss id. However, there is
953 * no planning of supporting multiple spread Sprectum entry for EverGreen
955 * @param [in] signal, ASSignalType to be converted to info index
956 * @param [in] index, number of entries that match the converted info index
957 * @param [out] ss_info, sprectrum information structure,
958 * @return Bios parser result code
960 static enum bp_result bios_parser_get_spread_spectrum_info(
962 enum as_signal_type signal,
964 struct spread_spectrum_info *ss_info)
966 struct bios_parser *bp = BP_FROM_DCB(dcb);
967 enum bp_result result = BP_RESULT_UNSUPPORTED;
968 struct atom_common_table_header *header;
969 struct atom_data_revision tbl_revision;
971 if (!ss_info) /* check for bad input */
972 return BP_RESULT_BADINPUT;
974 if (!DATA_TABLES(dce_info))
975 return BP_RESULT_UNSUPPORTED;
977 header = GET_IMAGE(struct atom_common_table_header,
978 DATA_TABLES(dce_info));
979 get_atom_data_table_revision(header, &tbl_revision);
981 switch (tbl_revision.major) {
983 switch (tbl_revision.minor) {
985 return get_ss_info_v4_1(bp, signal, index, ss_info);
987 return get_ss_info_v4_2(bp, signal, index, ss_info);
995 /* there can not be more then one entry for SS Info table */
999 static enum bp_result get_embedded_panel_info_v2_1(
1000 struct bios_parser *bp,
1001 struct embedded_panel_info *info)
1003 struct lcd_info_v2_1 *lvds;
1006 return BP_RESULT_BADINPUT;
1008 if (!DATA_TABLES(lcd_info))
1009 return BP_RESULT_UNSUPPORTED;
1011 lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
1014 return BP_RESULT_BADBIOSTABLE;
1016 /* TODO: previous vv1_3, should v2_1 */
1017 if (!((lvds->table_header.format_revision == 2)
1018 && (lvds->table_header.content_revision >= 1)))
1019 return BP_RESULT_UNSUPPORTED;
1021 memset(info, 0, sizeof(struct embedded_panel_info));
1023 /* We need to convert from 10KHz units into KHz units */
1024 info->lcd_timing.pixel_clk =
1025 le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
1026 /* usHActive does not include borders, according to VBIOS team */
1027 info->lcd_timing.horizontal_addressable =
1028 le16_to_cpu(lvds->lcd_timing.h_active);
1029 /* usHBlanking_Time includes borders, so we should really be
1030 * subtractingborders duing this translation, but LVDS generally
1031 * doesn't have borders, so we should be okay leaving this as is for
1032 * now. May need to revisit if we ever have LVDS with borders
1034 info->lcd_timing.horizontal_blanking_time =
1035 le16_to_cpu(lvds->lcd_timing.h_blanking_time);
1036 /* usVActive does not include borders, according to VBIOS team*/
1037 info->lcd_timing.vertical_addressable =
1038 le16_to_cpu(lvds->lcd_timing.v_active);
1039 /* usVBlanking_Time includes borders, so we should really be
1040 * subtracting borders duing this translation, but LVDS generally
1041 * doesn't have borders, so we should be okay leaving this as is for
1042 * now. May need to revisit if we ever have LVDS with borders
1044 info->lcd_timing.vertical_blanking_time =
1045 le16_to_cpu(lvds->lcd_timing.v_blanking_time);
1046 info->lcd_timing.horizontal_sync_offset =
1047 le16_to_cpu(lvds->lcd_timing.h_sync_offset);
1048 info->lcd_timing.horizontal_sync_width =
1049 le16_to_cpu(lvds->lcd_timing.h_sync_width);
1050 info->lcd_timing.vertical_sync_offset =
1051 le16_to_cpu(lvds->lcd_timing.v_sync_offset);
1052 info->lcd_timing.vertical_sync_width =
1053 le16_to_cpu(lvds->lcd_timing.v_syncwidth);
1054 info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
1055 info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
1057 /* not provided by VBIOS */
1058 info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
1060 info->lcd_timing.misc_info.H_SYNC_POLARITY =
1062 (lvds->lcd_timing.miscinfo & ATOM_HSYNC_POLARITY);
1063 info->lcd_timing.misc_info.V_SYNC_POLARITY =
1065 (lvds->lcd_timing.miscinfo & ATOM_VSYNC_POLARITY);
1067 /* not provided by VBIOS */
1068 info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
1070 info->lcd_timing.misc_info.H_REPLICATION_BY2 =
1071 !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
1072 info->lcd_timing.misc_info.V_REPLICATION_BY2 =
1073 !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
1074 info->lcd_timing.misc_info.COMPOSITE_SYNC =
1075 !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
1076 info->lcd_timing.misc_info.INTERLACE =
1077 !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
1079 /* not provided by VBIOS*/
1080 info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
1081 /* not provided by VBIOS*/
1084 info->realtek_eDPToLVDS =
1085 !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1087 return BP_RESULT_OK;
1090 static enum bp_result bios_parser_get_embedded_panel_info(
1091 struct dc_bios *dcb,
1092 struct embedded_panel_info *info)
1094 struct bios_parser *bp = BP_FROM_DCB(dcb);
1095 struct atom_common_table_header *header;
1096 struct atom_data_revision tbl_revision;
1098 if (!DATA_TABLES(lcd_info))
1099 return BP_RESULT_FAILURE;
1101 header = GET_IMAGE(struct atom_common_table_header,
1102 DATA_TABLES(lcd_info));
1105 return BP_RESULT_BADBIOSTABLE;
1107 get_atom_data_table_revision(header, &tbl_revision);
1110 switch (tbl_revision.major) {
1112 switch (tbl_revision.minor) {
1114 return get_embedded_panel_info_v2_1(bp, info);
1122 return BP_RESULT_FAILURE;
1125 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
1127 enum dal_device_type device_type = device_id.device_type;
1128 uint32_t enum_id = device_id.enum_id;
1130 switch (device_type) {
1131 case DEVICE_TYPE_LCD:
1134 return ATOM_DISPLAY_LCD1_SUPPORT;
1139 case DEVICE_TYPE_DFP:
1142 return ATOM_DISPLAY_DFP1_SUPPORT;
1144 return ATOM_DISPLAY_DFP2_SUPPORT;
1146 return ATOM_DISPLAY_DFP3_SUPPORT;
1148 return ATOM_DISPLAY_DFP4_SUPPORT;
1150 return ATOM_DISPLAY_DFP5_SUPPORT;
1152 return ATOM_DISPLAY_DFP6_SUPPORT;
1161 /* Unidentified device ID, return empty support mask. */
1165 static bool bios_parser_is_device_id_supported(
1166 struct dc_bios *dcb,
1167 struct device_id id)
1169 struct bios_parser *bp = BP_FROM_DCB(dcb);
1171 uint32_t mask = get_support_mask_for_device_id(id);
1173 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
1177 static void bios_parser_post_init(
1178 struct dc_bios *dcb)
1180 /* TODO for OPM module. Need implement later */
1183 static uint32_t bios_parser_get_ss_entry_number(
1184 struct dc_bios *dcb,
1185 enum as_signal_type signal)
1187 /* TODO: DAL2 atomfirmware implementation does not need this.
1188 * why DAL3 need this?
1193 static enum bp_result bios_parser_transmitter_control(
1194 struct dc_bios *dcb,
1195 struct bp_transmitter_control *cntl)
1197 struct bios_parser *bp = BP_FROM_DCB(dcb);
1199 if (!bp->cmd_tbl.transmitter_control)
1200 return BP_RESULT_FAILURE;
1202 return bp->cmd_tbl.transmitter_control(bp, cntl);
1205 static enum bp_result bios_parser_encoder_control(
1206 struct dc_bios *dcb,
1207 struct bp_encoder_control *cntl)
1209 struct bios_parser *bp = BP_FROM_DCB(dcb);
1211 if (!bp->cmd_tbl.dig_encoder_control)
1212 return BP_RESULT_FAILURE;
1214 return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1217 static enum bp_result bios_parser_set_pixel_clock(
1218 struct dc_bios *dcb,
1219 struct bp_pixel_clock_parameters *bp_params)
1221 struct bios_parser *bp = BP_FROM_DCB(dcb);
1223 if (!bp->cmd_tbl.set_pixel_clock)
1224 return BP_RESULT_FAILURE;
1226 return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1229 static enum bp_result bios_parser_set_dce_clock(
1230 struct dc_bios *dcb,
1231 struct bp_set_dce_clock_parameters *bp_params)
1233 struct bios_parser *bp = BP_FROM_DCB(dcb);
1235 if (!bp->cmd_tbl.set_dce_clock)
1236 return BP_RESULT_FAILURE;
1238 return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1241 static unsigned int bios_parser_get_smu_clock_info(
1242 struct dc_bios *dcb)
1244 struct bios_parser *bp = BP_FROM_DCB(dcb);
1246 if (!bp->cmd_tbl.get_smu_clock_info)
1247 return BP_RESULT_FAILURE;
1249 return bp->cmd_tbl.get_smu_clock_info(bp, 0);
1252 static enum bp_result bios_parser_program_crtc_timing(
1253 struct dc_bios *dcb,
1254 struct bp_hw_crtc_timing_parameters *bp_params)
1256 struct bios_parser *bp = BP_FROM_DCB(dcb);
1258 if (!bp->cmd_tbl.set_crtc_timing)
1259 return BP_RESULT_FAILURE;
1261 return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1264 static enum bp_result bios_parser_enable_crtc(
1265 struct dc_bios *dcb,
1266 enum controller_id id,
1269 struct bios_parser *bp = BP_FROM_DCB(dcb);
1271 if (!bp->cmd_tbl.enable_crtc)
1272 return BP_RESULT_FAILURE;
1274 return bp->cmd_tbl.enable_crtc(bp, id, enable);
1277 static enum bp_result bios_parser_crtc_source_select(
1278 struct dc_bios *dcb,
1279 struct bp_crtc_source_select *bp_params)
1281 struct bios_parser *bp = BP_FROM_DCB(dcb);
1283 if (!bp->cmd_tbl.select_crtc_source)
1284 return BP_RESULT_FAILURE;
1286 return bp->cmd_tbl.select_crtc_source(bp, bp_params);
1289 static enum bp_result bios_parser_enable_disp_power_gating(
1290 struct dc_bios *dcb,
1291 enum controller_id controller_id,
1292 enum bp_pipe_control_action action)
1294 struct bios_parser *bp = BP_FROM_DCB(dcb);
1296 if (!bp->cmd_tbl.enable_disp_power_gating)
1297 return BP_RESULT_FAILURE;
1299 return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1303 static bool bios_parser_is_accelerated_mode(
1304 struct dc_bios *dcb)
1306 return bios_is_accelerated_mode(dcb);
1309 static uint32_t bios_parser_get_vga_enabled_displays(
1310 struct dc_bios *bios)
1312 return bios_get_vga_enabled_displays(bios);
1317 * bios_parser_set_scratch_critical_state
1320 * update critical state bit in VBIOS scratch register
1323 * bool - to set or reset state
1325 static void bios_parser_set_scratch_critical_state(
1326 struct dc_bios *dcb,
1329 bios_set_scratch_critical_state(dcb, state);
1332 static enum bp_result bios_parser_get_firmware_info(
1333 struct dc_bios *dcb,
1334 struct dc_firmware_info *info)
1336 struct bios_parser *bp = BP_FROM_DCB(dcb);
1337 enum bp_result result = BP_RESULT_BADBIOSTABLE;
1338 struct atom_common_table_header *header;
1340 struct atom_data_revision revision;
1342 if (info && DATA_TABLES(firmwareinfo)) {
1343 header = GET_IMAGE(struct atom_common_table_header,
1344 DATA_TABLES(firmwareinfo));
1345 get_atom_data_table_revision(header, &revision);
1346 switch (revision.major) {
1348 switch (revision.minor) {
1350 result = get_firmware_info_v3_1(bp, info);
1353 result = get_firmware_info_v3_2(bp, info);
1356 result = get_firmware_info_v3_2(bp, info);
1370 static enum bp_result get_firmware_info_v3_1(
1371 struct bios_parser *bp,
1372 struct dc_firmware_info *info)
1374 struct atom_firmware_info_v3_1 *firmware_info;
1375 struct atom_display_controller_info_v4_1 *dce_info = NULL;
1378 return BP_RESULT_BADINPUT;
1380 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1381 DATA_TABLES(firmwareinfo));
1383 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1384 DATA_TABLES(dce_info));
1386 if (!firmware_info || !dce_info)
1387 return BP_RESULT_BADBIOSTABLE;
1389 memset(info, 0, sizeof(*info));
1391 /* Pixel clock pll information. */
1392 /* We need to convert from 10KHz units into KHz units */
1393 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1394 info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1396 /* 27MHz for Vega10: */
1397 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1399 /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1400 if (info->pll_info.crystal_frequency == 0)
1401 info->pll_info.crystal_frequency = 27000;
1402 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1403 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
1404 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1406 /* Get GPU PLL VCO Clock */
1408 if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1409 /* VBIOS gives in 10KHz */
1410 info->smu_gpu_pll_output_freq =
1411 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1414 return BP_RESULT_OK;
1417 static enum bp_result get_firmware_info_v3_2(
1418 struct bios_parser *bp,
1419 struct dc_firmware_info *info)
1421 struct atom_firmware_info_v3_2 *firmware_info;
1422 struct atom_display_controller_info_v4_1 *dce_info = NULL;
1423 struct atom_common_table_header *header;
1424 struct atom_data_revision revision;
1425 struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1426 struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1429 return BP_RESULT_BADINPUT;
1431 firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1432 DATA_TABLES(firmwareinfo));
1434 dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1435 DATA_TABLES(dce_info));
1437 if (!firmware_info || !dce_info)
1438 return BP_RESULT_BADBIOSTABLE;
1440 memset(info, 0, sizeof(*info));
1442 header = GET_IMAGE(struct atom_common_table_header,
1443 DATA_TABLES(smu_info));
1444 get_atom_data_table_revision(header, &revision);
1446 if (revision.minor == 2) {
1448 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1449 DATA_TABLES(smu_info));
1452 return BP_RESULT_BADBIOSTABLE;
1454 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1455 } else if (revision.minor == 3) {
1457 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1458 DATA_TABLES(smu_info));
1461 return BP_RESULT_BADBIOSTABLE;
1463 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1466 // We need to convert from 10KHz units into KHz units.
1467 info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1469 /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1470 info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1471 /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1472 if (info->pll_info.crystal_frequency == 0) {
1473 if (revision.minor == 2)
1474 info->pll_info.crystal_frequency = 27000;
1475 else if (revision.minor == 3)
1476 info->pll_info.crystal_frequency = 100000;
1478 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1479 info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
1480 info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1482 /* Get GPU PLL VCO Clock */
1483 if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1484 if (revision.minor == 2)
1485 info->smu_gpu_pll_output_freq =
1486 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1487 else if (revision.minor == 3)
1488 info->smu_gpu_pll_output_freq =
1489 bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1492 return BP_RESULT_OK;
1495 static enum bp_result bios_parser_get_encoder_cap_info(
1496 struct dc_bios *dcb,
1497 struct graphics_object_id object_id,
1498 struct bp_encoder_cap_info *info)
1500 struct bios_parser *bp = BP_FROM_DCB(dcb);
1501 struct atom_display_object_path_v2 *object;
1502 struct atom_encoder_caps_record *record = NULL;
1505 return BP_RESULT_BADINPUT;
1507 object = get_bios_object(bp, object_id);
1510 return BP_RESULT_BADINPUT;
1512 record = get_encoder_cap_record(bp, object);
1514 return BP_RESULT_NORECORD;
1516 info->DP_HBR2_CAP = (record->encodercaps &
1517 ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
1518 info->DP_HBR2_EN = (record->encodercaps &
1519 ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
1520 info->DP_HBR3_EN = (record->encodercaps &
1521 ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
1522 info->HDMI_6GB_EN = (record->encodercaps &
1523 ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
1525 return BP_RESULT_OK;
1529 static struct atom_encoder_caps_record *get_encoder_cap_record(
1530 struct bios_parser *bp,
1531 struct atom_display_object_path_v2 *object)
1533 struct atom_common_record_header *header;
1537 BREAK_TO_DEBUGGER(); /* Invalid object */
1541 offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
1544 header = GET_IMAGE(struct atom_common_record_header, offset);
1549 offset += header->record_size;
1551 if (header->record_type == LAST_RECORD_TYPE ||
1552 !header->record_size)
1555 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
1558 if (sizeof(struct atom_encoder_caps_record) <=
1559 header->record_size)
1560 return (struct atom_encoder_caps_record *)header;
1567 * get_integrated_info_v11
1570 * Get V8 integrated BIOS information
1573 * bios_parser *bp - [in]BIOS parser handler to get master data table
1574 * integrated_info *info - [out] store and output integrated info
1577 * enum bp_result - BP_RESULT_OK if information is available,
1578 * BP_RESULT_BADBIOSTABLE otherwise.
1580 static enum bp_result get_integrated_info_v11(
1581 struct bios_parser *bp,
1582 struct integrated_info *info)
1584 struct atom_integrated_system_info_v1_11 *info_v11;
1587 info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
1588 DATA_TABLES(integratedsysteminfo));
1590 if (info_v11 == NULL)
1591 return BP_RESULT_BADBIOSTABLE;
1593 info->gpu_cap_info =
1594 le32_to_cpu(info_v11->gpucapinfo);
1596 * system_config: Bit[0] = 0 : PCIE power gating disabled
1597 * = 1 : PCIE power gating enabled
1598 * Bit[1] = 0 : DDR-PLL shut down disabled
1599 * = 1 : DDR-PLL shut down enabled
1600 * Bit[2] = 0 : DDR-PLL power down disabled
1601 * = 1 : DDR-PLL power down enabled
1603 info->system_config = le32_to_cpu(info_v11->system_config);
1604 info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
1605 info->memory_type = info_v11->memorytype;
1606 info->ma_channel_number = info_v11->umachannelnumber;
1607 info->lvds_ss_percentage =
1608 le16_to_cpu(info_v11->lvds_ss_percentage);
1609 info->lvds_sspread_rate_in_10hz =
1610 le16_to_cpu(info_v11->lvds_ss_rate_10hz);
1611 info->hdmi_ss_percentage =
1612 le16_to_cpu(info_v11->hdmi_ss_percentage);
1613 info->hdmi_sspread_rate_in_10hz =
1614 le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
1615 info->dvi_ss_percentage =
1616 le16_to_cpu(info_v11->dvi_ss_percentage);
1617 info->dvi_sspread_rate_in_10_hz =
1618 le16_to_cpu(info_v11->dvi_ss_rate_10hz);
1619 info->lvds_misc = info_v11->lvds_misc;
1620 for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
1621 info->ext_disp_conn_info.gu_id[i] =
1622 info_v11->extdispconninfo.guid[i];
1625 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
1626 info->ext_disp_conn_info.path[i].device_connector_id =
1627 object_id_from_bios_object_id(
1628 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
1630 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
1631 object_id_from_bios_object_id(
1633 info_v11->extdispconninfo.path[i].ext_encoder_objid));
1635 info->ext_disp_conn_info.path[i].device_tag =
1637 info_v11->extdispconninfo.path[i].device_tag);
1638 info->ext_disp_conn_info.path[i].device_acpi_enum =
1640 info_v11->extdispconninfo.path[i].device_acpi_enum);
1641 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
1642 info_v11->extdispconninfo.path[i].auxddclut_index;
1643 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
1644 info_v11->extdispconninfo.path[i].hpdlut_index;
1645 info->ext_disp_conn_info.path[i].channel_mapping.raw =
1646 info_v11->extdispconninfo.path[i].channelmapping;
1647 info->ext_disp_conn_info.path[i].caps =
1648 le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
1650 info->ext_disp_conn_info.checksum =
1651 info_v11->extdispconninfo.checksum;
1653 info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
1654 info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
1655 for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
1656 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
1657 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1658 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
1659 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1661 info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
1662 for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
1663 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1664 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1665 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1666 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1669 info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
1670 info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
1671 for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
1672 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
1673 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1674 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
1675 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1677 info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
1678 for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
1679 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1680 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1681 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1682 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1685 info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
1686 info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
1687 for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
1688 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
1689 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1690 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
1691 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1693 info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
1694 for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
1695 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1696 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1697 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1698 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1701 info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
1702 info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
1703 for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
1704 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
1705 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1706 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
1707 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1709 info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
1710 for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
1711 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1712 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1713 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1714 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1718 /** TODO - review **/
1720 info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
1722 info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
1723 info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
1725 for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1726 /* Convert [10KHz] into [KHz] */
1727 info->disp_clk_voltage[i].max_supported_clk =
1728 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
1729 ulMaximumSupportedCLK) * 10;
1730 info->disp_clk_voltage[i].voltage_index =
1731 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
1734 info->boot_up_req_display_vector =
1735 le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
1736 info->boot_up_nb_voltage =
1737 le16_to_cpu(info_v11->usBootUpNBVoltage);
1738 info->ext_disp_conn_info_offset =
1739 le16_to_cpu(info_v11->usExtDispConnInfoOffset);
1740 info->gmc_restore_reset_time =
1741 le32_to_cpu(info_v11->ulGMCRestoreResetTime);
1742 info->minimum_n_clk =
1743 le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
1744 for (i = 1; i < 4; ++i)
1745 info->minimum_n_clk =
1746 info->minimum_n_clk <
1747 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
1748 info->minimum_n_clk : le32_to_cpu(
1749 info_v11->ulNbpStateNClkFreq[i]);
1751 info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
1752 info->ddr_dll_power_up_time =
1753 le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
1754 info->ddr_pll_power_up_time =
1755 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
1756 info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
1757 info->max_lvds_pclk_freq_in_single_link =
1758 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1759 info->max_lvds_pclk_freq_in_single_link =
1760 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1761 info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
1762 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
1763 info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
1764 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
1765 info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
1766 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
1767 info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
1768 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
1769 info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
1770 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
1771 info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
1772 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
1773 info->lvds_off_to_on_delay_in_4ms =
1774 info_v11->ucLVDSOffToOnDelay_in4Ms;
1775 info->lvds_bit_depth_control_val =
1776 le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
1778 for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
1779 /* Convert [10KHz] into [KHz] */
1780 info->avail_s_clk[i].supported_s_clk =
1781 le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
1783 info->avail_s_clk[i].voltage_index =
1784 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
1785 info->avail_s_clk[i].voltage_id =
1786 le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
1790 return BP_RESULT_OK;
1795 * construct_integrated_info
1798 * Get integrated BIOS information based on table revision
1801 * bios_parser *bp - [in]BIOS parser handler to get master data table
1802 * integrated_info *info - [out] store and output integrated info
1805 * enum bp_result - BP_RESULT_OK if information is available,
1806 * BP_RESULT_BADBIOSTABLE otherwise.
1808 static enum bp_result construct_integrated_info(
1809 struct bios_parser *bp,
1810 struct integrated_info *info)
1812 enum bp_result result = BP_RESULT_BADBIOSTABLE;
1814 struct atom_common_table_header *header;
1815 struct atom_data_revision revision;
1817 struct clock_voltage_caps temp = {0, 0};
1821 if (info && DATA_TABLES(integratedsysteminfo)) {
1822 header = GET_IMAGE(struct atom_common_table_header,
1823 DATA_TABLES(integratedsysteminfo));
1825 get_atom_data_table_revision(header, &revision);
1827 /* Don't need to check major revision as they are all 1 */
1828 switch (revision.minor) {
1830 result = get_integrated_info_v11(bp, info);
1837 if (result != BP_RESULT_OK)
1840 /* Sort voltage table from low to high*/
1841 for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1842 for (j = i; j > 0; --j) {
1843 if (info->disp_clk_voltage[j].max_supported_clk <
1844 info->disp_clk_voltage[j-1].max_supported_clk
1846 /* swap j and j - 1*/
1847 temp = info->disp_clk_voltage[j-1];
1848 info->disp_clk_voltage[j-1] =
1849 info->disp_clk_voltage[j];
1850 info->disp_clk_voltage[j] = temp;
1858 static struct integrated_info *bios_parser_create_integrated_info(
1859 struct dc_bios *dcb)
1861 struct bios_parser *bp = BP_FROM_DCB(dcb);
1862 struct integrated_info *info = NULL;
1864 info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
1871 if (construct_integrated_info(bp, info) == BP_RESULT_OK)
1879 static enum bp_result update_slot_layout_info(
1880 struct dc_bios *dcb,
1882 struct slot_layout_info *slot_layout_info)
1884 unsigned int record_offset;
1886 struct atom_display_object_path_v2 *object;
1887 struct atom_bracket_layout_record *record;
1888 struct atom_common_record_header *record_header;
1889 enum bp_result result;
1890 struct bios_parser *bp;
1891 struct object_info_table *tbl;
1892 struct display_object_info_table_v1_4 *v1_4;
1895 record_header = NULL;
1896 result = BP_RESULT_NORECORD;
1898 bp = BP_FROM_DCB(dcb);
1899 tbl = &bp->object_info_tbl;
1902 object = &v1_4->display_path[i];
1903 record_offset = (unsigned int)
1904 (object->disp_recordoffset) +
1905 (unsigned int)(bp->object_info_tbl_offset);
1909 record_header = (struct atom_common_record_header *)
1910 GET_IMAGE(struct atom_common_record_header,
1912 if (record_header == NULL) {
1913 result = BP_RESULT_BADBIOSTABLE;
1917 /* the end of the list */
1918 if (record_header->record_type == 0xff ||
1919 record_header->record_size == 0) {
1923 if (record_header->record_type ==
1924 ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
1925 sizeof(struct atom_bracket_layout_record)
1926 <= record_header->record_size) {
1927 record = (struct atom_bracket_layout_record *)
1929 result = BP_RESULT_OK;
1933 record_offset += record_header->record_size;
1936 /* return if the record not found */
1937 if (result != BP_RESULT_OK)
1940 /* get slot sizes */
1941 slot_layout_info->length = record->bracketlen;
1942 slot_layout_info->width = record->bracketwidth;
1944 /* get info for each connector in the slot */
1945 slot_layout_info->num_of_connectors = record->conn_num;
1946 for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
1947 slot_layout_info->connectors[j].connector_type =
1948 (enum connector_layout_type)
1949 (record->conn_info[j].connector_type);
1950 switch (record->conn_info[j].connector_type) {
1951 case CONNECTOR_TYPE_DVI_D:
1952 slot_layout_info->connectors[j].connector_type =
1953 CONNECTOR_LAYOUT_TYPE_DVI_D;
1954 slot_layout_info->connectors[j].length =
1958 case CONNECTOR_TYPE_HDMI:
1959 slot_layout_info->connectors[j].connector_type =
1960 CONNECTOR_LAYOUT_TYPE_HDMI;
1961 slot_layout_info->connectors[j].length =
1962 CONNECTOR_SIZE_HDMI;
1965 case CONNECTOR_TYPE_DISPLAY_PORT:
1966 slot_layout_info->connectors[j].connector_type =
1967 CONNECTOR_LAYOUT_TYPE_DP;
1968 slot_layout_info->connectors[j].length =
1972 case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
1973 slot_layout_info->connectors[j].connector_type =
1974 CONNECTOR_LAYOUT_TYPE_MINI_DP;
1975 slot_layout_info->connectors[j].length =
1976 CONNECTOR_SIZE_MINI_DP;
1980 slot_layout_info->connectors[j].connector_type =
1981 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
1982 slot_layout_info->connectors[j].length =
1983 CONNECTOR_SIZE_UNKNOWN;
1986 slot_layout_info->connectors[j].position =
1987 record->conn_info[j].position;
1988 slot_layout_info->connectors[j].connector_id =
1989 object_id_from_bios_object_id(
1990 record->conn_info[j].connectorobjid);
1996 static enum bp_result get_bracket_layout_record(
1997 struct dc_bios *dcb,
1998 unsigned int bracket_layout_id,
1999 struct slot_layout_info *slot_layout_info)
2002 struct bios_parser *bp = BP_FROM_DCB(dcb);
2003 enum bp_result result;
2004 struct object_info_table *tbl;
2005 struct display_object_info_table_v1_4 *v1_4;
2007 if (slot_layout_info == NULL) {
2008 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
2009 return BP_RESULT_BADINPUT;
2011 tbl = &bp->object_info_tbl;
2014 result = BP_RESULT_NORECORD;
2015 for (i = 0; i < v1_4->number_of_path; ++i) {
2017 if (bracket_layout_id ==
2018 v1_4->display_path[i].display_objid) {
2019 result = update_slot_layout_info(dcb, i,
2027 static enum bp_result bios_get_board_layout_info(
2028 struct dc_bios *dcb,
2029 struct board_layout_info *board_layout_info)
2032 struct bios_parser *bp;
2033 enum bp_result record_result;
2035 const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
2036 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
2037 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
2041 bp = BP_FROM_DCB(dcb);
2042 if (board_layout_info == NULL) {
2043 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
2044 return BP_RESULT_BADINPUT;
2047 board_layout_info->num_of_slots = 0;
2049 for (i = 0; i < MAX_BOARD_SLOTS; ++i) {
2050 record_result = get_bracket_layout_record(dcb,
2051 slot_index_to_vbios_id[i],
2052 &board_layout_info->slots[i]);
2054 if (record_result == BP_RESULT_NORECORD && i > 0)
2055 break; /* no more slots present in bios */
2056 else if (record_result != BP_RESULT_OK)
2057 return record_result; /* fail */
2059 ++board_layout_info->num_of_slots;
2062 /* all data is valid */
2063 board_layout_info->is_number_of_slots_valid = 1;
2064 board_layout_info->is_slots_size_valid = 1;
2065 board_layout_info->is_connector_offsets_valid = 1;
2066 board_layout_info->is_connector_lengths_valid = 1;
2068 return BP_RESULT_OK;
2071 static const struct dc_vbios_funcs vbios_funcs = {
2072 .get_connectors_number = bios_parser_get_connectors_number,
2074 .get_encoder_id = bios_parser_get_encoder_id,
2076 .get_connector_id = bios_parser_get_connector_id,
2078 .get_dst_number = bios_parser_get_dst_number,
2080 .get_src_obj = bios_parser_get_src_obj,
2082 .get_dst_obj = bios_parser_get_dst_obj,
2084 .get_i2c_info = bios_parser_get_i2c_info,
2086 .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info,
2088 .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info,
2090 .get_hpd_info = bios_parser_get_hpd_info,
2092 .get_device_tag = bios_parser_get_device_tag,
2094 .get_firmware_info = bios_parser_get_firmware_info,
2096 .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
2098 .get_ss_entry_number = bios_parser_get_ss_entry_number,
2100 .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
2102 .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
2104 .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
2106 .is_device_id_supported = bios_parser_is_device_id_supported,
2110 .is_accelerated_mode = bios_parser_is_accelerated_mode,
2111 .get_vga_enabled_displays = bios_parser_get_vga_enabled_displays,
2113 .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
2117 .encoder_control = bios_parser_encoder_control,
2119 .transmitter_control = bios_parser_transmitter_control,
2121 .enable_crtc = bios_parser_enable_crtc,
2123 .set_pixel_clock = bios_parser_set_pixel_clock,
2125 .set_dce_clock = bios_parser_set_dce_clock,
2127 .program_crtc_timing = bios_parser_program_crtc_timing,
2129 /* .blank_crtc = bios_parser_blank_crtc, */
2131 .crtc_source_select = bios_parser_crtc_source_select,
2133 /* .external_encoder_control = bios_parser_external_encoder_control, */
2135 .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
2137 .post_init = bios_parser_post_init,
2139 .bios_parser_destroy = firmware_parser_destroy,
2141 .get_smu_clock_info = bios_parser_get_smu_clock_info,
2143 .get_board_layout_info = bios_get_board_layout_info,
2146 static bool bios_parser_construct(
2147 struct bios_parser *bp,
2148 struct bp_init_data *init,
2149 enum dce_version dce_version)
2151 uint16_t *rom_header_offset = NULL;
2152 struct atom_rom_header_v2_2 *rom_header = NULL;
2153 struct display_object_info_table_v1_4 *object_info_tbl;
2154 struct atom_data_revision tbl_rev = {0};
2162 bp->base.funcs = &vbios_funcs;
2163 bp->base.bios = init->bios;
2164 bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
2166 bp->base.ctx = init->ctx;
2168 bp->base.bios_local_image = NULL;
2171 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2173 if (!rom_header_offset)
2176 rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
2181 get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
2182 if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
2185 bp->master_data_tbl =
2186 GET_IMAGE(struct atom_master_data_table_v2_1,
2187 rom_header->masterdatatable_offset);
2189 if (!bp->master_data_tbl)
2192 bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
2194 if (!bp->object_info_tbl_offset)
2198 GET_IMAGE(struct display_object_info_table_v1_4,
2199 bp->object_info_tbl_offset);
2201 if (!object_info_tbl)
2204 get_atom_data_table_revision(&object_info_tbl->table_header,
2205 &bp->object_info_tbl.revision);
2207 if (bp->object_info_tbl.revision.major == 1
2208 && bp->object_info_tbl.revision.minor >= 4) {
2209 struct display_object_info_table_v1_4 *tbl_v1_4;
2211 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
2212 bp->object_info_tbl_offset);
2216 bp->object_info_tbl.v1_4 = tbl_v1_4;
2220 dal_firmware_parser_init_cmd_tbl(bp);
2221 dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
2223 bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
2228 struct dc_bios *firmware_parser_create(
2229 struct bp_init_data *init,
2230 enum dce_version dce_version)
2232 struct bios_parser *bp = NULL;
2234 bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
2238 if (bios_parser_construct(bp, init, dce_version))