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