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"
46 #define LAST_RECORD_TYPE 0xff
49 struct i2c_id_config_access
{
50 uint8_t bfI2C_LineMux
:4;
51 uint8_t bfHW_EngineID
:3;
52 uint8_t bfHW_Capable
:1;
56 static enum bp_result
get_gpio_i2c_info(struct bios_parser
*bp
,
57 struct atom_i2c_record
*record
,
58 struct graphics_object_i2c_info
*info
);
60 static enum bp_result
bios_parser_get_firmware_info(
62 struct dc_firmware_info
*info
);
64 static enum bp_result
bios_parser_get_encoder_cap_info(
66 struct graphics_object_id object_id
,
67 struct bp_encoder_cap_info
*info
);
69 static enum bp_result
get_firmware_info_v3_1(
70 struct bios_parser
*bp
,
71 struct dc_firmware_info
*info
);
73 static struct atom_hpd_int_record
*get_hpd_record(struct bios_parser
*bp
,
74 struct atom_display_object_path_v2
*object
);
76 static struct atom_encoder_caps_record
*get_encoder_cap_record(
77 struct bios_parser
*bp
,
78 struct atom_display_object_path_v2
*object
);
80 #define BIOS_IMAGE_SIZE_OFFSET 2
81 #define BIOS_IMAGE_SIZE_UNIT 512
83 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
86 static void destruct(struct bios_parser
*bp
)
88 kfree(bp
->base
.bios_local_image
);
89 kfree(bp
->base
.integrated_info
);
92 static void firmware_parser_destroy(struct dc_bios
**dcb
)
94 struct bios_parser
*bp
= BP_FROM_DCB(*dcb
);
107 static void get_atom_data_table_revision(
108 struct atom_common_table_header
*atom_data_tbl
,
109 struct atom_data_revision
*tbl_revision
)
114 /* initialize the revision to 0 which is invalid revision */
115 tbl_revision
->major
= 0;
116 tbl_revision
->minor
= 0;
121 tbl_revision
->major
=
122 (uint32_t) atom_data_tbl
->format_revision
& 0x3f;
123 tbl_revision
->minor
=
124 (uint32_t) atom_data_tbl
->content_revision
& 0x3f;
127 /* BIOS oject table displaypath is per connector.
128 * There is extra path not for connector. BIOS fill its encoderid as 0
130 static uint8_t bios_parser_get_connectors_number(struct dc_bios
*dcb
)
132 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
133 unsigned int count
= 0;
136 for (i
= 0; i
< bp
->object_info_tbl
.v1_4
->number_of_path
; i
++) {
137 if (bp
->object_info_tbl
.v1_4
->display_path
[i
].encoderobjid
!= 0)
143 static struct graphics_object_id
bios_parser_get_encoder_id(
147 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
148 struct graphics_object_id object_id
= dal_graphics_object_id_init(
149 0, ENUM_ID_UNKNOWN
, OBJECT_TYPE_UNKNOWN
);
151 if (bp
->object_info_tbl
.v1_4
->number_of_path
> i
)
152 object_id
= object_id_from_bios_object_id(
153 bp
->object_info_tbl
.v1_4
->display_path
[i
].encoderobjid
);
158 static struct graphics_object_id
bios_parser_get_connector_id(
162 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
163 struct graphics_object_id object_id
= dal_graphics_object_id_init(
164 0, ENUM_ID_UNKNOWN
, OBJECT_TYPE_UNKNOWN
);
165 struct object_info_table
*tbl
= &bp
->object_info_tbl
;
166 struct display_object_info_table_v1_4
*v1_4
= tbl
->v1_4
;
168 if (v1_4
->number_of_path
> i
) {
169 /* If display_objid is generic object id, the encoderObj
170 * /extencoderobjId should be 0
172 if (v1_4
->display_path
[i
].encoderobjid
!= 0 &&
173 v1_4
->display_path
[i
].display_objid
!= 0)
174 object_id
= object_id_from_bios_object_id(
175 v1_4
->display_path
[i
].display_objid
);
182 /* TODO: GetNumberOfSrc*/
184 static uint32_t bios_parser_get_dst_number(struct dc_bios
*dcb
,
185 struct graphics_object_id id
)
187 /* connector has 1 Dest, encoder has 0 Dest */
189 case OBJECT_TYPE_ENCODER
:
191 case OBJECT_TYPE_CONNECTOR
:
198 /* removed getSrcObjList, getDestObjList*/
201 static enum bp_result
bios_parser_get_src_obj(struct dc_bios
*dcb
,
202 struct graphics_object_id object_id
, uint32_t index
,
203 struct graphics_object_id
*src_object_id
)
205 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
207 enum bp_result bp_result
= BP_RESULT_BADINPUT
;
208 struct graphics_object_id obj_id
= {0};
209 struct object_info_table
*tbl
= &bp
->object_info_tbl
;
214 switch (object_id
.type
) {
215 /* Encoder's Source is GPU. BIOS does not provide GPU, since all
216 * displaypaths point to same GPU (0x1100). Hardcode GPU object type
218 case OBJECT_TYPE_ENCODER
:
219 /* TODO: since num of src must be less than 2.
220 * If found in for loop, should break.
221 * DAL2 implementation may be changed too
223 for (i
= 0; i
< tbl
->v1_4
->number_of_path
; i
++) {
224 obj_id
= object_id_from_bios_object_id(
225 tbl
->v1_4
->display_path
[i
].encoderobjid
);
226 if (object_id
.type
== obj_id
.type
&&
227 object_id
.id
== obj_id
.id
&&
231 object_id_from_bios_object_id(0x1100);
235 bp_result
= BP_RESULT_OK
;
237 case OBJECT_TYPE_CONNECTOR
:
238 for (i
= 0; i
< tbl
->v1_4
->number_of_path
; i
++) {
239 obj_id
= object_id_from_bios_object_id(
240 tbl
->v1_4
->display_path
[i
].display_objid
);
242 if (object_id
.type
== obj_id
.type
&&
243 object_id
.id
== obj_id
.id
&&
244 object_id
.enum_id
== obj_id
.enum_id
) {
246 object_id_from_bios_object_id(
247 tbl
->v1_4
->display_path
[i
].encoderobjid
);
251 bp_result
= BP_RESULT_OK
;
260 static enum bp_result
bios_parser_get_dst_obj(struct dc_bios
*dcb
,
261 struct graphics_object_id object_id
, uint32_t index
,
262 struct graphics_object_id
*dest_object_id
)
264 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
266 enum bp_result bp_result
= BP_RESULT_BADINPUT
;
267 struct graphics_object_id obj_id
= {0};
268 struct object_info_table
*tbl
= &bp
->object_info_tbl
;
271 return BP_RESULT_BADINPUT
;
273 switch (object_id
.type
) {
274 case OBJECT_TYPE_ENCODER
:
275 /* TODO: since num of src must be less than 2.
276 * If found in for loop, should break.
277 * DAL2 implementation may be changed too
279 for (i
= 0; i
< tbl
->v1_4
->number_of_path
; i
++) {
280 obj_id
= object_id_from_bios_object_id(
281 tbl
->v1_4
->display_path
[i
].encoderobjid
);
282 if (object_id
.type
== obj_id
.type
&&
283 object_id
.id
== obj_id
.id
&&
287 object_id_from_bios_object_id(
288 tbl
->v1_4
->display_path
[i
].display_objid
);
292 bp_result
= BP_RESULT_OK
;
302 /* from graphics_object_id, find display path which includes the object_id */
303 static struct atom_display_object_path_v2
*get_bios_object(
304 struct bios_parser
*bp
,
305 struct graphics_object_id id
)
308 struct graphics_object_id obj_id
= {0};
311 case OBJECT_TYPE_ENCODER
:
312 for (i
= 0; i
< bp
->object_info_tbl
.v1_4
->number_of_path
; i
++) {
313 obj_id
= object_id_from_bios_object_id(
314 bp
->object_info_tbl
.v1_4
->display_path
[i
].encoderobjid
);
315 if (id
.type
== obj_id
.type
&&
316 id
.id
== obj_id
.id
&&
317 id
.enum_id
== obj_id
.enum_id
)
319 &bp
->object_info_tbl
.v1_4
->display_path
[i
];
321 case OBJECT_TYPE_CONNECTOR
:
322 case OBJECT_TYPE_GENERIC
:
323 /* Both Generic and Connector Object ID
324 * will be stored on display_objid
326 for (i
= 0; i
< bp
->object_info_tbl
.v1_4
->number_of_path
; i
++) {
327 obj_id
= object_id_from_bios_object_id(
328 bp
->object_info_tbl
.v1_4
->display_path
[i
].display_objid
330 if (id
.type
== obj_id
.type
&&
331 id
.id
== obj_id
.id
&&
332 id
.enum_id
== obj_id
.enum_id
)
334 &bp
->object_info_tbl
.v1_4
->display_path
[i
];
341 static enum bp_result
bios_parser_get_i2c_info(struct dc_bios
*dcb
,
342 struct graphics_object_id id
,
343 struct graphics_object_i2c_info
*info
)
346 struct atom_display_object_path_v2
*object
;
347 struct atom_common_record_header
*header
;
348 struct atom_i2c_record
*record
;
349 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
352 return BP_RESULT_BADINPUT
;
354 object
= get_bios_object(bp
, id
);
357 return BP_RESULT_BADINPUT
;
359 offset
= object
->disp_recordoffset
+ bp
->object_info_tbl_offset
;
362 header
= GET_IMAGE(struct atom_common_record_header
, offset
);
365 return BP_RESULT_BADBIOSTABLE
;
367 if (header
->record_type
== LAST_RECORD_TYPE
||
368 !header
->record_size
)
371 if (header
->record_type
== ATOM_I2C_RECORD_TYPE
372 && sizeof(struct atom_i2c_record
) <=
373 header
->record_size
) {
374 /* get the I2C info */
375 record
= (struct atom_i2c_record
*) header
;
377 if (get_gpio_i2c_info(bp
, record
, info
) ==
382 offset
+= header
->record_size
;
385 return BP_RESULT_NORECORD
;
388 static enum bp_result
get_gpio_i2c_info(
389 struct bios_parser
*bp
,
390 struct atom_i2c_record
*record
,
391 struct graphics_object_i2c_info
*info
)
393 struct atom_gpio_pin_lut_v2_1
*header
;
395 unsigned int table_index
= 0;
398 return BP_RESULT_BADINPUT
;
400 /* get the GPIO_I2C info */
401 if (!DATA_TABLES(gpio_pin_lut
))
402 return BP_RESULT_BADBIOSTABLE
;
404 header
= GET_IMAGE(struct atom_gpio_pin_lut_v2_1
,
405 DATA_TABLES(gpio_pin_lut
));
407 return BP_RESULT_BADBIOSTABLE
;
409 if (sizeof(struct atom_common_table_header
) +
410 sizeof(struct atom_gpio_pin_assignment
) >
411 le16_to_cpu(header
->table_header
.structuresize
))
412 return BP_RESULT_BADBIOSTABLE
;
414 /* TODO: is version change? */
415 if (header
->table_header
.content_revision
!= 1)
416 return BP_RESULT_UNSUPPORTED
;
419 count
= (le16_to_cpu(header
->table_header
.structuresize
)
420 - sizeof(struct atom_common_table_header
))
421 / sizeof(struct atom_gpio_pin_assignment
);
423 table_index
= record
->i2c_id
& I2C_HW_LANE_MUX
;
425 if (count
< table_index
) {
426 bool find_valid
= false;
428 for (table_index
= 0; table_index
< count
; table_index
++) {
429 if (((record
->i2c_id
& I2C_HW_CAP
) == (
430 header
->gpio_pin
[table_index
].gpio_id
&
432 ((record
->i2c_id
& I2C_HW_ENGINE_ID_MASK
) ==
433 (header
->gpio_pin
[table_index
].gpio_id
&
434 I2C_HW_ENGINE_ID_MASK
)) &&
435 ((record
->i2c_id
& I2C_HW_LANE_MUX
) ==
436 (header
->gpio_pin
[table_index
].gpio_id
&
443 /* If we don't find the entry that we are looking for then
444 * we will return BP_Result_BadBiosTable.
446 if (find_valid
== false)
447 return BP_RESULT_BADBIOSTABLE
;
450 /* get the GPIO_I2C_INFO */
451 info
->i2c_hw_assist
= (record
->i2c_id
& I2C_HW_CAP
) ? true : false;
452 info
->i2c_line
= record
->i2c_id
& I2C_HW_LANE_MUX
;
453 info
->i2c_engine_id
= (record
->i2c_id
& I2C_HW_ENGINE_ID_MASK
) >> 4;
454 info
->i2c_slave_address
= record
->i2c_slave_addr
;
456 /* TODO: check how to get register offset for en, Y, etc. */
457 info
->gpio_info
.clk_a_register_index
=
459 header
->gpio_pin
[table_index
].data_a_reg_index
);
460 info
->gpio_info
.clk_a_shift
=
461 header
->gpio_pin
[table_index
].gpio_bitshift
;
466 static enum bp_result
get_voltage_ddc_info_v4(
469 struct atom_common_table_header
*header
,
472 enum bp_result result
= BP_RESULT_NORECORD
;
473 struct atom_voltage_objects_info_v4_1
*info
=
474 (struct atom_voltage_objects_info_v4_1
*) address
;
476 uint8_t *voltage_current_object
=
477 (uint8_t *) (&(info
->voltage_object
[0]));
479 while ((address
+ le16_to_cpu(header
->structuresize
)) >
480 voltage_current_object
) {
481 struct atom_i2c_voltage_object_v4
*object
=
482 (struct atom_i2c_voltage_object_v4
*)
483 voltage_current_object
;
485 if (object
->header
.voltage_mode
==
486 ATOM_INIT_VOLTAGE_REGULATOR
) {
487 if (object
->header
.voltage_type
== index
) {
488 *i2c_line
= object
->i2c_id
^ 0x90;
489 result
= BP_RESULT_OK
;
494 voltage_current_object
+=
495 le16_to_cpu(object
->header
.object_size
);
500 static enum bp_result
bios_parser_get_thermal_ddc_info(
502 uint32_t i2c_channel_id
,
503 struct graphics_object_i2c_info
*info
)
505 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
506 struct i2c_id_config_access
*config
;
507 struct atom_i2c_record record
;
510 return BP_RESULT_BADINPUT
;
512 config
= (struct i2c_id_config_access
*) &i2c_channel_id
;
514 record
.i2c_id
= config
->bfHW_Capable
;
515 record
.i2c_id
|= config
->bfI2C_LineMux
;
516 record
.i2c_id
|= config
->bfHW_EngineID
;
518 return get_gpio_i2c_info(bp
, &record
, info
);
521 static enum bp_result
bios_parser_get_voltage_ddc_info(struct dc_bios
*dcb
,
523 struct graphics_object_i2c_info
*info
)
525 uint8_t i2c_line
= 0;
526 enum bp_result result
= BP_RESULT_NORECORD
;
527 uint8_t *voltage_info_address
;
528 struct atom_common_table_header
*header
;
529 struct atom_data_revision revision
= {0};
530 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
532 if (!DATA_TABLES(voltageobject_info
))
535 voltage_info_address
= bios_get_image(&bp
->base
,
536 DATA_TABLES(voltageobject_info
),
537 sizeof(struct atom_common_table_header
));
539 header
= (struct atom_common_table_header
*) voltage_info_address
;
541 get_atom_data_table_revision(header
, &revision
);
543 switch (revision
.major
) {
545 if (revision
.minor
!= 1)
547 result
= get_voltage_ddc_info_v4(&i2c_line
, index
, header
,
548 voltage_info_address
);
552 if (result
== BP_RESULT_OK
)
553 result
= bios_parser_get_thermal_ddc_info(dcb
,
559 static enum bp_result
bios_parser_get_hpd_info(
561 struct graphics_object_id id
,
562 struct graphics_object_hpd_info
*info
)
564 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
565 struct atom_display_object_path_v2
*object
;
566 struct atom_hpd_int_record
*record
= NULL
;
569 return BP_RESULT_BADINPUT
;
571 object
= get_bios_object(bp
, id
);
574 return BP_RESULT_BADINPUT
;
576 record
= get_hpd_record(bp
, object
);
578 if (record
!= NULL
) {
579 info
->hpd_int_gpio_uid
= record
->pin_id
;
580 info
->hpd_active
= record
->plugin_pin_state
;
584 return BP_RESULT_NORECORD
;
587 static struct atom_hpd_int_record
*get_hpd_record(
588 struct bios_parser
*bp
,
589 struct atom_display_object_path_v2
*object
)
591 struct atom_common_record_header
*header
;
595 BREAK_TO_DEBUGGER(); /* Invalid object */
599 offset
= le16_to_cpu(object
->disp_recordoffset
)
600 + bp
->object_info_tbl_offset
;
603 header
= GET_IMAGE(struct atom_common_record_header
, offset
);
608 if (header
->record_type
== LAST_RECORD_TYPE
||
609 !header
->record_size
)
612 if (header
->record_type
== ATOM_HPD_INT_RECORD_TYPE
613 && sizeof(struct atom_hpd_int_record
) <=
615 return (struct atom_hpd_int_record
*) header
;
617 offset
+= header
->record_size
;
624 * bios_parser_get_gpio_pin_info
625 * Get GpioPin information of input gpio id
627 * @param gpio_id, GPIO ID
628 * @param info, GpioPin information structure
629 * @return Bios parser result code
631 * to get the GPIO PIN INFO, we need:
632 * 1. get the GPIO_ID from other object table, see GetHPDInfo()
633 * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
634 * to get the registerA offset/mask
636 static enum bp_result
bios_parser_get_gpio_pin_info(
639 struct gpio_pin_info
*info
)
641 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
642 struct atom_gpio_pin_lut_v2_1
*header
;
646 if (!DATA_TABLES(gpio_pin_lut
))
647 return BP_RESULT_BADBIOSTABLE
;
649 header
= GET_IMAGE(struct atom_gpio_pin_lut_v2_1
,
650 DATA_TABLES(gpio_pin_lut
));
652 return BP_RESULT_BADBIOSTABLE
;
654 if (sizeof(struct atom_common_table_header
) +
655 sizeof(struct atom_gpio_pin_lut_v2_1
)
656 > le16_to_cpu(header
->table_header
.structuresize
))
657 return BP_RESULT_BADBIOSTABLE
;
659 if (header
->table_header
.content_revision
!= 1)
660 return BP_RESULT_UNSUPPORTED
;
662 /* Temporary hard code gpio pin info */
663 #if defined(FOR_SIMNOW_BOOT)
665 struct atom_gpio_pin_assignment gpio_pin
[8] = {
666 {0x5db5, 0, 0, 1, 0},
667 {0x5db5, 8, 8, 2, 0},
668 {0x5db5, 0x10, 0x10, 3, 0},
669 {0x5db5, 0x18, 0x14, 4, 0},
670 {0x5db5, 0x1A, 0x18, 5, 0},
671 {0x5db5, 0x1C, 0x1C, 6, 0},
675 memmove(header
->gpio_pin
, gpio_pin
, sizeof(gpio_pin
));
678 count
= (le16_to_cpu(header
->table_header
.structuresize
)
679 - sizeof(struct atom_common_table_header
))
680 / sizeof(struct atom_gpio_pin_assignment
);
682 for (i
= 0; i
< count
; ++i
) {
683 if (header
->gpio_pin
[i
].gpio_id
!= gpio_id
)
687 (uint32_t) le16_to_cpu(
688 header
->gpio_pin
[i
].data_a_reg_index
);
689 info
->offset_y
= info
->offset
+ 2;
690 info
->offset_en
= info
->offset
+ 1;
691 info
->offset_mask
= info
->offset
- 1;
693 info
->mask
= (uint32_t) (1 <<
694 header
->gpio_pin
[i
].gpio_bitshift
);
695 info
->mask_y
= info
->mask
+ 2;
696 info
->mask_en
= info
->mask
+ 1;
697 info
->mask_mask
= info
->mask
- 1;
702 return BP_RESULT_NORECORD
;
705 static struct device_id
device_type_from_device_id(uint16_t device_id
)
708 struct device_id result_device_id
;
710 result_device_id
.raw_device_tag
= device_id
;
713 case ATOM_DISPLAY_LCD1_SUPPORT
:
714 result_device_id
.device_type
= DEVICE_TYPE_LCD
;
715 result_device_id
.enum_id
= 1;
718 case ATOM_DISPLAY_DFP1_SUPPORT
:
719 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
720 result_device_id
.enum_id
= 1;
723 case ATOM_DISPLAY_DFP2_SUPPORT
:
724 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
725 result_device_id
.enum_id
= 2;
728 case ATOM_DISPLAY_DFP3_SUPPORT
:
729 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
730 result_device_id
.enum_id
= 3;
733 case ATOM_DISPLAY_DFP4_SUPPORT
:
734 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
735 result_device_id
.enum_id
= 4;
738 case ATOM_DISPLAY_DFP5_SUPPORT
:
739 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
740 result_device_id
.enum_id
= 5;
743 case ATOM_DISPLAY_DFP6_SUPPORT
:
744 result_device_id
.device_type
= DEVICE_TYPE_DFP
;
745 result_device_id
.enum_id
= 6;
749 BREAK_TO_DEBUGGER(); /* Invalid device Id */
750 result_device_id
.device_type
= DEVICE_TYPE_UNKNOWN
;
751 result_device_id
.enum_id
= 0;
753 return result_device_id
;
756 static enum bp_result
bios_parser_get_device_tag(
758 struct graphics_object_id connector_object_id
,
759 uint32_t device_tag_index
,
760 struct connector_device_tag_info
*info
)
762 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
763 struct atom_display_object_path_v2
*object
;
766 return BP_RESULT_BADINPUT
;
768 /* getBiosObject will return MXM object */
769 object
= get_bios_object(bp
, connector_object_id
);
772 BREAK_TO_DEBUGGER(); /* Invalid object id */
773 return BP_RESULT_BADINPUT
;
776 info
->acpi_device
= 0; /* BIOS no longer provides this */
777 info
->dev_id
= device_type_from_device_id(object
->device_tag
);
782 static enum bp_result
get_ss_info_v4_1(
783 struct bios_parser
*bp
,
786 struct spread_spectrum_info
*ss_info
)
788 enum bp_result result
= BP_RESULT_OK
;
789 struct atom_display_controller_info_v4_1
*disp_cntl_tbl
= NULL
;
792 return BP_RESULT_BADINPUT
;
794 if (!DATA_TABLES(dce_info
))
795 return BP_RESULT_BADBIOSTABLE
;
797 disp_cntl_tbl
= GET_IMAGE(struct atom_display_controller_info_v4_1
,
798 DATA_TABLES(dce_info
));
800 return BP_RESULT_BADBIOSTABLE
;
802 ss_info
->type
.STEP_AND_DELAY_INFO
= false;
803 ss_info
->spread_percentage_divider
= 1000;
804 /* BIOS no longer uses target clock. Always enable for now */
805 ss_info
->target_clock_range
= 0xffffffff;
808 case AS_SIGNAL_TYPE_DVI
:
809 ss_info
->spread_spectrum_percentage
=
810 disp_cntl_tbl
->dvi_ss_percentage
;
811 ss_info
->spread_spectrum_range
=
812 disp_cntl_tbl
->dvi_ss_rate_10hz
* 10;
813 if (disp_cntl_tbl
->dvi_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
814 ss_info
->type
.CENTER_MODE
= true;
816 case AS_SIGNAL_TYPE_HDMI
:
817 ss_info
->spread_spectrum_percentage
=
818 disp_cntl_tbl
->hdmi_ss_percentage
;
819 ss_info
->spread_spectrum_range
=
820 disp_cntl_tbl
->hdmi_ss_rate_10hz
* 10;
821 if (disp_cntl_tbl
->hdmi_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
822 ss_info
->type
.CENTER_MODE
= true;
824 /* TODO LVDS not support anymore? */
825 case AS_SIGNAL_TYPE_DISPLAY_PORT
:
826 ss_info
->spread_spectrum_percentage
=
827 disp_cntl_tbl
->dp_ss_percentage
;
828 ss_info
->spread_spectrum_range
=
829 disp_cntl_tbl
->dp_ss_rate_10hz
* 10;
830 if (disp_cntl_tbl
->dp_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
831 ss_info
->type
.CENTER_MODE
= true;
833 case AS_SIGNAL_TYPE_GPU_PLL
:
834 /* atom_firmware: DAL only get data from dce_info table.
835 * if data within smu_info is needed for DAL, VBIOS should
836 * copy it into dce_info
838 result
= BP_RESULT_UNSUPPORTED
;
841 result
= BP_RESULT_UNSUPPORTED
;
847 static enum bp_result
get_ss_info_v4_2(
848 struct bios_parser
*bp
,
851 struct spread_spectrum_info
*ss_info
)
853 enum bp_result result
= BP_RESULT_OK
;
854 struct atom_display_controller_info_v4_2
*disp_cntl_tbl
= NULL
;
855 struct atom_smu_info_v3_1
*smu_info
= NULL
;
858 return BP_RESULT_BADINPUT
;
860 if (!DATA_TABLES(dce_info
))
861 return BP_RESULT_BADBIOSTABLE
;
863 if (!DATA_TABLES(smu_info
))
864 return BP_RESULT_BADBIOSTABLE
;
866 disp_cntl_tbl
= GET_IMAGE(struct atom_display_controller_info_v4_2
,
867 DATA_TABLES(dce_info
));
869 return BP_RESULT_BADBIOSTABLE
;
871 smu_info
= GET_IMAGE(struct atom_smu_info_v3_1
, DATA_TABLES(smu_info
));
873 return BP_RESULT_BADBIOSTABLE
;
875 ss_info
->type
.STEP_AND_DELAY_INFO
= false;
876 ss_info
->spread_percentage_divider
= 1000;
877 /* BIOS no longer uses target clock. Always enable for now */
878 ss_info
->target_clock_range
= 0xffffffff;
881 case AS_SIGNAL_TYPE_DVI
:
882 ss_info
->spread_spectrum_percentage
=
883 disp_cntl_tbl
->dvi_ss_percentage
;
884 ss_info
->spread_spectrum_range
=
885 disp_cntl_tbl
->dvi_ss_rate_10hz
* 10;
886 if (disp_cntl_tbl
->dvi_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
887 ss_info
->type
.CENTER_MODE
= true;
889 case AS_SIGNAL_TYPE_HDMI
:
890 ss_info
->spread_spectrum_percentage
=
891 disp_cntl_tbl
->hdmi_ss_percentage
;
892 ss_info
->spread_spectrum_range
=
893 disp_cntl_tbl
->hdmi_ss_rate_10hz
* 10;
894 if (disp_cntl_tbl
->hdmi_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
895 ss_info
->type
.CENTER_MODE
= true;
897 /* TODO LVDS not support anymore? */
898 case AS_SIGNAL_TYPE_DISPLAY_PORT
:
899 ss_info
->spread_spectrum_percentage
=
900 smu_info
->gpuclk_ss_percentage
;
901 ss_info
->spread_spectrum_range
=
902 smu_info
->gpuclk_ss_rate_10hz
* 10;
903 if (smu_info
->gpuclk_ss_mode
& ATOM_SS_CENTRE_SPREAD_MODE
)
904 ss_info
->type
.CENTER_MODE
= true;
906 case AS_SIGNAL_TYPE_GPU_PLL
:
907 /* atom_firmware: DAL only get data from dce_info table.
908 * if data within smu_info is needed for DAL, VBIOS should
909 * copy it into dce_info
911 result
= BP_RESULT_UNSUPPORTED
;
914 result
= BP_RESULT_UNSUPPORTED
;
921 * bios_parser_get_spread_spectrum_info
922 * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
923 * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
924 * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
926 * there is only one entry for each signal /ss id. However, there is
927 * no planning of supporting multiple spread Sprectum entry for EverGreen
929 * @param [in] signal, ASSignalType to be converted to info index
930 * @param [in] index, number of entries that match the converted info index
931 * @param [out] ss_info, sprectrum information structure,
932 * @return Bios parser result code
934 static enum bp_result
bios_parser_get_spread_spectrum_info(
936 enum as_signal_type signal
,
938 struct spread_spectrum_info
*ss_info
)
940 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
941 enum bp_result result
= BP_RESULT_UNSUPPORTED
;
942 struct atom_common_table_header
*header
;
943 struct atom_data_revision tbl_revision
;
945 if (!ss_info
) /* check for bad input */
946 return BP_RESULT_BADINPUT
;
948 if (!DATA_TABLES(dce_info
))
949 return BP_RESULT_UNSUPPORTED
;
951 header
= GET_IMAGE(struct atom_common_table_header
,
952 DATA_TABLES(dce_info
));
953 get_atom_data_table_revision(header
, &tbl_revision
);
955 switch (tbl_revision
.major
) {
957 switch (tbl_revision
.minor
) {
959 return get_ss_info_v4_1(bp
, signal
, index
, ss_info
);
961 return get_ss_info_v4_2(bp
, signal
, index
, ss_info
);
969 /* there can not be more then one entry for SS Info table */
973 static enum bp_result
get_embedded_panel_info_v2_1(
974 struct bios_parser
*bp
,
975 struct embedded_panel_info
*info
)
977 struct lcd_info_v2_1
*lvds
;
980 return BP_RESULT_BADINPUT
;
982 if (!DATA_TABLES(lcd_info
))
983 return BP_RESULT_UNSUPPORTED
;
985 lvds
= GET_IMAGE(struct lcd_info_v2_1
, DATA_TABLES(lcd_info
));
988 return BP_RESULT_BADBIOSTABLE
;
990 /* TODO: previous vv1_3, should v2_1 */
991 if (!((lvds
->table_header
.format_revision
== 2)
992 && (lvds
->table_header
.content_revision
>= 1)))
993 return BP_RESULT_UNSUPPORTED
;
995 memset(info
, 0, sizeof(struct embedded_panel_info
));
997 /* We need to convert from 10KHz units into KHz units */
998 info
->lcd_timing
.pixel_clk
=
999 le16_to_cpu(lvds
->lcd_timing
.pixclk
) * 10;
1000 /* usHActive does not include borders, according to VBIOS team */
1001 info
->lcd_timing
.horizontal_addressable
=
1002 le16_to_cpu(lvds
->lcd_timing
.h_active
);
1003 /* usHBlanking_Time includes borders, so we should really be
1004 * subtractingborders duing this translation, but LVDS generally
1005 * doesn't have borders, so we should be okay leaving this as is for
1006 * now. May need to revisit if we ever have LVDS with borders
1008 info
->lcd_timing
.horizontal_blanking_time
=
1009 le16_to_cpu(lvds
->lcd_timing
.h_blanking_time
);
1010 /* usVActive does not include borders, according to VBIOS team*/
1011 info
->lcd_timing
.vertical_addressable
=
1012 le16_to_cpu(lvds
->lcd_timing
.v_active
);
1013 /* usVBlanking_Time includes borders, so we should really be
1014 * subtracting borders duing this translation, but LVDS generally
1015 * doesn't have borders, so we should be okay leaving this as is for
1016 * now. May need to revisit if we ever have LVDS with borders
1018 info
->lcd_timing
.vertical_blanking_time
=
1019 le16_to_cpu(lvds
->lcd_timing
.v_blanking_time
);
1020 info
->lcd_timing
.horizontal_sync_offset
=
1021 le16_to_cpu(lvds
->lcd_timing
.h_sync_offset
);
1022 info
->lcd_timing
.horizontal_sync_width
=
1023 le16_to_cpu(lvds
->lcd_timing
.h_sync_width
);
1024 info
->lcd_timing
.vertical_sync_offset
=
1025 le16_to_cpu(lvds
->lcd_timing
.v_sync_offset
);
1026 info
->lcd_timing
.vertical_sync_width
=
1027 le16_to_cpu(lvds
->lcd_timing
.v_syncwidth
);
1028 info
->lcd_timing
.horizontal_border
= lvds
->lcd_timing
.h_border
;
1029 info
->lcd_timing
.vertical_border
= lvds
->lcd_timing
.v_border
;
1031 /* not provided by VBIOS */
1032 info
->lcd_timing
.misc_info
.HORIZONTAL_CUT_OFF
= 0;
1034 info
->lcd_timing
.misc_info
.H_SYNC_POLARITY
=
1036 (lvds
->lcd_timing
.miscinfo
& ATOM_HSYNC_POLARITY
);
1037 info
->lcd_timing
.misc_info
.V_SYNC_POLARITY
=
1039 (lvds
->lcd_timing
.miscinfo
& ATOM_VSYNC_POLARITY
);
1041 /* not provided by VBIOS */
1042 info
->lcd_timing
.misc_info
.VERTICAL_CUT_OFF
= 0;
1044 info
->lcd_timing
.misc_info
.H_REPLICATION_BY2
=
1045 !!(lvds
->lcd_timing
.miscinfo
& ATOM_H_REPLICATIONBY2
);
1046 info
->lcd_timing
.misc_info
.V_REPLICATION_BY2
=
1047 !!(lvds
->lcd_timing
.miscinfo
& ATOM_V_REPLICATIONBY2
);
1048 info
->lcd_timing
.misc_info
.COMPOSITE_SYNC
=
1049 !!(lvds
->lcd_timing
.miscinfo
& ATOM_COMPOSITESYNC
);
1050 info
->lcd_timing
.misc_info
.INTERLACE
=
1051 !!(lvds
->lcd_timing
.miscinfo
& ATOM_INTERLACE
);
1053 /* not provided by VBIOS*/
1054 info
->lcd_timing
.misc_info
.DOUBLE_CLOCK
= 0;
1055 /* not provided by VBIOS*/
1058 info
->realtek_eDPToLVDS
=
1059 !!(lvds
->dplvdsrxid
== eDP_TO_LVDS_REALTEK_ID
);
1061 return BP_RESULT_OK
;
1064 static enum bp_result
bios_parser_get_embedded_panel_info(
1065 struct dc_bios
*dcb
,
1066 struct embedded_panel_info
*info
)
1068 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1069 struct atom_common_table_header
*header
;
1070 struct atom_data_revision tbl_revision
;
1072 if (!DATA_TABLES(lcd_info
))
1073 return BP_RESULT_FAILURE
;
1075 header
= GET_IMAGE(struct atom_common_table_header
,
1076 DATA_TABLES(lcd_info
));
1079 return BP_RESULT_BADBIOSTABLE
;
1081 get_atom_data_table_revision(header
, &tbl_revision
);
1084 switch (tbl_revision
.major
) {
1086 switch (tbl_revision
.minor
) {
1088 return get_embedded_panel_info_v2_1(bp
, info
);
1096 return BP_RESULT_FAILURE
;
1099 static uint32_t get_support_mask_for_device_id(struct device_id device_id
)
1101 enum dal_device_type device_type
= device_id
.device_type
;
1102 uint32_t enum_id
= device_id
.enum_id
;
1104 switch (device_type
) {
1105 case DEVICE_TYPE_LCD
:
1108 return ATOM_DISPLAY_LCD1_SUPPORT
;
1113 case DEVICE_TYPE_DFP
:
1116 return ATOM_DISPLAY_DFP1_SUPPORT
;
1118 return ATOM_DISPLAY_DFP2_SUPPORT
;
1120 return ATOM_DISPLAY_DFP3_SUPPORT
;
1122 return ATOM_DISPLAY_DFP4_SUPPORT
;
1124 return ATOM_DISPLAY_DFP5_SUPPORT
;
1126 return ATOM_DISPLAY_DFP6_SUPPORT
;
1135 /* Unidentified device ID, return empty support mask. */
1139 static bool bios_parser_is_device_id_supported(
1140 struct dc_bios
*dcb
,
1141 struct device_id id
)
1143 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1145 uint32_t mask
= get_support_mask_for_device_id(id
);
1147 return (le16_to_cpu(bp
->object_info_tbl
.v1_4
->supporteddevices
) &
1151 static void bios_parser_post_init(
1152 struct dc_bios
*dcb
)
1154 /* TODO for OPM module. Need implement later */
1157 static uint32_t bios_parser_get_ss_entry_number(
1158 struct dc_bios
*dcb
,
1159 enum as_signal_type signal
)
1161 /* TODO: DAL2 atomfirmware implementation does not need this.
1162 * why DAL3 need this?
1167 static enum bp_result
bios_parser_transmitter_control(
1168 struct dc_bios
*dcb
,
1169 struct bp_transmitter_control
*cntl
)
1171 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1173 if (!bp
->cmd_tbl
.transmitter_control
)
1174 return BP_RESULT_FAILURE
;
1176 return bp
->cmd_tbl
.transmitter_control(bp
, cntl
);
1179 static enum bp_result
bios_parser_encoder_control(
1180 struct dc_bios
*dcb
,
1181 struct bp_encoder_control
*cntl
)
1183 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1185 if (!bp
->cmd_tbl
.dig_encoder_control
)
1186 return BP_RESULT_FAILURE
;
1188 return bp
->cmd_tbl
.dig_encoder_control(bp
, cntl
);
1191 static enum bp_result
bios_parser_set_pixel_clock(
1192 struct dc_bios
*dcb
,
1193 struct bp_pixel_clock_parameters
*bp_params
)
1195 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1197 if (!bp
->cmd_tbl
.set_pixel_clock
)
1198 return BP_RESULT_FAILURE
;
1200 return bp
->cmd_tbl
.set_pixel_clock(bp
, bp_params
);
1203 static enum bp_result
bios_parser_set_dce_clock(
1204 struct dc_bios
*dcb
,
1205 struct bp_set_dce_clock_parameters
*bp_params
)
1207 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1209 if (!bp
->cmd_tbl
.set_dce_clock
)
1210 return BP_RESULT_FAILURE
;
1212 return bp
->cmd_tbl
.set_dce_clock(bp
, bp_params
);
1215 static unsigned int bios_parser_get_smu_clock_info(
1216 struct dc_bios
*dcb
)
1218 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1220 if (!bp
->cmd_tbl
.get_smu_clock_info
)
1221 return BP_RESULT_FAILURE
;
1223 return bp
->cmd_tbl
.get_smu_clock_info(bp
);
1226 static enum bp_result
bios_parser_program_crtc_timing(
1227 struct dc_bios
*dcb
,
1228 struct bp_hw_crtc_timing_parameters
*bp_params
)
1230 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1232 if (!bp
->cmd_tbl
.set_crtc_timing
)
1233 return BP_RESULT_FAILURE
;
1235 return bp
->cmd_tbl
.set_crtc_timing(bp
, bp_params
);
1238 static enum bp_result
bios_parser_enable_crtc(
1239 struct dc_bios
*dcb
,
1240 enum controller_id id
,
1243 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1245 if (!bp
->cmd_tbl
.enable_crtc
)
1246 return BP_RESULT_FAILURE
;
1248 return bp
->cmd_tbl
.enable_crtc(bp
, id
, enable
);
1251 static enum bp_result
bios_parser_crtc_source_select(
1252 struct dc_bios
*dcb
,
1253 struct bp_crtc_source_select
*bp_params
)
1255 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1257 if (!bp
->cmd_tbl
.select_crtc_source
)
1258 return BP_RESULT_FAILURE
;
1260 return bp
->cmd_tbl
.select_crtc_source(bp
, bp_params
);
1263 static enum bp_result
bios_parser_enable_disp_power_gating(
1264 struct dc_bios
*dcb
,
1265 enum controller_id controller_id
,
1266 enum bp_pipe_control_action action
)
1268 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1270 if (!bp
->cmd_tbl
.enable_disp_power_gating
)
1271 return BP_RESULT_FAILURE
;
1273 return bp
->cmd_tbl
.enable_disp_power_gating(bp
, controller_id
,
1277 static bool bios_parser_is_accelerated_mode(
1278 struct dc_bios
*dcb
)
1280 return bios_is_accelerated_mode(dcb
);
1285 * bios_parser_set_scratch_critical_state
1288 * update critical state bit in VBIOS scratch register
1291 * bool - to set or reset state
1293 static void bios_parser_set_scratch_critical_state(
1294 struct dc_bios
*dcb
,
1297 bios_set_scratch_critical_state(dcb
, state
);
1300 static enum bp_result
bios_parser_get_firmware_info(
1301 struct dc_bios
*dcb
,
1302 struct dc_firmware_info
*info
)
1304 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1305 enum bp_result result
= BP_RESULT_BADBIOSTABLE
;
1306 struct atom_common_table_header
*header
;
1308 struct atom_data_revision revision
;
1310 if (info
&& DATA_TABLES(firmwareinfo
)) {
1311 header
= GET_IMAGE(struct atom_common_table_header
,
1312 DATA_TABLES(firmwareinfo
));
1313 get_atom_data_table_revision(header
, &revision
);
1314 switch (revision
.major
) {
1316 switch (revision
.minor
) {
1318 result
= get_firmware_info_v3_1(bp
, info
);
1332 static enum bp_result
get_firmware_info_v3_1(
1333 struct bios_parser
*bp
,
1334 struct dc_firmware_info
*info
)
1336 struct atom_firmware_info_v3_1
*firmware_info
;
1337 struct atom_display_controller_info_v4_1
*dce_info
= NULL
;
1340 return BP_RESULT_BADINPUT
;
1342 firmware_info
= GET_IMAGE(struct atom_firmware_info_v3_1
,
1343 DATA_TABLES(firmwareinfo
));
1345 dce_info
= GET_IMAGE(struct atom_display_controller_info_v4_1
,
1346 DATA_TABLES(dce_info
));
1348 if (!firmware_info
|| !dce_info
)
1349 return BP_RESULT_BADBIOSTABLE
;
1351 memset(info
, 0, sizeof(*info
));
1353 /* Pixel clock pll information. */
1354 /* We need to convert from 10KHz units into KHz units */
1355 info
->default_memory_clk
= firmware_info
->bootup_mclk_in10khz
* 10;
1356 info
->default_engine_clk
= firmware_info
->bootup_sclk_in10khz
* 10;
1358 /* 27MHz for Vega10: */
1359 info
->pll_info
.crystal_frequency
= dce_info
->dce_refclk_10khz
* 10;
1361 /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1362 if (info
->pll_info
.crystal_frequency
== 0)
1363 info
->pll_info
.crystal_frequency
= 27000;
1364 /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1365 info
->dp_phy_ref_clk
= dce_info
->dpphy_refclk_10khz
* 10;
1366 info
->i2c_engine_ref_clk
= dce_info
->i2c_engine_refclk_10khz
* 10;
1368 /* Get GPU PLL VCO Clock */
1370 if (bp
->cmd_tbl
.get_smu_clock_info
!= NULL
) {
1371 /* VBIOS gives in 10KHz */
1372 info
->smu_gpu_pll_output_freq
=
1373 bp
->cmd_tbl
.get_smu_clock_info(bp
) * 10;
1376 return BP_RESULT_OK
;
1379 static enum bp_result
bios_parser_get_encoder_cap_info(
1380 struct dc_bios
*dcb
,
1381 struct graphics_object_id object_id
,
1382 struct bp_encoder_cap_info
*info
)
1384 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1385 struct atom_display_object_path_v2
*object
;
1386 struct atom_encoder_caps_record
*record
= NULL
;
1389 return BP_RESULT_BADINPUT
;
1391 object
= get_bios_object(bp
, object_id
);
1394 return BP_RESULT_BADINPUT
;
1396 record
= get_encoder_cap_record(bp
, object
);
1398 return BP_RESULT_NORECORD
;
1400 info
->DP_HBR2_CAP
= (record
->encodercaps
&
1401 ATOM_ENCODER_CAP_RECORD_HBR2
) ? 1 : 0;
1402 info
->DP_HBR2_EN
= (record
->encodercaps
&
1403 ATOM_ENCODER_CAP_RECORD_HBR2_EN
) ? 1 : 0;
1404 info
->DP_HBR3_EN
= (record
->encodercaps
&
1405 ATOM_ENCODER_CAP_RECORD_HBR3_EN
) ? 1 : 0;
1406 info
->HDMI_6GB_EN
= (record
->encodercaps
&
1407 ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN
) ? 1 : 0;
1409 return BP_RESULT_OK
;
1413 static struct atom_encoder_caps_record
*get_encoder_cap_record(
1414 struct bios_parser
*bp
,
1415 struct atom_display_object_path_v2
*object
)
1417 struct atom_common_record_header
*header
;
1421 BREAK_TO_DEBUGGER(); /* Invalid object */
1425 offset
= object
->encoder_recordoffset
+ bp
->object_info_tbl_offset
;
1428 header
= GET_IMAGE(struct atom_common_record_header
, offset
);
1433 offset
+= header
->record_size
;
1435 if (header
->record_type
== LAST_RECORD_TYPE
||
1436 !header
->record_size
)
1439 if (header
->record_type
!= ATOM_ENCODER_CAP_RECORD_TYPE
)
1442 if (sizeof(struct atom_encoder_caps_record
) <=
1443 header
->record_size
)
1444 return (struct atom_encoder_caps_record
*)header
;
1451 * get_integrated_info_v11
1454 * Get V8 integrated BIOS information
1457 * bios_parser *bp - [in]BIOS parser handler to get master data table
1458 * integrated_info *info - [out] store and output integrated info
1461 * enum bp_result - BP_RESULT_OK if information is available,
1462 * BP_RESULT_BADBIOSTABLE otherwise.
1464 static enum bp_result
get_integrated_info_v11(
1465 struct bios_parser
*bp
,
1466 struct integrated_info
*info
)
1468 struct atom_integrated_system_info_v1_11
*info_v11
;
1471 info_v11
= GET_IMAGE(struct atom_integrated_system_info_v1_11
,
1472 DATA_TABLES(integratedsysteminfo
));
1474 if (info_v11
== NULL
)
1475 return BP_RESULT_BADBIOSTABLE
;
1477 info
->gpu_cap_info
=
1478 le32_to_cpu(info_v11
->gpucapinfo
);
1480 * system_config: Bit[0] = 0 : PCIE power gating disabled
1481 * = 1 : PCIE power gating enabled
1482 * Bit[1] = 0 : DDR-PLL shut down disabled
1483 * = 1 : DDR-PLL shut down enabled
1484 * Bit[2] = 0 : DDR-PLL power down disabled
1485 * = 1 : DDR-PLL power down enabled
1487 info
->system_config
= le32_to_cpu(info_v11
->system_config
);
1488 info
->cpu_cap_info
= le32_to_cpu(info_v11
->cpucapinfo
);
1489 info
->memory_type
= info_v11
->memorytype
;
1490 info
->ma_channel_number
= info_v11
->umachannelnumber
;
1491 info
->lvds_ss_percentage
=
1492 le16_to_cpu(info_v11
->lvds_ss_percentage
);
1493 info
->lvds_sspread_rate_in_10hz
=
1494 le16_to_cpu(info_v11
->lvds_ss_rate_10hz
);
1495 info
->hdmi_ss_percentage
=
1496 le16_to_cpu(info_v11
->hdmi_ss_percentage
);
1497 info
->hdmi_sspread_rate_in_10hz
=
1498 le16_to_cpu(info_v11
->hdmi_ss_rate_10hz
);
1499 info
->dvi_ss_percentage
=
1500 le16_to_cpu(info_v11
->dvi_ss_percentage
);
1501 info
->dvi_sspread_rate_in_10_hz
=
1502 le16_to_cpu(info_v11
->dvi_ss_rate_10hz
);
1503 info
->lvds_misc
= info_v11
->lvds_misc
;
1504 for (i
= 0; i
< NUMBER_OF_UCHAR_FOR_GUID
; ++i
) {
1505 info
->ext_disp_conn_info
.gu_id
[i
] =
1506 info_v11
->extdispconninfo
.guid
[i
];
1509 for (i
= 0; i
< MAX_NUMBER_OF_EXT_DISPLAY_PATH
; ++i
) {
1510 info
->ext_disp_conn_info
.path
[i
].device_connector_id
=
1511 object_id_from_bios_object_id(
1512 le16_to_cpu(info_v11
->extdispconninfo
.path
[i
].connectorobjid
));
1514 info
->ext_disp_conn_info
.path
[i
].ext_encoder_obj_id
=
1515 object_id_from_bios_object_id(
1517 info_v11
->extdispconninfo
.path
[i
].ext_encoder_objid
));
1519 info
->ext_disp_conn_info
.path
[i
].device_tag
=
1521 info_v11
->extdispconninfo
.path
[i
].device_tag
);
1522 info
->ext_disp_conn_info
.path
[i
].device_acpi_enum
=
1524 info_v11
->extdispconninfo
.path
[i
].device_acpi_enum
);
1525 info
->ext_disp_conn_info
.path
[i
].ext_aux_ddc_lut_index
=
1526 info_v11
->extdispconninfo
.path
[i
].auxddclut_index
;
1527 info
->ext_disp_conn_info
.path
[i
].ext_hpd_pin_lut_index
=
1528 info_v11
->extdispconninfo
.path
[i
].hpdlut_index
;
1529 info
->ext_disp_conn_info
.path
[i
].channel_mapping
.raw
=
1530 info_v11
->extdispconninfo
.path
[i
].channelmapping
;
1531 info
->ext_disp_conn_info
.path
[i
].caps
=
1532 le16_to_cpu(info_v11
->extdispconninfo
.path
[i
].caps
);
1534 info
->ext_disp_conn_info
.checksum
=
1535 info_v11
->extdispconninfo
.checksum
;
1537 info
->dp0_ext_hdmi_slv_addr
= info_v11
->dp0_retimer_set
.HdmiSlvAddr
;
1538 info
->dp0_ext_hdmi_reg_num
= info_v11
->dp0_retimer_set
.HdmiRegNum
;
1539 for (i
= 0; i
< info
->dp0_ext_hdmi_reg_num
; i
++) {
1540 info
->dp0_ext_hdmi_reg_settings
[i
].i2c_reg_index
=
1541 info_v11
->dp0_retimer_set
.HdmiRegSetting
[i
].ucI2cRegIndex
;
1542 info
->dp0_ext_hdmi_reg_settings
[i
].i2c_reg_val
=
1543 info_v11
->dp0_retimer_set
.HdmiRegSetting
[i
].ucI2cRegVal
;
1545 info
->dp0_ext_hdmi_6g_reg_num
= info_v11
->dp0_retimer_set
.Hdmi6GRegNum
;
1546 for (i
= 0; i
< info
->dp0_ext_hdmi_6g_reg_num
; i
++) {
1547 info
->dp0_ext_hdmi_6g_reg_settings
[i
].i2c_reg_index
=
1548 info_v11
->dp0_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegIndex
;
1549 info
->dp0_ext_hdmi_6g_reg_settings
[i
].i2c_reg_val
=
1550 info_v11
->dp0_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegVal
;
1553 info
->dp1_ext_hdmi_slv_addr
= info_v11
->dp1_retimer_set
.HdmiSlvAddr
;
1554 info
->dp1_ext_hdmi_reg_num
= info_v11
->dp1_retimer_set
.HdmiRegNum
;
1555 for (i
= 0; i
< info
->dp1_ext_hdmi_reg_num
; i
++) {
1556 info
->dp1_ext_hdmi_reg_settings
[i
].i2c_reg_index
=
1557 info_v11
->dp1_retimer_set
.HdmiRegSetting
[i
].ucI2cRegIndex
;
1558 info
->dp1_ext_hdmi_reg_settings
[i
].i2c_reg_val
=
1559 info_v11
->dp1_retimer_set
.HdmiRegSetting
[i
].ucI2cRegVal
;
1561 info
->dp1_ext_hdmi_6g_reg_num
= info_v11
->dp1_retimer_set
.Hdmi6GRegNum
;
1562 for (i
= 0; i
< info
->dp1_ext_hdmi_6g_reg_num
; i
++) {
1563 info
->dp1_ext_hdmi_6g_reg_settings
[i
].i2c_reg_index
=
1564 info_v11
->dp1_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegIndex
;
1565 info
->dp1_ext_hdmi_6g_reg_settings
[i
].i2c_reg_val
=
1566 info_v11
->dp1_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegVal
;
1569 info
->dp2_ext_hdmi_slv_addr
= info_v11
->dp2_retimer_set
.HdmiSlvAddr
;
1570 info
->dp2_ext_hdmi_reg_num
= info_v11
->dp2_retimer_set
.HdmiRegNum
;
1571 for (i
= 0; i
< info
->dp2_ext_hdmi_reg_num
; i
++) {
1572 info
->dp2_ext_hdmi_reg_settings
[i
].i2c_reg_index
=
1573 info_v11
->dp2_retimer_set
.HdmiRegSetting
[i
].ucI2cRegIndex
;
1574 info
->dp2_ext_hdmi_reg_settings
[i
].i2c_reg_val
=
1575 info_v11
->dp2_retimer_set
.HdmiRegSetting
[i
].ucI2cRegVal
;
1577 info
->dp2_ext_hdmi_6g_reg_num
= info_v11
->dp2_retimer_set
.Hdmi6GRegNum
;
1578 for (i
= 0; i
< info
->dp2_ext_hdmi_6g_reg_num
; i
++) {
1579 info
->dp2_ext_hdmi_6g_reg_settings
[i
].i2c_reg_index
=
1580 info_v11
->dp2_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegIndex
;
1581 info
->dp2_ext_hdmi_6g_reg_settings
[i
].i2c_reg_val
=
1582 info_v11
->dp2_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegVal
;
1585 info
->dp3_ext_hdmi_slv_addr
= info_v11
->dp3_retimer_set
.HdmiSlvAddr
;
1586 info
->dp3_ext_hdmi_reg_num
= info_v11
->dp3_retimer_set
.HdmiRegNum
;
1587 for (i
= 0; i
< info
->dp3_ext_hdmi_reg_num
; i
++) {
1588 info
->dp3_ext_hdmi_reg_settings
[i
].i2c_reg_index
=
1589 info_v11
->dp3_retimer_set
.HdmiRegSetting
[i
].ucI2cRegIndex
;
1590 info
->dp3_ext_hdmi_reg_settings
[i
].i2c_reg_val
=
1591 info_v11
->dp3_retimer_set
.HdmiRegSetting
[i
].ucI2cRegVal
;
1593 info
->dp3_ext_hdmi_6g_reg_num
= info_v11
->dp3_retimer_set
.Hdmi6GRegNum
;
1594 for (i
= 0; i
< info
->dp3_ext_hdmi_6g_reg_num
; i
++) {
1595 info
->dp3_ext_hdmi_6g_reg_settings
[i
].i2c_reg_index
=
1596 info_v11
->dp3_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegIndex
;
1597 info
->dp3_ext_hdmi_6g_reg_settings
[i
].i2c_reg_val
=
1598 info_v11
->dp3_retimer_set
.Hdmi6GhzRegSetting
[i
].ucI2cRegVal
;
1602 /** TODO - review **/
1604 info
->boot_up_engine_clock
= le32_to_cpu(info_v11
->ulBootUpEngineClock
)
1606 info
->dentist_vco_freq
= le32_to_cpu(info_v11
->ulDentistVCOFreq
) * 10;
1607 info
->boot_up_uma_clock
= le32_to_cpu(info_v8
->ulBootUpUMAClock
) * 10;
1609 for (i
= 0; i
< NUMBER_OF_DISP_CLK_VOLTAGE
; ++i
) {
1610 /* Convert [10KHz] into [KHz] */
1611 info
->disp_clk_voltage
[i
].max_supported_clk
=
1612 le32_to_cpu(info_v11
->sDISPCLK_Voltage
[i
].
1613 ulMaximumSupportedCLK
) * 10;
1614 info
->disp_clk_voltage
[i
].voltage_index
=
1615 le32_to_cpu(info_v11
->sDISPCLK_Voltage
[i
].ulVoltageIndex
);
1618 info
->boot_up_req_display_vector
=
1619 le32_to_cpu(info_v11
->ulBootUpReqDisplayVector
);
1620 info
->boot_up_nb_voltage
=
1621 le16_to_cpu(info_v11
->usBootUpNBVoltage
);
1622 info
->ext_disp_conn_info_offset
=
1623 le16_to_cpu(info_v11
->usExtDispConnInfoOffset
);
1624 info
->gmc_restore_reset_time
=
1625 le32_to_cpu(info_v11
->ulGMCRestoreResetTime
);
1626 info
->minimum_n_clk
=
1627 le32_to_cpu(info_v11
->ulNbpStateNClkFreq
[0]);
1628 for (i
= 1; i
< 4; ++i
)
1629 info
->minimum_n_clk
=
1630 info
->minimum_n_clk
<
1631 le32_to_cpu(info_v11
->ulNbpStateNClkFreq
[i
]) ?
1632 info
->minimum_n_clk
: le32_to_cpu(
1633 info_v11
->ulNbpStateNClkFreq
[i
]);
1635 info
->idle_n_clk
= le32_to_cpu(info_v11
->ulIdleNClk
);
1636 info
->ddr_dll_power_up_time
=
1637 le32_to_cpu(info_v11
->ulDDR_DLL_PowerUpTime
);
1638 info
->ddr_pll_power_up_time
=
1639 le32_to_cpu(info_v11
->ulDDR_PLL_PowerUpTime
);
1640 info
->pcie_clk_ss_type
= le16_to_cpu(info_v11
->usPCIEClkSSType
);
1641 info
->max_lvds_pclk_freq_in_single_link
=
1642 le16_to_cpu(info_v11
->usMaxLVDSPclkFreqInSingleLink
);
1643 info
->max_lvds_pclk_freq_in_single_link
=
1644 le16_to_cpu(info_v11
->usMaxLVDSPclkFreqInSingleLink
);
1645 info
->lvds_pwr_on_seq_dig_on_to_de_in_4ms
=
1646 info_v11
->ucLVDSPwrOnSeqDIGONtoDE_in4Ms
;
1647 info
->lvds_pwr_on_seq_de_to_vary_bl_in_4ms
=
1648 info_v11
->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms
;
1649 info
->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms
=
1650 info_v11
->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms
;
1651 info
->lvds_pwr_off_seq_vary_bl_to_de_in4ms
=
1652 info_v11
->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms
;
1653 info
->lvds_pwr_off_seq_de_to_dig_on_in4ms
=
1654 info_v11
->ucLVDSPwrOffSeqDEtoDIGON_in4Ms
;
1655 info
->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms
=
1656 info_v11
->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms
;
1657 info
->lvds_off_to_on_delay_in_4ms
=
1658 info_v11
->ucLVDSOffToOnDelay_in4Ms
;
1659 info
->lvds_bit_depth_control_val
=
1660 le32_to_cpu(info_v11
->ulLCDBitDepthControlVal
);
1662 for (i
= 0; i
< NUMBER_OF_AVAILABLE_SCLK
; ++i
) {
1663 /* Convert [10KHz] into [KHz] */
1664 info
->avail_s_clk
[i
].supported_s_clk
=
1665 le32_to_cpu(info_v11
->sAvail_SCLK
[i
].ulSupportedSCLK
)
1667 info
->avail_s_clk
[i
].voltage_index
=
1668 le16_to_cpu(info_v11
->sAvail_SCLK
[i
].usVoltageIndex
);
1669 info
->avail_s_clk
[i
].voltage_id
=
1670 le16_to_cpu(info_v11
->sAvail_SCLK
[i
].usVoltageID
);
1674 return BP_RESULT_OK
;
1679 * construct_integrated_info
1682 * Get integrated BIOS information based on table revision
1685 * bios_parser *bp - [in]BIOS parser handler to get master data table
1686 * integrated_info *info - [out] store and output integrated info
1689 * enum bp_result - BP_RESULT_OK if information is available,
1690 * BP_RESULT_BADBIOSTABLE otherwise.
1692 static enum bp_result
construct_integrated_info(
1693 struct bios_parser
*bp
,
1694 struct integrated_info
*info
)
1696 enum bp_result result
= BP_RESULT_BADBIOSTABLE
;
1698 struct atom_common_table_header
*header
;
1699 struct atom_data_revision revision
;
1701 struct clock_voltage_caps temp
= {0, 0};
1705 if (info
&& DATA_TABLES(integratedsysteminfo
)) {
1706 header
= GET_IMAGE(struct atom_common_table_header
,
1707 DATA_TABLES(integratedsysteminfo
));
1709 get_atom_data_table_revision(header
, &revision
);
1711 /* Don't need to check major revision as they are all 1 */
1712 switch (revision
.minor
) {
1714 result
= get_integrated_info_v11(bp
, info
);
1721 if (result
!= BP_RESULT_OK
)
1724 /* Sort voltage table from low to high*/
1725 for (i
= 1; i
< NUMBER_OF_DISP_CLK_VOLTAGE
; ++i
) {
1726 for (j
= i
; j
> 0; --j
) {
1727 if (info
->disp_clk_voltage
[j
].max_supported_clk
<
1728 info
->disp_clk_voltage
[j
-1].max_supported_clk
1730 /* swap j and j - 1*/
1731 temp
= info
->disp_clk_voltage
[j
-1];
1732 info
->disp_clk_voltage
[j
-1] =
1733 info
->disp_clk_voltage
[j
];
1734 info
->disp_clk_voltage
[j
] = temp
;
1742 static struct integrated_info
*bios_parser_create_integrated_info(
1743 struct dc_bios
*dcb
)
1745 struct bios_parser
*bp
= BP_FROM_DCB(dcb
);
1746 struct integrated_info
*info
= NULL
;
1748 info
= kzalloc(sizeof(struct integrated_info
), GFP_KERNEL
);
1755 if (construct_integrated_info(bp
, info
) == BP_RESULT_OK
)
1763 static const struct dc_vbios_funcs vbios_funcs
= {
1764 .get_connectors_number
= bios_parser_get_connectors_number
,
1766 .get_encoder_id
= bios_parser_get_encoder_id
,
1768 .get_connector_id
= bios_parser_get_connector_id
,
1770 .get_dst_number
= bios_parser_get_dst_number
,
1772 .get_src_obj
= bios_parser_get_src_obj
,
1774 .get_dst_obj
= bios_parser_get_dst_obj
,
1776 .get_i2c_info
= bios_parser_get_i2c_info
,
1778 .get_voltage_ddc_info
= bios_parser_get_voltage_ddc_info
,
1780 .get_thermal_ddc_info
= bios_parser_get_thermal_ddc_info
,
1782 .get_hpd_info
= bios_parser_get_hpd_info
,
1784 .get_device_tag
= bios_parser_get_device_tag
,
1786 .get_firmware_info
= bios_parser_get_firmware_info
,
1788 .get_spread_spectrum_info
= bios_parser_get_spread_spectrum_info
,
1790 .get_ss_entry_number
= bios_parser_get_ss_entry_number
,
1792 .get_embedded_panel_info
= bios_parser_get_embedded_panel_info
,
1794 .get_gpio_pin_info
= bios_parser_get_gpio_pin_info
,
1796 .get_encoder_cap_info
= bios_parser_get_encoder_cap_info
,
1798 .is_device_id_supported
= bios_parser_is_device_id_supported
,
1802 .is_accelerated_mode
= bios_parser_is_accelerated_mode
,
1804 .set_scratch_critical_state
= bios_parser_set_scratch_critical_state
,
1808 .encoder_control
= bios_parser_encoder_control
,
1810 .transmitter_control
= bios_parser_transmitter_control
,
1812 .enable_crtc
= bios_parser_enable_crtc
,
1814 .set_pixel_clock
= bios_parser_set_pixel_clock
,
1816 .set_dce_clock
= bios_parser_set_dce_clock
,
1818 .program_crtc_timing
= bios_parser_program_crtc_timing
,
1820 /* .blank_crtc = bios_parser_blank_crtc, */
1822 .crtc_source_select
= bios_parser_crtc_source_select
,
1824 /* .external_encoder_control = bios_parser_external_encoder_control, */
1826 .enable_disp_power_gating
= bios_parser_enable_disp_power_gating
,
1828 .post_init
= bios_parser_post_init
,
1830 .bios_parser_destroy
= firmware_parser_destroy
,
1832 .get_smu_clock_info
= bios_parser_get_smu_clock_info
,
1835 static bool bios_parser_construct(
1836 struct bios_parser
*bp
,
1837 struct bp_init_data
*init
,
1838 enum dce_version dce_version
)
1840 uint16_t *rom_header_offset
= NULL
;
1841 struct atom_rom_header_v2_2
*rom_header
= NULL
;
1842 struct display_object_info_table_v1_4
*object_info_tbl
;
1843 struct atom_data_revision tbl_rev
= {0};
1851 bp
->base
.funcs
= &vbios_funcs
;
1852 bp
->base
.bios
= init
->bios
;
1853 bp
->base
.bios_size
= bp
->base
.bios
[OFFSET_TO_ATOM_ROM_IMAGE_SIZE
] * BIOS_IMAGE_SIZE_UNIT
;
1855 bp
->base
.ctx
= init
->ctx
;
1857 bp
->base
.bios_local_image
= NULL
;
1860 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER
);
1862 if (!rom_header_offset
)
1865 rom_header
= GET_IMAGE(struct atom_rom_header_v2_2
, *rom_header_offset
);
1870 get_atom_data_table_revision(&rom_header
->table_header
, &tbl_rev
);
1871 if (!(tbl_rev
.major
>= 2 && tbl_rev
.minor
>= 2))
1874 bp
->master_data_tbl
=
1875 GET_IMAGE(struct atom_master_data_table_v2_1
,
1876 rom_header
->masterdatatable_offset
);
1878 if (!bp
->master_data_tbl
)
1881 bp
->object_info_tbl_offset
= DATA_TABLES(displayobjectinfo
);
1883 if (!bp
->object_info_tbl_offset
)
1887 GET_IMAGE(struct display_object_info_table_v1_4
,
1888 bp
->object_info_tbl_offset
);
1890 if (!object_info_tbl
)
1893 get_atom_data_table_revision(&object_info_tbl
->table_header
,
1894 &bp
->object_info_tbl
.revision
);
1896 if (bp
->object_info_tbl
.revision
.major
== 1
1897 && bp
->object_info_tbl
.revision
.minor
>= 4) {
1898 struct display_object_info_table_v1_4
*tbl_v1_4
;
1900 tbl_v1_4
= GET_IMAGE(struct display_object_info_table_v1_4
,
1901 bp
->object_info_tbl_offset
);
1905 bp
->object_info_tbl
.v1_4
= tbl_v1_4
;
1909 dal_firmware_parser_init_cmd_tbl(bp
);
1910 dal_bios_parser_init_cmd_tbl_helper2(&bp
->cmd_helper
, dce_version
);
1912 bp
->base
.integrated_info
= bios_parser_create_integrated_info(&bp
->base
);
1917 struct dc_bios
*firmware_parser_create(
1918 struct bp_init_data
*init
,
1919 enum dce_version dce_version
)
1921 struct bios_parser
*bp
= NULL
;
1923 bp
= kzalloc(sizeof(struct bios_parser
), GFP_KERNEL
);
1927 if (bios_parser_construct(bp
, init
, dce_version
))