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