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