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