]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
Linux 6.14-rc3
[linux.git] / drivers / gpu / drm / amd / display / dc / bios / bios_parser2.c
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #include "dm_services.h"
27 #include "core_types.h"
28
29 #include "ObjectID.h"
30 #include "atomfirmware.h"
31
32 #include "dc_bios_types.h"
33 #include "include/grph_object_ctrl_defs.h"
34 #include "include/bios_parser_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 #define DC_LOGGER \
48         bp->base.ctx->logger
49
50 #define LAST_RECORD_TYPE 0xff
51 #define SMU9_SYSPLL0_ID  0
52
53 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
54         struct atom_i2c_record *record,
55         struct graphics_object_i2c_info *info);
56
57 static enum bp_result bios_parser_get_firmware_info(
58         struct dc_bios *dcb,
59         struct dc_firmware_info *info);
60
61 static enum bp_result bios_parser_get_encoder_cap_info(
62         struct dc_bios *dcb,
63         struct graphics_object_id object_id,
64         struct bp_encoder_cap_info *info);
65
66 static enum bp_result get_firmware_info_v3_1(
67         struct bios_parser *bp,
68         struct dc_firmware_info *info);
69
70 static enum bp_result get_firmware_info_v3_2(
71         struct bios_parser *bp,
72         struct dc_firmware_info *info);
73
74 static enum bp_result get_firmware_info_v3_4(
75         struct bios_parser *bp,
76         struct dc_firmware_info *info);
77
78 static enum bp_result get_firmware_info_v3_5(
79         struct bios_parser *bp,
80         struct dc_firmware_info *info);
81
82 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
83                 struct atom_display_object_path_v2 *object);
84
85 static struct atom_encoder_caps_record *get_encoder_cap_record(
86         struct bios_parser *bp,
87         struct atom_display_object_path_v2 *object);
88
89 #define BIOS_IMAGE_SIZE_OFFSET 2
90 #define BIOS_IMAGE_SIZE_UNIT 512
91
92 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
93
94 static void bios_parser2_destruct(struct bios_parser *bp)
95 {
96         kfree(bp->base.bios_local_image);
97         kfree(bp->base.integrated_info);
98 }
99
100 static void firmware_parser_destroy(struct dc_bios **dcb)
101 {
102         struct bios_parser *bp = BP_FROM_DCB(*dcb);
103
104         if (!bp) {
105                 BREAK_TO_DEBUGGER();
106                 return;
107         }
108
109         bios_parser2_destruct(bp);
110
111         kfree(bp);
112         *dcb = NULL;
113 }
114
115 static void get_atom_data_table_revision(
116         struct atom_common_table_header *atom_data_tbl,
117         struct atom_data_revision *tbl_revision)
118 {
119         if (!tbl_revision)
120                 return;
121
122         /* initialize the revision to 0 which is invalid revision */
123         tbl_revision->major = 0;
124         tbl_revision->minor = 0;
125
126         if (!atom_data_tbl)
127                 return;
128
129         tbl_revision->major =
130                         (uint32_t) atom_data_tbl->format_revision & 0x3f;
131         tbl_revision->minor =
132                         (uint32_t) atom_data_tbl->content_revision & 0x3f;
133 }
134
135 /* BIOS oject table displaypath is per connector.
136  * There is extra path not for connector. BIOS fill its encoderid as 0
137  */
138 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
139 {
140         struct bios_parser *bp = BP_FROM_DCB(dcb);
141         unsigned int count = 0;
142         unsigned int i;
143
144         switch (bp->object_info_tbl.revision.minor) {
145         default:
146         case 4:
147                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++)
148                         if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
149                                 count++;
150
151                 break;
152
153         case 5:
154                 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++)
155                         if (bp->object_info_tbl.v1_5->display_path[i].encoderobjid != 0)
156                                 count++;
157
158                 break;
159         }
160         return count;
161 }
162
163 static struct graphics_object_id bios_parser_get_connector_id(
164         struct dc_bios *dcb,
165         uint8_t i)
166 {
167         struct bios_parser *bp = BP_FROM_DCB(dcb);
168         struct graphics_object_id object_id = dal_graphics_object_id_init(
169                 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
170         struct object_info_table *tbl = &bp->object_info_tbl;
171         struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
172
173         struct display_object_info_table_v1_5 *v1_5 = tbl->v1_5;
174
175         switch (bp->object_info_tbl.revision.minor) {
176         default:
177         case 4:
178                 if (v1_4->number_of_path > i) {
179                         /* If display_objid is generic object id,  the encoderObj
180                          * /extencoderobjId should be 0
181                          */
182                         if (v1_4->display_path[i].encoderobjid != 0 &&
183                             v1_4->display_path[i].display_objid != 0)
184                                 object_id = object_id_from_bios_object_id(
185                                         v1_4->display_path[i].display_objid);
186                 }
187                 break;
188
189         case 5:
190                 if (v1_5->number_of_path > i) {
191                         /* If display_objid is generic object id,  the encoderObjId
192                  * should be 0
193                  */
194                         if (v1_5->display_path[i].encoderobjid != 0 &&
195                             v1_5->display_path[i].display_objid != 0)
196                                 object_id = object_id_from_bios_object_id(
197                                         v1_5->display_path[i].display_objid);
198                 }
199                 break;
200         }
201         return object_id;
202 }
203
204 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
205         struct graphics_object_id object_id, uint32_t index,
206         struct graphics_object_id *src_object_id)
207 {
208         struct bios_parser *bp = BP_FROM_DCB(dcb);
209         unsigned int i;
210         enum bp_result bp_result = BP_RESULT_BADINPUT;
211         struct graphics_object_id obj_id = { 0 };
212         struct object_info_table *tbl = &bp->object_info_tbl;
213
214         if (!src_object_id)
215                 return bp_result;
216
217         switch (object_id.type) {
218         /* Encoder's Source is GPU.  BIOS does not provide GPU, since all
219          * displaypaths point to same GPU (0x1100).  Hardcode GPU object type
220          */
221         case OBJECT_TYPE_ENCODER:
222                 /* TODO: since num of src must be less than 2.
223                  * If found in for loop, should break.
224                  * DAL2 implementation may be changed too
225                  */
226                 switch (bp->object_info_tbl.revision.minor) {
227                 default:
228                 case 4:
229                         for (i = 0; i < tbl->v1_4->number_of_path; i++) {
230                                 obj_id = object_id_from_bios_object_id(
231                                         tbl->v1_4->display_path[i].encoderobjid);
232                                 if (object_id.type == obj_id.type &&
233                                     object_id.id == obj_id.id &&
234                                     object_id.enum_id == obj_id.enum_id) {
235                                         *src_object_id =
236                                                 object_id_from_bios_object_id(
237                                                         0x1100);
238                                         /* break; */
239                                 }
240                         }
241                         bp_result = BP_RESULT_OK;
242                         break;
243
244                 case 5:
245                         for (i = 0; i < tbl->v1_5->number_of_path; i++) {
246                                 obj_id = object_id_from_bios_object_id(
247                                         tbl->v1_5->display_path[i].encoderobjid);
248                                 if (object_id.type == obj_id.type &&
249                                     object_id.id == obj_id.id &&
250                                     object_id.enum_id == obj_id.enum_id) {
251                                         *src_object_id =
252                                                 object_id_from_bios_object_id(
253                                                         0x1100);
254                                         /* break; */
255                                 }
256                         }
257                         bp_result = BP_RESULT_OK;
258                         break;
259                 }
260                 break;
261         case OBJECT_TYPE_CONNECTOR:
262                 switch (bp->object_info_tbl.revision.minor) {
263                 default:
264                 case 4:
265                         for (i = 0; i < tbl->v1_4->number_of_path; i++) {
266                                 obj_id = object_id_from_bios_object_id(
267                                         tbl->v1_4->display_path[i]
268                                                 .display_objid);
269
270                                 if (object_id.type == obj_id.type &&
271                                     object_id.id == obj_id.id &&
272                                     object_id.enum_id == obj_id.enum_id) {
273                                         *src_object_id =
274                                                 object_id_from_bios_object_id(
275                                                         tbl->v1_4
276                                                                 ->display_path[i]
277                                                                 .encoderobjid);
278                                         /* break; */
279                                 }
280                         }
281                         bp_result = BP_RESULT_OK;
282                         break;
283                 }
284                 bp_result = BP_RESULT_OK;
285                 break;
286                 case 5:
287                         for (i = 0; i < tbl->v1_5->number_of_path; i++) {
288                                 obj_id = object_id_from_bios_object_id(
289                                                                        tbl->v1_5->display_path[i].display_objid);
290
291                                 if (object_id.type == obj_id.type &&
292                                     object_id.id == obj_id.id &&
293                                     object_id.enum_id == obj_id.enum_id) {
294                                         *src_object_id = object_id_from_bios_object_id(
295                                                                                        tbl->v1_5->display_path[i].encoderobjid);
296                                         /* break; */
297                                 }
298                         }
299                 bp_result = BP_RESULT_OK;
300                 break;
301
302         default:
303                 bp_result = BP_RESULT_OK;
304                 break;
305         }
306
307         return bp_result;
308 }
309
310 /* from graphics_object_id, find display path which includes the object_id */
311 static struct atom_display_object_path_v2 *get_bios_object(
312                 struct bios_parser *bp,
313                 struct graphics_object_id id)
314 {
315         unsigned int i;
316         struct graphics_object_id obj_id = {0};
317
318         switch (id.type) {
319         case OBJECT_TYPE_ENCODER:
320                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
321                         obj_id = object_id_from_bios_object_id(
322                                         bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
323                         if (id.type == obj_id.type && id.id == obj_id.id
324                                         && id.enum_id == obj_id.enum_id)
325                                 return &bp->object_info_tbl.v1_4->display_path[i];
326                 }
327                 fallthrough;
328         case OBJECT_TYPE_CONNECTOR:
329         case OBJECT_TYPE_GENERIC:
330                 /* Both Generic and Connector Object ID
331                  * will be stored on display_objid
332                  */
333                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
334                         obj_id = object_id_from_bios_object_id(
335                                         bp->object_info_tbl.v1_4->display_path[i].display_objid);
336                         if (id.type == obj_id.type && id.id == obj_id.id
337                                         && id.enum_id == obj_id.enum_id)
338                                 return &bp->object_info_tbl.v1_4->display_path[i];
339                 }
340                 fallthrough;
341         default:
342                 return NULL;
343         }
344 }
345
346 /* from graphics_object_id, find display path which includes the object_id */
347 static struct atom_display_object_path_v3 *get_bios_object_from_path_v3(struct bios_parser *bp,
348                                                                         struct graphics_object_id id)
349 {
350         unsigned int i;
351         struct graphics_object_id obj_id = {0};
352
353         switch (id.type) {
354         case OBJECT_TYPE_ENCODER:
355                 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
356                         obj_id = object_id_from_bios_object_id(
357                                         bp->object_info_tbl.v1_5->display_path[i].encoderobjid);
358                         if (id.type == obj_id.type && id.id == obj_id.id
359                                         && id.enum_id == obj_id.enum_id)
360                                 return &bp->object_info_tbl.v1_5->display_path[i];
361                 }
362         break;
363
364         case OBJECT_TYPE_CONNECTOR:
365         case OBJECT_TYPE_GENERIC:
366                 /* Both Generic and Connector Object ID
367                  * will be stored on display_objid
368                  */
369                 for (i = 0; i < bp->object_info_tbl.v1_5->number_of_path; i++) {
370                         obj_id = object_id_from_bios_object_id(
371                                         bp->object_info_tbl.v1_5->display_path[i].display_objid);
372                         if (id.type == obj_id.type && id.id == obj_id.id
373                                         && id.enum_id == obj_id.enum_id)
374                                 return &bp->object_info_tbl.v1_5->display_path[i];
375                 }
376         break;
377
378         default:
379                 return NULL;
380         }
381
382         return NULL;
383 }
384
385 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
386         struct graphics_object_id id,
387         struct graphics_object_i2c_info *info)
388 {
389         uint32_t offset;
390         struct atom_display_object_path_v2 *object;
391
392         struct atom_display_object_path_v3 *object_path_v3;
393
394         struct atom_common_record_header *header;
395         struct atom_i2c_record *record;
396         struct atom_i2c_record dummy_record = {0};
397         struct bios_parser *bp = BP_FROM_DCB(dcb);
398
399         if (!info)
400                 return BP_RESULT_BADINPUT;
401
402         if (id.type == OBJECT_TYPE_GENERIC) {
403                 dummy_record.i2c_id = id.id;
404
405                 if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
406                         return BP_RESULT_OK;
407                 else
408                         return BP_RESULT_NORECORD;
409         }
410
411         switch (bp->object_info_tbl.revision.minor) {
412         case 4:
413         default:
414                 object = get_bios_object(bp, id);
415
416                 if (!object)
417                         return BP_RESULT_BADINPUT;
418
419                 offset = object->disp_recordoffset + bp->object_info_tbl_offset;
420                 break;
421         case 5:
422                 object_path_v3 = get_bios_object_from_path_v3(bp, id);
423
424                 if (!object_path_v3)
425                         return BP_RESULT_BADINPUT;
426
427                 offset = object_path_v3->disp_recordoffset + bp->object_info_tbl_offset;
428                 break;
429         }
430
431         for (;;) {
432                 header = GET_IMAGE(struct atom_common_record_header, offset);
433
434                 if (!header)
435                         return BP_RESULT_BADBIOSTABLE;
436
437                 if (header->record_type == LAST_RECORD_TYPE ||
438                         !header->record_size)
439                         break;
440
441                 if (header->record_type == ATOM_I2C_RECORD_TYPE
442                         && sizeof(struct atom_i2c_record) <=
443                                                         header->record_size) {
444                         /* get the I2C info */
445                         record = (struct atom_i2c_record *) header;
446
447                         if (get_gpio_i2c_info(bp, record, info) ==
448                                                                 BP_RESULT_OK)
449                                 return BP_RESULT_OK;
450                 }
451
452                 offset += header->record_size;
453         }
454
455         return BP_RESULT_NORECORD;
456 }
457
458 static enum bp_result get_gpio_i2c_info(
459         struct bios_parser *bp,
460         struct atom_i2c_record *record,
461         struct graphics_object_i2c_info *info)
462 {
463         struct atom_gpio_pin_lut_v2_1 *header;
464         uint32_t count = 0;
465         unsigned int table_index = 0;
466         bool find_valid = false;
467         struct atom_gpio_pin_assignment *pin;
468
469         if (!info)
470                 return BP_RESULT_BADINPUT;
471
472         /* get the GPIO_I2C info */
473         if (!DATA_TABLES(gpio_pin_lut))
474                 return BP_RESULT_BADBIOSTABLE;
475
476         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
477                                         DATA_TABLES(gpio_pin_lut));
478         if (!header)
479                 return BP_RESULT_BADBIOSTABLE;
480
481         if (sizeof(struct atom_common_table_header) +
482                         sizeof(struct atom_gpio_pin_assignment) >
483                         le16_to_cpu(header->table_header.structuresize))
484                 return BP_RESULT_BADBIOSTABLE;
485
486         /* TODO: is version change? */
487         if (header->table_header.content_revision != 1)
488                 return BP_RESULT_UNSUPPORTED;
489
490         /* get data count */
491         count = (le16_to_cpu(header->table_header.structuresize)
492                         - sizeof(struct atom_common_table_header))
493                                 / sizeof(struct atom_gpio_pin_assignment);
494
495         pin = (struct atom_gpio_pin_assignment *) header->gpio_pin;
496
497         for (table_index = 0; table_index < count; table_index++) {
498                 if (((record->i2c_id & I2C_HW_CAP)                              == (pin->gpio_id & I2C_HW_CAP)) &&
499                     ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)   == (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) &&
500                     ((record->i2c_id & I2C_HW_LANE_MUX)                 == (pin->gpio_id & I2C_HW_LANE_MUX))) {
501                         /* still valid */
502                         find_valid = true;
503                         break;
504                 }
505                 pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment));
506         }
507
508         /* If we don't find the entry that we are looking for then
509          *  we will return BP_Result_BadBiosTable.
510          */
511         if (find_valid == false)
512                 return BP_RESULT_BADBIOSTABLE;
513
514         /* get the GPIO_I2C_INFO */
515         info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
516         info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
517         info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
518         info->i2c_slave_address = record->i2c_slave_addr;
519
520         /* TODO: check how to get register offset for en, Y, etc. */
521         info->gpio_info.clk_a_register_index = le16_to_cpu(pin->data_a_reg_index);
522         info->gpio_info.clk_a_shift = pin->gpio_bitshift;
523
524         return BP_RESULT_OK;
525 }
526
527 static struct atom_hpd_int_record *get_hpd_record_for_path_v3(struct bios_parser *bp,
528                                                               struct atom_display_object_path_v3 *object)
529 {
530         struct atom_common_record_header *header;
531         uint32_t offset;
532
533         if (!object) {
534                 BREAK_TO_DEBUGGER(); /* Invalid object */
535                 return NULL;
536         }
537
538         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
539
540         for (;;) {
541                 header = GET_IMAGE(struct atom_common_record_header, offset);
542
543                 if (!header)
544                         return NULL;
545
546                 if (header->record_type == ATOM_RECORD_END_TYPE ||
547                         !header->record_size)
548                         break;
549
550                 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
551                         && sizeof(struct atom_hpd_int_record) <=
552                                                         header->record_size)
553                         return (struct atom_hpd_int_record *) header;
554
555                 offset += header->record_size;
556         }
557
558         return NULL;
559 }
560
561 static enum bp_result bios_parser_get_hpd_info(
562         struct dc_bios *dcb,
563         struct graphics_object_id id,
564         struct graphics_object_hpd_info *info)
565 {
566         struct bios_parser *bp = BP_FROM_DCB(dcb);
567         struct atom_display_object_path_v2 *object;
568         struct atom_display_object_path_v3 *object_path_v3;
569         struct atom_hpd_int_record *record = NULL;
570
571         if (!info)
572                 return BP_RESULT_BADINPUT;
573
574         switch (bp->object_info_tbl.revision.minor) {
575         case 4:
576         default:
577                 object = get_bios_object(bp, id);
578
579                 if (!object)
580                         return BP_RESULT_BADINPUT;
581
582                 record = get_hpd_record(bp, object);
583                 break;
584         case 5:
585                 object_path_v3 = get_bios_object_from_path_v3(bp, id);
586
587                 if (!object_path_v3)
588                         return BP_RESULT_BADINPUT;
589
590                 record = get_hpd_record_for_path_v3(bp, object_path_v3);
591                 break;
592         }
593
594         if (record != NULL) {
595                 info->hpd_int_gpio_uid = record->pin_id;
596                 info->hpd_active = record->plugin_pin_state;
597                 return BP_RESULT_OK;
598         }
599
600         return BP_RESULT_NORECORD;
601 }
602
603 static struct atom_hpd_int_record *get_hpd_record(
604         struct bios_parser *bp,
605         struct atom_display_object_path_v2 *object)
606 {
607         struct atom_common_record_header *header;
608         uint32_t offset;
609
610         if (!object) {
611                 BREAK_TO_DEBUGGER(); /* Invalid object */
612                 return NULL;
613         }
614
615         offset = le16_to_cpu(object->disp_recordoffset)
616                         + bp->object_info_tbl_offset;
617
618         for (;;) {
619                 header = GET_IMAGE(struct atom_common_record_header, offset);
620
621                 if (!header)
622                         return NULL;
623
624                 if (header->record_type == LAST_RECORD_TYPE ||
625                         !header->record_size)
626                         break;
627
628                 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
629                         && sizeof(struct atom_hpd_int_record) <=
630                                                         header->record_size)
631                         return (struct atom_hpd_int_record *) header;
632
633                 offset += header->record_size;
634         }
635
636         return NULL;
637 }
638
639 /**
640  * bios_parser_get_gpio_pin_info
641  * Get GpioPin information of input gpio id
642  *
643  * @dcb:     pointer to the DC BIOS
644  * @gpio_id: GPIO ID
645  * @info:    GpioPin information structure
646  * return: Bios parser result code
647  * note:
648  *  to get the GPIO PIN INFO, we need:
649  *  1. get the GPIO_ID from other object table, see GetHPDInfo()
650  *  2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
651  *      to get the registerA  offset/mask
652  */
653 static enum bp_result bios_parser_get_gpio_pin_info(
654         struct dc_bios *dcb,
655         uint32_t gpio_id,
656         struct gpio_pin_info *info)
657 {
658         struct bios_parser *bp = BP_FROM_DCB(dcb);
659         struct atom_gpio_pin_lut_v2_1 *header;
660         uint32_t count = 0;
661         uint32_t i = 0;
662
663         if (!DATA_TABLES(gpio_pin_lut))
664                 return BP_RESULT_BADBIOSTABLE;
665
666         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
667                                                 DATA_TABLES(gpio_pin_lut));
668         if (!header)
669                 return BP_RESULT_BADBIOSTABLE;
670
671         if (sizeof(struct atom_common_table_header) +
672                         sizeof(struct atom_gpio_pin_assignment)
673                         > le16_to_cpu(header->table_header.structuresize))
674                 return BP_RESULT_BADBIOSTABLE;
675
676         if (header->table_header.content_revision != 1)
677                 return BP_RESULT_UNSUPPORTED;
678
679         /* Temporary hard code gpio pin info */
680         count = (le16_to_cpu(header->table_header.structuresize)
681                         - sizeof(struct atom_common_table_header))
682                                 / sizeof(struct atom_gpio_pin_assignment);
683         for (i = 0; i < count; ++i) {
684                 if (header->gpio_pin[i].gpio_id != gpio_id)
685                         continue;
686
687                 info->offset =
688                         (uint32_t) le16_to_cpu(
689                                         header->gpio_pin[i].data_a_reg_index);
690                 info->offset_y = info->offset + 2;
691                 info->offset_en = info->offset + 1;
692                 info->offset_mask = info->offset - 1;
693
694                 info->mask = (uint32_t) (1 <<
695                         header->gpio_pin[i].gpio_bitshift);
696                 info->mask_y = info->mask + 2;
697                 info->mask_en = info->mask + 1;
698                 info->mask_mask = info->mask - 1;
699
700                 return BP_RESULT_OK;
701         }
702
703         return BP_RESULT_NORECORD;
704 }
705
706 static struct device_id device_type_from_device_id(uint16_t device_id)
707 {
708
709         struct device_id result_device_id;
710
711         result_device_id.raw_device_tag = device_id;
712
713         switch (device_id) {
714         case ATOM_DISPLAY_LCD1_SUPPORT:
715                 result_device_id.device_type = DEVICE_TYPE_LCD;
716                 result_device_id.enum_id = 1;
717                 break;
718
719         case ATOM_DISPLAY_LCD2_SUPPORT:
720                 result_device_id.device_type = DEVICE_TYPE_LCD;
721                 result_device_id.enum_id = 2;
722                 break;
723
724         case ATOM_DISPLAY_DFP1_SUPPORT:
725                 result_device_id.device_type = DEVICE_TYPE_DFP;
726                 result_device_id.enum_id = 1;
727                 break;
728
729         case ATOM_DISPLAY_DFP2_SUPPORT:
730                 result_device_id.device_type = DEVICE_TYPE_DFP;
731                 result_device_id.enum_id = 2;
732                 break;
733
734         case ATOM_DISPLAY_DFP3_SUPPORT:
735                 result_device_id.device_type = DEVICE_TYPE_DFP;
736                 result_device_id.enum_id = 3;
737                 break;
738
739         case ATOM_DISPLAY_DFP4_SUPPORT:
740                 result_device_id.device_type = DEVICE_TYPE_DFP;
741                 result_device_id.enum_id = 4;
742                 break;
743
744         case ATOM_DISPLAY_DFP5_SUPPORT:
745                 result_device_id.device_type = DEVICE_TYPE_DFP;
746                 result_device_id.enum_id = 5;
747                 break;
748
749         case ATOM_DISPLAY_DFP6_SUPPORT:
750                 result_device_id.device_type = DEVICE_TYPE_DFP;
751                 result_device_id.enum_id = 6;
752                 break;
753
754         default:
755                 BREAK_TO_DEBUGGER(); /* Invalid device Id */
756                 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
757                 result_device_id.enum_id = 0;
758         }
759         return result_device_id;
760 }
761
762 static enum bp_result bios_parser_get_device_tag(
763         struct dc_bios *dcb,
764         struct graphics_object_id connector_object_id,
765         uint32_t device_tag_index,
766         struct connector_device_tag_info *info)
767 {
768         struct bios_parser *bp = BP_FROM_DCB(dcb);
769         struct atom_display_object_path_v2 *object;
770
771         struct atom_display_object_path_v3 *object_path_v3;
772
773
774         if (!info)
775                 return BP_RESULT_BADINPUT;
776
777         switch (bp->object_info_tbl.revision.minor) {
778         case 4:
779         default:
780                 /* getBiosObject will return MXM object */
781                 object = get_bios_object(bp, connector_object_id);
782
783                 if (!object) {
784                         BREAK_TO_DEBUGGER(); /* Invalid object id */
785                         return BP_RESULT_BADINPUT;
786                 }
787
788                 info->acpi_device = 0; /* BIOS no longer provides this */
789                 info->dev_id = device_type_from_device_id(object->device_tag);
790                 break;
791         case 5:
792                 object_path_v3 = get_bios_object_from_path_v3(bp, connector_object_id);
793
794                 if (!object_path_v3) {
795                         BREAK_TO_DEBUGGER(); /* Invalid object id */
796                         return BP_RESULT_BADINPUT;
797                 }
798                 info->acpi_device = 0; /* BIOS no longer provides this */
799                 info->dev_id = device_type_from_device_id(object_path_v3->device_tag);
800                 break;
801         }
802
803         return BP_RESULT_OK;
804 }
805
806 static enum bp_result get_ss_info_v4_1(
807         struct bios_parser *bp,
808         uint32_t id,
809         uint32_t index,
810         struct spread_spectrum_info *ss_info)
811 {
812         enum bp_result result = BP_RESULT_OK;
813         struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
814         struct atom_smu_info_v3_3 *smu_info = NULL;
815
816         if (!ss_info)
817                 return BP_RESULT_BADINPUT;
818
819         if (!DATA_TABLES(dce_info))
820                 return BP_RESULT_BADBIOSTABLE;
821
822         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_1,
823                                                         DATA_TABLES(dce_info));
824         if (!disp_cntl_tbl)
825                 return BP_RESULT_BADBIOSTABLE;
826
827
828         ss_info->type.STEP_AND_DELAY_INFO = false;
829         ss_info->spread_percentage_divider = 1000;
830         /* BIOS no longer uses target clock.  Always enable for now */
831         ss_info->target_clock_range = 0xffffffff;
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
842                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
843                 break;
844         case AS_SIGNAL_TYPE_HDMI:
845                 ss_info->spread_spectrum_percentage =
846                                 disp_cntl_tbl->hdmi_ss_percentage;
847                 ss_info->spread_spectrum_range =
848                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
849                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
850                         ss_info->type.CENTER_MODE = true;
851
852                 DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
853                 break;
854         /* TODO LVDS not support anymore? */
855         case AS_SIGNAL_TYPE_DISPLAY_PORT:
856                 ss_info->spread_spectrum_percentage =
857                                 disp_cntl_tbl->dp_ss_percentage;
858                 ss_info->spread_spectrum_range =
859                                 disp_cntl_tbl->dp_ss_rate_10hz * 10;
860                 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
861                         ss_info->type.CENTER_MODE = true;
862
863                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
864                 break;
865         case AS_SIGNAL_TYPE_GPU_PLL:
866                 /* atom_firmware: DAL only get data from dce_info table.
867                  * if data within smu_info is needed for DAL, VBIOS should
868                  * copy it into dce_info
869                  */
870                 result = BP_RESULT_UNSUPPORTED;
871                 break;
872         case AS_SIGNAL_TYPE_XGMI:
873                 smu_info =  GET_IMAGE(struct atom_smu_info_v3_3,
874                                       DATA_TABLES(smu_info));
875                 if (!smu_info)
876                         return BP_RESULT_BADBIOSTABLE;
877                 DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info->gpuclk_ss_percentage);
878                 ss_info->spread_spectrum_percentage =
879                                 smu_info->waflclk_ss_percentage;
880                 ss_info->spread_spectrum_range =
881                                 smu_info->gpuclk_ss_rate_10hz * 10;
882                 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
883                         ss_info->type.CENTER_MODE = true;
884
885                 DC_LOG_BIOS("AS_SIGNAL_TYPE_XGMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
886                 break;
887         default:
888                 result = BP_RESULT_UNSUPPORTED;
889         }
890
891         return result;
892 }
893
894 static enum bp_result get_ss_info_v4_2(
895         struct bios_parser *bp,
896         uint32_t id,
897         uint32_t index,
898         struct spread_spectrum_info *ss_info)
899 {
900         enum bp_result result = BP_RESULT_OK;
901         struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
902         struct atom_smu_info_v3_1 *smu_info = NULL;
903
904         if (!ss_info)
905                 return BP_RESULT_BADINPUT;
906
907         if (!DATA_TABLES(dce_info))
908                 return BP_RESULT_BADBIOSTABLE;
909
910         if (!DATA_TABLES(smu_info))
911                 return BP_RESULT_BADBIOSTABLE;
912
913         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_2,
914                                                         DATA_TABLES(dce_info));
915         if (!disp_cntl_tbl)
916                 return BP_RESULT_BADBIOSTABLE;
917
918         smu_info =  GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
919         if (!smu_info)
920                 return BP_RESULT_BADBIOSTABLE;
921
922         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info->gpuclk_ss_percentage);
923         ss_info->type.STEP_AND_DELAY_INFO = false;
924         ss_info->spread_percentage_divider = 1000;
925         /* BIOS no longer uses target clock.  Always enable for now */
926         ss_info->target_clock_range = 0xffffffff;
927
928         switch (id) {
929         case AS_SIGNAL_TYPE_DVI:
930                 ss_info->spread_spectrum_percentage =
931                                 disp_cntl_tbl->dvi_ss_percentage;
932                 ss_info->spread_spectrum_range =
933                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
934                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
935                         ss_info->type.CENTER_MODE = true;
936
937                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
938                 break;
939         case AS_SIGNAL_TYPE_HDMI:
940                 ss_info->spread_spectrum_percentage =
941                                 disp_cntl_tbl->hdmi_ss_percentage;
942                 ss_info->spread_spectrum_range =
943                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
944                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
945                         ss_info->type.CENTER_MODE = true;
946
947                 DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
948                 break;
949         /* TODO LVDS not support anymore? */
950         case AS_SIGNAL_TYPE_DISPLAY_PORT:
951                 ss_info->spread_spectrum_percentage =
952                                 smu_info->gpuclk_ss_percentage;
953                 ss_info->spread_spectrum_range =
954                                 smu_info->gpuclk_ss_rate_10hz * 10;
955                 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
956                         ss_info->type.CENTER_MODE = true;
957
958                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
959                 break;
960         case AS_SIGNAL_TYPE_GPU_PLL:
961                 /* atom_firmware: DAL only get data from dce_info table.
962                  * if data within smu_info is needed for DAL, VBIOS should
963                  * copy it into dce_info
964                  */
965                 result = BP_RESULT_UNSUPPORTED;
966                 break;
967         default:
968                 result = BP_RESULT_UNSUPPORTED;
969         }
970
971         return result;
972 }
973
974 static enum bp_result get_ss_info_v4_5(
975         struct bios_parser *bp,
976         uint32_t id,
977         uint32_t index,
978         struct spread_spectrum_info *ss_info)
979 {
980         enum bp_result result = BP_RESULT_OK;
981         struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
982
983         if (!ss_info)
984                 return BP_RESULT_BADINPUT;
985
986         if (!DATA_TABLES(dce_info))
987                 return BP_RESULT_BADBIOSTABLE;
988
989         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_5,
990                                                         DATA_TABLES(dce_info));
991         if (!disp_cntl_tbl)
992                 return BP_RESULT_BADBIOSTABLE;
993
994         ss_info->type.STEP_AND_DELAY_INFO = false;
995         ss_info->spread_percentage_divider = 1000;
996         /* BIOS no longer uses target clock.  Always enable for now */
997         ss_info->target_clock_range = 0xffffffff;
998
999         switch (id) {
1000         case AS_SIGNAL_TYPE_DVI:
1001                 ss_info->spread_spectrum_percentage =
1002                                 disp_cntl_tbl->dvi_ss_percentage;
1003                 ss_info->spread_spectrum_range =
1004                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
1005                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1006                         ss_info->type.CENTER_MODE = true;
1007
1008                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DVI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
1009                 break;
1010         case AS_SIGNAL_TYPE_HDMI:
1011                 ss_info->spread_spectrum_percentage =
1012                                 disp_cntl_tbl->hdmi_ss_percentage;
1013                 ss_info->spread_spectrum_range =
1014                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
1015                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1016                         ss_info->type.CENTER_MODE = true;
1017
1018                 DC_LOG_BIOS("AS_SIGNAL_TYPE_HDMI ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
1019                 break;
1020         case AS_SIGNAL_TYPE_DISPLAY_PORT:
1021                 if (bp->base.integrated_info) {
1022                         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", bp->base.integrated_info->gpuclk_ss_percentage);
1023                         ss_info->spread_spectrum_percentage =
1024                                         bp->base.integrated_info->gpuclk_ss_percentage;
1025                         ss_info->type.CENTER_MODE =
1026                                         bp->base.integrated_info->gpuclk_ss_type;
1027                 } else {
1028                         ss_info->spread_spectrum_percentage =
1029                                 disp_cntl_tbl->dp_ss_percentage;
1030                         ss_info->spread_spectrum_range =
1031                                 disp_cntl_tbl->dp_ss_rate_10hz * 10;
1032                         if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
1033                                 ss_info->type.CENTER_MODE = true;
1034                 }
1035                 DC_LOG_BIOS("AS_SIGNAL_TYPE_DISPLAY_PORT ss_percentage: %d\n", ss_info->spread_spectrum_percentage);
1036                 break;
1037         case AS_SIGNAL_TYPE_GPU_PLL:
1038                 /* atom_smu_info_v4_0 does not have fields for SS for SMU Display PLL anymore.
1039                  * SMU Display PLL supposed to be without spread.
1040                  * Better place for it would be in atom_display_controller_info_v4_5 table.
1041                  */
1042                 result = BP_RESULT_UNSUPPORTED;
1043                 break;
1044         default:
1045                 result = BP_RESULT_UNSUPPORTED;
1046                 break;
1047         }
1048
1049         return result;
1050 }
1051
1052 /**
1053  * bios_parser_get_spread_spectrum_info
1054  * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
1055  * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
1056  * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
1057  * ver 3.1,
1058  * there is only one entry for each signal /ss id.  However, there is
1059  * no planning of supporting multiple spread Sprectum entry for EverGreen
1060  * @dcb:     pointer to the DC BIOS
1061  * @signal:  ASSignalType to be converted to info index
1062  * @index:   number of entries that match the converted info index
1063  * @ss_info: sprectrum information structure,
1064  * return: Bios parser result code
1065  */
1066 static enum bp_result bios_parser_get_spread_spectrum_info(
1067         struct dc_bios *dcb,
1068         enum as_signal_type signal,
1069         uint32_t index,
1070         struct spread_spectrum_info *ss_info)
1071 {
1072         struct bios_parser *bp = BP_FROM_DCB(dcb);
1073         enum bp_result result = BP_RESULT_UNSUPPORTED;
1074         struct atom_common_table_header *header;
1075         struct atom_data_revision tbl_revision;
1076
1077         if (!ss_info) /* check for bad input */
1078                 return BP_RESULT_BADINPUT;
1079
1080         if (!DATA_TABLES(dce_info))
1081                 return BP_RESULT_UNSUPPORTED;
1082
1083         header = GET_IMAGE(struct atom_common_table_header,
1084                                                 DATA_TABLES(dce_info));
1085         get_atom_data_table_revision(header, &tbl_revision);
1086
1087         switch (tbl_revision.major) {
1088         case 4:
1089                 switch (tbl_revision.minor) {
1090                 case 1:
1091                         return get_ss_info_v4_1(bp, signal, index, ss_info);
1092                 case 2:
1093                 case 3:
1094                 case 4:
1095                         return get_ss_info_v4_2(bp, signal, index, ss_info);
1096                 case 5:
1097                         return get_ss_info_v4_5(bp, signal, index, ss_info);
1098
1099                 default:
1100                         ASSERT(0);
1101                         break;
1102                 }
1103                 break;
1104         default:
1105                 break;
1106         }
1107         /* there can not be more then one entry for SS Info table */
1108         return result;
1109 }
1110
1111 static enum bp_result get_soc_bb_info_v4_4(
1112         struct bios_parser *bp,
1113         struct bp_soc_bb_info *soc_bb_info)
1114 {
1115         enum bp_result result = BP_RESULT_OK;
1116         struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1117
1118         if (!soc_bb_info)
1119                 return BP_RESULT_BADINPUT;
1120
1121         if (!DATA_TABLES(dce_info))
1122                 return BP_RESULT_BADBIOSTABLE;
1123
1124         if (!DATA_TABLES(smu_info))
1125                 return BP_RESULT_BADBIOSTABLE;
1126
1127         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_4,
1128                                                         DATA_TABLES(dce_info));
1129         if (!disp_cntl_tbl)
1130                 return BP_RESULT_BADBIOSTABLE;
1131
1132         soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
1133         soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
1134         soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
1135
1136         return result;
1137 }
1138
1139 static enum bp_result get_soc_bb_info_v4_5(
1140         struct bios_parser *bp,
1141         struct bp_soc_bb_info *soc_bb_info)
1142 {
1143         enum bp_result result = BP_RESULT_OK;
1144         struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1145
1146         if (!soc_bb_info)
1147                 return BP_RESULT_BADINPUT;
1148
1149         if (!DATA_TABLES(dce_info))
1150                 return BP_RESULT_BADBIOSTABLE;
1151
1152         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_5,
1153                                                         DATA_TABLES(dce_info));
1154         if (!disp_cntl_tbl)
1155                 return BP_RESULT_BADBIOSTABLE;
1156
1157         soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
1158         soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
1159         soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
1160
1161         return result;
1162 }
1163
1164 static enum bp_result bios_parser_get_soc_bb_info(
1165         struct dc_bios *dcb,
1166         struct bp_soc_bb_info *soc_bb_info)
1167 {
1168         struct bios_parser *bp = BP_FROM_DCB(dcb);
1169         enum bp_result result = BP_RESULT_UNSUPPORTED;
1170         struct atom_common_table_header *header;
1171         struct atom_data_revision tbl_revision;
1172
1173         if (!soc_bb_info) /* check for bad input */
1174                 return BP_RESULT_BADINPUT;
1175
1176         if (!DATA_TABLES(dce_info))
1177                 return BP_RESULT_UNSUPPORTED;
1178
1179         header = GET_IMAGE(struct atom_common_table_header,
1180                                                 DATA_TABLES(dce_info));
1181         get_atom_data_table_revision(header, &tbl_revision);
1182
1183         switch (tbl_revision.major) {
1184         case 4:
1185                 switch (tbl_revision.minor) {
1186                 case 1:
1187                 case 2:
1188                 case 3:
1189                         break;
1190                 case 4:
1191                         result = get_soc_bb_info_v4_4(bp, soc_bb_info);
1192                         break;
1193                 case 5:
1194                         result = get_soc_bb_info_v4_5(bp, soc_bb_info);
1195                         break;
1196                 default:
1197                         break;
1198                 }
1199                 break;
1200         default:
1201                 break;
1202         }
1203
1204         return result;
1205 }
1206
1207 static enum bp_result get_disp_caps_v4_1(
1208         struct bios_parser *bp,
1209         uint8_t *dce_caps)
1210 {
1211         enum bp_result result = BP_RESULT_OK;
1212         struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
1213
1214         if (!dce_caps)
1215                 return BP_RESULT_BADINPUT;
1216
1217         if (!DATA_TABLES(dce_info))
1218                 return BP_RESULT_BADBIOSTABLE;
1219
1220         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
1221                                                         DATA_TABLES(dce_info));
1222
1223         if (!disp_cntl_tbl)
1224                 return BP_RESULT_BADBIOSTABLE;
1225
1226         *dce_caps = disp_cntl_tbl->display_caps;
1227
1228         return result;
1229 }
1230
1231 static enum bp_result get_disp_caps_v4_2(
1232         struct bios_parser *bp,
1233         uint8_t *dce_caps)
1234 {
1235         enum bp_result result = BP_RESULT_OK;
1236         struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
1237
1238         if (!dce_caps)
1239                 return BP_RESULT_BADINPUT;
1240
1241         if (!DATA_TABLES(dce_info))
1242                 return BP_RESULT_BADBIOSTABLE;
1243
1244         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
1245                                                         DATA_TABLES(dce_info));
1246
1247         if (!disp_cntl_tbl)
1248                 return BP_RESULT_BADBIOSTABLE;
1249
1250         *dce_caps = disp_cntl_tbl->display_caps;
1251
1252         return result;
1253 }
1254
1255 static enum bp_result get_disp_caps_v4_3(
1256         struct bios_parser *bp,
1257         uint8_t *dce_caps)
1258 {
1259         enum bp_result result = BP_RESULT_OK;
1260         struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL;
1261
1262         if (!dce_caps)
1263                 return BP_RESULT_BADINPUT;
1264
1265         if (!DATA_TABLES(dce_info))
1266                 return BP_RESULT_BADBIOSTABLE;
1267
1268         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3,
1269                                                         DATA_TABLES(dce_info));
1270
1271         if (!disp_cntl_tbl)
1272                 return BP_RESULT_BADBIOSTABLE;
1273
1274         *dce_caps = disp_cntl_tbl->display_caps;
1275
1276         return result;
1277 }
1278
1279 static enum bp_result get_disp_caps_v4_4(
1280         struct bios_parser *bp,
1281         uint8_t *dce_caps)
1282 {
1283         enum bp_result result = BP_RESULT_OK;
1284         struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
1285
1286         if (!dce_caps)
1287                 return BP_RESULT_BADINPUT;
1288
1289         if (!DATA_TABLES(dce_info))
1290                 return BP_RESULT_BADBIOSTABLE;
1291
1292         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1293                                                         DATA_TABLES(dce_info));
1294
1295         if (!disp_cntl_tbl)
1296                 return BP_RESULT_BADBIOSTABLE;
1297
1298         *dce_caps = disp_cntl_tbl->display_caps;
1299
1300         return result;
1301 }
1302
1303 static enum bp_result get_disp_caps_v4_5(
1304         struct bios_parser *bp,
1305         uint8_t *dce_caps)
1306 {
1307         enum bp_result result = BP_RESULT_OK;
1308         struct atom_display_controller_info_v4_5 *disp_cntl_tbl = NULL;
1309
1310         if (!dce_caps)
1311                 return BP_RESULT_BADINPUT;
1312
1313         if (!DATA_TABLES(dce_info))
1314                 return BP_RESULT_BADBIOSTABLE;
1315
1316         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_5,
1317                                                         DATA_TABLES(dce_info));
1318
1319         if (!disp_cntl_tbl)
1320                 return BP_RESULT_BADBIOSTABLE;
1321
1322         *dce_caps = disp_cntl_tbl->display_caps;
1323
1324         return result;
1325 }
1326
1327 static enum bp_result bios_parser_get_lttpr_interop(
1328         struct dc_bios *dcb,
1329         uint8_t *dce_caps)
1330 {
1331         struct bios_parser *bp = BP_FROM_DCB(dcb);
1332         enum bp_result result = BP_RESULT_UNSUPPORTED;
1333         struct atom_common_table_header *header;
1334         struct atom_data_revision tbl_revision;
1335
1336         if (!DATA_TABLES(dce_info))
1337                 return BP_RESULT_UNSUPPORTED;
1338
1339         header = GET_IMAGE(struct atom_common_table_header,
1340                                                 DATA_TABLES(dce_info));
1341         get_atom_data_table_revision(header, &tbl_revision);
1342         switch (tbl_revision.major) {
1343         case 4:
1344                 switch (tbl_revision.minor) {
1345                 case 1:
1346                         result = get_disp_caps_v4_1(bp, dce_caps);
1347                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1348                         break;
1349                 case 2:
1350                         result = get_disp_caps_v4_2(bp, dce_caps);
1351                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1352                         break;
1353                 case 3:
1354                         result = get_disp_caps_v4_3(bp, dce_caps);
1355                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1356                         break;
1357                 case 4:
1358                         result = get_disp_caps_v4_4(bp, dce_caps);
1359                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1360                         break;
1361                 case 5:
1362                         result = get_disp_caps_v4_5(bp, dce_caps);
1363                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1364                         break;
1365
1366                 default:
1367                         break;
1368                 }
1369                 break;
1370         default:
1371                 break;
1372         }
1373         DC_LOG_BIOS("DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE: %d tbl_revision.major = %d tbl_revision.minor = %d\n", *dce_caps, tbl_revision.major, tbl_revision.minor);
1374         return result;
1375 }
1376
1377 static enum bp_result bios_parser_get_lttpr_caps(
1378         struct dc_bios *dcb,
1379         uint8_t *dce_caps)
1380 {
1381         struct bios_parser *bp = BP_FROM_DCB(dcb);
1382         enum bp_result result = BP_RESULT_UNSUPPORTED;
1383         struct atom_common_table_header *header;
1384         struct atom_data_revision tbl_revision;
1385
1386         if (!DATA_TABLES(dce_info))
1387                 return BP_RESULT_UNSUPPORTED;
1388
1389         *dce_caps  = 0;
1390         header = GET_IMAGE(struct atom_common_table_header,
1391                                                 DATA_TABLES(dce_info));
1392         get_atom_data_table_revision(header, &tbl_revision);
1393         switch (tbl_revision.major) {
1394         case 4:
1395                 switch (tbl_revision.minor) {
1396                 case 1:
1397                         result = get_disp_caps_v4_1(bp, dce_caps);
1398                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1399                         break;
1400                 case 2:
1401                         result = get_disp_caps_v4_2(bp, dce_caps);
1402                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1403                         break;
1404                 case 3:
1405                         result = get_disp_caps_v4_3(bp, dce_caps);
1406                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1407                         break;
1408                 case 4:
1409                         result = get_disp_caps_v4_4(bp, dce_caps);
1410                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1411                         break;
1412                 case 5:
1413                         result = get_disp_caps_v4_5(bp, dce_caps);
1414                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1415                         break;
1416                 default:
1417                         break;
1418                 }
1419                 break;
1420         default:
1421                 break;
1422         }
1423         DC_LOG_BIOS("DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE: %d tbl_revision.major = %d tbl_revision.minor = %d\n", *dce_caps, tbl_revision.major, tbl_revision.minor);
1424         if (dcb->ctx->dc->config.force_bios_enable_lttpr && *dce_caps == 0) {
1425                 *dce_caps = 1;
1426                 DC_LOG_BIOS("DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE: forced enabled");
1427         }
1428         return result;
1429 }
1430
1431 static enum bp_result get_embedded_panel_info_v2_1(
1432                 struct bios_parser *bp,
1433                 struct embedded_panel_info *info)
1434 {
1435         struct lcd_info_v2_1 *lvds;
1436
1437         if (!info)
1438                 return BP_RESULT_BADINPUT;
1439
1440         if (!DATA_TABLES(lcd_info))
1441                 return BP_RESULT_UNSUPPORTED;
1442
1443         lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
1444
1445         if (!lvds)
1446                 return BP_RESULT_BADBIOSTABLE;
1447
1448         /* TODO: previous vv1_3, should v2_1 */
1449         if (!((lvds->table_header.format_revision == 2)
1450                         && (lvds->table_header.content_revision >= 1)))
1451                 return BP_RESULT_UNSUPPORTED;
1452
1453         memset(info, 0, sizeof(struct embedded_panel_info));
1454
1455         /* We need to convert from 10KHz units into KHz units */
1456         info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
1457         /* usHActive does not include borders, according to VBIOS team */
1458         info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
1459         /* usHBlanking_Time includes borders, so we should really be
1460          * subtractingborders duing this translation, but LVDS generally
1461          * doesn't have borders, so we should be okay leaving this as is for
1462          * now.  May need to revisit if we ever have LVDS with borders
1463          */
1464         info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
1465         /* usVActive does not include borders, according to VBIOS team*/
1466         info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
1467         /* usVBlanking_Time includes borders, so we should really be
1468          * subtracting borders duing this translation, but LVDS generally
1469          * doesn't have borders, so we should be okay leaving this as is for
1470          * now. May need to revisit if we ever have LVDS with borders
1471          */
1472         info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time);
1473         info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset);
1474         info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width);
1475         info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset);
1476         info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth);
1477         info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
1478         info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
1479
1480         /* not provided by VBIOS */
1481         info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
1482
1483         info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1484                         & ATOM_HSYNC_POLARITY);
1485         info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1486                         & ATOM_VSYNC_POLARITY);
1487
1488         /* not provided by VBIOS */
1489         info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
1490
1491         info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1492                         & ATOM_H_REPLICATIONBY2);
1493         info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1494                         & ATOM_V_REPLICATIONBY2);
1495         info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo
1496                         & ATOM_COMPOSITESYNC);
1497         info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
1498
1499         /* not provided by VBIOS*/
1500         info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
1501         /* not provided by VBIOS*/
1502         info->ss_id = 0;
1503
1504         info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1505
1506         return BP_RESULT_OK;
1507 }
1508
1509 static enum bp_result bios_parser_get_embedded_panel_info(
1510                 struct dc_bios *dcb,
1511                 struct embedded_panel_info *info)
1512 {
1513         struct bios_parser
1514         *bp = BP_FROM_DCB(dcb);
1515         struct atom_common_table_header *header;
1516         struct atom_data_revision tbl_revision;
1517
1518         if (!DATA_TABLES(lcd_info))
1519                 return BP_RESULT_FAILURE;
1520
1521         header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
1522
1523         if (!header)
1524                 return BP_RESULT_BADBIOSTABLE;
1525
1526         get_atom_data_table_revision(header, &tbl_revision);
1527
1528         switch (tbl_revision.major) {
1529         case 2:
1530                 switch (tbl_revision.minor) {
1531                 case 1:
1532                         return get_embedded_panel_info_v2_1(bp, info);
1533                 default:
1534                         break;
1535                 }
1536                 break;
1537         default:
1538                 break;
1539         }
1540
1541         return BP_RESULT_FAILURE;
1542 }
1543
1544 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
1545 {
1546         enum dal_device_type device_type = device_id.device_type;
1547         uint32_t enum_id = device_id.enum_id;
1548
1549         switch (device_type) {
1550         case DEVICE_TYPE_LCD:
1551                 switch (enum_id) {
1552                 case 1:
1553                         return ATOM_DISPLAY_LCD1_SUPPORT;
1554                 default:
1555                         break;
1556                 }
1557                 break;
1558         case DEVICE_TYPE_DFP:
1559                 switch (enum_id) {
1560                 case 1:
1561                         return ATOM_DISPLAY_DFP1_SUPPORT;
1562                 case 2:
1563                         return ATOM_DISPLAY_DFP2_SUPPORT;
1564                 case 3:
1565                         return ATOM_DISPLAY_DFP3_SUPPORT;
1566                 case 4:
1567                         return ATOM_DISPLAY_DFP4_SUPPORT;
1568                 case 5:
1569                         return ATOM_DISPLAY_DFP5_SUPPORT;
1570                 case 6:
1571                         return ATOM_DISPLAY_DFP6_SUPPORT;
1572                 default:
1573                         break;
1574                 }
1575                 break;
1576         default:
1577                 break;
1578         }
1579
1580         /* Unidentified device ID, return empty support mask. */
1581         return 0;
1582 }
1583
1584 static bool bios_parser_is_device_id_supported(
1585         struct dc_bios *dcb,
1586         struct device_id id)
1587 {
1588         struct bios_parser *bp = BP_FROM_DCB(dcb);
1589
1590         uint32_t mask = get_support_mask_for_device_id(id);
1591
1592         switch (bp->object_info_tbl.revision.minor) {
1593         case 4:
1594         default:
1595                 return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & mask) != 0;
1596                 break;
1597         case 5:
1598                 return (le16_to_cpu(bp->object_info_tbl.v1_5->supporteddevices) & mask) != 0;
1599                 break;
1600         }
1601 }
1602
1603 static uint32_t bios_parser_get_ss_entry_number(
1604         struct dc_bios *dcb,
1605         enum as_signal_type signal)
1606 {
1607         /* TODO: DAL2 atomfirmware implementation does not need this.
1608          * why DAL3 need this?
1609          */
1610         return 1;
1611 }
1612
1613 static enum bp_result bios_parser_transmitter_control(
1614         struct dc_bios *dcb,
1615         struct bp_transmitter_control *cntl)
1616 {
1617         struct bios_parser *bp = BP_FROM_DCB(dcb);
1618
1619         if (!bp->cmd_tbl.transmitter_control)
1620                 return BP_RESULT_FAILURE;
1621
1622         return bp->cmd_tbl.transmitter_control(bp, cntl);
1623 }
1624
1625 static enum bp_result bios_parser_encoder_control(
1626         struct dc_bios *dcb,
1627         struct bp_encoder_control *cntl)
1628 {
1629         struct bios_parser *bp = BP_FROM_DCB(dcb);
1630
1631         if (!bp->cmd_tbl.dig_encoder_control)
1632                 return BP_RESULT_FAILURE;
1633
1634         return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1635 }
1636
1637 static enum bp_result bios_parser_set_pixel_clock(
1638         struct dc_bios *dcb,
1639         struct bp_pixel_clock_parameters *bp_params)
1640 {
1641         struct bios_parser *bp = BP_FROM_DCB(dcb);
1642
1643         if (!bp->cmd_tbl.set_pixel_clock)
1644                 return BP_RESULT_FAILURE;
1645
1646         return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1647 }
1648
1649 static enum bp_result bios_parser_set_dce_clock(
1650         struct dc_bios *dcb,
1651         struct bp_set_dce_clock_parameters *bp_params)
1652 {
1653         struct bios_parser *bp = BP_FROM_DCB(dcb);
1654
1655         if (!bp->cmd_tbl.set_dce_clock)
1656                 return BP_RESULT_FAILURE;
1657
1658         return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1659 }
1660
1661 static enum bp_result bios_parser_program_crtc_timing(
1662         struct dc_bios *dcb,
1663         struct bp_hw_crtc_timing_parameters *bp_params)
1664 {
1665         struct bios_parser *bp = BP_FROM_DCB(dcb);
1666
1667         if (!bp->cmd_tbl.set_crtc_timing)
1668                 return BP_RESULT_FAILURE;
1669
1670         return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1671 }
1672
1673 static enum bp_result bios_parser_enable_crtc(
1674         struct dc_bios *dcb,
1675         enum controller_id id,
1676         bool enable)
1677 {
1678         struct bios_parser *bp = BP_FROM_DCB(dcb);
1679
1680         if (!bp->cmd_tbl.enable_crtc)
1681                 return BP_RESULT_FAILURE;
1682
1683         return bp->cmd_tbl.enable_crtc(bp, id, enable);
1684 }
1685
1686 static enum bp_result bios_parser_enable_disp_power_gating(
1687         struct dc_bios *dcb,
1688         enum controller_id controller_id,
1689         enum bp_pipe_control_action action)
1690 {
1691         struct bios_parser *bp = BP_FROM_DCB(dcb);
1692
1693         if (!bp->cmd_tbl.enable_disp_power_gating)
1694                 return BP_RESULT_FAILURE;
1695
1696         return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1697                 action);
1698 }
1699
1700 static enum bp_result bios_parser_enable_lvtma_control(
1701         struct dc_bios *dcb,
1702         uint8_t uc_pwr_on,
1703         uint8_t pwrseq_instance,
1704         uint8_t bypass_panel_control_wait)
1705 {
1706         struct bios_parser *bp = BP_FROM_DCB(dcb);
1707
1708         if (!bp->cmd_tbl.enable_lvtma_control)
1709                 return BP_RESULT_FAILURE;
1710
1711         return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, pwrseq_instance, bypass_panel_control_wait);
1712 }
1713
1714 static bool bios_parser_is_accelerated_mode(
1715         struct dc_bios *dcb)
1716 {
1717         return bios_is_accelerated_mode(dcb);
1718 }
1719
1720 /**
1721  * bios_parser_set_scratch_critical_state - update critical state bit
1722  *                                          in VBIOS scratch register
1723  *
1724  * @dcb:   pointer to the DC BIO
1725  * @state: set or reset state
1726  */
1727 static void bios_parser_set_scratch_critical_state(
1728         struct dc_bios *dcb,
1729         bool state)
1730 {
1731         bios_set_scratch_critical_state(dcb, state);
1732 }
1733
1734 static enum bp_result bios_parser_get_firmware_info(
1735         struct dc_bios *dcb,
1736         struct dc_firmware_info *info)
1737 {
1738         struct bios_parser *bp = BP_FROM_DCB(dcb);
1739         static enum bp_result result = BP_RESULT_BADBIOSTABLE;
1740         struct atom_common_table_header *header;
1741
1742         struct atom_data_revision revision;
1743
1744         if (info && DATA_TABLES(firmwareinfo)) {
1745                 header = GET_IMAGE(struct atom_common_table_header,
1746                                 DATA_TABLES(firmwareinfo));
1747                 get_atom_data_table_revision(header, &revision);
1748                 switch (revision.major) {
1749                 case 3:
1750                         switch (revision.minor) {
1751                         case 1:
1752                                 result = get_firmware_info_v3_1(bp, info);
1753                                 break;
1754                         case 2:
1755                         case 3:
1756                                 result = get_firmware_info_v3_2(bp, info);
1757                                 break;
1758                         case 4:
1759                                 result = get_firmware_info_v3_4(bp, info);
1760                                 break;
1761                         case 5:
1762                                 result = get_firmware_info_v3_5(bp, info);
1763                                 break;
1764                         default:
1765                                 break;
1766                         }
1767                         break;
1768                 default:
1769                         break;
1770                 }
1771         }
1772
1773         return result;
1774 }
1775
1776 static enum bp_result get_firmware_info_v3_1(
1777         struct bios_parser *bp,
1778         struct dc_firmware_info *info)
1779 {
1780         struct atom_firmware_info_v3_1 *firmware_info;
1781         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1782
1783         if (!info)
1784                 return BP_RESULT_BADINPUT;
1785
1786         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1787                         DATA_TABLES(firmwareinfo));
1788
1789         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1790                         DATA_TABLES(dce_info));
1791
1792         if (!firmware_info || !dce_info)
1793                 return BP_RESULT_BADBIOSTABLE;
1794
1795         memset(info, 0, sizeof(*info));
1796
1797         /* Pixel clock pll information. */
1798          /* We need to convert from 10KHz units into KHz units */
1799         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1800         info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1801
1802          /* 27MHz for Vega10: */
1803         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1804
1805         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1806         if (info->pll_info.crystal_frequency == 0)
1807                 info->pll_info.crystal_frequency = 27000;
1808         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1809         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1810         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1811
1812         /* Get GPU PLL VCO Clock */
1813
1814         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1815                 /* VBIOS gives in 10KHz */
1816                 info->smu_gpu_pll_output_freq =
1817                                 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1818         }
1819
1820         info->oem_i2c_present = false;
1821
1822         return BP_RESULT_OK;
1823 }
1824
1825 static enum bp_result get_firmware_info_v3_2(
1826         struct bios_parser *bp,
1827         struct dc_firmware_info *info)
1828 {
1829         struct atom_firmware_info_v3_2 *firmware_info;
1830         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1831         struct atom_common_table_header *header;
1832         struct atom_data_revision revision;
1833         struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1834         struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1835
1836         if (!info)
1837                 return BP_RESULT_BADINPUT;
1838
1839         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1840                         DATA_TABLES(firmwareinfo));
1841
1842         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1843                         DATA_TABLES(dce_info));
1844
1845         if (!firmware_info || !dce_info)
1846                 return BP_RESULT_BADBIOSTABLE;
1847
1848         memset(info, 0, sizeof(*info));
1849
1850         header = GET_IMAGE(struct atom_common_table_header,
1851                                         DATA_TABLES(smu_info));
1852         get_atom_data_table_revision(header, &revision);
1853
1854         if (revision.minor == 2) {
1855                 /* Vega12 */
1856                 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1857                                                         DATA_TABLES(smu_info));
1858                 if (!smu_info_v3_2)
1859                         return BP_RESULT_BADBIOSTABLE;
1860
1861                 DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_2->gpuclk_ss_percentage);
1862
1863                 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1864         } else if (revision.minor == 3) {
1865                 /* Vega20 */
1866                 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1867                                                         DATA_TABLES(smu_info));
1868                 if (!smu_info_v3_3)
1869                         return BP_RESULT_BADBIOSTABLE;
1870
1871                 DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_3->gpuclk_ss_percentage);
1872
1873                 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1874         }
1875
1876          // We need to convert from 10KHz units into KHz units.
1877         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1878
1879          /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1880         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1881         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1882         if (info->pll_info.crystal_frequency == 0) {
1883                 if (revision.minor == 2)
1884                         info->pll_info.crystal_frequency = 27000;
1885                 else if (revision.minor == 3)
1886                         info->pll_info.crystal_frequency = 100000;
1887         }
1888         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1889         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1890         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1891
1892         /* Get GPU PLL VCO Clock */
1893         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1894                 if (revision.minor == 2)
1895                         info->smu_gpu_pll_output_freq =
1896                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1897                 else if (revision.minor == 3)
1898                         info->smu_gpu_pll_output_freq =
1899                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1900         }
1901
1902         if (firmware_info->board_i2c_feature_id == 0x2) {
1903                 info->oem_i2c_present = true;
1904                 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
1905         } else {
1906                 info->oem_i2c_present = false;
1907         }
1908
1909         return BP_RESULT_OK;
1910 }
1911
1912 static enum bp_result get_firmware_info_v3_4(
1913         struct bios_parser *bp,
1914         struct dc_firmware_info *info)
1915 {
1916         struct atom_firmware_info_v3_4 *firmware_info;
1917         struct atom_common_table_header *header;
1918         struct atom_data_revision revision;
1919         struct atom_display_controller_info_v4_1 *dce_info_v4_1 = NULL;
1920         struct atom_display_controller_info_v4_4 *dce_info_v4_4 = NULL;
1921
1922         struct atom_smu_info_v3_5 *smu_info_v3_5 = NULL;
1923         struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL;
1924         struct atom_smu_info_v4_0 *smu_info_v4_0 = NULL;
1925
1926         if (!info)
1927                 return BP_RESULT_BADINPUT;
1928
1929         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_4,
1930                         DATA_TABLES(firmwareinfo));
1931
1932         if (!firmware_info)
1933                 return BP_RESULT_BADBIOSTABLE;
1934
1935         memset(info, 0, sizeof(*info));
1936
1937         header = GET_IMAGE(struct atom_common_table_header,
1938                                         DATA_TABLES(dce_info));
1939
1940         get_atom_data_table_revision(header, &revision);
1941
1942         switch (revision.major) {
1943         case 4:
1944                 switch (revision.minor) {
1945                 case 5:
1946                         dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
1947                                                         DATA_TABLES(dce_info));
1948
1949                         if (!dce_info_v4_5)
1950                                 return BP_RESULT_BADBIOSTABLE;
1951
1952                          /* 100MHz expected */
1953                         info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10;
1954                         info->dp_phy_ref_clk             = dce_info_v4_5->dpphy_refclk_10khz * 10;
1955                          /* 50MHz expected */
1956                         info->i2c_engine_ref_clk         = dce_info_v4_5->i2c_engine_refclk_10khz * 10;
1957
1958                         /* For DCN32/321 Display PLL VCO Frequency from dce_info_v4_5 may not be reliable */
1959                         break;
1960
1961                 case 4:
1962                         dce_info_v4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
1963                                                         DATA_TABLES(dce_info));
1964
1965                         if (!dce_info_v4_4)
1966                                 return BP_RESULT_BADBIOSTABLE;
1967
1968                         /* 100MHz expected */
1969                         info->pll_info.crystal_frequency = dce_info_v4_4->dce_refclk_10khz * 10;
1970                         info->dp_phy_ref_clk             = dce_info_v4_4->dpphy_refclk_10khz * 10;
1971                         /* 50MHz expected */
1972                         info->i2c_engine_ref_clk         = dce_info_v4_4->i2c_engine_refclk_10khz * 10;
1973
1974                         /* Get SMU Display PLL VCO Frequency in KHz*/
1975                         info->smu_gpu_pll_output_freq = dce_info_v4_4->dispclk_pll_vco_freq * 10;
1976                         break;
1977
1978                 default:
1979                         /* should not come here, keep as backup, as was before */
1980                         dce_info_v4_1 = GET_IMAGE(struct atom_display_controller_info_v4_1,
1981                                                         DATA_TABLES(dce_info));
1982
1983                         if (!dce_info_v4_1)
1984                                 return BP_RESULT_BADBIOSTABLE;
1985
1986                         info->pll_info.crystal_frequency = dce_info_v4_1->dce_refclk_10khz * 10;
1987                         info->dp_phy_ref_clk             = dce_info_v4_1->dpphy_refclk_10khz * 10;
1988                         info->i2c_engine_ref_clk         = dce_info_v4_1->i2c_engine_refclk_10khz * 10;
1989                         break;
1990                 }
1991                 break;
1992
1993         default:
1994                 ASSERT(0);
1995                 break;
1996         }
1997
1998         header = GET_IMAGE(struct atom_common_table_header,
1999                                         DATA_TABLES(smu_info));
2000         get_atom_data_table_revision(header, &revision);
2001
2002         switch (revision.major) {
2003         case 3:
2004                 switch (revision.minor) {
2005                 case 5:
2006                         smu_info_v3_5 = GET_IMAGE(struct atom_smu_info_v3_5,
2007                                                         DATA_TABLES(smu_info));
2008
2009                         if (!smu_info_v3_5)
2010                                 return BP_RESULT_BADBIOSTABLE;
2011                         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_5->gpuclk_ss_percentage);
2012                         info->default_engine_clk = smu_info_v3_5->bootup_dcefclk_10khz * 10;
2013                         break;
2014
2015                 default:
2016                         break;
2017                 }
2018                 break;
2019
2020         case 4:
2021                 switch (revision.minor) {
2022                 case 0:
2023                         smu_info_v4_0 = GET_IMAGE(struct atom_smu_info_v4_0,
2024                                                         DATA_TABLES(smu_info));
2025
2026                         if (!smu_info_v4_0)
2027                                 return BP_RESULT_BADBIOSTABLE;
2028
2029                         /* For DCN32/321 bootup DCFCLK from smu_info_v4_0 may not be reliable */
2030                         break;
2031
2032                 default:
2033                         break;
2034                 }
2035                 break;
2036
2037         default:
2038                 break;
2039         }
2040
2041          // We need to convert from 10KHz units into KHz units.
2042         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
2043
2044         if (firmware_info->board_i2c_feature_id == 0x2) {
2045                 info->oem_i2c_present = true;
2046                 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
2047         } else {
2048                 info->oem_i2c_present = false;
2049         }
2050
2051         return BP_RESULT_OK;
2052 }
2053
2054 static enum bp_result get_firmware_info_v3_5(
2055         struct bios_parser *bp,
2056         struct dc_firmware_info *info)
2057 {
2058         struct atom_firmware_info_v3_5 *firmware_info;
2059         struct atom_common_table_header *header;
2060         struct atom_data_revision revision;
2061         struct atom_display_controller_info_v4_5 *dce_info_v4_5 = NULL;
2062
2063         if (!info)
2064                 return BP_RESULT_BADINPUT;
2065
2066         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_5,
2067                         DATA_TABLES(firmwareinfo));
2068
2069         if (!firmware_info)
2070                 return BP_RESULT_BADBIOSTABLE;
2071
2072         memset(info, 0, sizeof(*info));
2073
2074         if (firmware_info->board_i2c_feature_id == 0x2) {
2075                 info->oem_i2c_present = true;
2076                 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
2077         } else {
2078                 info->oem_i2c_present = false;
2079         }
2080
2081         header = GET_IMAGE(struct atom_common_table_header,
2082                                         DATA_TABLES(dce_info));
2083
2084         get_atom_data_table_revision(header, &revision);
2085
2086         switch (revision.major) {
2087         case 4:
2088                 switch (revision.minor) {
2089                 case 5:
2090                         dce_info_v4_5 = GET_IMAGE(struct atom_display_controller_info_v4_5,
2091                                                         DATA_TABLES(dce_info));
2092
2093                         if (!dce_info_v4_5)
2094                                 return BP_RESULT_BADBIOSTABLE;
2095
2096                          /* 100MHz expected */
2097                         info->pll_info.crystal_frequency = dce_info_v4_5->dce_refclk_10khz * 10;
2098                         break;
2099                 default:
2100                         break;
2101                 }
2102                 break;
2103         default:
2104                 break;
2105         }
2106
2107
2108         return BP_RESULT_OK;
2109 }
2110
2111 static enum bp_result bios_parser_get_encoder_cap_info(
2112         struct dc_bios *dcb,
2113         struct graphics_object_id object_id,
2114         struct bp_encoder_cap_info *info)
2115 {
2116         struct bios_parser *bp = BP_FROM_DCB(dcb);
2117         struct atom_display_object_path_v2 *object;
2118         struct atom_encoder_caps_record *record = NULL;
2119
2120         if (!info)
2121                 return BP_RESULT_BADINPUT;
2122
2123 #if defined(CONFIG_DRM_AMD_DC_FP)
2124         /* encoder cap record not available in v1_5 */
2125         if (bp->object_info_tbl.revision.minor == 5)
2126                 return BP_RESULT_NORECORD;
2127 #endif
2128
2129         object = get_bios_object(bp, object_id);
2130
2131         if (!object)
2132                 return BP_RESULT_BADINPUT;
2133
2134         record = get_encoder_cap_record(bp, object);
2135         if (!record)
2136                 return BP_RESULT_NORECORD;
2137         DC_LOG_BIOS("record->encodercaps 0x%x for object_id 0x%x", record->encodercaps, object_id.id);
2138
2139         info->DP_HBR2_CAP = (record->encodercaps &
2140                         ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
2141         info->DP_HBR2_EN = (record->encodercaps &
2142                         ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
2143         info->DP_HBR3_EN = (record->encodercaps &
2144                         ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
2145         info->HDMI_6GB_EN = (record->encodercaps &
2146                         ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
2147         info->IS_DP2_CAPABLE = (record->encodercaps &
2148                         ATOM_ENCODER_CAP_RECORD_DP2) ? 1 : 0;
2149         info->DP_UHBR10_EN = (record->encodercaps &
2150                         ATOM_ENCODER_CAP_RECORD_UHBR10_EN) ? 1 : 0;
2151         info->DP_UHBR13_5_EN = (record->encodercaps &
2152                         ATOM_ENCODER_CAP_RECORD_UHBR13_5_EN) ? 1 : 0;
2153         info->DP_UHBR20_EN = (record->encodercaps &
2154                         ATOM_ENCODER_CAP_RECORD_UHBR20_EN) ? 1 : 0;
2155         info->DP_IS_USB_C = (record->encodercaps &
2156                         ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
2157         DC_LOG_BIOS("\t info->DP_IS_USB_C %d", info->DP_IS_USB_C);
2158
2159         return BP_RESULT_OK;
2160 }
2161
2162
2163 static struct atom_encoder_caps_record *get_encoder_cap_record(
2164         struct bios_parser *bp,
2165         struct atom_display_object_path_v2 *object)
2166 {
2167         struct atom_common_record_header *header;
2168         uint32_t offset;
2169
2170         if (!object) {
2171                 BREAK_TO_DEBUGGER(); /* Invalid object */
2172                 return NULL;
2173         }
2174
2175         offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
2176
2177         for (;;) {
2178                 header = GET_IMAGE(struct atom_common_record_header, offset);
2179
2180                 if (!header)
2181                         return NULL;
2182
2183                 offset += header->record_size;
2184
2185                 if (header->record_type == LAST_RECORD_TYPE ||
2186                                 !header->record_size)
2187                         break;
2188
2189                 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
2190                         continue;
2191
2192                 if (sizeof(struct atom_encoder_caps_record) <=
2193                                                         header->record_size)
2194                         return (struct atom_encoder_caps_record *)header;
2195         }
2196
2197         return NULL;
2198 }
2199
2200 static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
2201         struct bios_parser *bp,
2202         struct atom_display_object_path_v2 *object)
2203 {
2204         struct atom_common_record_header *header;
2205         uint32_t offset;
2206
2207         if (!object) {
2208                 BREAK_TO_DEBUGGER(); /* Invalid object */
2209                 return NULL;
2210         }
2211
2212         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2213
2214         for (;;) {
2215                 header = GET_IMAGE(struct atom_common_record_header, offset);
2216
2217                 if (!header)
2218                         return NULL;
2219
2220                 offset += header->record_size;
2221
2222                 if (header->record_type == LAST_RECORD_TYPE ||
2223                                 !header->record_size)
2224                         break;
2225
2226                 if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE)
2227                         continue;
2228
2229                 if (sizeof(struct atom_disp_connector_caps_record) <=
2230                                                         header->record_size)
2231                         return (struct atom_disp_connector_caps_record *)header;
2232         }
2233
2234         return NULL;
2235 }
2236
2237 static struct atom_connector_caps_record *get_connector_caps_record(struct bios_parser *bp,
2238                                                                     struct atom_display_object_path_v3 *object)
2239 {
2240         struct atom_common_record_header *header;
2241         uint32_t offset;
2242
2243         if (!object) {
2244                 BREAK_TO_DEBUGGER(); /* Invalid object */
2245                 return NULL;
2246         }
2247
2248         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2249
2250         for (;;) {
2251                 header = GET_IMAGE(struct atom_common_record_header, offset);
2252
2253                 if (!header)
2254                         return NULL;
2255
2256                 offset += header->record_size;
2257
2258                 if (header->record_type == ATOM_RECORD_END_TYPE ||
2259                                 !header->record_size)
2260                         break;
2261
2262                 if (header->record_type != ATOM_CONNECTOR_CAP_RECORD_TYPE)
2263                         continue;
2264
2265                 if (sizeof(struct atom_connector_caps_record) <= header->record_size)
2266                         return (struct atom_connector_caps_record *)header;
2267         }
2268
2269         return NULL;
2270 }
2271
2272 static enum bp_result bios_parser_get_disp_connector_caps_info(
2273         struct dc_bios *dcb,
2274         struct graphics_object_id object_id,
2275         struct bp_disp_connector_caps_info *info)
2276 {
2277         struct bios_parser *bp = BP_FROM_DCB(dcb);
2278         struct atom_display_object_path_v2 *object;
2279         struct atom_display_object_path_v3 *object_path_v3;
2280         struct atom_connector_caps_record *record_path_v3;
2281         struct atom_disp_connector_caps_record *record = NULL;
2282
2283         if (!info)
2284                 return BP_RESULT_BADINPUT;
2285
2286         switch (bp->object_info_tbl.revision.minor) {
2287         case 4:
2288                 default:
2289                         object = get_bios_object(bp, object_id);
2290
2291                         if (!object)
2292                                 return BP_RESULT_BADINPUT;
2293
2294                         record = get_disp_connector_caps_record(bp, object);
2295                         if (!record)
2296                                 return BP_RESULT_NORECORD;
2297
2298                         info->INTERNAL_DISPLAY =
2299                                 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY) ? 1 : 0;
2300                         info->INTERNAL_DISPLAY_BL =
2301                                 (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL) ? 1 : 0;
2302                         break;
2303         case 5:
2304                 object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2305
2306                 if (!object_path_v3)
2307                         return BP_RESULT_BADINPUT;
2308
2309                 record_path_v3 = get_connector_caps_record(bp, object_path_v3);
2310                 if (!record_path_v3)
2311                         return BP_RESULT_NORECORD;
2312
2313                 info->INTERNAL_DISPLAY = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
2314                                                                         ? 1 : 0;
2315                 info->INTERNAL_DISPLAY_BL = (record_path_v3->connector_caps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
2316                                                                                 ? 1 : 0;
2317                 break;
2318         }
2319
2320         return BP_RESULT_OK;
2321 }
2322
2323 static struct atom_connector_speed_record *get_connector_speed_cap_record(struct bios_parser *bp,
2324                                                                           struct atom_display_object_path_v3 *object)
2325 {
2326         struct atom_common_record_header *header;
2327         uint32_t offset;
2328
2329         if (!object) {
2330                 BREAK_TO_DEBUGGER(); /* Invalid object */
2331                 return NULL;
2332         }
2333
2334         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
2335
2336         for (;;) {
2337                 header = GET_IMAGE(struct atom_common_record_header, offset);
2338
2339                 if (!header)
2340                         return NULL;
2341
2342                 offset += header->record_size;
2343
2344                 if (header->record_type == ATOM_RECORD_END_TYPE ||
2345                                 !header->record_size)
2346                         break;
2347
2348                 if (header->record_type != ATOM_CONNECTOR_SPEED_UPTO)
2349                         continue;
2350
2351                 if (sizeof(struct atom_connector_speed_record) <= header->record_size)
2352                         return (struct atom_connector_speed_record *)header;
2353         }
2354
2355         return NULL;
2356 }
2357
2358 static enum bp_result bios_parser_get_connector_speed_cap_info(
2359         struct dc_bios *dcb,
2360         struct graphics_object_id object_id,
2361         struct bp_connector_speed_cap_info *info)
2362 {
2363         struct bios_parser *bp = BP_FROM_DCB(dcb);
2364         struct atom_display_object_path_v3 *object_path_v3;
2365         //struct atom_connector_speed_record *record = NULL;
2366         struct atom_connector_speed_record *record;
2367
2368         if (!info)
2369                 return BP_RESULT_BADINPUT;
2370
2371         object_path_v3 = get_bios_object_from_path_v3(bp, object_id);
2372
2373         if (!object_path_v3)
2374                 return BP_RESULT_BADINPUT;
2375
2376         record = get_connector_speed_cap_record(bp, object_path_v3);
2377         if (!record)
2378                 return BP_RESULT_NORECORD;
2379
2380         info->DP_HBR2_EN = (record->connector_max_speed >= 5400) ? 1 : 0;
2381         info->DP_HBR3_EN = (record->connector_max_speed >= 8100) ? 1 : 0;
2382         info->HDMI_6GB_EN = (record->connector_max_speed >= 5940) ? 1 : 0;
2383         info->DP_UHBR10_EN = (record->connector_max_speed >= 10000) ? 1 : 0;
2384         info->DP_UHBR13_5_EN = (record->connector_max_speed >= 13500) ? 1 : 0;
2385         info->DP_UHBR20_EN = (record->connector_max_speed >= 20000) ? 1 : 0;
2386         return BP_RESULT_OK;
2387 }
2388
2389 static enum bp_result get_vram_info_v23(
2390         struct bios_parser *bp,
2391         struct dc_vram_info *info)
2392 {
2393         struct atom_vram_info_header_v2_3 *info_v23;
2394         static enum bp_result result = BP_RESULT_OK;
2395
2396         info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
2397                                                 DATA_TABLES(vram_info));
2398
2399         if (info_v23 == NULL)
2400                 return BP_RESULT_BADBIOSTABLE;
2401
2402         info->num_chans = info_v23->vram_module[0].channel_num;
2403         info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8;
2404
2405         return result;
2406 }
2407
2408 static enum bp_result get_vram_info_v24(
2409         struct bios_parser *bp,
2410         struct dc_vram_info *info)
2411 {
2412         struct atom_vram_info_header_v2_4 *info_v24;
2413         static enum bp_result result = BP_RESULT_OK;
2414
2415         info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
2416                                                 DATA_TABLES(vram_info));
2417
2418         if (info_v24 == NULL)
2419                 return BP_RESULT_BADBIOSTABLE;
2420
2421         info->num_chans = info_v24->vram_module[0].channel_num;
2422         info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8;
2423
2424         return result;
2425 }
2426
2427 static enum bp_result get_vram_info_v25(
2428         struct bios_parser *bp,
2429         struct dc_vram_info *info)
2430 {
2431         struct atom_vram_info_header_v2_5 *info_v25;
2432         static enum bp_result result = BP_RESULT_OK;
2433
2434         info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
2435                                                 DATA_TABLES(vram_info));
2436
2437         if (info_v25 == NULL)
2438                 return BP_RESULT_BADBIOSTABLE;
2439
2440         info->num_chans = info_v25->vram_module[0].channel_num;
2441         info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8;
2442
2443         return result;
2444 }
2445
2446 static enum bp_result get_vram_info_v30(
2447         struct bios_parser *bp,
2448         struct dc_vram_info *info)
2449 {
2450         struct atom_vram_info_header_v3_0 *info_v30;
2451         enum bp_result result = BP_RESULT_OK;
2452
2453         info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0,
2454                                                 DATA_TABLES(vram_info));
2455
2456         if (info_v30 == NULL)
2457                 return BP_RESULT_BADBIOSTABLE;
2458
2459         info->num_chans = info_v30->channel_num;
2460         info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8;
2461
2462         return result;
2463 }
2464
2465 static enum bp_result get_vram_info_from_umc_info_v40(
2466                 struct bios_parser *bp,
2467                 struct dc_vram_info *info)
2468 {
2469         struct atom_umc_info_v4_0 *info_v40;
2470         enum bp_result result = BP_RESULT_OK;
2471
2472         info_v40 = GET_IMAGE(struct atom_umc_info_v4_0,
2473                                                 DATA_TABLES(umc_info));
2474
2475         if (info_v40 == NULL)
2476                 return BP_RESULT_BADBIOSTABLE;
2477
2478         info->num_chans = info_v40->channel_num;
2479         info->dram_channel_width_bytes = (1 << info_v40->channel_width) / 8;
2480
2481         return result;
2482 }
2483
2484 /*
2485  * get_integrated_info_v11
2486  *
2487  * @brief
2488  * Get V8 integrated BIOS information
2489  *
2490  * @param
2491  * bios_parser *bp - [in]BIOS parser handler to get master data table
2492  * integrated_info *info - [out] store and output integrated info
2493  *
2494  * @return
2495  * static enum bp_result - BP_RESULT_OK if information is available,
2496  *                  BP_RESULT_BADBIOSTABLE otherwise.
2497  */
2498 static enum bp_result get_integrated_info_v11(
2499         struct bios_parser *bp,
2500         struct integrated_info *info)
2501 {
2502         struct atom_integrated_system_info_v1_11 *info_v11;
2503         uint32_t i;
2504
2505         info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
2506                                         DATA_TABLES(integratedsysteminfo));
2507
2508         if (info_v11 == NULL)
2509                 return BP_RESULT_BADBIOSTABLE;
2510
2511         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v11->gpuclk_ss_percentage);
2512
2513         info->gpu_cap_info =
2514         le32_to_cpu(info_v11->gpucapinfo);
2515         /*
2516         * system_config: Bit[0] = 0 : PCIE power gating disabled
2517         *                       = 1 : PCIE power gating enabled
2518         *                Bit[1] = 0 : DDR-PLL shut down disabled
2519         *                       = 1 : DDR-PLL shut down enabled
2520         *                Bit[2] = 0 : DDR-PLL power down disabled
2521         *                       = 1 : DDR-PLL power down enabled
2522         */
2523         info->system_config = le32_to_cpu(info_v11->system_config);
2524         info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
2525         info->memory_type = info_v11->memorytype;
2526         info->ma_channel_number = info_v11->umachannelnumber;
2527         info->lvds_ss_percentage =
2528         le16_to_cpu(info_v11->lvds_ss_percentage);
2529         info->dp_ss_control =
2530         le16_to_cpu(info_v11->reserved1);
2531         info->lvds_sspread_rate_in_10hz =
2532         le16_to_cpu(info_v11->lvds_ss_rate_10hz);
2533         info->hdmi_ss_percentage =
2534         le16_to_cpu(info_v11->hdmi_ss_percentage);
2535         info->hdmi_sspread_rate_in_10hz =
2536         le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
2537         info->dvi_ss_percentage =
2538         le16_to_cpu(info_v11->dvi_ss_percentage);
2539         info->dvi_sspread_rate_in_10_hz =
2540         le16_to_cpu(info_v11->dvi_ss_rate_10hz);
2541         info->lvds_misc = info_v11->lvds_misc;
2542         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2543                 info->ext_disp_conn_info.gu_id[i] =
2544                                 info_v11->extdispconninfo.guid[i];
2545         }
2546
2547         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2548                 info->ext_disp_conn_info.path[i].device_connector_id =
2549                 object_id_from_bios_object_id(
2550                 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
2551
2552                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2553                 object_id_from_bios_object_id(
2554                         le16_to_cpu(
2555                         info_v11->extdispconninfo.path[i].ext_encoder_objid));
2556
2557                 info->ext_disp_conn_info.path[i].device_tag =
2558                         le16_to_cpu(
2559                                 info_v11->extdispconninfo.path[i].device_tag);
2560                 info->ext_disp_conn_info.path[i].device_acpi_enum =
2561                 le16_to_cpu(
2562                         info_v11->extdispconninfo.path[i].device_acpi_enum);
2563                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2564                         info_v11->extdispconninfo.path[i].auxddclut_index;
2565                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2566                         info_v11->extdispconninfo.path[i].hpdlut_index;
2567                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2568                         info_v11->extdispconninfo.path[i].channelmapping;
2569                 info->ext_disp_conn_info.path[i].caps =
2570                                 le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
2571         }
2572         info->ext_disp_conn_info.checksum =
2573         info_v11->extdispconninfo.checksum;
2574
2575         info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
2576         info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
2577         for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
2578                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
2579                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2580                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
2581                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2582         }
2583         info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
2584         for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
2585                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2586                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2587                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2588                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2589         }
2590
2591         info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
2592         info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
2593         for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
2594                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
2595                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2596                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
2597                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2598         }
2599         info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
2600         for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
2601                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2602                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2603                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2604                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2605         }
2606
2607         info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
2608         info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
2609         for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
2610                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
2611                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2612                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
2613                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2614         }
2615         info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
2616         for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
2617                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2618                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2619                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2620                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2621         }
2622
2623         info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
2624         info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
2625         for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
2626                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
2627                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2628                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
2629                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2630         }
2631         info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
2632         for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
2633                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2634                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2635                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2636                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2637         }
2638
2639
2640         /** TODO - review **/
2641         #if 0
2642         info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
2643                                                                         * 10;
2644         info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
2645         info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
2646
2647         for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
2648                 /* Convert [10KHz] into [KHz] */
2649                 info->disp_clk_voltage[i].max_supported_clk =
2650                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
2651                         ulMaximumSupportedCLK) * 10;
2652                 info->disp_clk_voltage[i].voltage_index =
2653                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
2654         }
2655
2656         info->boot_up_req_display_vector =
2657                         le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
2658         info->boot_up_nb_voltage =
2659                         le16_to_cpu(info_v11->usBootUpNBVoltage);
2660         info->ext_disp_conn_info_offset =
2661                         le16_to_cpu(info_v11->usExtDispConnInfoOffset);
2662         info->gmc_restore_reset_time =
2663                         le32_to_cpu(info_v11->ulGMCRestoreResetTime);
2664         info->minimum_n_clk =
2665                         le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
2666         for (i = 1; i < 4; ++i)
2667                 info->minimum_n_clk =
2668                                 info->minimum_n_clk <
2669                                 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
2670                                 info->minimum_n_clk : le32_to_cpu(
2671                                         info_v11->ulNbpStateNClkFreq[i]);
2672
2673         info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
2674         info->ddr_dll_power_up_time =
2675             le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
2676         info->ddr_pll_power_up_time =
2677                 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
2678         info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
2679         info->max_lvds_pclk_freq_in_single_link =
2680                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
2681         info->max_lvds_pclk_freq_in_single_link =
2682                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
2683         info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
2684                 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
2685         info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
2686                 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
2687         info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
2688                 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
2689         info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
2690                 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
2691         info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
2692                 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
2693         info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
2694                 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
2695         info->lvds_off_to_on_delay_in_4ms =
2696                 info_v11->ucLVDSOffToOnDelay_in4Ms;
2697         info->lvds_bit_depth_control_val =
2698                 le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
2699
2700         for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
2701                 /* Convert [10KHz] into [KHz] */
2702                 info->avail_s_clk[i].supported_s_clk =
2703                         le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
2704                                                                         * 10;
2705                 info->avail_s_clk[i].voltage_index =
2706                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
2707                 info->avail_s_clk[i].voltage_id =
2708                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
2709         }
2710         #endif /* TODO*/
2711
2712         return BP_RESULT_OK;
2713 }
2714
2715 static enum bp_result get_integrated_info_v2_1(
2716         struct bios_parser *bp,
2717         struct integrated_info *info)
2718 {
2719         struct atom_integrated_system_info_v2_1 *info_v2_1;
2720         uint32_t i;
2721
2722         info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1,
2723                                         DATA_TABLES(integratedsysteminfo));
2724
2725         if (info_v2_1 == NULL)
2726                 return BP_RESULT_BADBIOSTABLE;
2727
2728         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_1->gpuclk_ss_percentage);
2729
2730         info->gpu_cap_info =
2731         le32_to_cpu(info_v2_1->gpucapinfo);
2732         /*
2733         * system_config: Bit[0] = 0 : PCIE power gating disabled
2734         *                       = 1 : PCIE power gating enabled
2735         *                Bit[1] = 0 : DDR-PLL shut down disabled
2736         *                       = 1 : DDR-PLL shut down enabled
2737         *                Bit[2] = 0 : DDR-PLL power down disabled
2738         *                       = 1 : DDR-PLL power down enabled
2739         */
2740         info->system_config = le32_to_cpu(info_v2_1->system_config);
2741         info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo);
2742         info->memory_type = info_v2_1->memorytype;
2743         info->ma_channel_number = info_v2_1->umachannelnumber;
2744         info->dp_ss_control =
2745                 le16_to_cpu(info_v2_1->reserved1);
2746
2747         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2748                 info->ext_disp_conn_info.gu_id[i] =
2749                                 info_v2_1->extdispconninfo.guid[i];
2750         }
2751
2752         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2753                 info->ext_disp_conn_info.path[i].device_connector_id =
2754                 object_id_from_bios_object_id(
2755                 le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid));
2756
2757                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2758                 object_id_from_bios_object_id(
2759                         le16_to_cpu(
2760                         info_v2_1->extdispconninfo.path[i].ext_encoder_objid));
2761
2762                 info->ext_disp_conn_info.path[i].device_tag =
2763                         le16_to_cpu(
2764                                 info_v2_1->extdispconninfo.path[i].device_tag);
2765                 info->ext_disp_conn_info.path[i].device_acpi_enum =
2766                 le16_to_cpu(
2767                         info_v2_1->extdispconninfo.path[i].device_acpi_enum);
2768                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2769                         info_v2_1->extdispconninfo.path[i].auxddclut_index;
2770                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2771                         info_v2_1->extdispconninfo.path[i].hpdlut_index;
2772                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2773                         info_v2_1->extdispconninfo.path[i].channelmapping;
2774                 info->ext_disp_conn_info.path[i].caps =
2775                                 le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps);
2776         }
2777
2778         info->ext_disp_conn_info.checksum =
2779                 info_v2_1->extdispconninfo.checksum;
2780         info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr;
2781         info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum;
2782         for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
2783                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
2784                                 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2785                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
2786                                 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2787         }
2788         info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum;
2789         for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
2790                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2791                                 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2792                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2793                                 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2794         }
2795         info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr;
2796         info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum;
2797         for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
2798                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
2799                                 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2800                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
2801                                 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2802         }
2803         info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum;
2804         for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
2805                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2806                                 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2807                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2808                                 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2809         }
2810         info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr;
2811         info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum;
2812         for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
2813                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
2814                                 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2815                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
2816                                 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2817         }
2818         info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum;
2819         for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
2820                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2821                                 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2822                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2823                                 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2824         }
2825         info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr;
2826         info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum;
2827         for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
2828                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
2829                                 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2830                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
2831                                 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2832         }
2833         info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum;
2834         for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
2835                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2836                                 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2837                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2838                                 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2839         }
2840
2841         info->edp1_info.edp_backlight_pwm_hz =
2842         le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz);
2843         info->edp1_info.edp_ss_percentage =
2844         le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage);
2845         info->edp1_info.edp_ss_rate_10hz =
2846         le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz);
2847         info->edp1_info.edp_pwr_on_off_delay =
2848                 info_v2_1->edp1_info.edp_pwr_on_off_delay;
2849         info->edp1_info.edp_pwr_on_vary_bl_to_blon =
2850                 info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon;
2851         info->edp1_info.edp_pwr_down_bloff_to_vary_bloff =
2852                 info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
2853         info->edp1_info.edp_panel_bpc =
2854                 info_v2_1->edp1_info.edp_panel_bpc;
2855         info->edp1_info.edp_bootup_bl_level = info_v2_1->edp1_info.edp_bootup_bl_level;
2856
2857         info->edp2_info.edp_backlight_pwm_hz =
2858         le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz);
2859         info->edp2_info.edp_ss_percentage =
2860         le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage);
2861         info->edp2_info.edp_ss_rate_10hz =
2862         le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz);
2863         info->edp2_info.edp_pwr_on_off_delay =
2864                 info_v2_1->edp2_info.edp_pwr_on_off_delay;
2865         info->edp2_info.edp_pwr_on_vary_bl_to_blon =
2866                 info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon;
2867         info->edp2_info.edp_pwr_down_bloff_to_vary_bloff =
2868                 info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff;
2869         info->edp2_info.edp_panel_bpc =
2870                 info_v2_1->edp2_info.edp_panel_bpc;
2871         info->edp2_info.edp_bootup_bl_level =
2872                 info_v2_1->edp2_info.edp_bootup_bl_level;
2873
2874         return BP_RESULT_OK;
2875 }
2876
2877 static enum bp_result get_integrated_info_v2_2(
2878         struct bios_parser *bp,
2879         struct integrated_info *info)
2880 {
2881         struct atom_integrated_system_info_v2_2 *info_v2_2;
2882         uint32_t i;
2883
2884         info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2,
2885                                         DATA_TABLES(integratedsysteminfo));
2886
2887         if (info_v2_2 == NULL)
2888                 return BP_RESULT_BADBIOSTABLE;
2889
2890         DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_2->gpuclk_ss_percentage);
2891
2892         info->gpu_cap_info =
2893         le32_to_cpu(info_v2_2->gpucapinfo);
2894         /*
2895         * system_config: Bit[0] = 0 : PCIE power gating disabled
2896         *                       = 1 : PCIE power gating enabled
2897         *                Bit[1] = 0 : DDR-PLL shut down disabled
2898         *                       = 1 : DDR-PLL shut down enabled
2899         *                Bit[2] = 0 : DDR-PLL power down disabled
2900         *                       = 1 : DDR-PLL power down enabled
2901         */
2902         info->system_config = le32_to_cpu(info_v2_2->system_config);
2903         info->cpu_cap_info = le32_to_cpu(info_v2_2->cpucapinfo);
2904         info->memory_type = info_v2_2->memorytype;
2905         info->ma_channel_number = info_v2_2->umachannelnumber;
2906         info->dp_ss_control =
2907                 le16_to_cpu(info_v2_2->reserved1);
2908         info->gpuclk_ss_percentage = info_v2_2->gpuclk_ss_percentage;
2909         info->gpuclk_ss_type = info_v2_2->gpuclk_ss_type;
2910
2911         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2912                 info->ext_disp_conn_info.gu_id[i] =
2913                                 info_v2_2->extdispconninfo.guid[i];
2914         }
2915
2916         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2917                 info->ext_disp_conn_info.path[i].device_connector_id =
2918                 object_id_from_bios_object_id(
2919                 le16_to_cpu(info_v2_2->extdispconninfo.path[i].connectorobjid));
2920
2921                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2922                 object_id_from_bios_object_id(
2923                         le16_to_cpu(
2924                         info_v2_2->extdispconninfo.path[i].ext_encoder_objid));
2925
2926                 info->ext_disp_conn_info.path[i].device_tag =
2927                         le16_to_cpu(
2928                                 info_v2_2->extdispconninfo.path[i].device_tag);
2929                 info->ext_disp_conn_info.path[i].device_acpi_enum =
2930                 le16_to_cpu(
2931                         info_v2_2->extdispconninfo.path[i].device_acpi_enum);
2932                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2933                         info_v2_2->extdispconninfo.path[i].auxddclut_index;
2934                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2935                         info_v2_2->extdispconninfo.path[i].hpdlut_index;
2936                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2937                         info_v2_2->extdispconninfo.path[i].channelmapping;
2938                 info->ext_disp_conn_info.path[i].caps =
2939                                 le16_to_cpu(info_v2_2->extdispconninfo.path[i].caps);
2940         }
2941
2942         info->ext_disp_conn_info.checksum =
2943                 info_v2_2->extdispconninfo.checksum;
2944         info->ext_disp_conn_info.fixdpvoltageswing =
2945                 info_v2_2->extdispconninfo.fixdpvoltageswing;
2946
2947         info->edp1_info.edp_backlight_pwm_hz =
2948         le16_to_cpu(info_v2_2->edp1_info.edp_backlight_pwm_hz);
2949         info->edp1_info.edp_ss_percentage =
2950         le16_to_cpu(info_v2_2->edp1_info.edp_ss_percentage);
2951         info->edp1_info.edp_ss_rate_10hz =
2952         le16_to_cpu(info_v2_2->edp1_info.edp_ss_rate_10hz);
2953         info->edp1_info.edp_pwr_on_off_delay =
2954                 info_v2_2->edp1_info.edp_pwr_on_off_delay;
2955         info->edp1_info.edp_pwr_on_vary_bl_to_blon =
2956                 info_v2_2->edp1_info.edp_pwr_on_vary_bl_to_blon;
2957         info->edp1_info.edp_pwr_down_bloff_to_vary_bloff =
2958                 info_v2_2->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
2959         info->edp1_info.edp_panel_bpc =
2960                 info_v2_2->edp1_info.edp_panel_bpc;
2961         info->edp1_info.edp_bootup_bl_level =
2962
2963         info->edp2_info.edp_backlight_pwm_hz =
2964         le16_to_cpu(info_v2_2->edp2_info.edp_backlight_pwm_hz);
2965         info->edp2_info.edp_ss_percentage =
2966         le16_to_cpu(info_v2_2->edp2_info.edp_ss_percentage);
2967         info->edp2_info.edp_ss_rate_10hz =
2968         le16_to_cpu(info_v2_2->edp2_info.edp_ss_rate_10hz);
2969         info->edp2_info.edp_pwr_on_off_delay =
2970                 info_v2_2->edp2_info.edp_pwr_on_off_delay;
2971         info->edp2_info.edp_pwr_on_vary_bl_to_blon =
2972                 info_v2_2->edp2_info.edp_pwr_on_vary_bl_to_blon;
2973         info->edp2_info.edp_pwr_down_bloff_to_vary_bloff =
2974                 info_v2_2->edp2_info.edp_pwr_down_bloff_to_vary_bloff;
2975         info->edp2_info.edp_panel_bpc =
2976                 info_v2_2->edp2_info.edp_panel_bpc;
2977         info->edp2_info.edp_bootup_bl_level =
2978                 info_v2_2->edp2_info.edp_bootup_bl_level;
2979
2980         return BP_RESULT_OK;
2981 }
2982
2983 /*
2984  * construct_integrated_info
2985  *
2986  * @brief
2987  * Get integrated BIOS information based on table revision
2988  *
2989  * @param
2990  * bios_parser *bp - [in]BIOS parser handler to get master data table
2991  * integrated_info *info - [out] store and output integrated info
2992  *
2993  * @return
2994  * static enum bp_result - BP_RESULT_OK if information is available,
2995  *                  BP_RESULT_BADBIOSTABLE otherwise.
2996  */
2997 static enum bp_result construct_integrated_info(
2998         struct bios_parser *bp,
2999         struct integrated_info *info)
3000 {
3001         static enum bp_result result = BP_RESULT_BADBIOSTABLE;
3002
3003         struct atom_common_table_header *header;
3004         struct atom_data_revision revision;
3005
3006         int32_t i;
3007         int32_t j;
3008
3009         if (!info)
3010                 return result;
3011
3012         if (info && DATA_TABLES(integratedsysteminfo)) {
3013                 header = GET_IMAGE(struct atom_common_table_header,
3014                                         DATA_TABLES(integratedsysteminfo));
3015
3016                 get_atom_data_table_revision(header, &revision);
3017
3018                 switch (revision.major) {
3019                 case 1:
3020                         switch (revision.minor) {
3021                         case 11:
3022                         case 12:
3023                                 result = get_integrated_info_v11(bp, info);
3024                                 break;
3025                         default:
3026                                 return result;
3027                         }
3028                         break;
3029                 case 2:
3030                         switch (revision.minor) {
3031                         case 1:
3032                                 result = get_integrated_info_v2_1(bp, info);
3033                                 break;
3034                         case 2:
3035                         case 3:
3036                                 result = get_integrated_info_v2_2(bp, info);
3037                                 break;
3038                         default:
3039                                 return result;
3040                         }
3041                         break;
3042                 default:
3043                         return result;
3044                 }
3045                 if (result == BP_RESULT_OK) {
3046
3047                         DC_LOG_BIOS("edp1:\n"
3048                                                 "\tedp_pwr_on_off_delay = %d\n"
3049                                                 "\tedp_pwr_on_vary_bl_to_blon = %d\n"
3050                                                 "\tedp_pwr_down_bloff_to_vary_bloff = %d\n"
3051                                                 "\tedp_bootup_bl_level = %d\n",
3052                                                 info->edp1_info.edp_pwr_on_off_delay,
3053                                                 info->edp1_info.edp_pwr_on_vary_bl_to_blon,
3054                                                 info->edp1_info.edp_pwr_down_bloff_to_vary_bloff,
3055                                                 info->edp1_info.edp_bootup_bl_level);
3056                         DC_LOG_BIOS("edp2:\n"
3057                                                 "\tedp_pwr_on_off_delayv = %d\n"
3058                                                 "\tedp_pwr_on_vary_bl_to_blon = %d\n"
3059                                                 "\tedp_pwr_down_bloff_to_vary_bloff = %d\n"
3060                                                 "\tedp_bootup_bl_level = %d\n",
3061                                                 info->edp2_info.edp_pwr_on_off_delay,
3062                                                 info->edp2_info.edp_pwr_on_vary_bl_to_blon,
3063                                                 info->edp2_info.edp_pwr_down_bloff_to_vary_bloff,
3064                                                 info->edp2_info.edp_bootup_bl_level);
3065                 }
3066         }
3067
3068         if (result != BP_RESULT_OK)
3069                 return result;
3070         else {
3071                 // Log each external path
3072                 for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; i++) {
3073                         if (info->ext_disp_conn_info.path[i].device_tag != 0)
3074                                 DC_LOG_BIOS("integrated_info:For EXTERNAL DISPLAY PATH %d --------------\n"
3075                                                 "DEVICE_TAG: 0x%x\n"
3076                                                 "DEVICE_ACPI_ENUM: 0x%x\n"
3077                                                 "DEVICE_CONNECTOR_ID: 0x%x\n"
3078                                                 "EXT_AUX_DDC_LUT_INDEX: %d\n"
3079                                                 "EXT_HPD_PIN_LUT_INDEX: %d\n"
3080                                                 "EXT_ENCODER_OBJ_ID: 0x%x\n"
3081                                                 "Encoder CAPS: 0x%x\n",
3082                                                 i,
3083                                                 info->ext_disp_conn_info.path[i].device_tag,
3084                                                 info->ext_disp_conn_info.path[i].device_acpi_enum,
3085                                                 info->ext_disp_conn_info.path[i].device_connector_id.id,
3086                                                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index,
3087                                                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index,
3088                                                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id.id,
3089                                                 info->ext_disp_conn_info.path[i].caps
3090                                                 );
3091                         if ((info->ext_disp_conn_info.path[i].caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)
3092                                 DC_LOG_BIOS("BIOS AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN on path %d\n", i);
3093                         else if (bp->base.ctx->dc->config.force_bios_fixed_vs) {
3094                                 info->ext_disp_conn_info.path[i].caps &= ~AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
3095                                 info->ext_disp_conn_info.path[i].caps |= AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN;
3096                                 DC_LOG_BIOS("driver forced AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN on path %d\n", i);
3097                         }
3098                 }
3099                 // Log the Checksum and Voltage Swing
3100                 DC_LOG_BIOS("Integrated info table CHECKSUM: %d\n"
3101                                         "Integrated info table FIX_DP_VOLTAGE_SWING: %d\n",
3102                                         info->ext_disp_conn_info.checksum,
3103                                         info->ext_disp_conn_info.fixdpvoltageswing);
3104                 if (bp->base.ctx->dc->config.force_bios_fixed_vs && info->ext_disp_conn_info.fixdpvoltageswing == 0) {
3105                         info->ext_disp_conn_info.fixdpvoltageswing = bp->base.ctx->dc->config.force_bios_fixed_vs & 0xF;
3106                         DC_LOG_BIOS("driver forced fixdpvoltageswing = %d\n", info->ext_disp_conn_info.fixdpvoltageswing);
3107                 }
3108         }
3109         /* Sort voltage table from low to high*/
3110         for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
3111                 for (j = i; j > 0; --j) {
3112                         if (info->disp_clk_voltage[j].max_supported_clk <
3113                             info->disp_clk_voltage[j-1].max_supported_clk)
3114                                 swap(info->disp_clk_voltage[j-1], info->disp_clk_voltage[j]);
3115                 }
3116         }
3117
3118         return result;
3119 }
3120
3121 static enum bp_result bios_parser_get_vram_info(
3122                 struct dc_bios *dcb,
3123                 struct dc_vram_info *info)
3124 {
3125         struct bios_parser *bp = BP_FROM_DCB(dcb);
3126         enum bp_result result = BP_RESULT_BADBIOSTABLE;
3127         struct atom_common_table_header *header;
3128         struct atom_data_revision revision;
3129
3130         // vram info moved to umc_info for DCN4x
3131         if (info && DATA_TABLES(umc_info)) {
3132                 header = GET_IMAGE(struct atom_common_table_header,
3133                                         DATA_TABLES(umc_info));
3134
3135                 get_atom_data_table_revision(header, &revision);
3136
3137                 switch (revision.major) {
3138                 case 4:
3139                         switch (revision.minor) {
3140                         case 0:
3141                                 result = get_vram_info_from_umc_info_v40(bp, info);
3142                                 break;
3143                         default:
3144                                 break;
3145                         }
3146                         break;
3147                 default:
3148                         break;
3149                 }
3150         }
3151
3152         if (result != BP_RESULT_OK && info && DATA_TABLES(vram_info)) {
3153                 header = GET_IMAGE(struct atom_common_table_header,
3154                                         DATA_TABLES(vram_info));
3155
3156                 get_atom_data_table_revision(header, &revision);
3157
3158                 switch (revision.major) {
3159                 case 2:
3160                         switch (revision.minor) {
3161                         case 3:
3162                                 result = get_vram_info_v23(bp, info);
3163                                 break;
3164                         case 4:
3165                                 result = get_vram_info_v24(bp, info);
3166                                 break;
3167                         case 5:
3168                                 result = get_vram_info_v25(bp, info);
3169                                 break;
3170                         default:
3171                                 break;
3172                         }
3173                         break;
3174
3175                 case 3:
3176                         switch (revision.minor) {
3177                         case 0:
3178                                 result = get_vram_info_v30(bp, info);
3179                                 break;
3180                         default:
3181                                 break;
3182                         }
3183                         break;
3184
3185                 default:
3186                         return result;
3187                 }
3188
3189         }
3190         return result;
3191 }
3192
3193 static struct integrated_info *bios_parser_create_integrated_info(
3194         struct dc_bios *dcb)
3195 {
3196         struct bios_parser *bp = BP_FROM_DCB(dcb);
3197         struct integrated_info *info;
3198
3199         info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
3200
3201         if (info == NULL) {
3202                 ASSERT_CRITICAL(0);
3203                 return NULL;
3204         }
3205
3206         if (construct_integrated_info(bp, info) == BP_RESULT_OK)
3207                 return info;
3208
3209         kfree(info);
3210
3211         return NULL;
3212 }
3213
3214 static enum bp_result update_slot_layout_info(
3215         struct dc_bios *dcb,
3216         unsigned int i,
3217         struct slot_layout_info *slot_layout_info)
3218 {
3219         unsigned int record_offset;
3220         unsigned int j;
3221         struct atom_display_object_path_v2 *object;
3222         struct atom_bracket_layout_record *record;
3223         struct atom_common_record_header *record_header;
3224         static enum bp_result result;
3225         struct bios_parser *bp;
3226         struct object_info_table *tbl;
3227         struct display_object_info_table_v1_4 *v1_4;
3228
3229         record = NULL;
3230         record_header = NULL;
3231         result = BP_RESULT_NORECORD;
3232
3233         bp = BP_FROM_DCB(dcb);
3234         tbl = &bp->object_info_tbl;
3235         v1_4 = tbl->v1_4;
3236
3237         object = &v1_4->display_path[i];
3238         record_offset = (unsigned int)
3239                 (object->disp_recordoffset) +
3240                 (unsigned int)(bp->object_info_tbl_offset);
3241
3242         for (;;) {
3243
3244                 record_header = (struct atom_common_record_header *)
3245                         GET_IMAGE(struct atom_common_record_header,
3246                         record_offset);
3247                 if (record_header == NULL) {
3248                         result = BP_RESULT_BADBIOSTABLE;
3249                         break;
3250                 }
3251
3252                 /* the end of the list */
3253                 if (record_header->record_type == 0xff ||
3254                         record_header->record_size == 0)        {
3255                         break;
3256                 }
3257
3258                 if (record_header->record_type ==
3259                         ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
3260                         sizeof(struct atom_bracket_layout_record)
3261                         <= record_header->record_size) {
3262                         record = (struct atom_bracket_layout_record *)
3263                                 (record_header);
3264                         result = BP_RESULT_OK;
3265                         break;
3266                 }
3267
3268                 record_offset += record_header->record_size;
3269         }
3270
3271         /* return if the record not found */
3272         if (result != BP_RESULT_OK)
3273                 return result;
3274
3275         /* get slot sizes */
3276         slot_layout_info->length = record->bracketlen;
3277         slot_layout_info->width = record->bracketwidth;
3278
3279         /* get info for each connector in the slot */
3280         slot_layout_info->num_of_connectors = record->conn_num;
3281         for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
3282                 slot_layout_info->connectors[j].connector_type =
3283                         (enum connector_layout_type)
3284                         (record->conn_info[j].connector_type);
3285                 switch (record->conn_info[j].connector_type) {
3286                 case CONNECTOR_TYPE_DVI_D:
3287                         slot_layout_info->connectors[j].connector_type =
3288                                 CONNECTOR_LAYOUT_TYPE_DVI_D;
3289                         slot_layout_info->connectors[j].length =
3290                                 CONNECTOR_SIZE_DVI;
3291                         break;
3292
3293                 case CONNECTOR_TYPE_HDMI:
3294                         slot_layout_info->connectors[j].connector_type =
3295                                 CONNECTOR_LAYOUT_TYPE_HDMI;
3296                         slot_layout_info->connectors[j].length =
3297                                 CONNECTOR_SIZE_HDMI;
3298                         break;
3299
3300                 case CONNECTOR_TYPE_DISPLAY_PORT:
3301                         slot_layout_info->connectors[j].connector_type =
3302                                 CONNECTOR_LAYOUT_TYPE_DP;
3303                         slot_layout_info->connectors[j].length =
3304                                 CONNECTOR_SIZE_DP;
3305                         break;
3306
3307                 case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
3308                         slot_layout_info->connectors[j].connector_type =
3309                                 CONNECTOR_LAYOUT_TYPE_MINI_DP;
3310                         slot_layout_info->connectors[j].length =
3311                                 CONNECTOR_SIZE_MINI_DP;
3312                         break;
3313
3314                 default:
3315                         slot_layout_info->connectors[j].connector_type =
3316                                 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3317                         slot_layout_info->connectors[j].length =
3318                                 CONNECTOR_SIZE_UNKNOWN;
3319                 }
3320
3321                 slot_layout_info->connectors[j].position =
3322                         record->conn_info[j].position;
3323                 slot_layout_info->connectors[j].connector_id =
3324                         object_id_from_bios_object_id(
3325                                 record->conn_info[j].connectorobjid);
3326         }
3327         return result;
3328 }
3329
3330 static enum bp_result update_slot_layout_info_v2(
3331         struct dc_bios *dcb,
3332         unsigned int i,
3333         struct slot_layout_info *slot_layout_info)
3334 {
3335         unsigned int record_offset;
3336         struct atom_display_object_path_v3 *object;
3337         struct atom_bracket_layout_record_v2 *record;
3338         struct atom_common_record_header *record_header;
3339         static enum bp_result result;
3340         struct bios_parser *bp;
3341         struct object_info_table *tbl;
3342         struct display_object_info_table_v1_5 *v1_5;
3343         struct graphics_object_id connector_id;
3344
3345         record = NULL;
3346         record_header = NULL;
3347         result = BP_RESULT_NORECORD;
3348
3349         bp = BP_FROM_DCB(dcb);
3350         tbl = &bp->object_info_tbl;
3351         v1_5 = tbl->v1_5;
3352
3353         object = &v1_5->display_path[i];
3354         record_offset = (unsigned int)
3355                 (object->disp_recordoffset) +
3356                 (unsigned int)(bp->object_info_tbl_offset);
3357
3358         for (;;) {
3359
3360                 record_header = (struct atom_common_record_header *)
3361                         GET_IMAGE(struct atom_common_record_header,
3362                         record_offset);
3363                 if (record_header == NULL) {
3364                         result = BP_RESULT_BADBIOSTABLE;
3365                         break;
3366                 }
3367
3368                 /* the end of the list */
3369                 if (record_header->record_type == ATOM_RECORD_END_TYPE ||
3370                         record_header->record_size == 0)        {
3371                         break;
3372                 }
3373
3374                 if (record_header->record_type ==
3375                         ATOM_BRACKET_LAYOUT_V2_RECORD_TYPE &&
3376                         sizeof(struct atom_bracket_layout_record_v2)
3377                         <= record_header->record_size) {
3378                         record = (struct atom_bracket_layout_record_v2 *)
3379                                 (record_header);
3380                         result = BP_RESULT_OK;
3381                         break;
3382                 }
3383
3384                 record_offset += record_header->record_size;
3385         }
3386
3387         /* return if the record not found */
3388         if (result != BP_RESULT_OK)
3389                 return result;
3390
3391         /* get slot sizes */
3392         connector_id = object_id_from_bios_object_id(object->display_objid);
3393
3394         slot_layout_info->length = record->bracketlen;
3395         slot_layout_info->width = record->bracketwidth;
3396         slot_layout_info->num_of_connectors = v1_5->number_of_path;
3397         slot_layout_info->connectors[i].position = record->conn_num;
3398         slot_layout_info->connectors[i].connector_id = connector_id;
3399
3400         switch (connector_id.id) {
3401         case CONNECTOR_ID_SINGLE_LINK_DVID:
3402         case CONNECTOR_ID_DUAL_LINK_DVID:
3403                 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DVI_D;
3404                 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DVI;
3405                 break;
3406
3407         case CONNECTOR_ID_HDMI_TYPE_A:
3408                 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_HDMI;
3409                 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_HDMI;
3410                 break;
3411
3412         case CONNECTOR_ID_DISPLAY_PORT:
3413         case CONNECTOR_ID_USBC:
3414                 if (record->mini_type == MINI_TYPE_NORMAL) {
3415                         slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_DP;
3416                         slot_layout_info->connectors[i].length = CONNECTOR_SIZE_DP;
3417                 } else {
3418                         slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_MINI_DP;
3419                         slot_layout_info->connectors[i].length = CONNECTOR_SIZE_MINI_DP;
3420                 }
3421                 break;
3422
3423         default:
3424                 slot_layout_info->connectors[i].connector_type = CONNECTOR_LAYOUT_TYPE_UNKNOWN;
3425                 slot_layout_info->connectors[i].length = CONNECTOR_SIZE_UNKNOWN;
3426         }
3427         return result;
3428 }
3429
3430 static enum bp_result get_bracket_layout_record(
3431         struct dc_bios *dcb,
3432         unsigned int bracket_layout_id,
3433         struct slot_layout_info *slot_layout_info)
3434 {
3435         unsigned int i;
3436         struct bios_parser *bp = BP_FROM_DCB(dcb);
3437         static enum bp_result result;
3438         struct object_info_table *tbl;
3439         struct display_object_info_table_v1_4 *v1_4;
3440         struct display_object_info_table_v1_5 *v1_5;
3441
3442         if (slot_layout_info == NULL) {
3443                 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
3444                 return BP_RESULT_BADINPUT;
3445         }
3446
3447         tbl = &bp->object_info_tbl;
3448         v1_4 = tbl->v1_4;
3449         v1_5 = tbl->v1_5;
3450
3451         result = BP_RESULT_NORECORD;
3452         switch (bp->object_info_tbl.revision.minor) {
3453         case 4:
3454         default:
3455                 for (i = 0; i < v1_4->number_of_path; ++i) {
3456                         if (bracket_layout_id == v1_4->display_path[i].display_objid) {
3457                                 result = update_slot_layout_info(dcb, i, slot_layout_info);
3458                                 break;
3459                         }
3460                 }
3461                 break;
3462         case 5:
3463                 for (i = 0; i < v1_5->number_of_path; ++i)
3464                         result = update_slot_layout_info_v2(dcb, i, slot_layout_info);
3465                 break;
3466         }
3467
3468         return result;
3469 }
3470
3471 static enum bp_result bios_get_board_layout_info(
3472         struct dc_bios *dcb,
3473         struct board_layout_info *board_layout_info)
3474 {
3475         unsigned int i;
3476         struct bios_parser *bp;
3477         static enum bp_result record_result;
3478         unsigned int max_slots;
3479
3480         const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
3481                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
3482                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
3483                 0, 0
3484         };
3485
3486         bp = BP_FROM_DCB(dcb);
3487
3488         if (board_layout_info == NULL) {
3489                 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
3490                 return BP_RESULT_BADINPUT;
3491         }
3492
3493         board_layout_info->num_of_slots = 0;
3494         max_slots = MAX_BOARD_SLOTS;
3495
3496         // Assume single slot on v1_5
3497         if (bp->object_info_tbl.revision.minor == 5) {
3498                 max_slots = 1;
3499         }
3500
3501         for (i = 0; i < max_slots; ++i) {
3502                 record_result = get_bracket_layout_record(dcb,
3503                         slot_index_to_vbios_id[i],
3504                         &board_layout_info->slots[i]);
3505
3506                 if (record_result == BP_RESULT_NORECORD && i > 0)
3507                         break; /* no more slots present in bios */
3508                 else if (record_result != BP_RESULT_OK)
3509                         return record_result;  /* fail */
3510
3511                 ++board_layout_info->num_of_slots;
3512         }
3513
3514         /* all data is valid */
3515         board_layout_info->is_number_of_slots_valid = 1;
3516         board_layout_info->is_slots_size_valid = 1;
3517         board_layout_info->is_connector_offsets_valid = 1;
3518         board_layout_info->is_connector_lengths_valid = 1;
3519
3520         return BP_RESULT_OK;
3521 }
3522
3523
3524 static uint16_t bios_parser_pack_data_tables(
3525         struct dc_bios *dcb,
3526         void *dst)
3527 {
3528         // TODO: There is data bytes alignment issue, disable it for now.
3529         return 0;
3530 }
3531
3532 static struct atom_dc_golden_table_v1 *bios_get_golden_table(
3533                 struct bios_parser *bp,
3534                 uint32_t rev_major,
3535                 uint32_t rev_minor,
3536                 uint16_t *dc_golden_table_ver)
3537 {
3538         struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL;
3539         uint32_t dc_golden_offset = 0;
3540         *dc_golden_table_ver = 0;
3541
3542         if (!DATA_TABLES(dce_info))
3543                 return NULL;
3544
3545         /* ver.4.4 or higher */
3546         switch (rev_major) {
3547         case 4:
3548                 switch (rev_minor) {
3549                 case 4:
3550                         disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
3551                                                                         DATA_TABLES(dce_info));
3552                         if (!disp_cntl_tbl_4_4)
3553                                 return NULL;
3554                         dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset;
3555                         *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
3556                         break;
3557                 case 5:
3558                 default:
3559                         /* For atom_display_controller_info_v4_5 there is no need to get golden table from
3560                          * dc_golden_table_offset as all these fields previously in golden table used for AUX
3561                          * pre-charge settings are now available directly in atom_display_controller_info_v4_5.
3562                          */
3563                         break;
3564                 }
3565                 break;
3566         }
3567
3568         if (!dc_golden_offset)
3569                 return NULL;
3570
3571         if (*dc_golden_table_ver != 1)
3572                 return NULL;
3573
3574         return GET_IMAGE(struct atom_dc_golden_table_v1,
3575                         dc_golden_offset);
3576 }
3577
3578 static enum bp_result bios_get_atom_dc_golden_table(
3579         struct dc_bios *dcb)
3580 {
3581         struct bios_parser *bp = BP_FROM_DCB(dcb);
3582         enum bp_result result = BP_RESULT_OK;
3583         struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL;
3584         struct atom_common_table_header *header;
3585         struct atom_data_revision tbl_revision;
3586         uint16_t dc_golden_table_ver = 0;
3587
3588         header = GET_IMAGE(struct atom_common_table_header,
3589                                                         DATA_TABLES(dce_info));
3590         if (!header)
3591                 return BP_RESULT_UNSUPPORTED;
3592
3593         get_atom_data_table_revision(header, &tbl_revision);
3594
3595         atom_dc_golden_table = bios_get_golden_table(bp,
3596                         tbl_revision.major,
3597                         tbl_revision.minor,
3598                         &dc_golden_table_ver);
3599
3600         if (!atom_dc_golden_table)
3601                 return BP_RESULT_UNSUPPORTED;
3602
3603         dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver;
3604         dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val;
3605         dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val;
3606         dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val;
3607         dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val;
3608         dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val;
3609         dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val;
3610         dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val;
3611         dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val;
3612         dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val;
3613
3614         return result;
3615 }
3616
3617
3618 static const struct dc_vbios_funcs vbios_funcs = {
3619         .get_connectors_number = bios_parser_get_connectors_number,
3620
3621         .get_connector_id = bios_parser_get_connector_id,
3622
3623         .get_src_obj = bios_parser_get_src_obj,
3624
3625         .get_i2c_info = bios_parser_get_i2c_info,
3626
3627         .get_hpd_info = bios_parser_get_hpd_info,
3628
3629         .get_device_tag = bios_parser_get_device_tag,
3630
3631         .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
3632
3633         .get_ss_entry_number = bios_parser_get_ss_entry_number,
3634
3635         .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
3636
3637         .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
3638
3639         .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
3640
3641         .is_device_id_supported = bios_parser_is_device_id_supported,
3642
3643         .is_accelerated_mode = bios_parser_is_accelerated_mode,
3644
3645         .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
3646
3647
3648 /*       COMMANDS */
3649         .encoder_control = bios_parser_encoder_control,
3650
3651         .transmitter_control = bios_parser_transmitter_control,
3652
3653         .enable_crtc = bios_parser_enable_crtc,
3654
3655         .set_pixel_clock = bios_parser_set_pixel_clock,
3656
3657         .set_dce_clock = bios_parser_set_dce_clock,
3658
3659         .program_crtc_timing = bios_parser_program_crtc_timing,
3660
3661         .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
3662
3663         .bios_parser_destroy = firmware_parser_destroy,
3664
3665         .get_board_layout_info = bios_get_board_layout_info,
3666         .pack_data_tables = bios_parser_pack_data_tables,
3667
3668         .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
3669
3670         .enable_lvtma_control = bios_parser_enable_lvtma_control,
3671
3672         .get_soc_bb_info = bios_parser_get_soc_bb_info,
3673
3674         .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info,
3675
3676         .get_lttpr_caps = bios_parser_get_lttpr_caps,
3677
3678         .get_lttpr_interop = bios_parser_get_lttpr_interop,
3679
3680         .get_connector_speed_cap_info = bios_parser_get_connector_speed_cap_info,
3681 };
3682
3683 static bool bios_parser2_construct(
3684         struct bios_parser *bp,
3685         struct bp_init_data *init,
3686         enum dce_version dce_version)
3687 {
3688         uint16_t *rom_header_offset = NULL;
3689         struct atom_rom_header_v2_2 *rom_header = NULL;
3690         struct display_object_info_table_v1_4 *object_info_tbl;
3691         struct atom_data_revision tbl_rev = {0};
3692
3693         if (!init)
3694                 return false;
3695
3696         if (!init->bios)
3697                 return false;
3698
3699         bp->base.funcs = &vbios_funcs;
3700         bp->base.bios = init->bios;
3701         bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
3702
3703         bp->base.ctx = init->ctx;
3704
3705         bp->base.bios_local_image = NULL;
3706
3707         rom_header_offset =
3708                         GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
3709
3710         if (!rom_header_offset)
3711                 return false;
3712
3713         rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
3714
3715         if (!rom_header)
3716                 return false;
3717
3718         get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
3719         if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
3720                 return false;
3721
3722         bp->master_data_tbl =
3723                 GET_IMAGE(struct atom_master_data_table_v2_1,
3724                                 rom_header->masterdatatable_offset);
3725
3726         if (!bp->master_data_tbl)
3727                 return false;
3728
3729         bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
3730
3731         if (!bp->object_info_tbl_offset)
3732                 return false;
3733
3734         object_info_tbl =
3735                         GET_IMAGE(struct display_object_info_table_v1_4,
3736                                                 bp->object_info_tbl_offset);
3737
3738         if (!object_info_tbl)
3739                 return false;
3740
3741         get_atom_data_table_revision(&object_info_tbl->table_header,
3742                 &bp->object_info_tbl.revision);
3743
3744         if (bp->object_info_tbl.revision.major == 1
3745                 && bp->object_info_tbl.revision.minor == 4) {
3746                 struct display_object_info_table_v1_4 *tbl_v1_4;
3747
3748                 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
3749                         bp->object_info_tbl_offset);
3750                 if (!tbl_v1_4)
3751                         return false;
3752
3753                 bp->object_info_tbl.v1_4 = tbl_v1_4;
3754         } else if (bp->object_info_tbl.revision.major == 1
3755                 && bp->object_info_tbl.revision.minor == 5) {
3756                 struct display_object_info_table_v1_5 *tbl_v1_5;
3757
3758                 tbl_v1_5 = GET_IMAGE(struct display_object_info_table_v1_5,
3759                         bp->object_info_tbl_offset);
3760                 if (!tbl_v1_5)
3761                         return false;
3762
3763                 bp->object_info_tbl.v1_5 = tbl_v1_5;
3764         } else {
3765                 ASSERT(0);
3766                 return false;
3767         }
3768
3769         dal_firmware_parser_init_cmd_tbl(bp);
3770         dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
3771
3772         bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
3773         bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
3774         bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);
3775         bios_parser_get_soc_bb_info(&bp->base, &bp->base.bb_info);
3776         return true;
3777 }
3778
3779 struct dc_bios *firmware_parser_create(
3780         struct bp_init_data *init,
3781         enum dce_version dce_version)
3782 {
3783         struct bios_parser *bp;
3784
3785         bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
3786         if (!bp)
3787                 return NULL;
3788
3789         if (bios_parser2_construct(bp, init, dce_version))
3790                 return &bp->base;
3791
3792         kfree(bp);
3793         return NULL;
3794 }
3795
3796
This page took 0.262656 seconds and 4 git commands to generate.