Bug Summary

File:dev/pci/drm/amd/display/dc/bios/bios_parser2.c
Warning:line 278, column 4
Value stored to 'bp_result' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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