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