drm/i915/icl: Fix CRC mismatch error for DP link layer compliance
[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 struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
101                 struct atom_display_object_path_v2 *object);
102
103 static struct atom_encoder_caps_record *get_encoder_cap_record(
104         struct bios_parser *bp,
105         struct atom_display_object_path_v2 *object);
106
107 #define BIOS_IMAGE_SIZE_OFFSET 2
108 #define BIOS_IMAGE_SIZE_UNIT 512
109
110 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
111
112 static void destruct(struct bios_parser *bp)
113 {
114         kfree(bp->base.bios_local_image);
115         kfree(bp->base.integrated_info);
116 }
117
118 static void firmware_parser_destroy(struct dc_bios **dcb)
119 {
120         struct bios_parser *bp = BP_FROM_DCB(*dcb);
121
122         if (!bp) {
123                 BREAK_TO_DEBUGGER();
124                 return;
125         }
126
127         destruct(bp);
128
129         kfree(bp);
130         *dcb = NULL;
131 }
132
133 static void get_atom_data_table_revision(
134         struct atom_common_table_header *atom_data_tbl,
135         struct atom_data_revision *tbl_revision)
136 {
137         if (!tbl_revision)
138                 return;
139
140         /* initialize the revision to 0 which is invalid revision */
141         tbl_revision->major = 0;
142         tbl_revision->minor = 0;
143
144         if (!atom_data_tbl)
145                 return;
146
147         tbl_revision->major =
148                         (uint32_t) atom_data_tbl->format_revision & 0x3f;
149         tbl_revision->minor =
150                         (uint32_t) atom_data_tbl->content_revision & 0x3f;
151 }
152
153 /* BIOS oject table displaypath is per connector.
154  * There is extra path not for connector. BIOS fill its encoderid as 0
155  */
156 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
157 {
158         struct bios_parser *bp = BP_FROM_DCB(dcb);
159         unsigned int count = 0;
160         unsigned int i;
161
162         for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
163                 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
164                         count++;
165         }
166         return count;
167 }
168
169 static struct graphics_object_id bios_parser_get_connector_id(
170         struct dc_bios *dcb,
171         uint8_t i)
172 {
173         struct bios_parser *bp = BP_FROM_DCB(dcb);
174         struct graphics_object_id object_id = dal_graphics_object_id_init(
175                 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
176         struct object_info_table *tbl = &bp->object_info_tbl;
177         struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
178
179         if (v1_4->number_of_path > i) {
180                 /* If display_objid is generic object id,  the encoderObj
181                  * /extencoderobjId should be 0
182                  */
183                 if (v1_4->display_path[i].encoderobjid != 0 &&
184                                 v1_4->display_path[i].display_objid != 0)
185                         object_id = object_id_from_bios_object_id(
186                                         v1_4->display_path[i].display_objid);
187         }
188
189         return object_id;
190 }
191
192 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
193         struct graphics_object_id object_id, uint32_t index,
194         struct graphics_object_id *src_object_id)
195 {
196         struct bios_parser *bp = BP_FROM_DCB(dcb);
197         unsigned int i;
198         enum bp_result  bp_result = BP_RESULT_BADINPUT;
199         struct graphics_object_id obj_id = {0};
200         struct object_info_table *tbl = &bp->object_info_tbl;
201
202         if (!src_object_id)
203                 return bp_result;
204
205         switch (object_id.type) {
206         /* Encoder's Source is GPU.  BIOS does not provide GPU, since all
207          * displaypaths point to same GPU (0x1100).  Hardcode GPU object type
208          */
209         case OBJECT_TYPE_ENCODER:
210                 /* TODO: since num of src must be less than 2.
211                  * If found in for loop, should break.
212                  * DAL2 implementation may be changed too
213                  */
214                 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
215                         obj_id = object_id_from_bios_object_id(
216                         tbl->v1_4->display_path[i].encoderobjid);
217                         if (object_id.type == obj_id.type &&
218                                         object_id.id == obj_id.id &&
219                                                 object_id.enum_id ==
220                                                         obj_id.enum_id) {
221                                 *src_object_id =
222                                 object_id_from_bios_object_id(0x1100);
223                                 /* break; */
224                         }
225                 }
226                 bp_result = BP_RESULT_OK;
227                 break;
228         case OBJECT_TYPE_CONNECTOR:
229                 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
230                         obj_id = object_id_from_bios_object_id(
231                                 tbl->v1_4->display_path[i].display_objid);
232
233                         if (object_id.type == obj_id.type &&
234                                 object_id.id == obj_id.id &&
235                                         object_id.enum_id == obj_id.enum_id) {
236                                 *src_object_id =
237                                 object_id_from_bios_object_id(
238                                 tbl->v1_4->display_path[i].encoderobjid);
239                                 /* break; */
240                         }
241                 }
242                 bp_result = BP_RESULT_OK;
243                 break;
244         default:
245                 break;
246         }
247
248         return bp_result;
249 }
250
251 /* from graphics_object_id, find display path which includes the object_id */
252 static struct atom_display_object_path_v2 *get_bios_object(
253                 struct bios_parser *bp,
254                 struct graphics_object_id id)
255 {
256         unsigned int i;
257         struct graphics_object_id obj_id = {0};
258
259         switch (id.type) {
260         case OBJECT_TYPE_ENCODER:
261                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
262                         obj_id = object_id_from_bios_object_id(
263                                         bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
264                         if (id.type == obj_id.type && id.id == obj_id.id
265                                         && id.enum_id == obj_id.enum_id)
266                                 return &bp->object_info_tbl.v1_4->display_path[i];
267                 }
268         case OBJECT_TYPE_CONNECTOR:
269         case OBJECT_TYPE_GENERIC:
270                 /* Both Generic and Connector Object ID
271                  * will be stored on display_objid
272                  */
273                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
274                         obj_id = object_id_from_bios_object_id(
275                                         bp->object_info_tbl.v1_4->display_path[i].display_objid);
276                         if (id.type == obj_id.type && id.id == obj_id.id
277                                         && id.enum_id == obj_id.enum_id)
278                                 return &bp->object_info_tbl.v1_4->display_path[i];
279                 }
280         default:
281                 return NULL;
282         }
283 }
284
285 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
286         struct graphics_object_id id,
287         struct graphics_object_i2c_info *info)
288 {
289         uint32_t offset;
290         struct atom_display_object_path_v2 *object;
291         struct atom_common_record_header *header;
292         struct atom_i2c_record *record;
293         struct bios_parser *bp = BP_FROM_DCB(dcb);
294
295         if (!info)
296                 return BP_RESULT_BADINPUT;
297
298         object = get_bios_object(bp, id);
299
300         if (!object)
301                 return BP_RESULT_BADINPUT;
302
303         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
304
305         for (;;) {
306                 header = GET_IMAGE(struct atom_common_record_header, offset);
307
308                 if (!header)
309                         return BP_RESULT_BADBIOSTABLE;
310
311                 if (header->record_type == LAST_RECORD_TYPE ||
312                         !header->record_size)
313                         break;
314
315                 if (header->record_type == ATOM_I2C_RECORD_TYPE
316                         && sizeof(struct atom_i2c_record) <=
317                                                         header->record_size) {
318                         /* get the I2C info */
319                         record = (struct atom_i2c_record *) header;
320
321                         if (get_gpio_i2c_info(bp, record, info) ==
322                                                                 BP_RESULT_OK)
323                                 return BP_RESULT_OK;
324                 }
325
326                 offset += header->record_size;
327         }
328
329         return BP_RESULT_NORECORD;
330 }
331
332 static enum bp_result get_gpio_i2c_info(
333         struct bios_parser *bp,
334         struct atom_i2c_record *record,
335         struct graphics_object_i2c_info *info)
336 {
337         struct atom_gpio_pin_lut_v2_1 *header;
338         uint32_t count = 0;
339         unsigned int table_index = 0;
340
341         if (!info)
342                 return BP_RESULT_BADINPUT;
343
344         /* get the GPIO_I2C info */
345         if (!DATA_TABLES(gpio_pin_lut))
346                 return BP_RESULT_BADBIOSTABLE;
347
348         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
349                                         DATA_TABLES(gpio_pin_lut));
350         if (!header)
351                 return BP_RESULT_BADBIOSTABLE;
352
353         if (sizeof(struct atom_common_table_header) +
354                         sizeof(struct atom_gpio_pin_assignment) >
355                         le16_to_cpu(header->table_header.structuresize))
356                 return BP_RESULT_BADBIOSTABLE;
357
358         /* TODO: is version change? */
359         if (header->table_header.content_revision != 1)
360                 return BP_RESULT_UNSUPPORTED;
361
362         /* get data count */
363         count = (le16_to_cpu(header->table_header.structuresize)
364                         - sizeof(struct atom_common_table_header))
365                                 / sizeof(struct atom_gpio_pin_assignment);
366
367         table_index = record->i2c_id  & I2C_HW_LANE_MUX;
368
369         if (count < table_index) {
370                 bool find_valid = false;
371
372                 for (table_index = 0; table_index < count; table_index++) {
373                         if (((record->i2c_id & I2C_HW_CAP) == (
374                         header->gpio_pin[table_index].gpio_id &
375                                                         I2C_HW_CAP)) &&
376                         ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==
377                         (header->gpio_pin[table_index].gpio_id &
378                                                 I2C_HW_ENGINE_ID_MASK)) &&
379                         ((record->i2c_id & I2C_HW_LANE_MUX) ==
380                         (header->gpio_pin[table_index].gpio_id &
381                                                         I2C_HW_LANE_MUX))) {
382                                 /* still valid */
383                                 find_valid = true;
384                                 break;
385                         }
386                 }
387                 /* If we don't find the entry that we are looking for then
388                  *  we will return BP_Result_BadBiosTable.
389                  */
390                 if (find_valid == false)
391                         return BP_RESULT_BADBIOSTABLE;
392         }
393
394         /* get the GPIO_I2C_INFO */
395         info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
396         info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
397         info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
398         info->i2c_slave_address = record->i2c_slave_addr;
399
400         /* TODO: check how to get register offset for en, Y, etc. */
401         info->gpio_info.clk_a_register_index =
402                         le16_to_cpu(
403                         header->gpio_pin[table_index].data_a_reg_index);
404         info->gpio_info.clk_a_shift =
405                         header->gpio_pin[table_index].gpio_bitshift;
406
407         return BP_RESULT_OK;
408 }
409
410 static enum bp_result bios_parser_get_hpd_info(
411         struct dc_bios *dcb,
412         struct graphics_object_id id,
413         struct graphics_object_hpd_info *info)
414 {
415         struct bios_parser *bp = BP_FROM_DCB(dcb);
416         struct atom_display_object_path_v2 *object;
417         struct atom_hpd_int_record *record = NULL;
418
419         if (!info)
420                 return BP_RESULT_BADINPUT;
421
422         object = get_bios_object(bp, id);
423
424         if (!object)
425                 return BP_RESULT_BADINPUT;
426
427         record = get_hpd_record(bp, object);
428
429         if (record != NULL) {
430                 info->hpd_int_gpio_uid = record->pin_id;
431                 info->hpd_active = record->plugin_pin_state;
432                 return BP_RESULT_OK;
433         }
434
435         return BP_RESULT_NORECORD;
436 }
437
438 static struct atom_hpd_int_record *get_hpd_record(
439         struct bios_parser *bp,
440         struct atom_display_object_path_v2 *object)
441 {
442         struct atom_common_record_header *header;
443         uint32_t offset;
444
445         if (!object) {
446                 BREAK_TO_DEBUGGER(); /* Invalid object */
447                 return NULL;
448         }
449
450         offset = le16_to_cpu(object->disp_recordoffset)
451                         + bp->object_info_tbl_offset;
452
453         for (;;) {
454                 header = GET_IMAGE(struct atom_common_record_header, offset);
455
456                 if (!header)
457                         return NULL;
458
459                 if (header->record_type == LAST_RECORD_TYPE ||
460                         !header->record_size)
461                         break;
462
463                 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
464                         && sizeof(struct atom_hpd_int_record) <=
465                                                         header->record_size)
466                         return (struct atom_hpd_int_record *) header;
467
468                 offset += header->record_size;
469         }
470
471         return NULL;
472 }
473
474 /**
475  * bios_parser_get_gpio_pin_info
476  * Get GpioPin information of input gpio id
477  *
478  * @param gpio_id, GPIO ID
479  * @param info, GpioPin information structure
480  * @return Bios parser result code
481  * @note
482  *  to get the GPIO PIN INFO, we need:
483  *  1. get the GPIO_ID from other object table, see GetHPDInfo()
484  *  2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
485  *      to get the registerA  offset/mask
486  */
487 static enum bp_result bios_parser_get_gpio_pin_info(
488         struct dc_bios *dcb,
489         uint32_t gpio_id,
490         struct gpio_pin_info *info)
491 {
492         struct bios_parser *bp = BP_FROM_DCB(dcb);
493         struct atom_gpio_pin_lut_v2_1 *header;
494         uint32_t count = 0;
495         uint32_t i = 0;
496
497         if (!DATA_TABLES(gpio_pin_lut))
498                 return BP_RESULT_BADBIOSTABLE;
499
500         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
501                                                 DATA_TABLES(gpio_pin_lut));
502         if (!header)
503                 return BP_RESULT_BADBIOSTABLE;
504
505         if (sizeof(struct atom_common_table_header) +
506                         sizeof(struct atom_gpio_pin_assignment)
507                         > le16_to_cpu(header->table_header.structuresize))
508                 return BP_RESULT_BADBIOSTABLE;
509
510         if (header->table_header.content_revision != 1)
511                 return BP_RESULT_UNSUPPORTED;
512
513         /* Temporary hard code gpio pin info */
514 #if defined(FOR_SIMNOW_BOOT)
515         {
516                 struct  atom_gpio_pin_assignment  gpio_pin[8] = {
517                                 {0x5db5, 0, 0, 1, 0},
518                                 {0x5db5, 8, 8, 2, 0},
519                                 {0x5db5, 0x10, 0x10, 3, 0},
520                                 {0x5db5, 0x18, 0x14, 4, 0},
521                                 {0x5db5, 0x1A, 0x18, 5, 0},
522                                 {0x5db5, 0x1C, 0x1C, 6, 0},
523                 };
524
525                 count = 6;
526                 memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
527         }
528 #else
529         count = (le16_to_cpu(header->table_header.structuresize)
530                         - sizeof(struct atom_common_table_header))
531                                 / sizeof(struct atom_gpio_pin_assignment);
532 #endif
533         for (i = 0; i < count; ++i) {
534                 if (header->gpio_pin[i].gpio_id != gpio_id)
535                         continue;
536
537                 info->offset =
538                         (uint32_t) le16_to_cpu(
539                                         header->gpio_pin[i].data_a_reg_index);
540                 info->offset_y = info->offset + 2;
541                 info->offset_en = info->offset + 1;
542                 info->offset_mask = info->offset - 1;
543
544                 info->mask = (uint32_t) (1 <<
545                         header->gpio_pin[i].gpio_bitshift);
546                 info->mask_y = info->mask + 2;
547                 info->mask_en = info->mask + 1;
548                 info->mask_mask = info->mask - 1;
549
550                 return BP_RESULT_OK;
551         }
552
553         return BP_RESULT_NORECORD;
554 }
555
556 static struct device_id device_type_from_device_id(uint16_t device_id)
557 {
558
559         struct device_id result_device_id;
560
561         result_device_id.raw_device_tag = device_id;
562
563         switch (device_id) {
564         case ATOM_DISPLAY_LCD1_SUPPORT:
565                 result_device_id.device_type = DEVICE_TYPE_LCD;
566                 result_device_id.enum_id = 1;
567                 break;
568
569         case ATOM_DISPLAY_DFP1_SUPPORT:
570                 result_device_id.device_type = DEVICE_TYPE_DFP;
571                 result_device_id.enum_id = 1;
572                 break;
573
574         case ATOM_DISPLAY_DFP2_SUPPORT:
575                 result_device_id.device_type = DEVICE_TYPE_DFP;
576                 result_device_id.enum_id = 2;
577                 break;
578
579         case ATOM_DISPLAY_DFP3_SUPPORT:
580                 result_device_id.device_type = DEVICE_TYPE_DFP;
581                 result_device_id.enum_id = 3;
582                 break;
583
584         case ATOM_DISPLAY_DFP4_SUPPORT:
585                 result_device_id.device_type = DEVICE_TYPE_DFP;
586                 result_device_id.enum_id = 4;
587                 break;
588
589         case ATOM_DISPLAY_DFP5_SUPPORT:
590                 result_device_id.device_type = DEVICE_TYPE_DFP;
591                 result_device_id.enum_id = 5;
592                 break;
593
594         case ATOM_DISPLAY_DFP6_SUPPORT:
595                 result_device_id.device_type = DEVICE_TYPE_DFP;
596                 result_device_id.enum_id = 6;
597                 break;
598
599         default:
600                 BREAK_TO_DEBUGGER(); /* Invalid device Id */
601                 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
602                 result_device_id.enum_id = 0;
603         }
604         return result_device_id;
605 }
606
607 static enum bp_result bios_parser_get_device_tag(
608         struct dc_bios *dcb,
609         struct graphics_object_id connector_object_id,
610         uint32_t device_tag_index,
611         struct connector_device_tag_info *info)
612 {
613         struct bios_parser *bp = BP_FROM_DCB(dcb);
614         struct atom_display_object_path_v2 *object;
615
616         if (!info)
617                 return BP_RESULT_BADINPUT;
618
619         /* getBiosObject will return MXM object */
620         object = get_bios_object(bp, connector_object_id);
621
622         if (!object) {
623                 BREAK_TO_DEBUGGER(); /* Invalid object id */
624                 return BP_RESULT_BADINPUT;
625         }
626
627         info->acpi_device = 0; /* BIOS no longer provides this */
628         info->dev_id = device_type_from_device_id(object->device_tag);
629
630         return BP_RESULT_OK;
631 }
632
633 static enum bp_result get_ss_info_v4_1(
634         struct bios_parser *bp,
635         uint32_t id,
636         uint32_t index,
637         struct spread_spectrum_info *ss_info)
638 {
639         enum bp_result result = BP_RESULT_OK;
640         struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
641         struct atom_smu_info_v3_3 *smu_info = NULL;
642
643         if (!ss_info)
644                 return BP_RESULT_BADINPUT;
645
646         if (!DATA_TABLES(dce_info))
647                 return BP_RESULT_BADBIOSTABLE;
648
649         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_1,
650                                                         DATA_TABLES(dce_info));
651         if (!disp_cntl_tbl)
652                 return BP_RESULT_BADBIOSTABLE;
653
654
655         ss_info->type.STEP_AND_DELAY_INFO = false;
656         ss_info->spread_percentage_divider = 1000;
657         /* BIOS no longer uses target clock.  Always enable for now */
658         ss_info->target_clock_range = 0xffffffff;
659
660         switch (id) {
661         case AS_SIGNAL_TYPE_DVI:
662                 ss_info->spread_spectrum_percentage =
663                                 disp_cntl_tbl->dvi_ss_percentage;
664                 ss_info->spread_spectrum_range =
665                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
666                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
667                         ss_info->type.CENTER_MODE = true;
668                 break;
669         case AS_SIGNAL_TYPE_HDMI:
670                 ss_info->spread_spectrum_percentage =
671                                 disp_cntl_tbl->hdmi_ss_percentage;
672                 ss_info->spread_spectrum_range =
673                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
674                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
675                         ss_info->type.CENTER_MODE = true;
676                 break;
677         /* TODO LVDS not support anymore? */
678         case AS_SIGNAL_TYPE_DISPLAY_PORT:
679                 ss_info->spread_spectrum_percentage =
680                                 disp_cntl_tbl->dp_ss_percentage;
681                 ss_info->spread_spectrum_range =
682                                 disp_cntl_tbl->dp_ss_rate_10hz * 10;
683                 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
684                         ss_info->type.CENTER_MODE = true;
685                 break;
686         case AS_SIGNAL_TYPE_GPU_PLL:
687                 /* atom_firmware: DAL only get data from dce_info table.
688                  * if data within smu_info is needed for DAL, VBIOS should
689                  * copy it into dce_info
690                  */
691                 result = BP_RESULT_UNSUPPORTED;
692                 break;
693         case AS_SIGNAL_TYPE_XGMI:
694                 smu_info =  GET_IMAGE(struct atom_smu_info_v3_3,
695                                       DATA_TABLES(smu_info));
696                 if (!smu_info)
697                         return BP_RESULT_BADBIOSTABLE;
698
699                 ss_info->spread_spectrum_percentage =
700                                 smu_info->waflclk_ss_percentage;
701                 ss_info->spread_spectrum_range =
702                                 smu_info->gpuclk_ss_rate_10hz * 10;
703                 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
704                         ss_info->type.CENTER_MODE = true;
705                 break;
706         default:
707                 result = BP_RESULT_UNSUPPORTED;
708         }
709
710         return result;
711 }
712
713 static enum bp_result get_ss_info_v4_2(
714         struct bios_parser *bp,
715         uint32_t id,
716         uint32_t index,
717         struct spread_spectrum_info *ss_info)
718 {
719         enum bp_result result = BP_RESULT_OK;
720         struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
721         struct atom_smu_info_v3_1 *smu_info = NULL;
722
723         if (!ss_info)
724                 return BP_RESULT_BADINPUT;
725
726         if (!DATA_TABLES(dce_info))
727                 return BP_RESULT_BADBIOSTABLE;
728
729         if (!DATA_TABLES(smu_info))
730                 return BP_RESULT_BADBIOSTABLE;
731
732         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_2,
733                                                         DATA_TABLES(dce_info));
734         if (!disp_cntl_tbl)
735                 return BP_RESULT_BADBIOSTABLE;
736
737         smu_info =  GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
738         if (!smu_info)
739                 return BP_RESULT_BADBIOSTABLE;
740
741         ss_info->type.STEP_AND_DELAY_INFO = false;
742         ss_info->spread_percentage_divider = 1000;
743         /* BIOS no longer uses target clock.  Always enable for now */
744         ss_info->target_clock_range = 0xffffffff;
745
746         switch (id) {
747         case AS_SIGNAL_TYPE_DVI:
748                 ss_info->spread_spectrum_percentage =
749                                 disp_cntl_tbl->dvi_ss_percentage;
750                 ss_info->spread_spectrum_range =
751                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
752                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
753                         ss_info->type.CENTER_MODE = true;
754                 break;
755         case AS_SIGNAL_TYPE_HDMI:
756                 ss_info->spread_spectrum_percentage =
757                                 disp_cntl_tbl->hdmi_ss_percentage;
758                 ss_info->spread_spectrum_range =
759                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
760                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
761                         ss_info->type.CENTER_MODE = true;
762                 break;
763         /* TODO LVDS not support anymore? */
764         case AS_SIGNAL_TYPE_DISPLAY_PORT:
765                 ss_info->spread_spectrum_percentage =
766                                 smu_info->gpuclk_ss_percentage;
767                 ss_info->spread_spectrum_range =
768                                 smu_info->gpuclk_ss_rate_10hz * 10;
769                 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
770                         ss_info->type.CENTER_MODE = true;
771                 break;
772         case AS_SIGNAL_TYPE_GPU_PLL:
773                 /* atom_firmware: DAL only get data from dce_info table.
774                  * if data within smu_info is needed for DAL, VBIOS should
775                  * copy it into dce_info
776                  */
777                 result = BP_RESULT_UNSUPPORTED;
778                 break;
779         default:
780                 result = BP_RESULT_UNSUPPORTED;
781         }
782
783         return result;
784 }
785
786 /**
787  * bios_parser_get_spread_spectrum_info
788  * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
789  * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
790  * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
791  * ver 3.1,
792  * there is only one entry for each signal /ss id.  However, there is
793  * no planning of supporting multiple spread Sprectum entry for EverGreen
794  * @param [in] this
795  * @param [in] signal, ASSignalType to be converted to info index
796  * @param [in] index, number of entries that match the converted info index
797  * @param [out] ss_info, sprectrum information structure,
798  * @return Bios parser result code
799  */
800 static enum bp_result bios_parser_get_spread_spectrum_info(
801         struct dc_bios *dcb,
802         enum as_signal_type signal,
803         uint32_t index,
804         struct spread_spectrum_info *ss_info)
805 {
806         struct bios_parser *bp = BP_FROM_DCB(dcb);
807         enum bp_result result = BP_RESULT_UNSUPPORTED;
808         struct atom_common_table_header *header;
809         struct atom_data_revision tbl_revision;
810
811         if (!ss_info) /* check for bad input */
812                 return BP_RESULT_BADINPUT;
813
814         if (!DATA_TABLES(dce_info))
815                 return BP_RESULT_UNSUPPORTED;
816
817         header = GET_IMAGE(struct atom_common_table_header,
818                                                 DATA_TABLES(dce_info));
819         get_atom_data_table_revision(header, &tbl_revision);
820
821         switch (tbl_revision.major) {
822         case 4:
823                 switch (tbl_revision.minor) {
824                 case 1:
825                         return get_ss_info_v4_1(bp, signal, index, ss_info);
826                 case 2:
827                         return get_ss_info_v4_2(bp, signal, index, ss_info);
828                 default:
829                         break;
830                 }
831                 break;
832         default:
833                 break;
834         }
835         /* there can not be more then one entry for SS Info table */
836         return result;
837 }
838
839 static enum bp_result get_embedded_panel_info_v2_1(
840                 struct bios_parser *bp,
841                 struct embedded_panel_info *info)
842 {
843         struct lcd_info_v2_1 *lvds;
844
845         if (!info)
846                 return BP_RESULT_BADINPUT;
847
848         if (!DATA_TABLES(lcd_info))
849                 return BP_RESULT_UNSUPPORTED;
850
851         lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
852
853         if (!lvds)
854                 return BP_RESULT_BADBIOSTABLE;
855
856         /* TODO: previous vv1_3, should v2_1 */
857         if (!((lvds->table_header.format_revision == 2)
858                         && (lvds->table_header.content_revision >= 1)))
859                 return BP_RESULT_UNSUPPORTED;
860
861         memset(info, 0, sizeof(struct embedded_panel_info));
862
863         /* We need to convert from 10KHz units into KHz units */
864         info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
865         /* usHActive does not include borders, according to VBIOS team */
866         info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
867         /* usHBlanking_Time includes borders, so we should really be
868          * subtractingborders duing this translation, but LVDS generally
869          * doesn't have borders, so we should be okay leaving this as is for
870          * now.  May need to revisit if we ever have LVDS with borders
871          */
872         info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
873         /* usVActive does not include borders, according to VBIOS team*/
874         info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
875         /* usVBlanking_Time includes borders, so we should really be
876          * subtracting borders duing this translation, but LVDS generally
877          * doesn't have borders, so we should be okay leaving this as is for
878          * now. May need to revisit if we ever have LVDS with borders
879          */
880         info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time);
881         info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset);
882         info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width);
883         info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset);
884         info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth);
885         info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
886         info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
887
888         /* not provided by VBIOS */
889         info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
890
891         info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
892                         & ATOM_HSYNC_POLARITY);
893         info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
894                         & ATOM_VSYNC_POLARITY);
895
896         /* not provided by VBIOS */
897         info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
898
899         info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
900                         & ATOM_H_REPLICATIONBY2);
901         info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
902                         & ATOM_V_REPLICATIONBY2);
903         info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo
904                         & ATOM_COMPOSITESYNC);
905         info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
906
907         /* not provided by VBIOS*/
908         info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
909         /* not provided by VBIOS*/
910         info->ss_id = 0;
911
912         info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
913
914         return BP_RESULT_OK;
915 }
916
917 static enum bp_result bios_parser_get_embedded_panel_info(
918                 struct dc_bios *dcb,
919                 struct embedded_panel_info *info)
920 {
921         struct bios_parser
922         *bp = BP_FROM_DCB(dcb);
923         struct atom_common_table_header *header;
924         struct atom_data_revision tbl_revision;
925
926         if (!DATA_TABLES(lcd_info))
927                 return BP_RESULT_FAILURE;
928
929         header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
930
931         if (!header)
932                 return BP_RESULT_BADBIOSTABLE;
933
934         get_atom_data_table_revision(header, &tbl_revision);
935
936         switch (tbl_revision.major) {
937         case 2:
938                 switch (tbl_revision.minor) {
939                 case 1:
940                         return get_embedded_panel_info_v2_1(bp, info);
941                 default:
942                         break;
943                 }
944         default:
945                 break;
946         }
947
948         return BP_RESULT_FAILURE;
949 }
950
951 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
952 {
953         enum dal_device_type device_type = device_id.device_type;
954         uint32_t enum_id = device_id.enum_id;
955
956         switch (device_type) {
957         case DEVICE_TYPE_LCD:
958                 switch (enum_id) {
959                 case 1:
960                         return ATOM_DISPLAY_LCD1_SUPPORT;
961                 default:
962                         break;
963                 }
964                 break;
965         case DEVICE_TYPE_DFP:
966                 switch (enum_id) {
967                 case 1:
968                         return ATOM_DISPLAY_DFP1_SUPPORT;
969                 case 2:
970                         return ATOM_DISPLAY_DFP2_SUPPORT;
971                 case 3:
972                         return ATOM_DISPLAY_DFP3_SUPPORT;
973                 case 4:
974                         return ATOM_DISPLAY_DFP4_SUPPORT;
975                 case 5:
976                         return ATOM_DISPLAY_DFP5_SUPPORT;
977                 case 6:
978                         return ATOM_DISPLAY_DFP6_SUPPORT;
979                 default:
980                         break;
981                 }
982                 break;
983         default:
984                 break;
985         };
986
987         /* Unidentified device ID, return empty support mask. */
988         return 0;
989 }
990
991 static bool bios_parser_is_device_id_supported(
992         struct dc_bios *dcb,
993         struct device_id id)
994 {
995         struct bios_parser *bp = BP_FROM_DCB(dcb);
996
997         uint32_t mask = get_support_mask_for_device_id(id);
998
999         return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
1000                                                                 mask) != 0;
1001 }
1002
1003 static uint32_t bios_parser_get_ss_entry_number(
1004         struct dc_bios *dcb,
1005         enum as_signal_type signal)
1006 {
1007         /* TODO: DAL2 atomfirmware implementation does not need this.
1008          * why DAL3 need this?
1009          */
1010         return 1;
1011 }
1012
1013 static enum bp_result bios_parser_transmitter_control(
1014         struct dc_bios *dcb,
1015         struct bp_transmitter_control *cntl)
1016 {
1017         struct bios_parser *bp = BP_FROM_DCB(dcb);
1018
1019         if (!bp->cmd_tbl.transmitter_control)
1020                 return BP_RESULT_FAILURE;
1021
1022         return bp->cmd_tbl.transmitter_control(bp, cntl);
1023 }
1024
1025 static enum bp_result bios_parser_encoder_control(
1026         struct dc_bios *dcb,
1027         struct bp_encoder_control *cntl)
1028 {
1029         struct bios_parser *bp = BP_FROM_DCB(dcb);
1030
1031         if (!bp->cmd_tbl.dig_encoder_control)
1032                 return BP_RESULT_FAILURE;
1033
1034         return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1035 }
1036
1037 static enum bp_result bios_parser_set_pixel_clock(
1038         struct dc_bios *dcb,
1039         struct bp_pixel_clock_parameters *bp_params)
1040 {
1041         struct bios_parser *bp = BP_FROM_DCB(dcb);
1042
1043         if (!bp->cmd_tbl.set_pixel_clock)
1044                 return BP_RESULT_FAILURE;
1045
1046         return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1047 }
1048
1049 static enum bp_result bios_parser_set_dce_clock(
1050         struct dc_bios *dcb,
1051         struct bp_set_dce_clock_parameters *bp_params)
1052 {
1053         struct bios_parser *bp = BP_FROM_DCB(dcb);
1054
1055         if (!bp->cmd_tbl.set_dce_clock)
1056                 return BP_RESULT_FAILURE;
1057
1058         return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1059 }
1060
1061 static enum bp_result bios_parser_program_crtc_timing(
1062         struct dc_bios *dcb,
1063         struct bp_hw_crtc_timing_parameters *bp_params)
1064 {
1065         struct bios_parser *bp = BP_FROM_DCB(dcb);
1066
1067         if (!bp->cmd_tbl.set_crtc_timing)
1068                 return BP_RESULT_FAILURE;
1069
1070         return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1071 }
1072
1073 static enum bp_result bios_parser_enable_crtc(
1074         struct dc_bios *dcb,
1075         enum controller_id id,
1076         bool enable)
1077 {
1078         struct bios_parser *bp = BP_FROM_DCB(dcb);
1079
1080         if (!bp->cmd_tbl.enable_crtc)
1081                 return BP_RESULT_FAILURE;
1082
1083         return bp->cmd_tbl.enable_crtc(bp, id, enable);
1084 }
1085
1086 static enum bp_result bios_parser_enable_disp_power_gating(
1087         struct dc_bios *dcb,
1088         enum controller_id controller_id,
1089         enum bp_pipe_control_action action)
1090 {
1091         struct bios_parser *bp = BP_FROM_DCB(dcb);
1092
1093         if (!bp->cmd_tbl.enable_disp_power_gating)
1094                 return BP_RESULT_FAILURE;
1095
1096         return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1097                 action);
1098 }
1099
1100 static bool bios_parser_is_accelerated_mode(
1101         struct dc_bios *dcb)
1102 {
1103         return bios_is_accelerated_mode(dcb);
1104 }
1105
1106 /**
1107  * bios_parser_set_scratch_critical_state
1108  *
1109  * @brief
1110  *  update critical state bit in VBIOS scratch register
1111  *
1112  * @param
1113  *  bool - to set or reset state
1114  */
1115 static void bios_parser_set_scratch_critical_state(
1116         struct dc_bios *dcb,
1117         bool state)
1118 {
1119         bios_set_scratch_critical_state(dcb, state);
1120 }
1121
1122 static enum bp_result bios_parser_get_firmware_info(
1123         struct dc_bios *dcb,
1124         struct dc_firmware_info *info)
1125 {
1126         struct bios_parser *bp = BP_FROM_DCB(dcb);
1127         enum bp_result result = BP_RESULT_BADBIOSTABLE;
1128         struct atom_common_table_header *header;
1129
1130         struct atom_data_revision revision;
1131
1132         if (info && DATA_TABLES(firmwareinfo)) {
1133                 header = GET_IMAGE(struct atom_common_table_header,
1134                                 DATA_TABLES(firmwareinfo));
1135                 get_atom_data_table_revision(header, &revision);
1136                 switch (revision.major) {
1137                 case 3:
1138                         switch (revision.minor) {
1139                         case 1:
1140                                 result = get_firmware_info_v3_1(bp, info);
1141                                 break;
1142                         case 2:
1143                                 result = get_firmware_info_v3_2(bp, info);
1144                                 break;
1145                         case 3:
1146                                 result = get_firmware_info_v3_2(bp, info);
1147                                 break;
1148                         default:
1149                                 break;
1150                         }
1151                         break;
1152                 default:
1153                         break;
1154                 }
1155         }
1156
1157         return result;
1158 }
1159
1160 static enum bp_result get_firmware_info_v3_1(
1161         struct bios_parser *bp,
1162         struct dc_firmware_info *info)
1163 {
1164         struct atom_firmware_info_v3_1 *firmware_info;
1165         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1166
1167         if (!info)
1168                 return BP_RESULT_BADINPUT;
1169
1170         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1171                         DATA_TABLES(firmwareinfo));
1172
1173         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1174                         DATA_TABLES(dce_info));
1175
1176         if (!firmware_info || !dce_info)
1177                 return BP_RESULT_BADBIOSTABLE;
1178
1179         memset(info, 0, sizeof(*info));
1180
1181         /* Pixel clock pll information. */
1182          /* We need to convert from 10KHz units into KHz units */
1183         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1184         info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1185
1186          /* 27MHz for Vega10: */
1187         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1188
1189         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1190         if (info->pll_info.crystal_frequency == 0)
1191                 info->pll_info.crystal_frequency = 27000;
1192         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1193         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1194         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1195
1196         /* Get GPU PLL VCO Clock */
1197
1198         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1199                 /* VBIOS gives in 10KHz */
1200                 info->smu_gpu_pll_output_freq =
1201                                 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1202         }
1203
1204         return BP_RESULT_OK;
1205 }
1206
1207 static enum bp_result get_firmware_info_v3_2(
1208         struct bios_parser *bp,
1209         struct dc_firmware_info *info)
1210 {
1211         struct atom_firmware_info_v3_2 *firmware_info;
1212         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1213         struct atom_common_table_header *header;
1214         struct atom_data_revision revision;
1215         struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1216         struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1217
1218         if (!info)
1219                 return BP_RESULT_BADINPUT;
1220
1221         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1222                         DATA_TABLES(firmwareinfo));
1223
1224         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1225                         DATA_TABLES(dce_info));
1226
1227         if (!firmware_info || !dce_info)
1228                 return BP_RESULT_BADBIOSTABLE;
1229
1230         memset(info, 0, sizeof(*info));
1231
1232         header = GET_IMAGE(struct atom_common_table_header,
1233                                         DATA_TABLES(smu_info));
1234         get_atom_data_table_revision(header, &revision);
1235
1236         if (revision.minor == 2) {
1237                 /* Vega12 */
1238                 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1239                                                         DATA_TABLES(smu_info));
1240
1241                 if (!smu_info_v3_2)
1242                         return BP_RESULT_BADBIOSTABLE;
1243
1244                 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1245         } else if (revision.minor == 3) {
1246                 /* Vega20 */
1247                 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1248                                                         DATA_TABLES(smu_info));
1249
1250                 if (!smu_info_v3_3)
1251                         return BP_RESULT_BADBIOSTABLE;
1252
1253                 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1254         }
1255
1256          // We need to convert from 10KHz units into KHz units.
1257         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1258
1259          /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1260         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1261         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1262         if (info->pll_info.crystal_frequency == 0) {
1263                 if (revision.minor == 2)
1264                         info->pll_info.crystal_frequency = 27000;
1265                 else if (revision.minor == 3)
1266                         info->pll_info.crystal_frequency = 100000;
1267         }
1268         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1269         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1270         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1271
1272         /* Get GPU PLL VCO Clock */
1273         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1274                 if (revision.minor == 2)
1275                         info->smu_gpu_pll_output_freq =
1276                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1277                 else if (revision.minor == 3)
1278                         info->smu_gpu_pll_output_freq =
1279                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1280         }
1281
1282         return BP_RESULT_OK;
1283 }
1284
1285 static enum bp_result bios_parser_get_encoder_cap_info(
1286         struct dc_bios *dcb,
1287         struct graphics_object_id object_id,
1288         struct bp_encoder_cap_info *info)
1289 {
1290         struct bios_parser *bp = BP_FROM_DCB(dcb);
1291         struct atom_display_object_path_v2 *object;
1292         struct atom_encoder_caps_record *record = NULL;
1293
1294         if (!info)
1295                 return BP_RESULT_BADINPUT;
1296
1297         object = get_bios_object(bp, object_id);
1298
1299         if (!object)
1300                 return BP_RESULT_BADINPUT;
1301
1302         record = get_encoder_cap_record(bp, object);
1303         if (!record)
1304                 return BP_RESULT_NORECORD;
1305
1306         info->DP_HBR2_CAP = (record->encodercaps &
1307                         ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
1308         info->DP_HBR2_EN = (record->encodercaps &
1309                         ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
1310         info->DP_HBR3_EN = (record->encodercaps &
1311                         ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
1312         info->HDMI_6GB_EN = (record->encodercaps &
1313                         ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
1314
1315         return BP_RESULT_OK;
1316 }
1317
1318
1319 static struct atom_encoder_caps_record *get_encoder_cap_record(
1320         struct bios_parser *bp,
1321         struct atom_display_object_path_v2 *object)
1322 {
1323         struct atom_common_record_header *header;
1324         uint32_t offset;
1325
1326         if (!object) {
1327                 BREAK_TO_DEBUGGER(); /* Invalid object */
1328                 return NULL;
1329         }
1330
1331         offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
1332
1333         for (;;) {
1334                 header = GET_IMAGE(struct atom_common_record_header, offset);
1335
1336                 if (!header)
1337                         return NULL;
1338
1339                 offset += header->record_size;
1340
1341                 if (header->record_type == LAST_RECORD_TYPE ||
1342                                 !header->record_size)
1343                         break;
1344
1345                 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
1346                         continue;
1347
1348                 if (sizeof(struct atom_encoder_caps_record) <=
1349                                                         header->record_size)
1350                         return (struct atom_encoder_caps_record *)header;
1351         }
1352
1353         return NULL;
1354 }
1355
1356 /*
1357  * get_integrated_info_v11
1358  *
1359  * @brief
1360  * Get V8 integrated BIOS information
1361  *
1362  * @param
1363  * bios_parser *bp - [in]BIOS parser handler to get master data table
1364  * integrated_info *info - [out] store and output integrated info
1365  *
1366  * @return
1367  * enum bp_result - BP_RESULT_OK if information is available,
1368  *                  BP_RESULT_BADBIOSTABLE otherwise.
1369  */
1370 static enum bp_result get_integrated_info_v11(
1371         struct bios_parser *bp,
1372         struct integrated_info *info)
1373 {
1374         struct atom_integrated_system_info_v1_11 *info_v11;
1375         uint32_t i;
1376
1377         info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
1378                                         DATA_TABLES(integratedsysteminfo));
1379
1380         if (info_v11 == NULL)
1381                 return BP_RESULT_BADBIOSTABLE;
1382
1383         info->gpu_cap_info =
1384         le32_to_cpu(info_v11->gpucapinfo);
1385         /*
1386         * system_config: Bit[0] = 0 : PCIE power gating disabled
1387         *                       = 1 : PCIE power gating enabled
1388         *                Bit[1] = 0 : DDR-PLL shut down disabled
1389         *                       = 1 : DDR-PLL shut down enabled
1390         *                Bit[2] = 0 : DDR-PLL power down disabled
1391         *                       = 1 : DDR-PLL power down enabled
1392         */
1393         info->system_config = le32_to_cpu(info_v11->system_config);
1394         info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
1395         info->memory_type = info_v11->memorytype;
1396         info->ma_channel_number = info_v11->umachannelnumber;
1397         info->lvds_ss_percentage =
1398         le16_to_cpu(info_v11->lvds_ss_percentage);
1399         info->lvds_sspread_rate_in_10hz =
1400         le16_to_cpu(info_v11->lvds_ss_rate_10hz);
1401         info->hdmi_ss_percentage =
1402         le16_to_cpu(info_v11->hdmi_ss_percentage);
1403         info->hdmi_sspread_rate_in_10hz =
1404         le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
1405         info->dvi_ss_percentage =
1406         le16_to_cpu(info_v11->dvi_ss_percentage);
1407         info->dvi_sspread_rate_in_10_hz =
1408         le16_to_cpu(info_v11->dvi_ss_rate_10hz);
1409         info->lvds_misc = info_v11->lvds_misc;
1410         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
1411                 info->ext_disp_conn_info.gu_id[i] =
1412                                 info_v11->extdispconninfo.guid[i];
1413         }
1414
1415         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
1416                 info->ext_disp_conn_info.path[i].device_connector_id =
1417                 object_id_from_bios_object_id(
1418                 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
1419
1420                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
1421                 object_id_from_bios_object_id(
1422                         le16_to_cpu(
1423                         info_v11->extdispconninfo.path[i].ext_encoder_objid));
1424
1425                 info->ext_disp_conn_info.path[i].device_tag =
1426                         le16_to_cpu(
1427                                 info_v11->extdispconninfo.path[i].device_tag);
1428                 info->ext_disp_conn_info.path[i].device_acpi_enum =
1429                 le16_to_cpu(
1430                         info_v11->extdispconninfo.path[i].device_acpi_enum);
1431                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
1432                         info_v11->extdispconninfo.path[i].auxddclut_index;
1433                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
1434                         info_v11->extdispconninfo.path[i].hpdlut_index;
1435                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
1436                         info_v11->extdispconninfo.path[i].channelmapping;
1437                 info->ext_disp_conn_info.path[i].caps =
1438                                 le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
1439         }
1440         info->ext_disp_conn_info.checksum =
1441         info_v11->extdispconninfo.checksum;
1442
1443         info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
1444         info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
1445         for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
1446                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
1447                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1448                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
1449                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1450         }
1451         info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
1452         for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
1453                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1454                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1455                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1456                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1457         }
1458
1459         info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
1460         info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
1461         for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
1462                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
1463                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1464                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
1465                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1466         }
1467         info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
1468         for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
1469                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1470                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1471                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1472                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1473         }
1474
1475         info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
1476         info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
1477         for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
1478                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
1479                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1480                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
1481                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1482         }
1483         info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
1484         for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
1485                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1486                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1487                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1488                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1489         }
1490
1491         info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
1492         info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
1493         for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
1494                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
1495                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1496                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
1497                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1498         }
1499         info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
1500         for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
1501                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1502                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1503                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1504                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1505         }
1506
1507
1508         /** TODO - review **/
1509         #if 0
1510         info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
1511                                                                         * 10;
1512         info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
1513         info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
1514
1515         for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1516                 /* Convert [10KHz] into [KHz] */
1517                 info->disp_clk_voltage[i].max_supported_clk =
1518                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
1519                         ulMaximumSupportedCLK) * 10;
1520                 info->disp_clk_voltage[i].voltage_index =
1521                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
1522         }
1523
1524         info->boot_up_req_display_vector =
1525                         le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
1526         info->boot_up_nb_voltage =
1527                         le16_to_cpu(info_v11->usBootUpNBVoltage);
1528         info->ext_disp_conn_info_offset =
1529                         le16_to_cpu(info_v11->usExtDispConnInfoOffset);
1530         info->gmc_restore_reset_time =
1531                         le32_to_cpu(info_v11->ulGMCRestoreResetTime);
1532         info->minimum_n_clk =
1533                         le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
1534         for (i = 1; i < 4; ++i)
1535                 info->minimum_n_clk =
1536                                 info->minimum_n_clk <
1537                                 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
1538                                 info->minimum_n_clk : le32_to_cpu(
1539                                         info_v11->ulNbpStateNClkFreq[i]);
1540
1541         info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
1542         info->ddr_dll_power_up_time =
1543             le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
1544         info->ddr_pll_power_up_time =
1545                 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
1546         info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
1547         info->max_lvds_pclk_freq_in_single_link =
1548                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1549         info->max_lvds_pclk_freq_in_single_link =
1550                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1551         info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
1552                 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
1553         info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
1554                 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
1555         info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
1556                 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
1557         info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
1558                 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
1559         info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
1560                 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
1561         info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
1562                 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
1563         info->lvds_off_to_on_delay_in_4ms =
1564                 info_v11->ucLVDSOffToOnDelay_in4Ms;
1565         info->lvds_bit_depth_control_val =
1566                 le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
1567
1568         for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
1569                 /* Convert [10KHz] into [KHz] */
1570                 info->avail_s_clk[i].supported_s_clk =
1571                         le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
1572                                                                         * 10;
1573                 info->avail_s_clk[i].voltage_index =
1574                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
1575                 info->avail_s_clk[i].voltage_id =
1576                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
1577         }
1578         #endif /* TODO*/
1579
1580         return BP_RESULT_OK;
1581 }
1582
1583
1584 /*
1585  * construct_integrated_info
1586  *
1587  * @brief
1588  * Get integrated BIOS information based on table revision
1589  *
1590  * @param
1591  * bios_parser *bp - [in]BIOS parser handler to get master data table
1592  * integrated_info *info - [out] store and output integrated info
1593  *
1594  * @return
1595  * enum bp_result - BP_RESULT_OK if information is available,
1596  *                  BP_RESULT_BADBIOSTABLE otherwise.
1597  */
1598 static enum bp_result construct_integrated_info(
1599         struct bios_parser *bp,
1600         struct integrated_info *info)
1601 {
1602         enum bp_result result = BP_RESULT_BADBIOSTABLE;
1603
1604         struct atom_common_table_header *header;
1605         struct atom_data_revision revision;
1606
1607         struct clock_voltage_caps temp = {0, 0};
1608         uint32_t i;
1609         uint32_t j;
1610
1611         if (info && DATA_TABLES(integratedsysteminfo)) {
1612                 header = GET_IMAGE(struct atom_common_table_header,
1613                                         DATA_TABLES(integratedsysteminfo));
1614
1615                 get_atom_data_table_revision(header, &revision);
1616
1617                 /* Don't need to check major revision as they are all 1 */
1618                 switch (revision.minor) {
1619                 case 11:
1620                         result = get_integrated_info_v11(bp, info);
1621                         break;
1622                 default:
1623                         return result;
1624                 }
1625         }
1626
1627         if (result != BP_RESULT_OK)
1628                 return result;
1629
1630         /* Sort voltage table from low to high*/
1631         for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1632                 for (j = i; j > 0; --j) {
1633                         if (info->disp_clk_voltage[j].max_supported_clk <
1634                                 info->disp_clk_voltage[j-1].max_supported_clk
1635                                 ) {
1636                                 /* swap j and j - 1*/
1637                                 temp = info->disp_clk_voltage[j-1];
1638                                 info->disp_clk_voltage[j-1] =
1639                                         info->disp_clk_voltage[j];
1640                                 info->disp_clk_voltage[j] = temp;
1641                         }
1642                 }
1643         }
1644
1645         return result;
1646 }
1647
1648 static struct integrated_info *bios_parser_create_integrated_info(
1649         struct dc_bios *dcb)
1650 {
1651         struct bios_parser *bp = BP_FROM_DCB(dcb);
1652         struct integrated_info *info = NULL;
1653
1654         info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
1655
1656         if (info == NULL) {
1657                 ASSERT_CRITICAL(0);
1658                 return NULL;
1659         }
1660
1661         if (construct_integrated_info(bp, info) == BP_RESULT_OK)
1662                 return info;
1663
1664         kfree(info);
1665
1666         return NULL;
1667 }
1668
1669 static enum bp_result update_slot_layout_info(
1670         struct dc_bios *dcb,
1671         unsigned int i,
1672         struct slot_layout_info *slot_layout_info)
1673 {
1674         unsigned int record_offset;
1675         unsigned int j;
1676         struct atom_display_object_path_v2 *object;
1677         struct atom_bracket_layout_record *record;
1678         struct atom_common_record_header *record_header;
1679         enum bp_result result;
1680         struct bios_parser *bp;
1681         struct object_info_table *tbl;
1682         struct display_object_info_table_v1_4 *v1_4;
1683
1684         record = NULL;
1685         record_header = NULL;
1686         result = BP_RESULT_NORECORD;
1687
1688         bp = BP_FROM_DCB(dcb);
1689         tbl = &bp->object_info_tbl;
1690         v1_4 = tbl->v1_4;
1691
1692         object = &v1_4->display_path[i];
1693         record_offset = (unsigned int)
1694                 (object->disp_recordoffset) +
1695                 (unsigned int)(bp->object_info_tbl_offset);
1696
1697         for (;;) {
1698
1699                 record_header = (struct atom_common_record_header *)
1700                         GET_IMAGE(struct atom_common_record_header,
1701                         record_offset);
1702                 if (record_header == NULL) {
1703                         result = BP_RESULT_BADBIOSTABLE;
1704                         break;
1705                 }
1706
1707                 /* the end of the list */
1708                 if (record_header->record_type == 0xff ||
1709                         record_header->record_size == 0)        {
1710                         break;
1711                 }
1712
1713                 if (record_header->record_type ==
1714                         ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
1715                         sizeof(struct atom_bracket_layout_record)
1716                         <= record_header->record_size) {
1717                         record = (struct atom_bracket_layout_record *)
1718                                 (record_header);
1719                         result = BP_RESULT_OK;
1720                         break;
1721                 }
1722
1723                 record_offset += record_header->record_size;
1724         }
1725
1726         /* return if the record not found */
1727         if (result != BP_RESULT_OK)
1728                 return result;
1729
1730         /* get slot sizes */
1731         slot_layout_info->length = record->bracketlen;
1732         slot_layout_info->width = record->bracketwidth;
1733
1734         /* get info for each connector in the slot */
1735         slot_layout_info->num_of_connectors = record->conn_num;
1736         for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
1737                 slot_layout_info->connectors[j].connector_type =
1738                         (enum connector_layout_type)
1739                         (record->conn_info[j].connector_type);
1740                 switch (record->conn_info[j].connector_type) {
1741                 case CONNECTOR_TYPE_DVI_D:
1742                         slot_layout_info->connectors[j].connector_type =
1743                                 CONNECTOR_LAYOUT_TYPE_DVI_D;
1744                         slot_layout_info->connectors[j].length =
1745                                 CONNECTOR_SIZE_DVI;
1746                         break;
1747
1748                 case CONNECTOR_TYPE_HDMI:
1749                         slot_layout_info->connectors[j].connector_type =
1750                                 CONNECTOR_LAYOUT_TYPE_HDMI;
1751                         slot_layout_info->connectors[j].length =
1752                                 CONNECTOR_SIZE_HDMI;
1753                         break;
1754
1755                 case CONNECTOR_TYPE_DISPLAY_PORT:
1756                         slot_layout_info->connectors[j].connector_type =
1757                                 CONNECTOR_LAYOUT_TYPE_DP;
1758                         slot_layout_info->connectors[j].length =
1759                                 CONNECTOR_SIZE_DP;
1760                         break;
1761
1762                 case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
1763                         slot_layout_info->connectors[j].connector_type =
1764                                 CONNECTOR_LAYOUT_TYPE_MINI_DP;
1765                         slot_layout_info->connectors[j].length =
1766                                 CONNECTOR_SIZE_MINI_DP;
1767                         break;
1768
1769                 default:
1770                         slot_layout_info->connectors[j].connector_type =
1771                                 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
1772                         slot_layout_info->connectors[j].length =
1773                                 CONNECTOR_SIZE_UNKNOWN;
1774                 }
1775
1776                 slot_layout_info->connectors[j].position =
1777                         record->conn_info[j].position;
1778                 slot_layout_info->connectors[j].connector_id =
1779                         object_id_from_bios_object_id(
1780                                 record->conn_info[j].connectorobjid);
1781         }
1782         return result;
1783 }
1784
1785
1786 static enum bp_result get_bracket_layout_record(
1787         struct dc_bios *dcb,
1788         unsigned int bracket_layout_id,
1789         struct slot_layout_info *slot_layout_info)
1790 {
1791         unsigned int i;
1792         struct bios_parser *bp = BP_FROM_DCB(dcb);
1793         enum bp_result result;
1794         struct object_info_table *tbl;
1795         struct display_object_info_table_v1_4 *v1_4;
1796
1797         if (slot_layout_info == NULL) {
1798                 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
1799                 return BP_RESULT_BADINPUT;
1800         }
1801         tbl = &bp->object_info_tbl;
1802         v1_4 = tbl->v1_4;
1803
1804         result = BP_RESULT_NORECORD;
1805         for (i = 0; i < v1_4->number_of_path; ++i)      {
1806
1807                 if (bracket_layout_id ==
1808                         v1_4->display_path[i].display_objid) {
1809                         result = update_slot_layout_info(dcb, i,
1810                                 slot_layout_info);
1811                         break;
1812                 }
1813         }
1814         return result;
1815 }
1816
1817 static enum bp_result bios_get_board_layout_info(
1818         struct dc_bios *dcb,
1819         struct board_layout_info *board_layout_info)
1820 {
1821         unsigned int i;
1822         struct bios_parser *bp;
1823         enum bp_result record_result;
1824
1825         const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
1826                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
1827                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
1828                 0, 0
1829         };
1830
1831         bp = BP_FROM_DCB(dcb);
1832         if (board_layout_info == NULL) {
1833                 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
1834                 return BP_RESULT_BADINPUT;
1835         }
1836
1837         board_layout_info->num_of_slots = 0;
1838
1839         for (i = 0; i < MAX_BOARD_SLOTS; ++i) {
1840                 record_result = get_bracket_layout_record(dcb,
1841                         slot_index_to_vbios_id[i],
1842                         &board_layout_info->slots[i]);
1843
1844                 if (record_result == BP_RESULT_NORECORD && i > 0)
1845                         break; /* no more slots present in bios */
1846                 else if (record_result != BP_RESULT_OK)
1847                         return record_result;  /* fail */
1848
1849                 ++board_layout_info->num_of_slots;
1850         }
1851
1852         /* all data is valid */
1853         board_layout_info->is_number_of_slots_valid = 1;
1854         board_layout_info->is_slots_size_valid = 1;
1855         board_layout_info->is_connector_offsets_valid = 1;
1856         board_layout_info->is_connector_lengths_valid = 1;
1857
1858         return BP_RESULT_OK;
1859 }
1860
1861 static const struct dc_vbios_funcs vbios_funcs = {
1862         .get_connectors_number = bios_parser_get_connectors_number,
1863
1864         .get_connector_id = bios_parser_get_connector_id,
1865
1866         .get_src_obj = bios_parser_get_src_obj,
1867
1868         .get_i2c_info = bios_parser_get_i2c_info,
1869
1870         .get_hpd_info = bios_parser_get_hpd_info,
1871
1872         .get_device_tag = bios_parser_get_device_tag,
1873
1874         .get_firmware_info = bios_parser_get_firmware_info,
1875
1876         .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
1877
1878         .get_ss_entry_number = bios_parser_get_ss_entry_number,
1879
1880         .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
1881
1882         .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
1883
1884         .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
1885
1886         .is_device_id_supported = bios_parser_is_device_id_supported,
1887
1888         .is_accelerated_mode = bios_parser_is_accelerated_mode,
1889
1890         .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
1891
1892
1893 /*       COMMANDS */
1894         .encoder_control = bios_parser_encoder_control,
1895
1896         .transmitter_control = bios_parser_transmitter_control,
1897
1898         .enable_crtc = bios_parser_enable_crtc,
1899
1900         .set_pixel_clock = bios_parser_set_pixel_clock,
1901
1902         .set_dce_clock = bios_parser_set_dce_clock,
1903
1904         .program_crtc_timing = bios_parser_program_crtc_timing,
1905
1906         .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
1907
1908         .bios_parser_destroy = firmware_parser_destroy,
1909
1910         .get_board_layout_info = bios_get_board_layout_info,
1911 };
1912
1913 static bool bios_parser_construct(
1914         struct bios_parser *bp,
1915         struct bp_init_data *init,
1916         enum dce_version dce_version)
1917 {
1918         uint16_t *rom_header_offset = NULL;
1919         struct atom_rom_header_v2_2 *rom_header = NULL;
1920         struct display_object_info_table_v1_4 *object_info_tbl;
1921         struct atom_data_revision tbl_rev = {0};
1922
1923         if (!init)
1924                 return false;
1925
1926         if (!init->bios)
1927                 return false;
1928
1929         bp->base.funcs = &vbios_funcs;
1930         bp->base.bios = init->bios;
1931         bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
1932
1933         bp->base.ctx = init->ctx;
1934
1935         bp->base.bios_local_image = NULL;
1936
1937         rom_header_offset =
1938                         GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
1939
1940         if (!rom_header_offset)
1941                 return false;
1942
1943         rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
1944
1945         if (!rom_header)
1946                 return false;
1947
1948         get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
1949         if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
1950                 return false;
1951
1952         bp->master_data_tbl =
1953                 GET_IMAGE(struct atom_master_data_table_v2_1,
1954                                 rom_header->masterdatatable_offset);
1955
1956         if (!bp->master_data_tbl)
1957                 return false;
1958
1959         bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
1960
1961         if (!bp->object_info_tbl_offset)
1962                 return false;
1963
1964         object_info_tbl =
1965                         GET_IMAGE(struct display_object_info_table_v1_4,
1966                                                 bp->object_info_tbl_offset);
1967
1968         if (!object_info_tbl)
1969                 return false;
1970
1971         get_atom_data_table_revision(&object_info_tbl->table_header,
1972                 &bp->object_info_tbl.revision);
1973
1974         if (bp->object_info_tbl.revision.major == 1
1975                 && bp->object_info_tbl.revision.minor >= 4) {
1976                 struct display_object_info_table_v1_4 *tbl_v1_4;
1977
1978                 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
1979                         bp->object_info_tbl_offset);
1980                 if (!tbl_v1_4)
1981                         return false;
1982
1983                 bp->object_info_tbl.v1_4 = tbl_v1_4;
1984         } else
1985                 return false;
1986
1987         dal_firmware_parser_init_cmd_tbl(bp);
1988         dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
1989
1990         bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
1991
1992         return true;
1993 }
1994
1995 struct dc_bios *firmware_parser_create(
1996         struct bp_init_data *init,
1997         enum dce_version dce_version)
1998 {
1999         struct bios_parser *bp = NULL;
2000
2001         bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
2002         if (!bp)
2003                 return NULL;
2004
2005         if (bios_parser_construct(bp, init, dce_version))
2006                 return &bp->base;
2007
2008         kfree(bp);
2009         return NULL;
2010 }
2011
2012