Merge tag 'amd-drm-next-5.14-2021-05-19' of https://gitlab.freedesktop.org/agd5f...
[sfrench/cifs-2.6.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 <linux/slab.h>
27
28 #include "dm_services.h"
29
30 #include "ObjectID.h"
31 #include "atomfirmware.h"
32
33 #include "dc_bios_types.h"
34 #include "include/grph_object_ctrl_defs.h"
35 #include "include/bios_parser_interface.h"
36 #include "include/i2caux_interface.h"
37 #include "include/logger_interface.h"
38
39 #include "command_table2.h"
40
41 #include "bios_parser_helper.h"
42 #include "command_table_helper2.h"
43 #include "bios_parser2.h"
44 #include "bios_parser_types_internal2.h"
45 #include "bios_parser_interface.h"
46
47 #include "bios_parser_common.h"
48
49 /* Temporarily add in defines until ObjectID.h patch is updated in a few days */
50 #ifndef GENERIC_OBJECT_ID_BRACKET_LAYOUT
51 #define GENERIC_OBJECT_ID_BRACKET_LAYOUT          0x05
52 #endif /* GENERIC_OBJECT_ID_BRACKET_LAYOUT */
53
54 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1
55 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1   \
56         (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
57         GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
58         GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
59 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1 */
60
61 #ifndef GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2
62 #define GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2   \
63         (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\
64         GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
65         GENERIC_OBJECT_ID_BRACKET_LAYOUT << OBJECT_ID_SHIFT)
66 #endif /* GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2 */
67
68 #define DC_LOGGER \
69         bp->base.ctx->logger
70
71 #define LAST_RECORD_TYPE 0xff
72 #define SMU9_SYSPLL0_ID  0
73
74 struct i2c_id_config_access {
75         uint8_t bfI2C_LineMux:4;
76         uint8_t bfHW_EngineID:3;
77         uint8_t bfHW_Capable:1;
78         uint8_t ucAccess;
79 };
80
81 static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
82         struct atom_i2c_record *record,
83         struct graphics_object_i2c_info *info);
84
85 static enum bp_result bios_parser_get_firmware_info(
86         struct dc_bios *dcb,
87         struct dc_firmware_info *info);
88
89 static enum bp_result bios_parser_get_encoder_cap_info(
90         struct dc_bios *dcb,
91         struct graphics_object_id object_id,
92         struct bp_encoder_cap_info *info);
93
94 static enum bp_result get_firmware_info_v3_1(
95         struct bios_parser *bp,
96         struct dc_firmware_info *info);
97
98 static enum bp_result get_firmware_info_v3_2(
99         struct bios_parser *bp,
100         struct dc_firmware_info *info);
101
102 static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
103                 struct atom_display_object_path_v2 *object);
104
105 static struct atom_encoder_caps_record *get_encoder_cap_record(
106         struct bios_parser *bp,
107         struct atom_display_object_path_v2 *object);
108
109 #define BIOS_IMAGE_SIZE_OFFSET 2
110 #define BIOS_IMAGE_SIZE_UNIT 512
111
112 #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
113
114 static void bios_parser2_destruct(struct bios_parser *bp)
115 {
116         kfree(bp->base.bios_local_image);
117         kfree(bp->base.integrated_info);
118 }
119
120 static void firmware_parser_destroy(struct dc_bios **dcb)
121 {
122         struct bios_parser *bp = BP_FROM_DCB(*dcb);
123
124         if (!bp) {
125                 BREAK_TO_DEBUGGER();
126                 return;
127         }
128
129         bios_parser2_destruct(bp);
130
131         kfree(bp);
132         *dcb = NULL;
133 }
134
135 static void get_atom_data_table_revision(
136         struct atom_common_table_header *atom_data_tbl,
137         struct atom_data_revision *tbl_revision)
138 {
139         if (!tbl_revision)
140                 return;
141
142         /* initialize the revision to 0 which is invalid revision */
143         tbl_revision->major = 0;
144         tbl_revision->minor = 0;
145
146         if (!atom_data_tbl)
147                 return;
148
149         tbl_revision->major =
150                         (uint32_t) atom_data_tbl->format_revision & 0x3f;
151         tbl_revision->minor =
152                         (uint32_t) atom_data_tbl->content_revision & 0x3f;
153 }
154
155 /* BIOS oject table displaypath is per connector.
156  * There is extra path not for connector. BIOS fill its encoderid as 0
157  */
158 static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
159 {
160         struct bios_parser *bp = BP_FROM_DCB(dcb);
161         unsigned int count = 0;
162         unsigned int i;
163
164         for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
165                 if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
166                         count++;
167         }
168         return count;
169 }
170
171 static struct graphics_object_id bios_parser_get_connector_id(
172         struct dc_bios *dcb,
173         uint8_t i)
174 {
175         struct bios_parser *bp = BP_FROM_DCB(dcb);
176         struct graphics_object_id object_id = dal_graphics_object_id_init(
177                 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
178         struct object_info_table *tbl = &bp->object_info_tbl;
179         struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
180
181         if (v1_4->number_of_path > i) {
182                 /* If display_objid is generic object id,  the encoderObj
183                  * /extencoderobjId should be 0
184                  */
185                 if (v1_4->display_path[i].encoderobjid != 0 &&
186                                 v1_4->display_path[i].display_objid != 0)
187                         object_id = object_id_from_bios_object_id(
188                                         v1_4->display_path[i].display_objid);
189         }
190
191         return object_id;
192 }
193
194 static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
195         struct graphics_object_id object_id, uint32_t index,
196         struct graphics_object_id *src_object_id)
197 {
198         struct bios_parser *bp = BP_FROM_DCB(dcb);
199         unsigned int i;
200         enum bp_result  bp_result = BP_RESULT_BADINPUT;
201         struct graphics_object_id obj_id = {0};
202         struct object_info_table *tbl = &bp->object_info_tbl;
203
204         if (!src_object_id)
205                 return bp_result;
206
207         switch (object_id.type) {
208         /* Encoder's Source is GPU.  BIOS does not provide GPU, since all
209          * displaypaths point to same GPU (0x1100).  Hardcode GPU object type
210          */
211         case OBJECT_TYPE_ENCODER:
212                 /* TODO: since num of src must be less than 2.
213                  * If found in for loop, should break.
214                  * DAL2 implementation may be changed too
215                  */
216                 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
217                         obj_id = object_id_from_bios_object_id(
218                         tbl->v1_4->display_path[i].encoderobjid);
219                         if (object_id.type == obj_id.type &&
220                                         object_id.id == obj_id.id &&
221                                                 object_id.enum_id ==
222                                                         obj_id.enum_id) {
223                                 *src_object_id =
224                                 object_id_from_bios_object_id(0x1100);
225                                 /* break; */
226                         }
227                 }
228                 bp_result = BP_RESULT_OK;
229                 break;
230         case OBJECT_TYPE_CONNECTOR:
231                 for (i = 0; i < tbl->v1_4->number_of_path; i++) {
232                         obj_id = object_id_from_bios_object_id(
233                                 tbl->v1_4->display_path[i].display_objid);
234
235                         if (object_id.type == obj_id.type &&
236                                 object_id.id == obj_id.id &&
237                                         object_id.enum_id == obj_id.enum_id) {
238                                 *src_object_id =
239                                 object_id_from_bios_object_id(
240                                 tbl->v1_4->display_path[i].encoderobjid);
241                                 /* break; */
242                         }
243                 }
244                 bp_result = BP_RESULT_OK;
245                 break;
246         default:
247                 break;
248         }
249
250         return bp_result;
251 }
252
253 /* from graphics_object_id, find display path which includes the object_id */
254 static struct atom_display_object_path_v2 *get_bios_object(
255                 struct bios_parser *bp,
256                 struct graphics_object_id id)
257 {
258         unsigned int i;
259         struct graphics_object_id obj_id = {0};
260
261         switch (id.type) {
262         case OBJECT_TYPE_ENCODER:
263                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
264                         obj_id = object_id_from_bios_object_id(
265                                         bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
266                         if (id.type == obj_id.type && id.id == obj_id.id
267                                         && id.enum_id == obj_id.enum_id)
268                                 return &bp->object_info_tbl.v1_4->display_path[i];
269                 }
270                 fallthrough;
271         case OBJECT_TYPE_CONNECTOR:
272         case OBJECT_TYPE_GENERIC:
273                 /* Both Generic and Connector Object ID
274                  * will be stored on display_objid
275                  */
276                 for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
277                         obj_id = object_id_from_bios_object_id(
278                                         bp->object_info_tbl.v1_4->display_path[i].display_objid);
279                         if (id.type == obj_id.type && id.id == obj_id.id
280                                         && id.enum_id == obj_id.enum_id)
281                                 return &bp->object_info_tbl.v1_4->display_path[i];
282                 }
283                 fallthrough;
284         default:
285                 return NULL;
286         }
287 }
288
289 static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
290         struct graphics_object_id id,
291         struct graphics_object_i2c_info *info)
292 {
293         uint32_t offset;
294         struct atom_display_object_path_v2 *object;
295         struct atom_common_record_header *header;
296         struct atom_i2c_record *record;
297         struct atom_i2c_record dummy_record = {0};
298         struct bios_parser *bp = BP_FROM_DCB(dcb);
299
300         if (!info)
301                 return BP_RESULT_BADINPUT;
302
303         if (id.type == OBJECT_TYPE_GENERIC) {
304                 dummy_record.i2c_id = id.id;
305
306                 if (get_gpio_i2c_info(bp, &dummy_record, info) == BP_RESULT_OK)
307                         return BP_RESULT_OK;
308                 else
309                         return BP_RESULT_NORECORD;
310         }
311
312         object = get_bios_object(bp, id);
313
314         if (!object)
315                 return BP_RESULT_BADINPUT;
316
317         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
318
319         for (;;) {
320                 header = GET_IMAGE(struct atom_common_record_header, offset);
321
322                 if (!header)
323                         return BP_RESULT_BADBIOSTABLE;
324
325                 if (header->record_type == LAST_RECORD_TYPE ||
326                         !header->record_size)
327                         break;
328
329                 if (header->record_type == ATOM_I2C_RECORD_TYPE
330                         && sizeof(struct atom_i2c_record) <=
331                                                         header->record_size) {
332                         /* get the I2C info */
333                         record = (struct atom_i2c_record *) header;
334
335                         if (get_gpio_i2c_info(bp, record, info) ==
336                                                                 BP_RESULT_OK)
337                                 return BP_RESULT_OK;
338                 }
339
340                 offset += header->record_size;
341         }
342
343         return BP_RESULT_NORECORD;
344 }
345
346 static enum bp_result get_gpio_i2c_info(
347         struct bios_parser *bp,
348         struct atom_i2c_record *record,
349         struct graphics_object_i2c_info *info)
350 {
351         struct atom_gpio_pin_lut_v2_1 *header;
352         uint32_t count = 0;
353         unsigned int table_index = 0;
354         bool find_valid = false;
355
356         if (!info)
357                 return BP_RESULT_BADINPUT;
358
359         /* get the GPIO_I2C info */
360         if (!DATA_TABLES(gpio_pin_lut))
361                 return BP_RESULT_BADBIOSTABLE;
362
363         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
364                                         DATA_TABLES(gpio_pin_lut));
365         if (!header)
366                 return BP_RESULT_BADBIOSTABLE;
367
368         if (sizeof(struct atom_common_table_header) +
369                         sizeof(struct atom_gpio_pin_assignment) >
370                         le16_to_cpu(header->table_header.structuresize))
371                 return BP_RESULT_BADBIOSTABLE;
372
373         /* TODO: is version change? */
374         if (header->table_header.content_revision != 1)
375                 return BP_RESULT_UNSUPPORTED;
376
377         /* get data count */
378         count = (le16_to_cpu(header->table_header.structuresize)
379                         - sizeof(struct atom_common_table_header))
380                                 / sizeof(struct atom_gpio_pin_assignment);
381
382         for (table_index = 0; table_index < count; table_index++) {
383                 if (((record->i2c_id & I2C_HW_CAP) == (
384                 header->gpio_pin[table_index].gpio_id &
385                                                 I2C_HW_CAP)) &&
386                 ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==
387                 (header->gpio_pin[table_index].gpio_id &
388                                         I2C_HW_ENGINE_ID_MASK)) &&
389                 ((record->i2c_id & I2C_HW_LANE_MUX) ==
390                 (header->gpio_pin[table_index].gpio_id &
391                                                 I2C_HW_LANE_MUX))) {
392                         /* still valid */
393                         find_valid = true;
394                         break;
395                 }
396         }
397
398         /* If we don't find the entry that we are looking for then
399          *  we will return BP_Result_BadBiosTable.
400          */
401         if (find_valid == false)
402                 return BP_RESULT_BADBIOSTABLE;
403
404         /* get the GPIO_I2C_INFO */
405         info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
406         info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
407         info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
408         info->i2c_slave_address = record->i2c_slave_addr;
409
410         /* TODO: check how to get register offset for en, Y, etc. */
411         info->gpio_info.clk_a_register_index =
412                         le16_to_cpu(
413                         header->gpio_pin[table_index].data_a_reg_index);
414         info->gpio_info.clk_a_shift =
415                         header->gpio_pin[table_index].gpio_bitshift;
416
417         return BP_RESULT_OK;
418 }
419
420 static enum bp_result bios_parser_get_hpd_info(
421         struct dc_bios *dcb,
422         struct graphics_object_id id,
423         struct graphics_object_hpd_info *info)
424 {
425         struct bios_parser *bp = BP_FROM_DCB(dcb);
426         struct atom_display_object_path_v2 *object;
427         struct atom_hpd_int_record *record = NULL;
428
429         if (!info)
430                 return BP_RESULT_BADINPUT;
431
432         object = get_bios_object(bp, id);
433
434         if (!object)
435                 return BP_RESULT_BADINPUT;
436
437         record = get_hpd_record(bp, object);
438
439         if (record != NULL) {
440                 info->hpd_int_gpio_uid = record->pin_id;
441                 info->hpd_active = record->plugin_pin_state;
442                 return BP_RESULT_OK;
443         }
444
445         return BP_RESULT_NORECORD;
446 }
447
448 static struct atom_hpd_int_record *get_hpd_record(
449         struct bios_parser *bp,
450         struct atom_display_object_path_v2 *object)
451 {
452         struct atom_common_record_header *header;
453         uint32_t offset;
454
455         if (!object) {
456                 BREAK_TO_DEBUGGER(); /* Invalid object */
457                 return NULL;
458         }
459
460         offset = le16_to_cpu(object->disp_recordoffset)
461                         + bp->object_info_tbl_offset;
462
463         for (;;) {
464                 header = GET_IMAGE(struct atom_common_record_header, offset);
465
466                 if (!header)
467                         return NULL;
468
469                 if (header->record_type == LAST_RECORD_TYPE ||
470                         !header->record_size)
471                         break;
472
473                 if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
474                         && sizeof(struct atom_hpd_int_record) <=
475                                                         header->record_size)
476                         return (struct atom_hpd_int_record *) header;
477
478                 offset += header->record_size;
479         }
480
481         return NULL;
482 }
483
484 /**
485  * bios_parser_get_gpio_pin_info
486  * Get GpioPin information of input gpio id
487  *
488  * @dcb:     pointer to the DC BIOS
489  * @gpio_id: GPIO ID
490  * @info:    GpioPin information structure
491  * return: Bios parser result code
492  * note:
493  *  to get the GPIO PIN INFO, we need:
494  *  1. get the GPIO_ID from other object table, see GetHPDInfo()
495  *  2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
496  *      to get the registerA  offset/mask
497  */
498 static enum bp_result bios_parser_get_gpio_pin_info(
499         struct dc_bios *dcb,
500         uint32_t gpio_id,
501         struct gpio_pin_info *info)
502 {
503         struct bios_parser *bp = BP_FROM_DCB(dcb);
504         struct atom_gpio_pin_lut_v2_1 *header;
505         uint32_t count = 0;
506         uint32_t i = 0;
507
508         if (!DATA_TABLES(gpio_pin_lut))
509                 return BP_RESULT_BADBIOSTABLE;
510
511         header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
512                                                 DATA_TABLES(gpio_pin_lut));
513         if (!header)
514                 return BP_RESULT_BADBIOSTABLE;
515
516         if (sizeof(struct atom_common_table_header) +
517                         sizeof(struct atom_gpio_pin_assignment)
518                         > le16_to_cpu(header->table_header.structuresize))
519                 return BP_RESULT_BADBIOSTABLE;
520
521         if (header->table_header.content_revision != 1)
522                 return BP_RESULT_UNSUPPORTED;
523
524         /* Temporary hard code gpio pin info */
525 #if defined(FOR_SIMNOW_BOOT)
526         {
527                 struct  atom_gpio_pin_assignment  gpio_pin[8] = {
528                                 {0x5db5, 0, 0, 1, 0},
529                                 {0x5db5, 8, 8, 2, 0},
530                                 {0x5db5, 0x10, 0x10, 3, 0},
531                                 {0x5db5, 0x18, 0x14, 4, 0},
532                                 {0x5db5, 0x1A, 0x18, 5, 0},
533                                 {0x5db5, 0x1C, 0x1C, 6, 0},
534                 };
535
536                 count = 6;
537                 memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
538         }
539 #else
540         count = (le16_to_cpu(header->table_header.structuresize)
541                         - sizeof(struct atom_common_table_header))
542                                 / sizeof(struct atom_gpio_pin_assignment);
543 #endif
544         for (i = 0; i < count; ++i) {
545                 if (header->gpio_pin[i].gpio_id != gpio_id)
546                         continue;
547
548                 info->offset =
549                         (uint32_t) le16_to_cpu(
550                                         header->gpio_pin[i].data_a_reg_index);
551                 info->offset_y = info->offset + 2;
552                 info->offset_en = info->offset + 1;
553                 info->offset_mask = info->offset - 1;
554
555                 info->mask = (uint32_t) (1 <<
556                         header->gpio_pin[i].gpio_bitshift);
557                 info->mask_y = info->mask + 2;
558                 info->mask_en = info->mask + 1;
559                 info->mask_mask = info->mask - 1;
560
561                 return BP_RESULT_OK;
562         }
563
564         return BP_RESULT_NORECORD;
565 }
566
567 static struct device_id device_type_from_device_id(uint16_t device_id)
568 {
569
570         struct device_id result_device_id;
571
572         result_device_id.raw_device_tag = device_id;
573
574         switch (device_id) {
575         case ATOM_DISPLAY_LCD1_SUPPORT:
576                 result_device_id.device_type = DEVICE_TYPE_LCD;
577                 result_device_id.enum_id = 1;
578                 break;
579
580         case ATOM_DISPLAY_DFP1_SUPPORT:
581                 result_device_id.device_type = DEVICE_TYPE_DFP;
582                 result_device_id.enum_id = 1;
583                 break;
584
585         case ATOM_DISPLAY_DFP2_SUPPORT:
586                 result_device_id.device_type = DEVICE_TYPE_DFP;
587                 result_device_id.enum_id = 2;
588                 break;
589
590         case ATOM_DISPLAY_DFP3_SUPPORT:
591                 result_device_id.device_type = DEVICE_TYPE_DFP;
592                 result_device_id.enum_id = 3;
593                 break;
594
595         case ATOM_DISPLAY_DFP4_SUPPORT:
596                 result_device_id.device_type = DEVICE_TYPE_DFP;
597                 result_device_id.enum_id = 4;
598                 break;
599
600         case ATOM_DISPLAY_DFP5_SUPPORT:
601                 result_device_id.device_type = DEVICE_TYPE_DFP;
602                 result_device_id.enum_id = 5;
603                 break;
604
605         case ATOM_DISPLAY_DFP6_SUPPORT:
606                 result_device_id.device_type = DEVICE_TYPE_DFP;
607                 result_device_id.enum_id = 6;
608                 break;
609
610         default:
611                 BREAK_TO_DEBUGGER(); /* Invalid device Id */
612                 result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
613                 result_device_id.enum_id = 0;
614         }
615         return result_device_id;
616 }
617
618 static enum bp_result bios_parser_get_device_tag(
619         struct dc_bios *dcb,
620         struct graphics_object_id connector_object_id,
621         uint32_t device_tag_index,
622         struct connector_device_tag_info *info)
623 {
624         struct bios_parser *bp = BP_FROM_DCB(dcb);
625         struct atom_display_object_path_v2 *object;
626
627         if (!info)
628                 return BP_RESULT_BADINPUT;
629
630         /* getBiosObject will return MXM object */
631         object = get_bios_object(bp, connector_object_id);
632
633         if (!object) {
634                 BREAK_TO_DEBUGGER(); /* Invalid object id */
635                 return BP_RESULT_BADINPUT;
636         }
637
638         info->acpi_device = 0; /* BIOS no longer provides this */
639         info->dev_id = device_type_from_device_id(object->device_tag);
640
641         return BP_RESULT_OK;
642 }
643
644 static enum bp_result get_ss_info_v4_1(
645         struct bios_parser *bp,
646         uint32_t id,
647         uint32_t index,
648         struct spread_spectrum_info *ss_info)
649 {
650         enum bp_result result = BP_RESULT_OK;
651         struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
652         struct atom_smu_info_v3_3 *smu_info = NULL;
653
654         if (!ss_info)
655                 return BP_RESULT_BADINPUT;
656
657         if (!DATA_TABLES(dce_info))
658                 return BP_RESULT_BADBIOSTABLE;
659
660         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_1,
661                                                         DATA_TABLES(dce_info));
662         if (!disp_cntl_tbl)
663                 return BP_RESULT_BADBIOSTABLE;
664
665
666         ss_info->type.STEP_AND_DELAY_INFO = false;
667         ss_info->spread_percentage_divider = 1000;
668         /* BIOS no longer uses target clock.  Always enable for now */
669         ss_info->target_clock_range = 0xffffffff;
670
671         switch (id) {
672         case AS_SIGNAL_TYPE_DVI:
673                 ss_info->spread_spectrum_percentage =
674                                 disp_cntl_tbl->dvi_ss_percentage;
675                 ss_info->spread_spectrum_range =
676                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
677                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
678                         ss_info->type.CENTER_MODE = true;
679                 break;
680         case AS_SIGNAL_TYPE_HDMI:
681                 ss_info->spread_spectrum_percentage =
682                                 disp_cntl_tbl->hdmi_ss_percentage;
683                 ss_info->spread_spectrum_range =
684                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
685                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
686                         ss_info->type.CENTER_MODE = true;
687                 break;
688         /* TODO LVDS not support anymore? */
689         case AS_SIGNAL_TYPE_DISPLAY_PORT:
690                 ss_info->spread_spectrum_percentage =
691                                 disp_cntl_tbl->dp_ss_percentage;
692                 ss_info->spread_spectrum_range =
693                                 disp_cntl_tbl->dp_ss_rate_10hz * 10;
694                 if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
695                         ss_info->type.CENTER_MODE = true;
696                 break;
697         case AS_SIGNAL_TYPE_GPU_PLL:
698                 /* atom_firmware: DAL only get data from dce_info table.
699                  * if data within smu_info is needed for DAL, VBIOS should
700                  * copy it into dce_info
701                  */
702                 result = BP_RESULT_UNSUPPORTED;
703                 break;
704         case AS_SIGNAL_TYPE_XGMI:
705                 smu_info =  GET_IMAGE(struct atom_smu_info_v3_3,
706                                       DATA_TABLES(smu_info));
707                 if (!smu_info)
708                         return BP_RESULT_BADBIOSTABLE;
709
710                 ss_info->spread_spectrum_percentage =
711                                 smu_info->waflclk_ss_percentage;
712                 ss_info->spread_spectrum_range =
713                                 smu_info->gpuclk_ss_rate_10hz * 10;
714                 if (smu_info->waflclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
715                         ss_info->type.CENTER_MODE = true;
716                 break;
717         default:
718                 result = BP_RESULT_UNSUPPORTED;
719         }
720
721         return result;
722 }
723
724 static enum bp_result get_ss_info_v4_2(
725         struct bios_parser *bp,
726         uint32_t id,
727         uint32_t index,
728         struct spread_spectrum_info *ss_info)
729 {
730         enum bp_result result = BP_RESULT_OK;
731         struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
732         struct atom_smu_info_v3_1 *smu_info = NULL;
733
734         if (!ss_info)
735                 return BP_RESULT_BADINPUT;
736
737         if (!DATA_TABLES(dce_info))
738                 return BP_RESULT_BADBIOSTABLE;
739
740         if (!DATA_TABLES(smu_info))
741                 return BP_RESULT_BADBIOSTABLE;
742
743         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_2,
744                                                         DATA_TABLES(dce_info));
745         if (!disp_cntl_tbl)
746                 return BP_RESULT_BADBIOSTABLE;
747
748         smu_info =  GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
749         if (!smu_info)
750                 return BP_RESULT_BADBIOSTABLE;
751
752         ss_info->type.STEP_AND_DELAY_INFO = false;
753         ss_info->spread_percentage_divider = 1000;
754         /* BIOS no longer uses target clock.  Always enable for now */
755         ss_info->target_clock_range = 0xffffffff;
756
757         switch (id) {
758         case AS_SIGNAL_TYPE_DVI:
759                 ss_info->spread_spectrum_percentage =
760                                 disp_cntl_tbl->dvi_ss_percentage;
761                 ss_info->spread_spectrum_range =
762                                 disp_cntl_tbl->dvi_ss_rate_10hz * 10;
763                 if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
764                         ss_info->type.CENTER_MODE = true;
765                 break;
766         case AS_SIGNAL_TYPE_HDMI:
767                 ss_info->spread_spectrum_percentage =
768                                 disp_cntl_tbl->hdmi_ss_percentage;
769                 ss_info->spread_spectrum_range =
770                                 disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
771                 if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
772                         ss_info->type.CENTER_MODE = true;
773                 break;
774         /* TODO LVDS not support anymore? */
775         case AS_SIGNAL_TYPE_DISPLAY_PORT:
776                 ss_info->spread_spectrum_percentage =
777                                 smu_info->gpuclk_ss_percentage;
778                 ss_info->spread_spectrum_range =
779                                 smu_info->gpuclk_ss_rate_10hz * 10;
780                 if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
781                         ss_info->type.CENTER_MODE = true;
782                 break;
783         case AS_SIGNAL_TYPE_GPU_PLL:
784                 /* atom_firmware: DAL only get data from dce_info table.
785                  * if data within smu_info is needed for DAL, VBIOS should
786                  * copy it into dce_info
787                  */
788                 result = BP_RESULT_UNSUPPORTED;
789                 break;
790         default:
791                 result = BP_RESULT_UNSUPPORTED;
792         }
793
794         return result;
795 }
796
797 /**
798  * bios_parser_get_spread_spectrum_info
799  * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
800  * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
801  * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
802  * ver 3.1,
803  * there is only one entry for each signal /ss id.  However, there is
804  * no planning of supporting multiple spread Sprectum entry for EverGreen
805  * @dcb:     pointer to the DC BIOS
806  * @signal:  ASSignalType to be converted to info index
807  * @index:   number of entries that match the converted info index
808  * @ss_info: sprectrum information structure,
809  * return: Bios parser result code
810  */
811 static enum bp_result bios_parser_get_spread_spectrum_info(
812         struct dc_bios *dcb,
813         enum as_signal_type signal,
814         uint32_t index,
815         struct spread_spectrum_info *ss_info)
816 {
817         struct bios_parser *bp = BP_FROM_DCB(dcb);
818         enum bp_result result = BP_RESULT_UNSUPPORTED;
819         struct atom_common_table_header *header;
820         struct atom_data_revision tbl_revision;
821
822         if (!ss_info) /* check for bad input */
823                 return BP_RESULT_BADINPUT;
824
825         if (!DATA_TABLES(dce_info))
826                 return BP_RESULT_UNSUPPORTED;
827
828         header = GET_IMAGE(struct atom_common_table_header,
829                                                 DATA_TABLES(dce_info));
830         get_atom_data_table_revision(header, &tbl_revision);
831
832         switch (tbl_revision.major) {
833         case 4:
834                 switch (tbl_revision.minor) {
835                 case 1:
836                         return get_ss_info_v4_1(bp, signal, index, ss_info);
837                 case 2:
838                 case 3:
839                 case 4:
840                         return get_ss_info_v4_2(bp, signal, index, ss_info);
841                 default:
842                         ASSERT(0);
843                         break;
844                 }
845                 break;
846         default:
847                 break;
848         }
849         /* there can not be more then one entry for SS Info table */
850         return result;
851 }
852
853 static enum bp_result get_soc_bb_info_v4_4(
854         struct bios_parser *bp,
855         struct bp_soc_bb_info *soc_bb_info)
856 {
857         enum bp_result result = BP_RESULT_OK;
858         struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
859
860         if (!soc_bb_info)
861                 return BP_RESULT_BADINPUT;
862
863         if (!DATA_TABLES(dce_info))
864                 return BP_RESULT_BADBIOSTABLE;
865
866         if (!DATA_TABLES(smu_info))
867                 return BP_RESULT_BADBIOSTABLE;
868
869         disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_4,
870                                                         DATA_TABLES(dce_info));
871         if (!disp_cntl_tbl)
872                 return BP_RESULT_BADBIOSTABLE;
873
874         soc_bb_info->dram_clock_change_latency_100ns = disp_cntl_tbl->max_mclk_chg_lat;
875         soc_bb_info->dram_sr_enter_exit_latency_100ns = disp_cntl_tbl->max_sr_enter_exit_lat;
876         soc_bb_info->dram_sr_exit_latency_100ns = disp_cntl_tbl->max_sr_exit_lat;
877
878         return result;
879 }
880
881 static enum bp_result bios_parser_get_soc_bb_info(
882         struct dc_bios *dcb,
883         struct bp_soc_bb_info *soc_bb_info)
884 {
885         struct bios_parser *bp = BP_FROM_DCB(dcb);
886         enum bp_result result = BP_RESULT_UNSUPPORTED;
887         struct atom_common_table_header *header;
888         struct atom_data_revision tbl_revision;
889
890         if (!soc_bb_info) /* check for bad input */
891                 return BP_RESULT_BADINPUT;
892
893         if (!DATA_TABLES(dce_info))
894                 return BP_RESULT_UNSUPPORTED;
895
896         header = GET_IMAGE(struct atom_common_table_header,
897                                                 DATA_TABLES(dce_info));
898         get_atom_data_table_revision(header, &tbl_revision);
899
900         switch (tbl_revision.major) {
901         case 4:
902                 switch (tbl_revision.minor) {
903                 case 1:
904                 case 2:
905                 case 3:
906                         break;
907                 case 4:
908                         result = get_soc_bb_info_v4_4(bp, soc_bb_info);
909                         break;
910                 default:
911                         break;
912                 }
913                 break;
914         default:
915                 break;
916         }
917
918         return result;
919 }
920
921 static enum bp_result get_disp_caps_v4_1(
922         struct bios_parser *bp,
923         uint8_t *dce_caps)
924 {
925         enum bp_result result = BP_RESULT_OK;
926         struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
927
928         if (!dce_caps)
929                 return BP_RESULT_BADINPUT;
930
931         if (!DATA_TABLES(dce_info))
932                 return BP_RESULT_BADBIOSTABLE;
933
934         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
935                                                         DATA_TABLES(dce_info));
936
937         if (!disp_cntl_tbl)
938                 return BP_RESULT_BADBIOSTABLE;
939
940         *dce_caps = disp_cntl_tbl->display_caps;
941
942         return result;
943 }
944
945 static enum bp_result get_disp_caps_v4_2(
946         struct bios_parser *bp,
947         uint8_t *dce_caps)
948 {
949         enum bp_result result = BP_RESULT_OK;
950         struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
951
952         if (!dce_caps)
953                 return BP_RESULT_BADINPUT;
954
955         if (!DATA_TABLES(dce_info))
956                 return BP_RESULT_BADBIOSTABLE;
957
958         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
959                                                         DATA_TABLES(dce_info));
960
961         if (!disp_cntl_tbl)
962                 return BP_RESULT_BADBIOSTABLE;
963
964         *dce_caps = disp_cntl_tbl->display_caps;
965
966         return result;
967 }
968
969 static enum bp_result get_disp_caps_v4_3(
970         struct bios_parser *bp,
971         uint8_t *dce_caps)
972 {
973         enum bp_result result = BP_RESULT_OK;
974         struct atom_display_controller_info_v4_3 *disp_cntl_tbl = NULL;
975
976         if (!dce_caps)
977                 return BP_RESULT_BADINPUT;
978
979         if (!DATA_TABLES(dce_info))
980                 return BP_RESULT_BADBIOSTABLE;
981
982         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_3,
983                                                         DATA_TABLES(dce_info));
984
985         if (!disp_cntl_tbl)
986                 return BP_RESULT_BADBIOSTABLE;
987
988         *dce_caps = disp_cntl_tbl->display_caps;
989
990         return result;
991 }
992
993 static enum bp_result get_disp_caps_v4_4(
994         struct bios_parser *bp,
995         uint8_t *dce_caps)
996 {
997         enum bp_result result = BP_RESULT_OK;
998         struct atom_display_controller_info_v4_4 *disp_cntl_tbl = NULL;
999
1000         if (!dce_caps)
1001                 return BP_RESULT_BADINPUT;
1002
1003         if (!DATA_TABLES(dce_info))
1004                 return BP_RESULT_BADBIOSTABLE;
1005
1006         disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_4,
1007                                                         DATA_TABLES(dce_info));
1008
1009         if (!disp_cntl_tbl)
1010                 return BP_RESULT_BADBIOSTABLE;
1011
1012         *dce_caps = disp_cntl_tbl->display_caps;
1013
1014         return result;
1015 }
1016
1017 static enum bp_result bios_parser_get_lttpr_interop(
1018         struct dc_bios *dcb,
1019         uint8_t *dce_caps)
1020 {
1021         struct bios_parser *bp = BP_FROM_DCB(dcb);
1022         enum bp_result result = BP_RESULT_UNSUPPORTED;
1023         struct atom_common_table_header *header;
1024         struct atom_data_revision tbl_revision;
1025
1026         if (!DATA_TABLES(dce_info))
1027                 return BP_RESULT_UNSUPPORTED;
1028
1029         header = GET_IMAGE(struct atom_common_table_header,
1030                                                 DATA_TABLES(dce_info));
1031         get_atom_data_table_revision(header, &tbl_revision);
1032         switch (tbl_revision.major) {
1033         case 4:
1034                 switch (tbl_revision.minor) {
1035                 case 1:
1036                         result = get_disp_caps_v4_1(bp, dce_caps);
1037                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1038                         break;
1039                 case 2:
1040                         result = get_disp_caps_v4_2(bp, dce_caps);
1041                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1042                         break;
1043                 case 3:
1044                         result = get_disp_caps_v4_3(bp, dce_caps);
1045                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1046                         break;
1047                 case 4:
1048                         result = get_disp_caps_v4_4(bp, dce_caps);
1049                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_VBIOS_LTTPR_TRANSPARENT_ENABLE);
1050                         break;
1051                 default:
1052                         break;
1053                 }
1054                 break;
1055         default:
1056                 break;
1057         }
1058
1059         return result;
1060 }
1061
1062 static enum bp_result bios_parser_get_lttpr_caps(
1063         struct dc_bios *dcb,
1064         uint8_t *dce_caps)
1065 {
1066         struct bios_parser *bp = BP_FROM_DCB(dcb);
1067         enum bp_result result = BP_RESULT_UNSUPPORTED;
1068         struct atom_common_table_header *header;
1069         struct atom_data_revision tbl_revision;
1070
1071         if (!DATA_TABLES(dce_info))
1072                 return BP_RESULT_UNSUPPORTED;
1073
1074         header = GET_IMAGE(struct atom_common_table_header,
1075                                                 DATA_TABLES(dce_info));
1076         get_atom_data_table_revision(header, &tbl_revision);
1077         switch (tbl_revision.major) {
1078         case 4:
1079                 switch (tbl_revision.minor) {
1080                 case 1:
1081                         result = get_disp_caps_v4_1(bp, dce_caps);
1082                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1083                         break;
1084                 case 2:
1085                         result = get_disp_caps_v4_2(bp, dce_caps);
1086                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1087                         break;
1088                 case 3:
1089                         result = get_disp_caps_v4_3(bp, dce_caps);
1090                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1091                         break;
1092                 case 4:
1093                         result = get_disp_caps_v4_4(bp, dce_caps);
1094                         *dce_caps = !!(*dce_caps & DCE_INFO_CAPS_LTTPR_SUPPORT_ENABLE);
1095                         break;
1096                 default:
1097                         break;
1098                 }
1099                 break;
1100         default:
1101                 break;
1102         }
1103
1104         return result;
1105 }
1106
1107 static enum bp_result get_embedded_panel_info_v2_1(
1108                 struct bios_parser *bp,
1109                 struct embedded_panel_info *info)
1110 {
1111         struct lcd_info_v2_1 *lvds;
1112
1113         if (!info)
1114                 return BP_RESULT_BADINPUT;
1115
1116         if (!DATA_TABLES(lcd_info))
1117                 return BP_RESULT_UNSUPPORTED;
1118
1119         lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
1120
1121         if (!lvds)
1122                 return BP_RESULT_BADBIOSTABLE;
1123
1124         /* TODO: previous vv1_3, should v2_1 */
1125         if (!((lvds->table_header.format_revision == 2)
1126                         && (lvds->table_header.content_revision >= 1)))
1127                 return BP_RESULT_UNSUPPORTED;
1128
1129         memset(info, 0, sizeof(struct embedded_panel_info));
1130
1131         /* We need to convert from 10KHz units into KHz units */
1132         info->lcd_timing.pixel_clk = le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
1133         /* usHActive does not include borders, according to VBIOS team */
1134         info->lcd_timing.horizontal_addressable = le16_to_cpu(lvds->lcd_timing.h_active);
1135         /* usHBlanking_Time includes borders, so we should really be
1136          * subtractingborders duing this translation, but LVDS generally
1137          * doesn't have borders, so we should be okay leaving this as is for
1138          * now.  May need to revisit if we ever have LVDS with borders
1139          */
1140         info->lcd_timing.horizontal_blanking_time = le16_to_cpu(lvds->lcd_timing.h_blanking_time);
1141         /* usVActive does not include borders, according to VBIOS team*/
1142         info->lcd_timing.vertical_addressable = le16_to_cpu(lvds->lcd_timing.v_active);
1143         /* usVBlanking_Time includes borders, so we should really be
1144          * subtracting borders duing this translation, but LVDS generally
1145          * doesn't have borders, so we should be okay leaving this as is for
1146          * now. May need to revisit if we ever have LVDS with borders
1147          */
1148         info->lcd_timing.vertical_blanking_time = le16_to_cpu(lvds->lcd_timing.v_blanking_time);
1149         info->lcd_timing.horizontal_sync_offset = le16_to_cpu(lvds->lcd_timing.h_sync_offset);
1150         info->lcd_timing.horizontal_sync_width = le16_to_cpu(lvds->lcd_timing.h_sync_width);
1151         info->lcd_timing.vertical_sync_offset = le16_to_cpu(lvds->lcd_timing.v_sync_offset);
1152         info->lcd_timing.vertical_sync_width = le16_to_cpu(lvds->lcd_timing.v_syncwidth);
1153         info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
1154         info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
1155
1156         /* not provided by VBIOS */
1157         info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
1158
1159         info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1160                         & ATOM_HSYNC_POLARITY);
1161         info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo
1162                         & ATOM_VSYNC_POLARITY);
1163
1164         /* not provided by VBIOS */
1165         info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
1166
1167         info->lcd_timing.misc_info.H_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1168                         & ATOM_H_REPLICATIONBY2);
1169         info->lcd_timing.misc_info.V_REPLICATION_BY2 = !!(lvds->lcd_timing.miscinfo
1170                         & ATOM_V_REPLICATIONBY2);
1171         info->lcd_timing.misc_info.COMPOSITE_SYNC = !!(lvds->lcd_timing.miscinfo
1172                         & ATOM_COMPOSITESYNC);
1173         info->lcd_timing.misc_info.INTERLACE = !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
1174
1175         /* not provided by VBIOS*/
1176         info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
1177         /* not provided by VBIOS*/
1178         info->ss_id = 0;
1179
1180         info->realtek_eDPToLVDS = !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
1181
1182         return BP_RESULT_OK;
1183 }
1184
1185 static enum bp_result bios_parser_get_embedded_panel_info(
1186                 struct dc_bios *dcb,
1187                 struct embedded_panel_info *info)
1188 {
1189         struct bios_parser
1190         *bp = BP_FROM_DCB(dcb);
1191         struct atom_common_table_header *header;
1192         struct atom_data_revision tbl_revision;
1193
1194         if (!DATA_TABLES(lcd_info))
1195                 return BP_RESULT_FAILURE;
1196
1197         header = GET_IMAGE(struct atom_common_table_header, DATA_TABLES(lcd_info));
1198
1199         if (!header)
1200                 return BP_RESULT_BADBIOSTABLE;
1201
1202         get_atom_data_table_revision(header, &tbl_revision);
1203
1204         switch (tbl_revision.major) {
1205         case 2:
1206                 switch (tbl_revision.minor) {
1207                 case 1:
1208                         return get_embedded_panel_info_v2_1(bp, info);
1209                 default:
1210                         break;
1211                 }
1212                 break;
1213         default:
1214                 break;
1215         }
1216
1217         return BP_RESULT_FAILURE;
1218 }
1219
1220 static uint32_t get_support_mask_for_device_id(struct device_id device_id)
1221 {
1222         enum dal_device_type device_type = device_id.device_type;
1223         uint32_t enum_id = device_id.enum_id;
1224
1225         switch (device_type) {
1226         case DEVICE_TYPE_LCD:
1227                 switch (enum_id) {
1228                 case 1:
1229                         return ATOM_DISPLAY_LCD1_SUPPORT;
1230                 default:
1231                         break;
1232                 }
1233                 break;
1234         case DEVICE_TYPE_DFP:
1235                 switch (enum_id) {
1236                 case 1:
1237                         return ATOM_DISPLAY_DFP1_SUPPORT;
1238                 case 2:
1239                         return ATOM_DISPLAY_DFP2_SUPPORT;
1240                 case 3:
1241                         return ATOM_DISPLAY_DFP3_SUPPORT;
1242                 case 4:
1243                         return ATOM_DISPLAY_DFP4_SUPPORT;
1244                 case 5:
1245                         return ATOM_DISPLAY_DFP5_SUPPORT;
1246                 case 6:
1247                         return ATOM_DISPLAY_DFP6_SUPPORT;
1248                 default:
1249                         break;
1250                 }
1251                 break;
1252         default:
1253                 break;
1254         }
1255
1256         /* Unidentified device ID, return empty support mask. */
1257         return 0;
1258 }
1259
1260 static bool bios_parser_is_device_id_supported(
1261         struct dc_bios *dcb,
1262         struct device_id id)
1263 {
1264         struct bios_parser *bp = BP_FROM_DCB(dcb);
1265
1266         uint32_t mask = get_support_mask_for_device_id(id);
1267
1268         return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
1269                                                                 mask) != 0;
1270 }
1271
1272 static uint32_t bios_parser_get_ss_entry_number(
1273         struct dc_bios *dcb,
1274         enum as_signal_type signal)
1275 {
1276         /* TODO: DAL2 atomfirmware implementation does not need this.
1277          * why DAL3 need this?
1278          */
1279         return 1;
1280 }
1281
1282 static enum bp_result bios_parser_transmitter_control(
1283         struct dc_bios *dcb,
1284         struct bp_transmitter_control *cntl)
1285 {
1286         struct bios_parser *bp = BP_FROM_DCB(dcb);
1287
1288         if (!bp->cmd_tbl.transmitter_control)
1289                 return BP_RESULT_FAILURE;
1290
1291         return bp->cmd_tbl.transmitter_control(bp, cntl);
1292 }
1293
1294 static enum bp_result bios_parser_encoder_control(
1295         struct dc_bios *dcb,
1296         struct bp_encoder_control *cntl)
1297 {
1298         struct bios_parser *bp = BP_FROM_DCB(dcb);
1299
1300         if (!bp->cmd_tbl.dig_encoder_control)
1301                 return BP_RESULT_FAILURE;
1302
1303         return bp->cmd_tbl.dig_encoder_control(bp, cntl);
1304 }
1305
1306 static enum bp_result bios_parser_set_pixel_clock(
1307         struct dc_bios *dcb,
1308         struct bp_pixel_clock_parameters *bp_params)
1309 {
1310         struct bios_parser *bp = BP_FROM_DCB(dcb);
1311
1312         if (!bp->cmd_tbl.set_pixel_clock)
1313                 return BP_RESULT_FAILURE;
1314
1315         return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
1316 }
1317
1318 static enum bp_result bios_parser_set_dce_clock(
1319         struct dc_bios *dcb,
1320         struct bp_set_dce_clock_parameters *bp_params)
1321 {
1322         struct bios_parser *bp = BP_FROM_DCB(dcb);
1323
1324         if (!bp->cmd_tbl.set_dce_clock)
1325                 return BP_RESULT_FAILURE;
1326
1327         return bp->cmd_tbl.set_dce_clock(bp, bp_params);
1328 }
1329
1330 static enum bp_result bios_parser_program_crtc_timing(
1331         struct dc_bios *dcb,
1332         struct bp_hw_crtc_timing_parameters *bp_params)
1333 {
1334         struct bios_parser *bp = BP_FROM_DCB(dcb);
1335
1336         if (!bp->cmd_tbl.set_crtc_timing)
1337                 return BP_RESULT_FAILURE;
1338
1339         return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
1340 }
1341
1342 static enum bp_result bios_parser_enable_crtc(
1343         struct dc_bios *dcb,
1344         enum controller_id id,
1345         bool enable)
1346 {
1347         struct bios_parser *bp = BP_FROM_DCB(dcb);
1348
1349         if (!bp->cmd_tbl.enable_crtc)
1350                 return BP_RESULT_FAILURE;
1351
1352         return bp->cmd_tbl.enable_crtc(bp, id, enable);
1353 }
1354
1355 static enum bp_result bios_parser_enable_disp_power_gating(
1356         struct dc_bios *dcb,
1357         enum controller_id controller_id,
1358         enum bp_pipe_control_action action)
1359 {
1360         struct bios_parser *bp = BP_FROM_DCB(dcb);
1361
1362         if (!bp->cmd_tbl.enable_disp_power_gating)
1363                 return BP_RESULT_FAILURE;
1364
1365         return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
1366                 action);
1367 }
1368
1369 static enum bp_result bios_parser_enable_lvtma_control(
1370         struct dc_bios *dcb,
1371         uint8_t uc_pwr_on,
1372         uint8_t panel_instance)
1373 {
1374         struct bios_parser *bp = BP_FROM_DCB(dcb);
1375
1376         if (!bp->cmd_tbl.enable_lvtma_control)
1377                 return BP_RESULT_FAILURE;
1378
1379         return bp->cmd_tbl.enable_lvtma_control(bp, uc_pwr_on, panel_instance);
1380 }
1381
1382 static bool bios_parser_is_accelerated_mode(
1383         struct dc_bios *dcb)
1384 {
1385         return bios_is_accelerated_mode(dcb);
1386 }
1387
1388 /**
1389  * bios_parser_set_scratch_critical_state - update critical state bit
1390  *                                          in VBIOS scratch register
1391  *
1392  * @dcb:   pointer to the DC BIO
1393  * @state: set or reset state
1394  */
1395 static void bios_parser_set_scratch_critical_state(
1396         struct dc_bios *dcb,
1397         bool state)
1398 {
1399         bios_set_scratch_critical_state(dcb, state);
1400 }
1401
1402 static enum bp_result bios_parser_get_firmware_info(
1403         struct dc_bios *dcb,
1404         struct dc_firmware_info *info)
1405 {
1406         struct bios_parser *bp = BP_FROM_DCB(dcb);
1407         enum bp_result result = BP_RESULT_BADBIOSTABLE;
1408         struct atom_common_table_header *header;
1409
1410         struct atom_data_revision revision;
1411
1412         if (info && DATA_TABLES(firmwareinfo)) {
1413                 header = GET_IMAGE(struct atom_common_table_header,
1414                                 DATA_TABLES(firmwareinfo));
1415                 get_atom_data_table_revision(header, &revision);
1416                 switch (revision.major) {
1417                 case 3:
1418                         switch (revision.minor) {
1419                         case 1:
1420                                 result = get_firmware_info_v3_1(bp, info);
1421                                 break;
1422                         case 2:
1423                         case 3:
1424                         case 4:
1425                                 result = get_firmware_info_v3_2(bp, info);
1426                                 break;
1427                         default:
1428                                 break;
1429                         }
1430                         break;
1431                 default:
1432                         break;
1433                 }
1434         }
1435
1436         return result;
1437 }
1438
1439 static enum bp_result get_firmware_info_v3_1(
1440         struct bios_parser *bp,
1441         struct dc_firmware_info *info)
1442 {
1443         struct atom_firmware_info_v3_1 *firmware_info;
1444         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1445
1446         if (!info)
1447                 return BP_RESULT_BADINPUT;
1448
1449         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1450                         DATA_TABLES(firmwareinfo));
1451
1452         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1453                         DATA_TABLES(dce_info));
1454
1455         if (!firmware_info || !dce_info)
1456                 return BP_RESULT_BADBIOSTABLE;
1457
1458         memset(info, 0, sizeof(*info));
1459
1460         /* Pixel clock pll information. */
1461          /* We need to convert from 10KHz units into KHz units */
1462         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1463         info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1464
1465          /* 27MHz for Vega10: */
1466         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1467
1468         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1469         if (info->pll_info.crystal_frequency == 0)
1470                 info->pll_info.crystal_frequency = 27000;
1471         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1472         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1473         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1474
1475         /* Get GPU PLL VCO Clock */
1476
1477         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1478                 /* VBIOS gives in 10KHz */
1479                 info->smu_gpu_pll_output_freq =
1480                                 bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1481         }
1482
1483         info->oem_i2c_present = false;
1484
1485         return BP_RESULT_OK;
1486 }
1487
1488 static enum bp_result get_firmware_info_v3_2(
1489         struct bios_parser *bp,
1490         struct dc_firmware_info *info)
1491 {
1492         struct atom_firmware_info_v3_2 *firmware_info;
1493         struct atom_display_controller_info_v4_1 *dce_info = NULL;
1494         struct atom_common_table_header *header;
1495         struct atom_data_revision revision;
1496         struct atom_smu_info_v3_2 *smu_info_v3_2 = NULL;
1497         struct atom_smu_info_v3_3 *smu_info_v3_3 = NULL;
1498
1499         if (!info)
1500                 return BP_RESULT_BADINPUT;
1501
1502         firmware_info = GET_IMAGE(struct atom_firmware_info_v3_2,
1503                         DATA_TABLES(firmwareinfo));
1504
1505         dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1506                         DATA_TABLES(dce_info));
1507
1508         if (!firmware_info || !dce_info)
1509                 return BP_RESULT_BADBIOSTABLE;
1510
1511         memset(info, 0, sizeof(*info));
1512
1513         header = GET_IMAGE(struct atom_common_table_header,
1514                                         DATA_TABLES(smu_info));
1515         get_atom_data_table_revision(header, &revision);
1516
1517         if (revision.minor == 2) {
1518                 /* Vega12 */
1519                 smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2,
1520                                                         DATA_TABLES(smu_info));
1521
1522                 if (!smu_info_v3_2)
1523                         return BP_RESULT_BADBIOSTABLE;
1524
1525                 info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10;
1526         } else if (revision.minor == 3) {
1527                 /* Vega20 */
1528                 smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3,
1529                                                         DATA_TABLES(smu_info));
1530
1531                 if (!smu_info_v3_3)
1532                         return BP_RESULT_BADBIOSTABLE;
1533
1534                 info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10;
1535         }
1536
1537          // We need to convert from 10KHz units into KHz units.
1538         info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1539
1540          /* 27MHz for Vega10 & Vega12; 100MHz for Vega20 */
1541         info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1542         /* Hardcode frequency if BIOS gives no DCE Ref Clk */
1543         if (info->pll_info.crystal_frequency == 0) {
1544                 if (revision.minor == 2)
1545                         info->pll_info.crystal_frequency = 27000;
1546                 else if (revision.minor == 3)
1547                         info->pll_info.crystal_frequency = 100000;
1548         }
1549         /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1550         info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1551         info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1552
1553         /* Get GPU PLL VCO Clock */
1554         if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1555                 if (revision.minor == 2)
1556                         info->smu_gpu_pll_output_freq =
1557                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1558                 else if (revision.minor == 3)
1559                         info->smu_gpu_pll_output_freq =
1560                                         bp->cmd_tbl.get_smu_clock_info(bp, SMU11_SYSPLL3_0_ID) * 10;
1561         }
1562
1563         if (firmware_info->board_i2c_feature_id == 0x2) {
1564                 info->oem_i2c_present = true;
1565                 info->oem_i2c_obj_id = firmware_info->board_i2c_feature_gpio_id;
1566         } else {
1567                 info->oem_i2c_present = false;
1568         }
1569
1570         return BP_RESULT_OK;
1571 }
1572
1573 static enum bp_result bios_parser_get_encoder_cap_info(
1574         struct dc_bios *dcb,
1575         struct graphics_object_id object_id,
1576         struct bp_encoder_cap_info *info)
1577 {
1578         struct bios_parser *bp = BP_FROM_DCB(dcb);
1579         struct atom_display_object_path_v2 *object;
1580         struct atom_encoder_caps_record *record = NULL;
1581
1582         if (!info)
1583                 return BP_RESULT_BADINPUT;
1584
1585         object = get_bios_object(bp, object_id);
1586
1587         if (!object)
1588                 return BP_RESULT_BADINPUT;
1589
1590         record = get_encoder_cap_record(bp, object);
1591         if (!record)
1592                 return BP_RESULT_NORECORD;
1593
1594         info->DP_HBR2_CAP = (record->encodercaps &
1595                         ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
1596         info->DP_HBR2_EN = (record->encodercaps &
1597                         ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
1598         info->DP_HBR3_EN = (record->encodercaps &
1599                         ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
1600         info->HDMI_6GB_EN = (record->encodercaps &
1601                         ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
1602         info->DP_IS_USB_C = (record->encodercaps &
1603                         ATOM_ENCODER_CAP_RECORD_USB_C_TYPE) ? 1 : 0;
1604
1605         return BP_RESULT_OK;
1606 }
1607
1608
1609 static struct atom_encoder_caps_record *get_encoder_cap_record(
1610         struct bios_parser *bp,
1611         struct atom_display_object_path_v2 *object)
1612 {
1613         struct atom_common_record_header *header;
1614         uint32_t offset;
1615
1616         if (!object) {
1617                 BREAK_TO_DEBUGGER(); /* Invalid object */
1618                 return NULL;
1619         }
1620
1621         offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
1622
1623         for (;;) {
1624                 header = GET_IMAGE(struct atom_common_record_header, offset);
1625
1626                 if (!header)
1627                         return NULL;
1628
1629                 offset += header->record_size;
1630
1631                 if (header->record_type == LAST_RECORD_TYPE ||
1632                                 !header->record_size)
1633                         break;
1634
1635                 if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
1636                         continue;
1637
1638                 if (sizeof(struct atom_encoder_caps_record) <=
1639                                                         header->record_size)
1640                         return (struct atom_encoder_caps_record *)header;
1641         }
1642
1643         return NULL;
1644 }
1645
1646 static struct atom_disp_connector_caps_record *get_disp_connector_caps_record(
1647         struct bios_parser *bp,
1648         struct atom_display_object_path_v2 *object)
1649 {
1650         struct atom_common_record_header *header;
1651         uint32_t offset;
1652
1653         if (!object) {
1654                 BREAK_TO_DEBUGGER(); /* Invalid object */
1655                 return NULL;
1656         }
1657
1658         offset = object->disp_recordoffset + bp->object_info_tbl_offset;
1659
1660         for (;;) {
1661                 header = GET_IMAGE(struct atom_common_record_header, offset);
1662
1663                 if (!header)
1664                         return NULL;
1665
1666                 offset += header->record_size;
1667
1668                 if (header->record_type == LAST_RECORD_TYPE ||
1669                                 !header->record_size)
1670                         break;
1671
1672                 if (header->record_type != ATOM_DISP_CONNECTOR_CAPS_RECORD_TYPE)
1673                         continue;
1674
1675                 if (sizeof(struct atom_disp_connector_caps_record) <=
1676                                                         header->record_size)
1677                         return (struct atom_disp_connector_caps_record *)header;
1678         }
1679
1680         return NULL;
1681 }
1682
1683 static enum bp_result bios_parser_get_disp_connector_caps_info(
1684         struct dc_bios *dcb,
1685         struct graphics_object_id object_id,
1686         struct bp_disp_connector_caps_info *info)
1687 {
1688         struct bios_parser *bp = BP_FROM_DCB(dcb);
1689         struct atom_display_object_path_v2 *object;
1690         struct atom_disp_connector_caps_record *record = NULL;
1691
1692         if (!info)
1693                 return BP_RESULT_BADINPUT;
1694
1695         object = get_bios_object(bp, object_id);
1696
1697         if (!object)
1698                 return BP_RESULT_BADINPUT;
1699
1700         record = get_disp_connector_caps_record(bp, object);
1701         if (!record)
1702                 return BP_RESULT_NORECORD;
1703
1704         info->INTERNAL_DISPLAY = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY)
1705                                                                         ? 1 : 0;
1706         info->INTERNAL_DISPLAY_BL = (record->connectcaps & ATOM_CONNECTOR_CAP_INTERNAL_DISPLAY_BL)
1707                                                                                         ? 1 : 0;
1708
1709         return BP_RESULT_OK;
1710 }
1711
1712 static enum bp_result get_vram_info_v23(
1713         struct bios_parser *bp,
1714         struct dc_vram_info *info)
1715 {
1716         struct atom_vram_info_header_v2_3 *info_v23;
1717         enum bp_result result = BP_RESULT_OK;
1718
1719         info_v23 = GET_IMAGE(struct atom_vram_info_header_v2_3,
1720                                                 DATA_TABLES(vram_info));
1721
1722         if (info_v23 == NULL)
1723                 return BP_RESULT_BADBIOSTABLE;
1724
1725         info->num_chans = info_v23->vram_module[0].channel_num;
1726         info->dram_channel_width_bytes = (1 << info_v23->vram_module[0].channel_width) / 8;
1727
1728         return result;
1729 }
1730
1731 static enum bp_result get_vram_info_v24(
1732         struct bios_parser *bp,
1733         struct dc_vram_info *info)
1734 {
1735         struct atom_vram_info_header_v2_4 *info_v24;
1736         enum bp_result result = BP_RESULT_OK;
1737
1738         info_v24 = GET_IMAGE(struct atom_vram_info_header_v2_4,
1739                                                 DATA_TABLES(vram_info));
1740
1741         if (info_v24 == NULL)
1742                 return BP_RESULT_BADBIOSTABLE;
1743
1744         info->num_chans = info_v24->vram_module[0].channel_num;
1745         info->dram_channel_width_bytes = (1 << info_v24->vram_module[0].channel_width) / 8;
1746
1747         return result;
1748 }
1749
1750 static enum bp_result get_vram_info_v25(
1751         struct bios_parser *bp,
1752         struct dc_vram_info *info)
1753 {
1754         struct atom_vram_info_header_v2_5 *info_v25;
1755         enum bp_result result = BP_RESULT_OK;
1756
1757         info_v25 = GET_IMAGE(struct atom_vram_info_header_v2_5,
1758                                                 DATA_TABLES(vram_info));
1759
1760         if (info_v25 == NULL)
1761                 return BP_RESULT_BADBIOSTABLE;
1762
1763         info->num_chans = info_v25->vram_module[0].channel_num;
1764         info->dram_channel_width_bytes = (1 << info_v25->vram_module[0].channel_width) / 8;
1765
1766         return result;
1767 }
1768
1769 /*
1770  * get_integrated_info_v11
1771  *
1772  * @brief
1773  * Get V8 integrated BIOS information
1774  *
1775  * @param
1776  * bios_parser *bp - [in]BIOS parser handler to get master data table
1777  * integrated_info *info - [out] store and output integrated info
1778  *
1779  * @return
1780  * enum bp_result - BP_RESULT_OK if information is available,
1781  *                  BP_RESULT_BADBIOSTABLE otherwise.
1782  */
1783 static enum bp_result get_integrated_info_v11(
1784         struct bios_parser *bp,
1785         struct integrated_info *info)
1786 {
1787         struct atom_integrated_system_info_v1_11 *info_v11;
1788         uint32_t i;
1789
1790         info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
1791                                         DATA_TABLES(integratedsysteminfo));
1792
1793         if (info_v11 == NULL)
1794                 return BP_RESULT_BADBIOSTABLE;
1795
1796         info->gpu_cap_info =
1797         le32_to_cpu(info_v11->gpucapinfo);
1798         /*
1799         * system_config: Bit[0] = 0 : PCIE power gating disabled
1800         *                       = 1 : PCIE power gating enabled
1801         *                Bit[1] = 0 : DDR-PLL shut down disabled
1802         *                       = 1 : DDR-PLL shut down enabled
1803         *                Bit[2] = 0 : DDR-PLL power down disabled
1804         *                       = 1 : DDR-PLL power down enabled
1805         */
1806         info->system_config = le32_to_cpu(info_v11->system_config);
1807         info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
1808         info->memory_type = info_v11->memorytype;
1809         info->ma_channel_number = info_v11->umachannelnumber;
1810         info->lvds_ss_percentage =
1811         le16_to_cpu(info_v11->lvds_ss_percentage);
1812         info->dp_ss_control =
1813         le16_to_cpu(info_v11->reserved1);
1814         info->lvds_sspread_rate_in_10hz =
1815         le16_to_cpu(info_v11->lvds_ss_rate_10hz);
1816         info->hdmi_ss_percentage =
1817         le16_to_cpu(info_v11->hdmi_ss_percentage);
1818         info->hdmi_sspread_rate_in_10hz =
1819         le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
1820         info->dvi_ss_percentage =
1821         le16_to_cpu(info_v11->dvi_ss_percentage);
1822         info->dvi_sspread_rate_in_10_hz =
1823         le16_to_cpu(info_v11->dvi_ss_rate_10hz);
1824         info->lvds_misc = info_v11->lvds_misc;
1825         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
1826                 info->ext_disp_conn_info.gu_id[i] =
1827                                 info_v11->extdispconninfo.guid[i];
1828         }
1829
1830         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
1831                 info->ext_disp_conn_info.path[i].device_connector_id =
1832                 object_id_from_bios_object_id(
1833                 le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
1834
1835                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
1836                 object_id_from_bios_object_id(
1837                         le16_to_cpu(
1838                         info_v11->extdispconninfo.path[i].ext_encoder_objid));
1839
1840                 info->ext_disp_conn_info.path[i].device_tag =
1841                         le16_to_cpu(
1842                                 info_v11->extdispconninfo.path[i].device_tag);
1843                 info->ext_disp_conn_info.path[i].device_acpi_enum =
1844                 le16_to_cpu(
1845                         info_v11->extdispconninfo.path[i].device_acpi_enum);
1846                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
1847                         info_v11->extdispconninfo.path[i].auxddclut_index;
1848                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
1849                         info_v11->extdispconninfo.path[i].hpdlut_index;
1850                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
1851                         info_v11->extdispconninfo.path[i].channelmapping;
1852                 info->ext_disp_conn_info.path[i].caps =
1853                                 le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
1854         }
1855         info->ext_disp_conn_info.checksum =
1856         info_v11->extdispconninfo.checksum;
1857
1858         info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
1859         info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
1860         for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
1861                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
1862                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1863                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
1864                                 info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1865         }
1866         info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
1867         for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
1868                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1869                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1870                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1871                                 info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1872         }
1873
1874         info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
1875         info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
1876         for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
1877                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
1878                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1879                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
1880                                 info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1881         }
1882         info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
1883         for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
1884                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1885                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1886                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1887                                 info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1888         }
1889
1890         info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
1891         info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
1892         for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
1893                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
1894                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1895                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
1896                                 info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1897         }
1898         info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
1899         for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
1900                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1901                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1902                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1903                                 info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1904         }
1905
1906         info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
1907         info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
1908         for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
1909                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
1910                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1911                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
1912                                 info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1913         }
1914         info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
1915         for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
1916                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1917                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1918                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1919                                 info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1920         }
1921
1922
1923         /** TODO - review **/
1924         #if 0
1925         info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
1926                                                                         * 10;
1927         info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
1928         info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
1929
1930         for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1931                 /* Convert [10KHz] into [KHz] */
1932                 info->disp_clk_voltage[i].max_supported_clk =
1933                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
1934                         ulMaximumSupportedCLK) * 10;
1935                 info->disp_clk_voltage[i].voltage_index =
1936                 le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
1937         }
1938
1939         info->boot_up_req_display_vector =
1940                         le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
1941         info->boot_up_nb_voltage =
1942                         le16_to_cpu(info_v11->usBootUpNBVoltage);
1943         info->ext_disp_conn_info_offset =
1944                         le16_to_cpu(info_v11->usExtDispConnInfoOffset);
1945         info->gmc_restore_reset_time =
1946                         le32_to_cpu(info_v11->ulGMCRestoreResetTime);
1947         info->minimum_n_clk =
1948                         le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
1949         for (i = 1; i < 4; ++i)
1950                 info->minimum_n_clk =
1951                                 info->minimum_n_clk <
1952                                 le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
1953                                 info->minimum_n_clk : le32_to_cpu(
1954                                         info_v11->ulNbpStateNClkFreq[i]);
1955
1956         info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
1957         info->ddr_dll_power_up_time =
1958             le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
1959         info->ddr_pll_power_up_time =
1960                 le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
1961         info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
1962         info->max_lvds_pclk_freq_in_single_link =
1963                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1964         info->max_lvds_pclk_freq_in_single_link =
1965                 le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1966         info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
1967                 info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
1968         info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
1969                 info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
1970         info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
1971                 info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
1972         info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
1973                 info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
1974         info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
1975                 info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
1976         info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
1977                 info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
1978         info->lvds_off_to_on_delay_in_4ms =
1979                 info_v11->ucLVDSOffToOnDelay_in4Ms;
1980         info->lvds_bit_depth_control_val =
1981                 le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
1982
1983         for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
1984                 /* Convert [10KHz] into [KHz] */
1985                 info->avail_s_clk[i].supported_s_clk =
1986                         le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
1987                                                                         * 10;
1988                 info->avail_s_clk[i].voltage_index =
1989                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
1990                 info->avail_s_clk[i].voltage_id =
1991                         le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
1992         }
1993         #endif /* TODO*/
1994
1995         return BP_RESULT_OK;
1996 }
1997
1998 static enum bp_result get_integrated_info_v2_1(
1999         struct bios_parser *bp,
2000         struct integrated_info *info)
2001 {
2002         struct atom_integrated_system_info_v2_1 *info_v2_1;
2003         uint32_t i;
2004
2005         info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1,
2006                                         DATA_TABLES(integratedsysteminfo));
2007
2008         if (info_v2_1 == NULL)
2009                 return BP_RESULT_BADBIOSTABLE;
2010
2011         info->gpu_cap_info =
2012         le32_to_cpu(info_v2_1->gpucapinfo);
2013         /*
2014         * system_config: Bit[0] = 0 : PCIE power gating disabled
2015         *                       = 1 : PCIE power gating enabled
2016         *                Bit[1] = 0 : DDR-PLL shut down disabled
2017         *                       = 1 : DDR-PLL shut down enabled
2018         *                Bit[2] = 0 : DDR-PLL power down disabled
2019         *                       = 1 : DDR-PLL power down enabled
2020         */
2021         info->system_config = le32_to_cpu(info_v2_1->system_config);
2022         info->cpu_cap_info = le32_to_cpu(info_v2_1->cpucapinfo);
2023         info->memory_type = info_v2_1->memorytype;
2024         info->ma_channel_number = info_v2_1->umachannelnumber;
2025         info->dp_ss_control =
2026                 le16_to_cpu(info_v2_1->reserved1);
2027
2028         for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
2029                 info->ext_disp_conn_info.gu_id[i] =
2030                                 info_v2_1->extdispconninfo.guid[i];
2031         }
2032
2033         for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
2034                 info->ext_disp_conn_info.path[i].device_connector_id =
2035                 object_id_from_bios_object_id(
2036                 le16_to_cpu(info_v2_1->extdispconninfo.path[i].connectorobjid));
2037
2038                 info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
2039                 object_id_from_bios_object_id(
2040                         le16_to_cpu(
2041                         info_v2_1->extdispconninfo.path[i].ext_encoder_objid));
2042
2043                 info->ext_disp_conn_info.path[i].device_tag =
2044                         le16_to_cpu(
2045                                 info_v2_1->extdispconninfo.path[i].device_tag);
2046                 info->ext_disp_conn_info.path[i].device_acpi_enum =
2047                 le16_to_cpu(
2048                         info_v2_1->extdispconninfo.path[i].device_acpi_enum);
2049                 info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
2050                         info_v2_1->extdispconninfo.path[i].auxddclut_index;
2051                 info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
2052                         info_v2_1->extdispconninfo.path[i].hpdlut_index;
2053                 info->ext_disp_conn_info.path[i].channel_mapping.raw =
2054                         info_v2_1->extdispconninfo.path[i].channelmapping;
2055                 info->ext_disp_conn_info.path[i].caps =
2056                                 le16_to_cpu(info_v2_1->extdispconninfo.path[i].caps);
2057         }
2058
2059         info->ext_disp_conn_info.checksum =
2060                 info_v2_1->extdispconninfo.checksum;
2061         info->dp0_ext_hdmi_slv_addr = info_v2_1->dp0_retimer_set.HdmiSlvAddr;
2062         info->dp0_ext_hdmi_reg_num = info_v2_1->dp0_retimer_set.HdmiRegNum;
2063         for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
2064                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
2065                                 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2066                 info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
2067                                 info_v2_1->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2068         }
2069         info->dp0_ext_hdmi_6g_reg_num = info_v2_1->dp0_retimer_set.Hdmi6GRegNum;
2070         for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
2071                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2072                                 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2073                 info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2074                                 info_v2_1->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2075         }
2076         info->dp1_ext_hdmi_slv_addr = info_v2_1->dp1_retimer_set.HdmiSlvAddr;
2077         info->dp1_ext_hdmi_reg_num = info_v2_1->dp1_retimer_set.HdmiRegNum;
2078         for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
2079                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
2080                                 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2081                 info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
2082                                 info_v2_1->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2083         }
2084         info->dp1_ext_hdmi_6g_reg_num = info_v2_1->dp1_retimer_set.Hdmi6GRegNum;
2085         for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
2086                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2087                                 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2088                 info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2089                                 info_v2_1->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2090         }
2091         info->dp2_ext_hdmi_slv_addr = info_v2_1->dp2_retimer_set.HdmiSlvAddr;
2092         info->dp2_ext_hdmi_reg_num = info_v2_1->dp2_retimer_set.HdmiRegNum;
2093         for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
2094                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
2095                                 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2096                 info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
2097                                 info_v2_1->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2098         }
2099         info->dp2_ext_hdmi_6g_reg_num = info_v2_1->dp2_retimer_set.Hdmi6GRegNum;
2100         for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
2101                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2102                                 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2103                 info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2104                                 info_v2_1->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2105         }
2106         info->dp3_ext_hdmi_slv_addr = info_v2_1->dp3_retimer_set.HdmiSlvAddr;
2107         info->dp3_ext_hdmi_reg_num = info_v2_1->dp3_retimer_set.HdmiRegNum;
2108         for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
2109                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
2110                                 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
2111                 info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
2112                                 info_v2_1->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
2113         }
2114         info->dp3_ext_hdmi_6g_reg_num = info_v2_1->dp3_retimer_set.Hdmi6GRegNum;
2115         for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
2116                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
2117                                 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
2118                 info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
2119                                 info_v2_1->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
2120         }
2121
2122         info->edp1_info.edp_backlight_pwm_hz =
2123         le16_to_cpu(info_v2_1->edp1_info.edp_backlight_pwm_hz);
2124         info->edp1_info.edp_ss_percentage =
2125         le16_to_cpu(info_v2_1->edp1_info.edp_ss_percentage);
2126         info->edp1_info.edp_ss_rate_10hz =
2127         le16_to_cpu(info_v2_1->edp1_info.edp_ss_rate_10hz);
2128         info->edp1_info.edp_pwr_on_off_delay =
2129                 info_v2_1->edp1_info.edp_pwr_on_off_delay;
2130         info->edp1_info.edp_pwr_on_vary_bl_to_blon =
2131                 info_v2_1->edp1_info.edp_pwr_on_vary_bl_to_blon;
2132         info->edp1_info.edp_pwr_down_bloff_to_vary_bloff =
2133                 info_v2_1->edp1_info.edp_pwr_down_bloff_to_vary_bloff;
2134         info->edp1_info.edp_panel_bpc =
2135                 info_v2_1->edp1_info.edp_panel_bpc;
2136         info->edp1_info.edp_bootup_bl_level =
2137
2138         info->edp2_info.edp_backlight_pwm_hz =
2139         le16_to_cpu(info_v2_1->edp2_info.edp_backlight_pwm_hz);
2140         info->edp2_info.edp_ss_percentage =
2141         le16_to_cpu(info_v2_1->edp2_info.edp_ss_percentage);
2142         info->edp2_info.edp_ss_rate_10hz =
2143         le16_to_cpu(info_v2_1->edp2_info.edp_ss_rate_10hz);
2144         info->edp2_info.edp_pwr_on_off_delay =
2145                 info_v2_1->edp2_info.edp_pwr_on_off_delay;
2146         info->edp2_info.edp_pwr_on_vary_bl_to_blon =
2147                 info_v2_1->edp2_info.edp_pwr_on_vary_bl_to_blon;
2148         info->edp2_info.edp_pwr_down_bloff_to_vary_bloff =
2149                 info_v2_1->edp2_info.edp_pwr_down_bloff_to_vary_bloff;
2150         info->edp2_info.edp_panel_bpc =
2151                 info_v2_1->edp2_info.edp_panel_bpc;
2152         info->edp2_info.edp_bootup_bl_level =
2153                 info_v2_1->edp2_info.edp_bootup_bl_level;
2154
2155         return BP_RESULT_OK;
2156 }
2157
2158 /*
2159  * construct_integrated_info
2160  *
2161  * @brief
2162  * Get integrated BIOS information based on table revision
2163  *
2164  * @param
2165  * bios_parser *bp - [in]BIOS parser handler to get master data table
2166  * integrated_info *info - [out] store and output integrated info
2167  *
2168  * @return
2169  * enum bp_result - BP_RESULT_OK if information is available,
2170  *                  BP_RESULT_BADBIOSTABLE otherwise.
2171  */
2172 static enum bp_result construct_integrated_info(
2173         struct bios_parser *bp,
2174         struct integrated_info *info)
2175 {
2176         enum bp_result result = BP_RESULT_BADBIOSTABLE;
2177
2178         struct atom_common_table_header *header;
2179         struct atom_data_revision revision;
2180         uint32_t i;
2181         uint32_t j;
2182
2183         if (info && DATA_TABLES(integratedsysteminfo)) {
2184                 header = GET_IMAGE(struct atom_common_table_header,
2185                                         DATA_TABLES(integratedsysteminfo));
2186
2187                 get_atom_data_table_revision(header, &revision);
2188
2189                 switch (revision.major) {
2190                 case 1:
2191                         switch (revision.minor) {
2192                         case 11:
2193                         case 12:
2194                                 result = get_integrated_info_v11(bp, info);
2195                                 break;
2196                         default:
2197                                 return result;
2198                         }
2199                         break;
2200                 case 2:
2201                         switch (revision.minor) {
2202                         case 1:
2203                                 result = get_integrated_info_v2_1(bp, info);
2204                                 break;
2205                         default:
2206                                 return result;
2207                         }
2208                         break;
2209                 default:
2210                         return result;
2211                 }
2212         }
2213
2214         if (result != BP_RESULT_OK)
2215                 return result;
2216
2217         /* Sort voltage table from low to high*/
2218         for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
2219                 for (j = i; j > 0; --j) {
2220                         if (info->disp_clk_voltage[j].max_supported_clk <
2221                                 info->disp_clk_voltage[j-1].max_supported_clk
2222                                 ) {
2223                                 /* swap j and j - 1*/
2224                                 swap(info->disp_clk_voltage[j - 1],
2225                                      info->disp_clk_voltage[j]);
2226                         }
2227                 }
2228         }
2229
2230         return result;
2231 }
2232
2233 static enum bp_result bios_parser_get_vram_info(
2234                 struct dc_bios *dcb,
2235                 struct dc_vram_info *info)
2236 {
2237         struct bios_parser *bp = BP_FROM_DCB(dcb);
2238         enum bp_result result = BP_RESULT_BADBIOSTABLE;
2239         struct atom_common_table_header *header;
2240         struct atom_data_revision revision;
2241
2242         if (info && DATA_TABLES(vram_info)) {
2243                 header = GET_IMAGE(struct atom_common_table_header,
2244                                         DATA_TABLES(vram_info));
2245
2246                 get_atom_data_table_revision(header, &revision);
2247
2248                 switch (revision.major) {
2249                 case 2:
2250                         switch (revision.minor) {
2251                         case 3:
2252                                 result = get_vram_info_v23(bp, info);
2253                                 break;
2254                         case 4:
2255                                 result = get_vram_info_v24(bp, info);
2256                                 break;
2257                         case 5:
2258                                 result = get_vram_info_v25(bp, info);
2259                                 break;
2260                         default:
2261                                 break;
2262                         }
2263                         break;
2264
2265                 default:
2266                         return result;
2267                 }
2268
2269         }
2270         return result;
2271 }
2272
2273 static struct integrated_info *bios_parser_create_integrated_info(
2274         struct dc_bios *dcb)
2275 {
2276         struct bios_parser *bp = BP_FROM_DCB(dcb);
2277         struct integrated_info *info = NULL;
2278
2279         info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
2280
2281         if (info == NULL) {
2282                 ASSERT_CRITICAL(0);
2283                 return NULL;
2284         }
2285
2286         if (construct_integrated_info(bp, info) == BP_RESULT_OK)
2287                 return info;
2288
2289         kfree(info);
2290
2291         return NULL;
2292 }
2293
2294 static enum bp_result update_slot_layout_info(
2295         struct dc_bios *dcb,
2296         unsigned int i,
2297         struct slot_layout_info *slot_layout_info)
2298 {
2299         unsigned int record_offset;
2300         unsigned int j;
2301         struct atom_display_object_path_v2 *object;
2302         struct atom_bracket_layout_record *record;
2303         struct atom_common_record_header *record_header;
2304         enum bp_result result;
2305         struct bios_parser *bp;
2306         struct object_info_table *tbl;
2307         struct display_object_info_table_v1_4 *v1_4;
2308
2309         record = NULL;
2310         record_header = NULL;
2311         result = BP_RESULT_NORECORD;
2312
2313         bp = BP_FROM_DCB(dcb);
2314         tbl = &bp->object_info_tbl;
2315         v1_4 = tbl->v1_4;
2316
2317         object = &v1_4->display_path[i];
2318         record_offset = (unsigned int)
2319                 (object->disp_recordoffset) +
2320                 (unsigned int)(bp->object_info_tbl_offset);
2321
2322         for (;;) {
2323
2324                 record_header = (struct atom_common_record_header *)
2325                         GET_IMAGE(struct atom_common_record_header,
2326                         record_offset);
2327                 if (record_header == NULL) {
2328                         result = BP_RESULT_BADBIOSTABLE;
2329                         break;
2330                 }
2331
2332                 /* the end of the list */
2333                 if (record_header->record_type == 0xff ||
2334                         record_header->record_size == 0)        {
2335                         break;
2336                 }
2337
2338                 if (record_header->record_type ==
2339                         ATOM_BRACKET_LAYOUT_RECORD_TYPE &&
2340                         sizeof(struct atom_bracket_layout_record)
2341                         <= record_header->record_size) {
2342                         record = (struct atom_bracket_layout_record *)
2343                                 (record_header);
2344                         result = BP_RESULT_OK;
2345                         break;
2346                 }
2347
2348                 record_offset += record_header->record_size;
2349         }
2350
2351         /* return if the record not found */
2352         if (result != BP_RESULT_OK)
2353                 return result;
2354
2355         /* get slot sizes */
2356         slot_layout_info->length = record->bracketlen;
2357         slot_layout_info->width = record->bracketwidth;
2358
2359         /* get info for each connector in the slot */
2360         slot_layout_info->num_of_connectors = record->conn_num;
2361         for (j = 0; j < slot_layout_info->num_of_connectors; ++j) {
2362                 slot_layout_info->connectors[j].connector_type =
2363                         (enum connector_layout_type)
2364                         (record->conn_info[j].connector_type);
2365                 switch (record->conn_info[j].connector_type) {
2366                 case CONNECTOR_TYPE_DVI_D:
2367                         slot_layout_info->connectors[j].connector_type =
2368                                 CONNECTOR_LAYOUT_TYPE_DVI_D;
2369                         slot_layout_info->connectors[j].length =
2370                                 CONNECTOR_SIZE_DVI;
2371                         break;
2372
2373                 case CONNECTOR_TYPE_HDMI:
2374                         slot_layout_info->connectors[j].connector_type =
2375                                 CONNECTOR_LAYOUT_TYPE_HDMI;
2376                         slot_layout_info->connectors[j].length =
2377                                 CONNECTOR_SIZE_HDMI;
2378                         break;
2379
2380                 case CONNECTOR_TYPE_DISPLAY_PORT:
2381                         slot_layout_info->connectors[j].connector_type =
2382                                 CONNECTOR_LAYOUT_TYPE_DP;
2383                         slot_layout_info->connectors[j].length =
2384                                 CONNECTOR_SIZE_DP;
2385                         break;
2386
2387                 case CONNECTOR_TYPE_MINI_DISPLAY_PORT:
2388                         slot_layout_info->connectors[j].connector_type =
2389                                 CONNECTOR_LAYOUT_TYPE_MINI_DP;
2390                         slot_layout_info->connectors[j].length =
2391                                 CONNECTOR_SIZE_MINI_DP;
2392                         break;
2393
2394                 default:
2395                         slot_layout_info->connectors[j].connector_type =
2396                                 CONNECTOR_LAYOUT_TYPE_UNKNOWN;
2397                         slot_layout_info->connectors[j].length =
2398                                 CONNECTOR_SIZE_UNKNOWN;
2399                 }
2400
2401                 slot_layout_info->connectors[j].position =
2402                         record->conn_info[j].position;
2403                 slot_layout_info->connectors[j].connector_id =
2404                         object_id_from_bios_object_id(
2405                                 record->conn_info[j].connectorobjid);
2406         }
2407         return result;
2408 }
2409
2410
2411 static enum bp_result get_bracket_layout_record(
2412         struct dc_bios *dcb,
2413         unsigned int bracket_layout_id,
2414         struct slot_layout_info *slot_layout_info)
2415 {
2416         unsigned int i;
2417         struct bios_parser *bp = BP_FROM_DCB(dcb);
2418         enum bp_result result;
2419         struct object_info_table *tbl;
2420         struct display_object_info_table_v1_4 *v1_4;
2421
2422         if (slot_layout_info == NULL) {
2423                 DC_LOG_DETECTION_EDID_PARSER("Invalid slot_layout_info\n");
2424                 return BP_RESULT_BADINPUT;
2425         }
2426         tbl = &bp->object_info_tbl;
2427         v1_4 = tbl->v1_4;
2428
2429         result = BP_RESULT_NORECORD;
2430         for (i = 0; i < v1_4->number_of_path; ++i)      {
2431
2432                 if (bracket_layout_id ==
2433                         v1_4->display_path[i].display_objid) {
2434                         result = update_slot_layout_info(dcb, i,
2435                                 slot_layout_info);
2436                         break;
2437                 }
2438         }
2439         return result;
2440 }
2441
2442 static enum bp_result bios_get_board_layout_info(
2443         struct dc_bios *dcb,
2444         struct board_layout_info *board_layout_info)
2445 {
2446         unsigned int i;
2447         enum bp_result record_result;
2448
2449         const unsigned int slot_index_to_vbios_id[MAX_BOARD_SLOTS] = {
2450                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID1,
2451                 GENERICOBJECT_BRACKET_LAYOUT_ENUM_ID2,
2452                 0, 0
2453         };
2454
2455         if (board_layout_info == NULL) {
2456                 DC_LOG_DETECTION_EDID_PARSER("Invalid board_layout_info\n");
2457                 return BP_RESULT_BADINPUT;
2458         }
2459
2460         board_layout_info->num_of_slots = 0;
2461
2462         for (i = 0; i < MAX_BOARD_SLOTS; ++i) {
2463                 record_result = get_bracket_layout_record(dcb,
2464                         slot_index_to_vbios_id[i],
2465                         &board_layout_info->slots[i]);
2466
2467                 if (record_result == BP_RESULT_NORECORD && i > 0)
2468                         break; /* no more slots present in bios */
2469                 else if (record_result != BP_RESULT_OK)
2470                         return record_result;  /* fail */
2471
2472                 ++board_layout_info->num_of_slots;
2473         }
2474
2475         /* all data is valid */
2476         board_layout_info->is_number_of_slots_valid = 1;
2477         board_layout_info->is_slots_size_valid = 1;
2478         board_layout_info->is_connector_offsets_valid = 1;
2479         board_layout_info->is_connector_lengths_valid = 1;
2480
2481         return BP_RESULT_OK;
2482 }
2483
2484
2485 static uint16_t bios_parser_pack_data_tables(
2486         struct dc_bios *dcb,
2487         void *dst)
2488 {
2489 #ifdef PACK_BIOS_DATA
2490         struct bios_parser *bp = BP_FROM_DCB(dcb);
2491         struct atom_rom_header_v2_2 *rom_header = NULL;
2492         struct atom_rom_header_v2_2 *packed_rom_header = NULL;
2493         struct atom_common_table_header *data_tbl_header = NULL;
2494         struct atom_master_list_of_data_tables_v2_1 *data_tbl_list = NULL;
2495         struct atom_master_data_table_v2_1 *packed_master_data_tbl = NULL;
2496         struct atom_data_revision tbl_rev = {0};
2497         uint16_t *rom_header_offset = NULL;
2498         const uint8_t *bios = bp->base.bios;
2499         uint8_t *bios_dst = (uint8_t *)dst;
2500         uint16_t packed_rom_header_offset;
2501         uint16_t packed_masterdatatable_offset;
2502         uint16_t packed_data_tbl_offset;
2503         uint16_t data_tbl_offset;
2504         unsigned int i;
2505
2506         rom_header_offset =
2507                 GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2508
2509         if (!rom_header_offset)
2510                 return 0;
2511
2512         rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
2513
2514         if (!rom_header)
2515                 return 0;
2516
2517         get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
2518         if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
2519                 return 0;
2520
2521         get_atom_data_table_revision(&bp->master_data_tbl->table_header, &tbl_rev);
2522         if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 1))
2523                 return 0;
2524
2525         packed_rom_header_offset =
2526                 OFFSET_TO_ATOM_ROM_HEADER_POINTER + sizeof(*rom_header_offset);
2527
2528         packed_masterdatatable_offset =
2529                 packed_rom_header_offset + rom_header->table_header.structuresize;
2530
2531         packed_data_tbl_offset =
2532                 packed_masterdatatable_offset +
2533                 bp->master_data_tbl->table_header.structuresize;
2534
2535         packed_rom_header =
2536                 (struct atom_rom_header_v2_2 *)(bios_dst + packed_rom_header_offset);
2537
2538         packed_master_data_tbl =
2539                 (struct atom_master_data_table_v2_1 *)(bios_dst +
2540                 packed_masterdatatable_offset);
2541
2542         memcpy(bios_dst, bios, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2543
2544         *((uint16_t *)(bios_dst + OFFSET_TO_ATOM_ROM_HEADER_POINTER)) =
2545                 packed_rom_header_offset;
2546
2547         memcpy(bios_dst + packed_rom_header_offset, rom_header,
2548                 rom_header->table_header.structuresize);
2549
2550         packed_rom_header->masterdatatable_offset = packed_masterdatatable_offset;
2551
2552         memcpy(&packed_master_data_tbl->table_header,
2553                 &bp->master_data_tbl->table_header,
2554                 sizeof(bp->master_data_tbl->table_header));
2555
2556         data_tbl_list = &bp->master_data_tbl->listOfdatatables;
2557
2558         /* Each data table offset in data table list is 2 bytes,
2559          * we can use that to iterate through listOfdatatables
2560          * without knowing the name of each member.
2561          */
2562         for (i = 0; i < sizeof(*data_tbl_list)/sizeof(uint16_t); i++) {
2563                 data_tbl_offset = *((uint16_t *)data_tbl_list + i);
2564
2565                 if (data_tbl_offset) {
2566                         data_tbl_header =
2567                                 (struct atom_common_table_header *)(bios + data_tbl_offset);
2568
2569                         memcpy(bios_dst + packed_data_tbl_offset, data_tbl_header,
2570                                 data_tbl_header->structuresize);
2571
2572                         *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) =
2573                                 packed_data_tbl_offset;
2574
2575                         packed_data_tbl_offset += data_tbl_header->structuresize;
2576                 } else {
2577                         *((uint16_t *)&packed_master_data_tbl->listOfdatatables + i) = 0;
2578                 }
2579         }
2580         return packed_data_tbl_offset;
2581 #endif
2582         // TODO: There is data bytes alignment issue, disable it for now.
2583         return 0;
2584 }
2585
2586 static struct atom_dc_golden_table_v1 *bios_get_golden_table(
2587                 struct bios_parser *bp,
2588                 uint32_t rev_major,
2589                 uint32_t rev_minor,
2590                 uint16_t *dc_golden_table_ver)
2591 {
2592         struct atom_display_controller_info_v4_4 *disp_cntl_tbl_4_4 = NULL;
2593         uint32_t dc_golden_offset = 0;
2594         *dc_golden_table_ver = 0;
2595
2596         if (!DATA_TABLES(dce_info))
2597                 return NULL;
2598
2599         /* ver.4.4 or higher */
2600         switch (rev_major) {
2601         case 4:
2602                 switch (rev_minor) {
2603                 case 4:
2604                         disp_cntl_tbl_4_4 = GET_IMAGE(struct atom_display_controller_info_v4_4,
2605                                                                         DATA_TABLES(dce_info));
2606                         if (!disp_cntl_tbl_4_4)
2607                                 return NULL;
2608                         dc_golden_offset = DATA_TABLES(dce_info) + disp_cntl_tbl_4_4->dc_golden_table_offset;
2609                         *dc_golden_table_ver = disp_cntl_tbl_4_4->dc_golden_table_ver;
2610                         break;
2611                 }
2612                 break;
2613         }
2614
2615         if (!dc_golden_offset)
2616                 return NULL;
2617
2618         if (*dc_golden_table_ver != 1)
2619                 return NULL;
2620
2621         return GET_IMAGE(struct atom_dc_golden_table_v1,
2622                         dc_golden_offset);
2623 }
2624
2625 static enum bp_result bios_get_atom_dc_golden_table(
2626         struct dc_bios *dcb)
2627 {
2628         struct bios_parser *bp = BP_FROM_DCB(dcb);
2629         enum bp_result result = BP_RESULT_OK;
2630         struct atom_dc_golden_table_v1 *atom_dc_golden_table = NULL;
2631         struct atom_common_table_header *header;
2632         struct atom_data_revision tbl_revision;
2633         uint16_t dc_golden_table_ver = 0;
2634
2635         header = GET_IMAGE(struct atom_common_table_header,
2636                                                         DATA_TABLES(dce_info));
2637         if (!header)
2638                 return BP_RESULT_UNSUPPORTED;
2639
2640         get_atom_data_table_revision(header, &tbl_revision);
2641
2642         atom_dc_golden_table = bios_get_golden_table(bp,
2643                         tbl_revision.major,
2644                         tbl_revision.minor,
2645                         &dc_golden_table_ver);
2646
2647         if (!atom_dc_golden_table)
2648                 return BP_RESULT_UNSUPPORTED;
2649
2650         dcb->golden_table.dc_golden_table_ver = dc_golden_table_ver;
2651         dcb->golden_table.aux_dphy_rx_control0_val = atom_dc_golden_table->aux_dphy_rx_control0_val;
2652         dcb->golden_table.aux_dphy_rx_control1_val = atom_dc_golden_table->aux_dphy_rx_control1_val;
2653         dcb->golden_table.aux_dphy_tx_control_val = atom_dc_golden_table->aux_dphy_tx_control_val;
2654         dcb->golden_table.dc_gpio_aux_ctrl_0_val = atom_dc_golden_table->dc_gpio_aux_ctrl_0_val;
2655         dcb->golden_table.dc_gpio_aux_ctrl_1_val = atom_dc_golden_table->dc_gpio_aux_ctrl_1_val;
2656         dcb->golden_table.dc_gpio_aux_ctrl_2_val = atom_dc_golden_table->dc_gpio_aux_ctrl_2_val;
2657         dcb->golden_table.dc_gpio_aux_ctrl_3_val = atom_dc_golden_table->dc_gpio_aux_ctrl_3_val;
2658         dcb->golden_table.dc_gpio_aux_ctrl_4_val = atom_dc_golden_table->dc_gpio_aux_ctrl_4_val;
2659         dcb->golden_table.dc_gpio_aux_ctrl_5_val = atom_dc_golden_table->dc_gpio_aux_ctrl_5_val;
2660
2661         return result;
2662 }
2663
2664
2665 static const struct dc_vbios_funcs vbios_funcs = {
2666         .get_connectors_number = bios_parser_get_connectors_number,
2667
2668         .get_connector_id = bios_parser_get_connector_id,
2669
2670         .get_src_obj = bios_parser_get_src_obj,
2671
2672         .get_i2c_info = bios_parser_get_i2c_info,
2673
2674         .get_hpd_info = bios_parser_get_hpd_info,
2675
2676         .get_device_tag = bios_parser_get_device_tag,
2677
2678         .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
2679
2680         .get_ss_entry_number = bios_parser_get_ss_entry_number,
2681
2682         .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
2683
2684         .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
2685
2686         .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
2687
2688         .is_device_id_supported = bios_parser_is_device_id_supported,
2689
2690         .is_accelerated_mode = bios_parser_is_accelerated_mode,
2691
2692         .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
2693
2694
2695 /*       COMMANDS */
2696         .encoder_control = bios_parser_encoder_control,
2697
2698         .transmitter_control = bios_parser_transmitter_control,
2699
2700         .enable_crtc = bios_parser_enable_crtc,
2701
2702         .set_pixel_clock = bios_parser_set_pixel_clock,
2703
2704         .set_dce_clock = bios_parser_set_dce_clock,
2705
2706         .program_crtc_timing = bios_parser_program_crtc_timing,
2707
2708         .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
2709
2710         .bios_parser_destroy = firmware_parser_destroy,
2711
2712         .get_board_layout_info = bios_get_board_layout_info,
2713         .pack_data_tables = bios_parser_pack_data_tables,
2714
2715         .get_atom_dc_golden_table = bios_get_atom_dc_golden_table,
2716
2717         .enable_lvtma_control = bios_parser_enable_lvtma_control,
2718
2719         .get_soc_bb_info = bios_parser_get_soc_bb_info,
2720
2721         .get_disp_connector_caps_info = bios_parser_get_disp_connector_caps_info,
2722
2723         .get_lttpr_caps = bios_parser_get_lttpr_caps,
2724
2725         .get_lttpr_interop = bios_parser_get_lttpr_interop,
2726 };
2727
2728 static bool bios_parser2_construct(
2729         struct bios_parser *bp,
2730         struct bp_init_data *init,
2731         enum dce_version dce_version)
2732 {
2733         uint16_t *rom_header_offset = NULL;
2734         struct atom_rom_header_v2_2 *rom_header = NULL;
2735         struct display_object_info_table_v1_4 *object_info_tbl;
2736         struct atom_data_revision tbl_rev = {0};
2737
2738         if (!init)
2739                 return false;
2740
2741         if (!init->bios)
2742                 return false;
2743
2744         bp->base.funcs = &vbios_funcs;
2745         bp->base.bios = init->bios;
2746         bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
2747
2748         bp->base.ctx = init->ctx;
2749
2750         bp->base.bios_local_image = NULL;
2751
2752         rom_header_offset =
2753                         GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
2754
2755         if (!rom_header_offset)
2756                 return false;
2757
2758         rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
2759
2760         if (!rom_header)
2761                 return false;
2762
2763         get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
2764         if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
2765                 return false;
2766
2767         bp->master_data_tbl =
2768                 GET_IMAGE(struct atom_master_data_table_v2_1,
2769                                 rom_header->masterdatatable_offset);
2770
2771         if (!bp->master_data_tbl)
2772                 return false;
2773
2774         bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
2775
2776         if (!bp->object_info_tbl_offset)
2777                 return false;
2778
2779         object_info_tbl =
2780                         GET_IMAGE(struct display_object_info_table_v1_4,
2781                                                 bp->object_info_tbl_offset);
2782
2783         if (!object_info_tbl)
2784                 return false;
2785
2786         get_atom_data_table_revision(&object_info_tbl->table_header,
2787                 &bp->object_info_tbl.revision);
2788
2789         if (bp->object_info_tbl.revision.major == 1
2790                 && bp->object_info_tbl.revision.minor >= 4) {
2791                 struct display_object_info_table_v1_4 *tbl_v1_4;
2792
2793                 tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
2794                         bp->object_info_tbl_offset);
2795                 if (!tbl_v1_4)
2796                         return false;
2797
2798                 bp->object_info_tbl.v1_4 = tbl_v1_4;
2799         } else
2800                 return false;
2801
2802         dal_firmware_parser_init_cmd_tbl(bp);
2803         dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
2804
2805         bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
2806         bp->base.fw_info_valid = bios_parser_get_firmware_info(&bp->base, &bp->base.fw_info) == BP_RESULT_OK;
2807         bios_parser_get_vram_info(&bp->base, &bp->base.vram_info);
2808
2809         return true;
2810 }
2811
2812 struct dc_bios *firmware_parser_create(
2813         struct bp_init_data *init,
2814         enum dce_version dce_version)
2815 {
2816         struct bios_parser *bp = NULL;
2817
2818         bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
2819         if (!bp)
2820                 return NULL;
2821
2822         if (bios_parser2_construct(bp, init, dce_version))
2823                 return &bp->base;
2824
2825         kfree(bp);
2826         return NULL;
2827 }
2828
2829