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 			case 2:
1325 				result = get_firmware_info_v3_1(bp, info);
1326 				break;
1327 			default:
1328 				break;
1329 			}
1330 			break;
1331 		default:
1332 			break;
1333 		}
1334 	}
1335 
1336 	return result;
1337 }
1338 
1339 static enum bp_result get_firmware_info_v3_1(
1340 	struct bios_parser *bp,
1341 	struct dc_firmware_info *info)
1342 {
1343 	struct atom_firmware_info_v3_1 *firmware_info;
1344 	struct atom_display_controller_info_v4_1 *dce_info = NULL;
1345 
1346 	if (!info)
1347 		return BP_RESULT_BADINPUT;
1348 
1349 	firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
1350 			DATA_TABLES(firmwareinfo));
1351 
1352 	dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
1353 			DATA_TABLES(dce_info));
1354 
1355 	if (!firmware_info || !dce_info)
1356 		return BP_RESULT_BADBIOSTABLE;
1357 
1358 	memset(info, 0, sizeof(*info));
1359 
1360 	/* Pixel clock pll information. */
1361 	 /* We need to convert from 10KHz units into KHz units */
1362 	info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
1363 	info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
1364 
1365 	 /* 27MHz for Vega10: */
1366 	info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
1367 
1368 	/* Hardcode frequency if BIOS gives no DCE Ref Clk */
1369 	if (info->pll_info.crystal_frequency == 0)
1370 		info->pll_info.crystal_frequency = 27000;
1371 	/*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
1372 	info->dp_phy_ref_clk     = dce_info->dpphy_refclk_10khz * 10;
1373 	info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
1374 
1375 	/* Get GPU PLL VCO Clock */
1376 
1377 	if (bp->cmd_tbl.get_smu_clock_info != NULL) {
1378 		/* VBIOS gives in 10KHz */
1379 		info->smu_gpu_pll_output_freq =
1380 				bp->cmd_tbl.get_smu_clock_info(bp, SMU9_SYSPLL0_ID) * 10;
1381 	}
1382 
1383 	return BP_RESULT_OK;
1384 }
1385 
1386 static enum bp_result bios_parser_get_encoder_cap_info(
1387 	struct dc_bios *dcb,
1388 	struct graphics_object_id object_id,
1389 	struct bp_encoder_cap_info *info)
1390 {
1391 	struct bios_parser *bp = BP_FROM_DCB(dcb);
1392 	struct atom_display_object_path_v2 *object;
1393 	struct atom_encoder_caps_record *record = NULL;
1394 
1395 	if (!info)
1396 		return BP_RESULT_BADINPUT;
1397 
1398 	object = get_bios_object(bp, object_id);
1399 
1400 	if (!object)
1401 		return BP_RESULT_BADINPUT;
1402 
1403 	record = get_encoder_cap_record(bp, object);
1404 	if (!record)
1405 		return BP_RESULT_NORECORD;
1406 
1407 	info->DP_HBR2_CAP = (record->encodercaps &
1408 			ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
1409 	info->DP_HBR2_EN = (record->encodercaps &
1410 			ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
1411 	info->DP_HBR3_EN = (record->encodercaps &
1412 			ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
1413 	info->HDMI_6GB_EN = (record->encodercaps &
1414 			ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
1415 
1416 	return BP_RESULT_OK;
1417 }
1418 
1419 
1420 static struct atom_encoder_caps_record *get_encoder_cap_record(
1421 	struct bios_parser *bp,
1422 	struct atom_display_object_path_v2 *object)
1423 {
1424 	struct atom_common_record_header *header;
1425 	uint32_t offset;
1426 
1427 	if (!object) {
1428 		BREAK_TO_DEBUGGER(); /* Invalid object */
1429 		return NULL;
1430 	}
1431 
1432 	offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
1433 
1434 	for (;;) {
1435 		header = GET_IMAGE(struct atom_common_record_header, offset);
1436 
1437 		if (!header)
1438 			return NULL;
1439 
1440 		offset += header->record_size;
1441 
1442 		if (header->record_type == LAST_RECORD_TYPE ||
1443 				!header->record_size)
1444 			break;
1445 
1446 		if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
1447 			continue;
1448 
1449 		if (sizeof(struct atom_encoder_caps_record) <=
1450 							header->record_size)
1451 			return (struct atom_encoder_caps_record *)header;
1452 	}
1453 
1454 	return NULL;
1455 }
1456 
1457 /*
1458  * get_integrated_info_v11
1459  *
1460  * @brief
1461  * Get V8 integrated BIOS information
1462  *
1463  * @param
1464  * bios_parser *bp - [in]BIOS parser handler to get master data table
1465  * integrated_info *info - [out] store and output integrated info
1466  *
1467  * @return
1468  * enum bp_result - BP_RESULT_OK if information is available,
1469  *                  BP_RESULT_BADBIOSTABLE otherwise.
1470  */
1471 static enum bp_result get_integrated_info_v11(
1472 	struct bios_parser *bp,
1473 	struct integrated_info *info)
1474 {
1475 	struct atom_integrated_system_info_v1_11 *info_v11;
1476 	uint32_t i;
1477 
1478 	info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
1479 					DATA_TABLES(integratedsysteminfo));
1480 
1481 	if (info_v11 == NULL)
1482 		return BP_RESULT_BADBIOSTABLE;
1483 
1484 	info->gpu_cap_info =
1485 	le32_to_cpu(info_v11->gpucapinfo);
1486 	/*
1487 	* system_config: Bit[0] = 0 : PCIE power gating disabled
1488 	*                       = 1 : PCIE power gating enabled
1489 	*                Bit[1] = 0 : DDR-PLL shut down disabled
1490 	*                       = 1 : DDR-PLL shut down enabled
1491 	*                Bit[2] = 0 : DDR-PLL power down disabled
1492 	*                       = 1 : DDR-PLL power down enabled
1493 	*/
1494 	info->system_config = le32_to_cpu(info_v11->system_config);
1495 	info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
1496 	info->memory_type = info_v11->memorytype;
1497 	info->ma_channel_number = info_v11->umachannelnumber;
1498 	info->lvds_ss_percentage =
1499 	le16_to_cpu(info_v11->lvds_ss_percentage);
1500 	info->lvds_sspread_rate_in_10hz =
1501 	le16_to_cpu(info_v11->lvds_ss_rate_10hz);
1502 	info->hdmi_ss_percentage =
1503 	le16_to_cpu(info_v11->hdmi_ss_percentage);
1504 	info->hdmi_sspread_rate_in_10hz =
1505 	le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
1506 	info->dvi_ss_percentage =
1507 	le16_to_cpu(info_v11->dvi_ss_percentage);
1508 	info->dvi_sspread_rate_in_10_hz =
1509 	le16_to_cpu(info_v11->dvi_ss_rate_10hz);
1510 	info->lvds_misc = info_v11->lvds_misc;
1511 	for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
1512 		info->ext_disp_conn_info.gu_id[i] =
1513 				info_v11->extdispconninfo.guid[i];
1514 	}
1515 
1516 	for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
1517 		info->ext_disp_conn_info.path[i].device_connector_id =
1518 		object_id_from_bios_object_id(
1519 		le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
1520 
1521 		info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
1522 		object_id_from_bios_object_id(
1523 			le16_to_cpu(
1524 			info_v11->extdispconninfo.path[i].ext_encoder_objid));
1525 
1526 		info->ext_disp_conn_info.path[i].device_tag =
1527 			le16_to_cpu(
1528 				info_v11->extdispconninfo.path[i].device_tag);
1529 		info->ext_disp_conn_info.path[i].device_acpi_enum =
1530 		le16_to_cpu(
1531 			info_v11->extdispconninfo.path[i].device_acpi_enum);
1532 		info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
1533 			info_v11->extdispconninfo.path[i].auxddclut_index;
1534 		info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
1535 			info_v11->extdispconninfo.path[i].hpdlut_index;
1536 		info->ext_disp_conn_info.path[i].channel_mapping.raw =
1537 			info_v11->extdispconninfo.path[i].channelmapping;
1538 		info->ext_disp_conn_info.path[i].caps =
1539 				le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
1540 	}
1541 	info->ext_disp_conn_info.checksum =
1542 	info_v11->extdispconninfo.checksum;
1543 
1544 	info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
1545 	info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
1546 	for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
1547 		info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
1548 				info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1549 		info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
1550 				info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1551 	}
1552 	info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
1553 	for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
1554 		info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1555 				info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1556 		info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1557 				info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1558 	}
1559 
1560 	info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
1561 	info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
1562 	for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
1563 		info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
1564 				info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1565 		info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
1566 				info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1567 	}
1568 	info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
1569 	for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
1570 		info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1571 				info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1572 		info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1573 				info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1574 	}
1575 
1576 	info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
1577 	info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
1578 	for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
1579 		info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
1580 				info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1581 		info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
1582 				info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1583 	}
1584 	info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
1585 	for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
1586 		info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1587 				info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1588 		info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1589 				info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1590 	}
1591 
1592 	info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
1593 	info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
1594 	for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
1595 		info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
1596 				info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
1597 		info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
1598 				info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
1599 	}
1600 	info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
1601 	for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
1602 		info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
1603 				info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
1604 		info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
1605 				info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
1606 	}
1607 
1608 
1609 	/** TODO - review **/
1610 	#if 0
1611 	info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
1612 									* 10;
1613 	info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
1614 	info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
1615 
1616 	for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1617 		/* Convert [10KHz] into [KHz] */
1618 		info->disp_clk_voltage[i].max_supported_clk =
1619 		le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
1620 			ulMaximumSupportedCLK) * 10;
1621 		info->disp_clk_voltage[i].voltage_index =
1622 		le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
1623 	}
1624 
1625 	info->boot_up_req_display_vector =
1626 			le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
1627 	info->boot_up_nb_voltage =
1628 			le16_to_cpu(info_v11->usBootUpNBVoltage);
1629 	info->ext_disp_conn_info_offset =
1630 			le16_to_cpu(info_v11->usExtDispConnInfoOffset);
1631 	info->gmc_restore_reset_time =
1632 			le32_to_cpu(info_v11->ulGMCRestoreResetTime);
1633 	info->minimum_n_clk =
1634 			le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
1635 	for (i = 1; i < 4; ++i)
1636 		info->minimum_n_clk =
1637 				info->minimum_n_clk <
1638 				le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
1639 				info->minimum_n_clk : le32_to_cpu(
1640 					info_v11->ulNbpStateNClkFreq[i]);
1641 
1642 	info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
1643 	info->ddr_dll_power_up_time =
1644 	    le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
1645 	info->ddr_pll_power_up_time =
1646 		le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
1647 	info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
1648 	info->max_lvds_pclk_freq_in_single_link =
1649 		le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1650 	info->max_lvds_pclk_freq_in_single_link =
1651 		le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
1652 	info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
1653 		info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
1654 	info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
1655 		info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
1656 	info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
1657 		info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
1658 	info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
1659 		info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
1660 	info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
1661 		info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
1662 	info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
1663 		info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
1664 	info->lvds_off_to_on_delay_in_4ms =
1665 		info_v11->ucLVDSOffToOnDelay_in4Ms;
1666 	info->lvds_bit_depth_control_val =
1667 		le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
1668 
1669 	for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
1670 		/* Convert [10KHz] into [KHz] */
1671 		info->avail_s_clk[i].supported_s_clk =
1672 			le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
1673 									* 10;
1674 		info->avail_s_clk[i].voltage_index =
1675 			le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
1676 		info->avail_s_clk[i].voltage_id =
1677 			le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
1678 	}
1679 	#endif /* TODO*/
1680 
1681 	return BP_RESULT_OK;
1682 }
1683 
1684 
1685 /*
1686  * construct_integrated_info
1687  *
1688  * @brief
1689  * Get integrated BIOS information based on table revision
1690  *
1691  * @param
1692  * bios_parser *bp - [in]BIOS parser handler to get master data table
1693  * integrated_info *info - [out] store and output integrated info
1694  *
1695  * @return
1696  * enum bp_result - BP_RESULT_OK if information is available,
1697  *                  BP_RESULT_BADBIOSTABLE otherwise.
1698  */
1699 static enum bp_result construct_integrated_info(
1700 	struct bios_parser *bp,
1701 	struct integrated_info *info)
1702 {
1703 	enum bp_result result = BP_RESULT_BADBIOSTABLE;
1704 
1705 	struct atom_common_table_header *header;
1706 	struct atom_data_revision revision;
1707 
1708 	struct clock_voltage_caps temp = {0, 0};
1709 	uint32_t i;
1710 	uint32_t j;
1711 
1712 	if (info && DATA_TABLES(integratedsysteminfo)) {
1713 		header = GET_IMAGE(struct atom_common_table_header,
1714 					DATA_TABLES(integratedsysteminfo));
1715 
1716 		get_atom_data_table_revision(header, &revision);
1717 
1718 		/* Don't need to check major revision as they are all 1 */
1719 		switch (revision.minor) {
1720 		case 11:
1721 			result = get_integrated_info_v11(bp, info);
1722 			break;
1723 		default:
1724 			return result;
1725 		}
1726 	}
1727 
1728 	if (result != BP_RESULT_OK)
1729 		return result;
1730 
1731 	/* Sort voltage table from low to high*/
1732 	for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
1733 		for (j = i; j > 0; --j) {
1734 			if (info->disp_clk_voltage[j].max_supported_clk <
1735 				info->disp_clk_voltage[j-1].max_supported_clk
1736 				) {
1737 				/* swap j and j - 1*/
1738 				temp = info->disp_clk_voltage[j-1];
1739 				info->disp_clk_voltage[j-1] =
1740 					info->disp_clk_voltage[j];
1741 				info->disp_clk_voltage[j] = temp;
1742 			}
1743 		}
1744 	}
1745 
1746 	return result;
1747 }
1748 
1749 static struct integrated_info *bios_parser_create_integrated_info(
1750 	struct dc_bios *dcb)
1751 {
1752 	struct bios_parser *bp = BP_FROM_DCB(dcb);
1753 	struct integrated_info *info = NULL;
1754 
1755 	info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
1756 
1757 	if (info == NULL) {
1758 		ASSERT_CRITICAL(0);
1759 		return NULL;
1760 	}
1761 
1762 	if (construct_integrated_info(bp, info) == BP_RESULT_OK)
1763 		return info;
1764 
1765 	kfree(info);
1766 
1767 	return NULL;
1768 }
1769 
1770 static const struct dc_vbios_funcs vbios_funcs = {
1771 	.get_connectors_number = bios_parser_get_connectors_number,
1772 
1773 	.get_encoder_id = bios_parser_get_encoder_id,
1774 
1775 	.get_connector_id = bios_parser_get_connector_id,
1776 
1777 	.get_dst_number = bios_parser_get_dst_number,
1778 
1779 	.get_src_obj = bios_parser_get_src_obj,
1780 
1781 	.get_dst_obj = bios_parser_get_dst_obj,
1782 
1783 	.get_i2c_info = bios_parser_get_i2c_info,
1784 
1785 	.get_voltage_ddc_info = bios_parser_get_voltage_ddc_info,
1786 
1787 	.get_thermal_ddc_info = bios_parser_get_thermal_ddc_info,
1788 
1789 	.get_hpd_info = bios_parser_get_hpd_info,
1790 
1791 	.get_device_tag = bios_parser_get_device_tag,
1792 
1793 	.get_firmware_info = bios_parser_get_firmware_info,
1794 
1795 	.get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
1796 
1797 	.get_ss_entry_number = bios_parser_get_ss_entry_number,
1798 
1799 	.get_embedded_panel_info = bios_parser_get_embedded_panel_info,
1800 
1801 	.get_gpio_pin_info = bios_parser_get_gpio_pin_info,
1802 
1803 	.get_encoder_cap_info = bios_parser_get_encoder_cap_info,
1804 
1805 	.is_device_id_supported = bios_parser_is_device_id_supported,
1806 
1807 
1808 
1809 	.is_accelerated_mode = bios_parser_is_accelerated_mode,
1810 	.get_vga_enabled_displays = bios_parser_get_vga_enabled_displays,
1811 
1812 	.set_scratch_critical_state = bios_parser_set_scratch_critical_state,
1813 
1814 
1815 /*	 COMMANDS */
1816 	.encoder_control = bios_parser_encoder_control,
1817 
1818 	.transmitter_control = bios_parser_transmitter_control,
1819 
1820 	.enable_crtc = bios_parser_enable_crtc,
1821 
1822 	.set_pixel_clock = bios_parser_set_pixel_clock,
1823 
1824 	.set_dce_clock = bios_parser_set_dce_clock,
1825 
1826 	.program_crtc_timing = bios_parser_program_crtc_timing,
1827 
1828 	/* .blank_crtc = bios_parser_blank_crtc, */
1829 
1830 	.crtc_source_select = bios_parser_crtc_source_select,
1831 
1832 	/* .external_encoder_control = bios_parser_external_encoder_control, */
1833 
1834 	.enable_disp_power_gating = bios_parser_enable_disp_power_gating,
1835 
1836 	.post_init = bios_parser_post_init,
1837 
1838 	.bios_parser_destroy = firmware_parser_destroy,
1839 
1840 	.get_smu_clock_info = bios_parser_get_smu_clock_info,
1841 };
1842 
1843 static bool bios_parser_construct(
1844 	struct bios_parser *bp,
1845 	struct bp_init_data *init,
1846 	enum dce_version dce_version)
1847 {
1848 	uint16_t *rom_header_offset = NULL;
1849 	struct atom_rom_header_v2_2 *rom_header = NULL;
1850 	struct display_object_info_table_v1_4 *object_info_tbl;
1851 	struct atom_data_revision tbl_rev = {0};
1852 
1853 	if (!init)
1854 		return false;
1855 
1856 	if (!init->bios)
1857 		return false;
1858 
1859 	bp->base.funcs = &vbios_funcs;
1860 	bp->base.bios = init->bios;
1861 	bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
1862 
1863 	bp->base.ctx = init->ctx;
1864 
1865 	bp->base.bios_local_image = NULL;
1866 
1867 	rom_header_offset =
1868 			GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
1869 
1870 	if (!rom_header_offset)
1871 		return false;
1872 
1873 	rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
1874 
1875 	if (!rom_header)
1876 		return false;
1877 
1878 	get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
1879 	if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
1880 		return false;
1881 
1882 	bp->master_data_tbl =
1883 		GET_IMAGE(struct atom_master_data_table_v2_1,
1884 				rom_header->masterdatatable_offset);
1885 
1886 	if (!bp->master_data_tbl)
1887 		return false;
1888 
1889 	bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
1890 
1891 	if (!bp->object_info_tbl_offset)
1892 		return false;
1893 
1894 	object_info_tbl =
1895 			GET_IMAGE(struct display_object_info_table_v1_4,
1896 						bp->object_info_tbl_offset);
1897 
1898 	if (!object_info_tbl)
1899 		return false;
1900 
1901 	get_atom_data_table_revision(&object_info_tbl->table_header,
1902 		&bp->object_info_tbl.revision);
1903 
1904 	if (bp->object_info_tbl.revision.major == 1
1905 		&& bp->object_info_tbl.revision.minor >= 4) {
1906 		struct display_object_info_table_v1_4 *tbl_v1_4;
1907 
1908 		tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
1909 			bp->object_info_tbl_offset);
1910 		if (!tbl_v1_4)
1911 			return false;
1912 
1913 		bp->object_info_tbl.v1_4 = tbl_v1_4;
1914 	} else
1915 		return false;
1916 
1917 	dal_firmware_parser_init_cmd_tbl(bp);
1918 	dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
1919 
1920 	bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
1921 
1922 	return true;
1923 }
1924 
1925 struct dc_bios *firmware_parser_create(
1926 	struct bp_init_data *init,
1927 	enum dce_version dce_version)
1928 {
1929 	struct bios_parser *bp = NULL;
1930 
1931 	bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
1932 	if (!bp)
1933 		return NULL;
1934 
1935 	if (bios_parser_construct(bp, init, dce_version))
1936 		return &bp->base;
1937 
1938 	kfree(bp);
1939 	return NULL;
1940 }
1941 
1942 
1943