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