1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include "dm_services.h"
27 
28 #include "atom.h"
29 
30 #include "include/bios_parser_interface.h"
31 
32 #include "command_table.h"
33 #include "command_table_helper.h"
34 #include "bios_parser_helper.h"
35 #include "bios_parser_types_internal.h"
36 
37 #define EXEC_BIOS_CMD_TABLE(command, params)\
38 	(cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
39 		GetIndexIntoMasterTable(COMMAND, command), \
40 		&params) == 0)
41 
42 #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
43 	cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
44 		GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
45 
46 #define BIOS_CMD_TABLE_PARA_REVISION(command)\
47 	bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
48 		GetIndexIntoMasterTable(COMMAND, command))
49 
50 static void init_dig_encoder_control(struct bios_parser *bp);
51 static void init_transmitter_control(struct bios_parser *bp);
52 static void init_set_pixel_clock(struct bios_parser *bp);
53 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
54 static void init_adjust_display_pll(struct bios_parser *bp);
55 static void init_dac_encoder_control(struct bios_parser *bp);
56 static void init_dac_output_control(struct bios_parser *bp);
57 static void init_set_crtc_timing(struct bios_parser *bp);
58 static void init_select_crtc_source(struct bios_parser *bp);
59 static void init_enable_crtc(struct bios_parser *bp);
60 static void init_enable_crtc_mem_req(struct bios_parser *bp);
61 static void init_external_encoder_control(struct bios_parser *bp);
62 static void init_enable_disp_power_gating(struct bios_parser *bp);
63 static void init_program_clock(struct bios_parser *bp);
64 static void init_set_dce_clock(struct bios_parser *bp);
65 
66 void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
67 {
68 	init_dig_encoder_control(bp);
69 	init_transmitter_control(bp);
70 	init_set_pixel_clock(bp);
71 	init_enable_spread_spectrum_on_ppll(bp);
72 	init_adjust_display_pll(bp);
73 	init_dac_encoder_control(bp);
74 	init_dac_output_control(bp);
75 	init_set_crtc_timing(bp);
76 	init_select_crtc_source(bp);
77 	init_enable_crtc(bp);
78 	init_enable_crtc_mem_req(bp);
79 	init_program_clock(bp);
80 	init_external_encoder_control(bp);
81 	init_enable_disp_power_gating(bp);
82 	init_set_dce_clock(bp);
83 }
84 
85 static uint32_t bios_cmd_table_para_revision(void *cgs_device,
86 					     uint32_t index)
87 {
88 	uint8_t frev, crev;
89 
90 	if (cgs_atom_get_cmd_table_revs(cgs_device,
91 					index,
92 					&frev, &crev) != 0)
93 		return 0;
94 	return crev;
95 }
96 
97 /*******************************************************************************
98  ********************************************************************************
99  **
100  **                  D I G E N C O D E R C O N T R O L
101  **
102  ********************************************************************************
103  *******************************************************************************/
104 static enum bp_result encoder_control_digx_v3(
105 	struct bios_parser *bp,
106 	struct bp_encoder_control *cntl);
107 
108 static enum bp_result encoder_control_digx_v4(
109 	struct bios_parser *bp,
110 	struct bp_encoder_control *cntl);
111 
112 static enum bp_result encoder_control_digx_v5(
113 	struct bios_parser *bp,
114 	struct bp_encoder_control *cntl);
115 
116 static void init_encoder_control_dig_v1(struct bios_parser *bp);
117 
118 static void init_dig_encoder_control(struct bios_parser *bp)
119 {
120 	uint32_t version =
121 		BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
122 
123 	switch (version) {
124 	case 2:
125 		bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
126 		break;
127 	case 4:
128 		bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
129 		break;
130 
131 	case 5:
132 		bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
133 		break;
134 
135 	default:
136 		init_encoder_control_dig_v1(bp);
137 		break;
138 	}
139 }
140 
141 static enum bp_result encoder_control_dig_v1(
142 	struct bios_parser *bp,
143 	struct bp_encoder_control *cntl);
144 static enum bp_result encoder_control_dig1_v1(
145 	struct bios_parser *bp,
146 	struct bp_encoder_control *cntl);
147 static enum bp_result encoder_control_dig2_v1(
148 	struct bios_parser *bp,
149 	struct bp_encoder_control *cntl);
150 
151 static void init_encoder_control_dig_v1(struct bios_parser *bp)
152 {
153 	struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
154 
155 	if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
156 		cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
157 	else
158 		cmd_tbl->encoder_control_dig1 = NULL;
159 
160 	if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
161 		cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
162 	else
163 		cmd_tbl->encoder_control_dig2 = NULL;
164 
165 	cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
166 }
167 
168 static enum bp_result encoder_control_dig_v1(
169 	struct bios_parser *bp,
170 	struct bp_encoder_control *cntl)
171 {
172 	enum bp_result result = BP_RESULT_FAILURE;
173 	struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
174 
175 	if (cntl != NULL)
176 		switch (cntl->engine_id) {
177 		case ENGINE_ID_DIGA:
178 			if (cmd_tbl->encoder_control_dig1 != NULL)
179 				result =
180 					cmd_tbl->encoder_control_dig1(bp, cntl);
181 			break;
182 		case ENGINE_ID_DIGB:
183 			if (cmd_tbl->encoder_control_dig2 != NULL)
184 				result =
185 					cmd_tbl->encoder_control_dig2(bp, cntl);
186 			break;
187 
188 		default:
189 			break;
190 		}
191 
192 	return result;
193 }
194 
195 static enum bp_result encoder_control_dig1_v1(
196 	struct bios_parser *bp,
197 	struct bp_encoder_control *cntl)
198 {
199 	enum bp_result result = BP_RESULT_FAILURE;
200 	DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
201 
202 	bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
203 
204 	if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
205 		result = BP_RESULT_OK;
206 
207 	return result;
208 }
209 
210 static enum bp_result encoder_control_dig2_v1(
211 	struct bios_parser *bp,
212 	struct bp_encoder_control *cntl)
213 {
214 	enum bp_result result = BP_RESULT_FAILURE;
215 	DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
216 
217 	bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
218 
219 	if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
220 		result = BP_RESULT_OK;
221 
222 	return result;
223 }
224 
225 static enum bp_result encoder_control_digx_v3(
226 	struct bios_parser *bp,
227 	struct bp_encoder_control *cntl)
228 {
229 	enum bp_result result = BP_RESULT_FAILURE;
230 	DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
231 
232 	if (LANE_COUNT_FOUR < cntl->lanes_number)
233 		params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
234 	else
235 		params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
236 
237 	params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
238 
239 	/* We need to convert from KHz units into 10KHz units */
240 	params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
241 	params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
242 	params.ucEncoderMode =
243 			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
244 					cntl->signal,
245 					cntl->enable_dp_audio);
246 	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
247 
248 	if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
249 		result = BP_RESULT_OK;
250 
251 	return result;
252 }
253 
254 static enum bp_result encoder_control_digx_v4(
255 	struct bios_parser *bp,
256 	struct bp_encoder_control *cntl)
257 {
258 	enum bp_result result = BP_RESULT_FAILURE;
259 	DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
260 
261 	if (LANE_COUNT_FOUR < cntl->lanes_number)
262 		params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
263 	else
264 		params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
265 
266 	params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
267 
268 	/* We need to convert from KHz units into 10KHz units */
269 	params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
270 	params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
271 	params.ucEncoderMode =
272 			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
273 					cntl->signal,
274 					cntl->enable_dp_audio));
275 	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
276 
277 	if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
278 		result = BP_RESULT_OK;
279 
280 	return result;
281 }
282 
283 static enum bp_result encoder_control_digx_v5(
284 	struct bios_parser *bp,
285 	struct bp_encoder_control *cntl)
286 {
287 	enum bp_result result = BP_RESULT_FAILURE;
288 	ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
289 
290 	params.ucDigId = (uint8_t)(cntl->engine_id);
291 	params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
292 
293 	params.ulPixelClock = cntl->pixel_clock / 10;
294 	params.ucDigMode =
295 			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
296 					cntl->signal,
297 					cntl->enable_dp_audio));
298 	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
299 
300 	switch (cntl->color_depth) {
301 	case COLOR_DEPTH_888:
302 		params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
303 		break;
304 	case COLOR_DEPTH_101010:
305 		params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
306 		break;
307 	case COLOR_DEPTH_121212:
308 		params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
309 		break;
310 	case COLOR_DEPTH_161616:
311 		params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
312 		break;
313 	default:
314 		break;
315 	}
316 
317 	if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
318 		switch (cntl->color_depth) {
319 		case COLOR_DEPTH_101010:
320 			params.ulPixelClock =
321 				(params.ulPixelClock * 30) / 24;
322 			break;
323 		case COLOR_DEPTH_121212:
324 			params.ulPixelClock =
325 				(params.ulPixelClock * 36) / 24;
326 			break;
327 		case COLOR_DEPTH_161616:
328 			params.ulPixelClock =
329 				(params.ulPixelClock * 48) / 24;
330 			break;
331 		default:
332 			break;
333 		}
334 
335 	if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
336 		result = BP_RESULT_OK;
337 
338 	return result;
339 }
340 
341 /*******************************************************************************
342  ********************************************************************************
343  **
344  **                  TRANSMITTER CONTROL
345  **
346  ********************************************************************************
347  *******************************************************************************/
348 
349 static enum bp_result transmitter_control_v2(
350 	struct bios_parser *bp,
351 	struct bp_transmitter_control *cntl);
352 static enum bp_result transmitter_control_v3(
353 	struct bios_parser *bp,
354 	struct bp_transmitter_control *cntl);
355 static enum bp_result transmitter_control_v4(
356 	struct bios_parser *bp,
357 	struct bp_transmitter_control *cntl);
358 static enum bp_result transmitter_control_v1_5(
359 	struct bios_parser *bp,
360 	struct bp_transmitter_control *cntl);
361 static enum bp_result transmitter_control_v1_6(
362 	struct bios_parser *bp,
363 	struct bp_transmitter_control *cntl);
364 
365 static void init_transmitter_control(struct bios_parser *bp)
366 {
367 	uint8_t frev;
368 	uint8_t crev;
369 
370 	if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
371 			frev, crev) != 0)
372 		BREAK_TO_DEBUGGER();
373 	switch (crev) {
374 	case 2:
375 		bp->cmd_tbl.transmitter_control = transmitter_control_v2;
376 		break;
377 	case 3:
378 		bp->cmd_tbl.transmitter_control = transmitter_control_v3;
379 		break;
380 	case 4:
381 		bp->cmd_tbl.transmitter_control = transmitter_control_v4;
382 		break;
383 	case 5:
384 		bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
385 		break;
386 	case 6:
387 		bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
388 		break;
389 	default:
390 		bp->cmd_tbl.transmitter_control = NULL;
391 		break;
392 	}
393 }
394 
395 static enum bp_result transmitter_control_v2(
396 	struct bios_parser *bp,
397 	struct bp_transmitter_control *cntl)
398 {
399 	enum bp_result result = BP_RESULT_FAILURE;
400 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
401 	enum connector_id connector_id =
402 		dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
403 
404 	memset(&params, 0, sizeof(params));
405 
406 	switch (cntl->transmitter) {
407 	case TRANSMITTER_UNIPHY_A:
408 	case TRANSMITTER_UNIPHY_B:
409 	case TRANSMITTER_UNIPHY_C:
410 	case TRANSMITTER_UNIPHY_D:
411 	case TRANSMITTER_UNIPHY_E:
412 	case TRANSMITTER_UNIPHY_F:
413 	case TRANSMITTER_TRAVIS_LCD:
414 		break;
415 	default:
416 		return BP_RESULT_BADINPUT;
417 	}
418 
419 	switch (cntl->action) {
420 	case TRANSMITTER_CONTROL_INIT:
421 		if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
422 				(CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
423 			/* on INIT this bit should be set according to the
424 			 * phisycal connector
425 			 * Bit0: dual link connector flag
426 			 * =0 connector is single link connector
427 			 * =1 connector is dual link connector
428 			 */
429 			params.acConfig.fDualLinkConnector = 1;
430 
431 		/* connector object id */
432 		params.usInitInfo =
433 				cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
434 		break;
435 	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
436 		/* votage swing and pre-emphsis */
437 		params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
438 		params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
439 		break;
440 	default:
441 		/* if dual-link */
442 		if (LANE_COUNT_FOUR < cntl->lanes_number) {
443 			/* on ENABLE/DISABLE this bit should be set according to
444 			 * actual timing (number of lanes)
445 			 * Bit0: dual link connector flag
446 			 * =0 connector is single link connector
447 			 * =1 connector is dual link connector
448 			 */
449 			params.acConfig.fDualLinkConnector = 1;
450 
451 			/* link rate, half for dual link
452 			 * We need to convert from KHz units into 20KHz units
453 			 */
454 			params.usPixelClock =
455 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
456 		} else
457 			/* link rate, half for dual link
458 			 * We need to convert from KHz units into 10KHz units
459 			 */
460 			params.usPixelClock =
461 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
462 		break;
463 	}
464 
465 	/* 00 - coherent mode
466 	 * 01 - incoherent mode
467 	 */
468 
469 	params.acConfig.fCoherentMode = cntl->coherent;
470 
471 	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
472 			|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
473 			|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
474 		/* Bit2: Transmitter Link selection
475 		 * =0 when bit0=0, single link A/C/E, when bit0=1,
476 		 * master link A/C/E
477 		 * =1 when bit0=0, single link B/D/F, when bit0=1,
478 		 * master link B/D/F
479 		 */
480 		params.acConfig.ucLinkSel = 1;
481 
482 	if (ENGINE_ID_DIGB == cntl->engine_id)
483 		/* Bit3: Transmitter data source selection
484 		 * =0 DIGA is data source.
485 		 * =1 DIGB is data source.
486 		 * This bit is only useful when ucAction= ATOM_ENABLE
487 		 */
488 		params.acConfig.ucEncoderSel = 1;
489 
490 	if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
491 		/* Bit4: DP connector flag
492 		 * =0 connector is none-DP connector
493 		 * =1 connector is DP connector
494 		 */
495 		params.acConfig.fDPConnector = 1;
496 
497 	/* Bit[7:6]: Transmitter selection
498 	 * =0 UNIPHY_ENCODER: UNIPHYA/B
499 	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
500 	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
501 	 * =3 reserved
502 	 */
503 	params.acConfig.ucTransmitterSel =
504 			(uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
505 					cntl->transmitter);
506 
507 	params.ucAction = (uint8_t)cntl->action;
508 
509 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
510 		result = BP_RESULT_OK;
511 
512 	return result;
513 }
514 
515 static enum bp_result transmitter_control_v3(
516 	struct bios_parser *bp,
517 	struct bp_transmitter_control *cntl)
518 {
519 	enum bp_result result = BP_RESULT_FAILURE;
520 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
521 	uint32_t pll_id;
522 	enum connector_id conn_id =
523 			dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
524 	const struct command_table_helper *cmd = bp->cmd_helper;
525 	bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
526 					|| (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
527 
528 	memset(&params, 0, sizeof(params));
529 
530 	switch (cntl->transmitter) {
531 	case TRANSMITTER_UNIPHY_A:
532 	case TRANSMITTER_UNIPHY_B:
533 	case TRANSMITTER_UNIPHY_C:
534 	case TRANSMITTER_UNIPHY_D:
535 	case TRANSMITTER_UNIPHY_E:
536 	case TRANSMITTER_UNIPHY_F:
537 	case TRANSMITTER_TRAVIS_LCD:
538 		break;
539 	default:
540 		return BP_RESULT_BADINPUT;
541 	}
542 
543 	if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
544 		return BP_RESULT_BADINPUT;
545 
546 	/* fill information based on the action */
547 	switch (cntl->action) {
548 	case TRANSMITTER_CONTROL_INIT:
549 		if (dual_link_conn) {
550 			/* on INIT this bit should be set according to the
551 			 * phisycal connector
552 			 * Bit0: dual link connector flag
553 			 * =0 connector is single link connector
554 			 * =1 connector is dual link connector
555 			 */
556 			params.acConfig.fDualLinkConnector = 1;
557 		}
558 
559 		/* connector object id */
560 		params.usInitInfo =
561 				cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
562 		break;
563 	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
564 		/* votage swing and pre-emphsis */
565 		params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
566 		params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
567 		break;
568 	default:
569 		if (dual_link_conn && cntl->multi_path)
570 			/* on ENABLE/DISABLE this bit should be set according to
571 			 * actual timing (number of lanes)
572 			 * Bit0: dual link connector flag
573 			 * =0 connector is single link connector
574 			 * =1 connector is dual link connector
575 			 */
576 			params.acConfig.fDualLinkConnector = 1;
577 
578 		/* if dual-link */
579 		if (LANE_COUNT_FOUR < cntl->lanes_number) {
580 			/* on ENABLE/DISABLE this bit should be set according to
581 			 * actual timing (number of lanes)
582 			 * Bit0: dual link connector flag
583 			 * =0 connector is single link connector
584 			 * =1 connector is dual link connector
585 			 */
586 			params.acConfig.fDualLinkConnector = 1;
587 
588 			/* link rate, half for dual link
589 			 * We need to convert from KHz units into 20KHz units
590 			 */
591 			params.usPixelClock =
592 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
593 		} else {
594 			/* link rate, half for dual link
595 			 * We need to convert from KHz units into 10KHz units
596 			 */
597 			params.usPixelClock =
598 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
599 		}
600 		break;
601 	}
602 
603 	/* 00 - coherent mode
604 	 * 01 - incoherent mode
605 	 */
606 
607 	params.acConfig.fCoherentMode = cntl->coherent;
608 
609 	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
610 		|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
611 		|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
612 		/* Bit2: Transmitter Link selection
613 		 * =0 when bit0=0, single link A/C/E, when bit0=1,
614 		 * master link A/C/E
615 		 * =1 when bit0=0, single link B/D/F, when bit0=1,
616 		 * master link B/D/F
617 		 */
618 		params.acConfig.ucLinkSel = 1;
619 
620 	if (ENGINE_ID_DIGB == cntl->engine_id)
621 		/* Bit3: Transmitter data source selection
622 		 * =0 DIGA is data source.
623 		 * =1 DIGB is data source.
624 		 * This bit is only useful when ucAction= ATOM_ENABLE
625 		 */
626 		params.acConfig.ucEncoderSel = 1;
627 
628 	/* Bit[7:6]: Transmitter selection
629 	 * =0 UNIPHY_ENCODER: UNIPHYA/B
630 	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
631 	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
632 	 * =3 reserved
633 	 */
634 	params.acConfig.ucTransmitterSel =
635 			(uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
636 
637 	params.ucLaneNum = (uint8_t)cntl->lanes_number;
638 
639 	params.acConfig.ucRefClkSource = (uint8_t)pll_id;
640 
641 	params.ucAction = (uint8_t)cntl->action;
642 
643 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
644 		result = BP_RESULT_OK;
645 
646 	return result;
647 }
648 
649 static enum bp_result transmitter_control_v4(
650 	struct bios_parser *bp,
651 	struct bp_transmitter_control *cntl)
652 {
653 	enum bp_result result = BP_RESULT_FAILURE;
654 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
655 	uint32_t ref_clk_src_id;
656 	enum connector_id conn_id =
657 			dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
658 	const struct command_table_helper *cmd = bp->cmd_helper;
659 
660 	memset(&params, 0, sizeof(params));
661 
662 	switch (cntl->transmitter) {
663 	case TRANSMITTER_UNIPHY_A:
664 	case TRANSMITTER_UNIPHY_B:
665 	case TRANSMITTER_UNIPHY_C:
666 	case TRANSMITTER_UNIPHY_D:
667 	case TRANSMITTER_UNIPHY_E:
668 	case TRANSMITTER_UNIPHY_F:
669 	case TRANSMITTER_TRAVIS_LCD:
670 		break;
671 	default:
672 		return BP_RESULT_BADINPUT;
673 	}
674 
675 	if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
676 		return BP_RESULT_BADINPUT;
677 
678 	switch (cntl->action) {
679 	case TRANSMITTER_CONTROL_INIT:
680 	{
681 		if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
682 				(CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
683 			/* on INIT this bit should be set according to the
684 			 * phisycal connector
685 			 * Bit0: dual link connector flag
686 			 * =0 connector is single link connector
687 			 * =1 connector is dual link connector
688 			 */
689 			params.acConfig.fDualLinkConnector = 1;
690 
691 		/* connector object id */
692 		params.usInitInfo =
693 				cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
694 	}
695 	break;
696 	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
697 		/* votage swing and pre-emphsis */
698 		params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
699 		params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
700 		break;
701 	default:
702 		if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
703 				(CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
704 			/* on ENABLE/DISABLE this bit should be set according to
705 			 * actual timing (number of lanes)
706 			 * Bit0: dual link connector flag
707 			 * =0 connector is single link connector
708 			 * =1 connector is dual link connector
709 			 */
710 			params.acConfig.fDualLinkConnector = 1;
711 
712 		/* if dual-link */
713 		if (LANE_COUNT_FOUR < cntl->lanes_number)
714 			/* link rate, half for dual link
715 			 * We need to convert from KHz units into 20KHz units
716 			 */
717 			params.usPixelClock =
718 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
719 		else {
720 			/* link rate, half for dual link
721 			 * We need to convert from KHz units into 10KHz units
722 			 */
723 			params.usPixelClock =
724 					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
725 		}
726 		break;
727 	}
728 
729 	/* 00 - coherent mode
730 	 * 01 - incoherent mode
731 	 */
732 
733 	params.acConfig.fCoherentMode = cntl->coherent;
734 
735 	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
736 		|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
737 		|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
738 		/* Bit2: Transmitter Link selection
739 		 * =0 when bit0=0, single link A/C/E, when bit0=1,
740 		 * master link A/C/E
741 		 * =1 when bit0=0, single link B/D/F, when bit0=1,
742 		 * master link B/D/F
743 		 */
744 		params.acConfig.ucLinkSel = 1;
745 
746 	if (ENGINE_ID_DIGB == cntl->engine_id)
747 		/* Bit3: Transmitter data source selection
748 		 * =0 DIGA is data source.
749 		 * =1 DIGB is data source.
750 		 * This bit is only useful when ucAction= ATOM_ENABLE
751 		 */
752 		params.acConfig.ucEncoderSel = 1;
753 
754 	/* Bit[7:6]: Transmitter selection
755 	 * =0 UNIPHY_ENCODER: UNIPHYA/B
756 	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
757 	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
758 	 * =3 reserved
759 	 */
760 	params.acConfig.ucTransmitterSel =
761 		(uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
762 	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
763 	params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
764 	params.ucAction = (uint8_t)(cntl->action);
765 
766 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
767 		result = BP_RESULT_OK;
768 
769 	return result;
770 }
771 
772 static enum bp_result transmitter_control_v1_5(
773 	struct bios_parser *bp,
774 	struct bp_transmitter_control *cntl)
775 {
776 	enum bp_result result = BP_RESULT_FAILURE;
777 	const struct command_table_helper *cmd = bp->cmd_helper;
778 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
779 
780 	memset(&params, 0, sizeof(params));
781 	params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
782 	params.ucAction = (uint8_t)cntl->action;
783 	params.ucLaneNum = (uint8_t)cntl->lanes_number;
784 	params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
785 
786 	params.ucDigMode =
787 		cmd->signal_type_to_atom_dig_mode(cntl->signal);
788 	params.asConfig.ucPhyClkSrcId =
789 		cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
790 	/* 00 - coherent mode */
791 	params.asConfig.ucCoherentMode = cntl->coherent;
792 	params.asConfig.ucHPDSel =
793 		cmd->hpd_sel_to_atom(cntl->hpd_sel);
794 	params.ucDigEncoderSel =
795 		cmd->dig_encoder_sel_to_atom(cntl->engine_id);
796 	params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
797 	params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
798 	/*
799 	 * In SI/TN case, caller have to set usPixelClock as following:
800 	 * DP mode: usPixelClock = DP_LINK_CLOCK/10
801 	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
802 	 * DVI single link mode: usPixelClock = pixel clock
803 	 * DVI dual link mode: usPixelClock = pixel clock
804 	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
805 	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
806 	 * LVDS mode: usPixelClock = pixel clock
807 	 */
808 
809 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
810 		result = BP_RESULT_OK;
811 
812 	return result;
813 }
814 
815 static enum bp_result transmitter_control_v1_6(
816 	struct bios_parser *bp,
817 	struct bp_transmitter_control *cntl)
818 {
819 	enum bp_result result = BP_RESULT_FAILURE;
820 	const struct command_table_helper *cmd = bp->cmd_helper;
821 	DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_6 params;
822 
823 	memset(&params, 0, sizeof(params));
824 	params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
825 	params.ucAction = (uint8_t)cntl->action;
826 
827 	if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
828 		params.ucDPLaneSet = (uint8_t)cntl->lane_settings;
829 	else
830 		params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
831 
832 	params.ucLaneNum = (uint8_t)cntl->lanes_number;
833 	params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
834 	params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
835 	params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
836 	params.ulSymClock = cntl->pixel_clock/10;
837 
838 	/*
839 	 * In SI/TN case, caller have to set usPixelClock as following:
840 	 * DP mode: usPixelClock = DP_LINK_CLOCK/10
841 	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
842 	 * DVI single link mode: usPixelClock = pixel clock
843 	 * DVI dual link mode: usPixelClock = pixel clock
844 	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
845 	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
846 	 * LVDS mode: usPixelClock = pixel clock
847 	 */
848 	switch (cntl->signal) {
849 	case SIGNAL_TYPE_HDMI_TYPE_A:
850 		switch (cntl->color_depth) {
851 		case COLOR_DEPTH_101010:
852 			params.ulSymClock =
853 				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
854 			break;
855 		case COLOR_DEPTH_121212:
856 			params.ulSymClock =
857 				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
858 			break;
859 		case COLOR_DEPTH_161616:
860 			params.ulSymClock =
861 				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
862 			break;
863 		default:
864 			break;
865 		}
866 		break;
867 		default:
868 			break;
869 	}
870 
871 	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
872 		result = BP_RESULT_OK;
873 	return result;
874 }
875 
876 /*******************************************************************************
877  ********************************************************************************
878  **
879  **                  SET PIXEL CLOCK
880  **
881  ********************************************************************************
882  *******************************************************************************/
883 
884 static enum bp_result set_pixel_clock_v3(
885 	struct bios_parser *bp,
886 	struct bp_pixel_clock_parameters *bp_params);
887 static enum bp_result set_pixel_clock_v5(
888 	struct bios_parser *bp,
889 	struct bp_pixel_clock_parameters *bp_params);
890 static enum bp_result set_pixel_clock_v6(
891 	struct bios_parser *bp,
892 	struct bp_pixel_clock_parameters *bp_params);
893 static enum bp_result set_pixel_clock_v7(
894 	struct bios_parser *bp,
895 	struct bp_pixel_clock_parameters *bp_params);
896 
897 static void init_set_pixel_clock(struct bios_parser *bp)
898 {
899 	switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
900 	case 3:
901 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
902 		break;
903 	case 5:
904 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
905 		break;
906 	case 6:
907 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
908 		break;
909 	case 7:
910 		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
911 		break;
912 	default:
913 		bp->cmd_tbl.set_pixel_clock = NULL;
914 		break;
915 	}
916 }
917 
918 static enum bp_result set_pixel_clock_v3(
919 	struct bios_parser *bp,
920 	struct bp_pixel_clock_parameters *bp_params)
921 {
922 	enum bp_result result = BP_RESULT_FAILURE;
923 	PIXEL_CLOCK_PARAMETERS_V3 *params;
924 	SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
925 
926 	memset(&allocation, 0, sizeof(allocation));
927 
928 	if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
929 		allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
930 	else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
931 		allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
932 	else
933 		return BP_RESULT_BADINPUT;
934 
935 	allocation.sPCLKInput.usRefDiv =
936 			cpu_to_le16((uint16_t)bp_params->reference_divider);
937 	allocation.sPCLKInput.usFbDiv =
938 			cpu_to_le16((uint16_t)bp_params->feedback_divider);
939 	allocation.sPCLKInput.ucFracFbDiv =
940 			(uint8_t)bp_params->fractional_feedback_divider;
941 	allocation.sPCLKInput.ucPostDiv =
942 			(uint8_t)bp_params->pixel_clock_post_divider;
943 
944 	/* We need to convert from KHz units into 10KHz units */
945 	allocation.sPCLKInput.usPixelClock =
946 			cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
947 
948 	params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
949 	params->ucTransmitterId =
950 			bp->cmd_helper->encoder_id_to_atom(
951 					dal_graphics_object_id_get_encoder_id(
952 							bp_params->encoder_object_id));
953 	params->ucEncoderMode =
954 			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
955 					bp_params->signal_type, false));
956 
957 	if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
958 		params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
959 
960 	if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
961 		params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
962 
963 	if (CONTROLLER_ID_D1 != bp_params->controller_id)
964 		params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
965 
966 	if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
967 		result = BP_RESULT_OK;
968 
969 	return result;
970 }
971 
972 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
973 /* video bios did not define this: */
974 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
975 	PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
976 	/* Caller doesn't need to init this portion */
977 	ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
978 } SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
979 #endif
980 
981 #ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
982 /* video bios did not define this: */
983 typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
984 	PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
985 	/* Caller doesn't need to init this portion */
986 	ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
987 } SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
988 #endif
989 
990 static enum bp_result set_pixel_clock_v5(
991 	struct bios_parser *bp,
992 	struct bp_pixel_clock_parameters *bp_params)
993 {
994 	enum bp_result result = BP_RESULT_FAILURE;
995 	SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
996 	uint8_t controller_id;
997 	uint32_t pll_id;
998 
999 	memset(&clk, 0, sizeof(clk));
1000 
1001 	if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1002 			&& bp->cmd_helper->controller_id_to_atom(
1003 					bp_params->controller_id, &controller_id)) {
1004 		clk.sPCLKInput.ucCRTC = controller_id;
1005 		clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
1006 		clk.sPCLKInput.ucRefDiv =
1007 				(uint8_t)(bp_params->reference_divider);
1008 		clk.sPCLKInput.usFbDiv =
1009 				cpu_to_le16((uint16_t)(bp_params->feedback_divider));
1010 		clk.sPCLKInput.ulFbDivDecFrac =
1011 				cpu_to_le32(bp_params->fractional_feedback_divider);
1012 		clk.sPCLKInput.ucPostDiv =
1013 				(uint8_t)(bp_params->pixel_clock_post_divider);
1014 		clk.sPCLKInput.ucTransmitterID =
1015 				bp->cmd_helper->encoder_id_to_atom(
1016 						dal_graphics_object_id_get_encoder_id(
1017 								bp_params->encoder_object_id));
1018 		clk.sPCLKInput.ucEncoderMode =
1019 				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1020 						bp_params->signal_type, false);
1021 
1022 		/* We need to convert from KHz units into 10KHz units */
1023 		clk.sPCLKInput.usPixelClock =
1024 				cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
1025 
1026 		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1027 			clk.sPCLKInput.ucMiscInfo |=
1028 					PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
1029 
1030 		if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1031 			clk.sPCLKInput.ucMiscInfo |=
1032 					PIXEL_CLOCK_MISC_REF_DIV_SRC;
1033 
1034 		/* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
1035 		 * =1:30bpp, =2:32bpp
1036 		 * driver choose program it itself, i.e. here we program it
1037 		 * to 888 by default.
1038 		 */
1039 
1040 		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1041 			result = BP_RESULT_OK;
1042 	}
1043 
1044 	return result;
1045 }
1046 
1047 static enum bp_result set_pixel_clock_v6(
1048 	struct bios_parser *bp,
1049 	struct bp_pixel_clock_parameters *bp_params)
1050 {
1051 	enum bp_result result = BP_RESULT_FAILURE;
1052 	SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
1053 	uint8_t controller_id;
1054 	uint32_t pll_id;
1055 
1056 	memset(&clk, 0, sizeof(clk));
1057 
1058 	if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1059 			&& bp->cmd_helper->controller_id_to_atom(
1060 					bp_params->controller_id, &controller_id)) {
1061 		/* Note: VBIOS still wants to use ucCRTC name which is now
1062 		 * 1 byte in ULONG
1063 		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1064 		 *{
1065 		 * target the pixel clock to drive the CRTC timing.
1066 		 * ULONG ulPixelClock:24;
1067 		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1068 		 * previous version.
1069 		 * ATOM_CRTC1~6, indicate the CRTC controller to
1070 		 * ULONG ucCRTC:8;
1071 		 * drive the pixel clock. not used for DCPLL case.
1072 		 *}CRTC_PIXEL_CLOCK_FREQ;
1073 		 *union
1074 		 *{
1075 		 * pixel clock and CRTC id frequency
1076 		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1077 		 * ULONG ulDispEngClkFreq; dispclk frequency
1078 		 *};
1079 		 */
1080 		clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
1081 		clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
1082 		clk.sPCLKInput.ucRefDiv =
1083 				(uint8_t) bp_params->reference_divider;
1084 		clk.sPCLKInput.usFbDiv =
1085 				cpu_to_le16((uint16_t) bp_params->feedback_divider);
1086 		clk.sPCLKInput.ulFbDivDecFrac =
1087 				cpu_to_le32(bp_params->fractional_feedback_divider);
1088 		clk.sPCLKInput.ucPostDiv =
1089 				(uint8_t) bp_params->pixel_clock_post_divider;
1090 		clk.sPCLKInput.ucTransmitterID =
1091 				bp->cmd_helper->encoder_id_to_atom(
1092 						dal_graphics_object_id_get_encoder_id(
1093 								bp_params->encoder_object_id));
1094 		clk.sPCLKInput.ucEncoderMode =
1095 				(uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
1096 						bp_params->signal_type, false);
1097 
1098 		/* We need to convert from KHz units into 10KHz units */
1099 		clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
1100 				cpu_to_le32(bp_params->target_pixel_clock / 10);
1101 
1102 		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
1103 			clk.sPCLKInput.ucMiscInfo |=
1104 					PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
1105 		}
1106 
1107 		if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
1108 			clk.sPCLKInput.ucMiscInfo |=
1109 					PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
1110 		}
1111 
1112 		/* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
1113 		 * 24bpp =1:30bpp, =2:32bpp
1114 		 * driver choose program it itself, i.e. here we pass required
1115 		 * target rate that includes deep color.
1116 		 */
1117 
1118 		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1119 			result = BP_RESULT_OK;
1120 	}
1121 
1122 	return result;
1123 }
1124 
1125 static enum bp_result set_pixel_clock_v7(
1126 	struct bios_parser *bp,
1127 	struct bp_pixel_clock_parameters *bp_params)
1128 {
1129 	enum bp_result result = BP_RESULT_FAILURE;
1130 	PIXEL_CLOCK_PARAMETERS_V7 clk;
1131 	uint8_t controller_id;
1132 	uint32_t pll_id;
1133 
1134 	memset(&clk, 0, sizeof(clk));
1135 
1136 	if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
1137 			&& bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, &controller_id)) {
1138 		/* Note: VBIOS still wants to use ucCRTC name which is now
1139 		 * 1 byte in ULONG
1140 		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
1141 		 *{
1142 		 * target the pixel clock to drive the CRTC timing.
1143 		 * ULONG ulPixelClock:24;
1144 		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
1145 		 * previous version.
1146 		 * ATOM_CRTC1~6, indicate the CRTC controller to
1147 		 * ULONG ucCRTC:8;
1148 		 * drive the pixel clock. not used for DCPLL case.
1149 		 *}CRTC_PIXEL_CLOCK_FREQ;
1150 		 *union
1151 		 *{
1152 		 * pixel clock and CRTC id frequency
1153 		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
1154 		 * ULONG ulDispEngClkFreq; dispclk frequency
1155 		 *};
1156 		 */
1157 		clk.ucCRTC = controller_id;
1158 		clk.ucPpll = (uint8_t) pll_id;
1159 		clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
1160 		clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
1161 
1162 		/* We need to convert from KHz units into 10KHz units */
1163 		clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock * 10);
1164 
1165 		clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
1166 
1167 		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
1168 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
1169 
1170 		if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
1171 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
1172 
1173 		if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
1174 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
1175 
1176 		if (bp_params->flags.SUPPORT_YUV_420)
1177 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
1178 
1179 		if (bp_params->flags.SET_XTALIN_REF_SRC)
1180 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
1181 
1182 		if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
1183 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
1184 
1185 		if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1186 			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
1187 
1188 		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
1189 			result = BP_RESULT_OK;
1190 	}
1191 	return result;
1192 }
1193 
1194 /*******************************************************************************
1195  ********************************************************************************
1196  **
1197  **                  ENABLE PIXEL CLOCK SS
1198  **
1199  ********************************************************************************
1200  *******************************************************************************/
1201 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1202 	struct bios_parser *bp,
1203 	struct bp_spread_spectrum_parameters *bp_params,
1204 	bool enable);
1205 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1206 	struct bios_parser *bp,
1207 	struct bp_spread_spectrum_parameters *bp_params,
1208 	bool enable);
1209 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1210 	struct bios_parser *bp,
1211 	struct bp_spread_spectrum_parameters *bp_params,
1212 	bool enable);
1213 
1214 static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
1215 {
1216 	switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
1217 	case 1:
1218 		bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1219 				enable_spread_spectrum_on_ppll_v1;
1220 		break;
1221 	case 2:
1222 		bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1223 				enable_spread_spectrum_on_ppll_v2;
1224 		break;
1225 	case 3:
1226 		bp->cmd_tbl.enable_spread_spectrum_on_ppll =
1227 				enable_spread_spectrum_on_ppll_v3;
1228 		break;
1229 	default:
1230 		bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
1231 		break;
1232 	}
1233 }
1234 
1235 static enum bp_result enable_spread_spectrum_on_ppll_v1(
1236 	struct bios_parser *bp,
1237 	struct bp_spread_spectrum_parameters *bp_params,
1238 	bool enable)
1239 {
1240 	enum bp_result result = BP_RESULT_FAILURE;
1241 	ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
1242 
1243 	memset(&params, 0, sizeof(params));
1244 
1245 	if ((enable == true) && (bp_params->percentage > 0))
1246 		params.ucEnable = ATOM_ENABLE;
1247 	else
1248 		params.ucEnable = ATOM_DISABLE;
1249 
1250 	params.usSpreadSpectrumPercentage =
1251 			cpu_to_le16((uint16_t)bp_params->percentage);
1252 	params.ucSpreadSpectrumStep =
1253 			(uint8_t)bp_params->ver1.step;
1254 	params.ucSpreadSpectrumDelay =
1255 			(uint8_t)bp_params->ver1.delay;
1256 	/* convert back to unit of 10KHz */
1257 	params.ucSpreadSpectrumRange =
1258 			(uint8_t)(bp_params->ver1.range / 10000);
1259 
1260 	if (bp_params->flags.EXTERNAL_SS)
1261 		params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
1262 
1263 	if (bp_params->flags.CENTER_SPREAD)
1264 		params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
1265 
1266 	if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1267 		params.ucPpll = ATOM_PPLL1;
1268 	else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1269 		params.ucPpll = ATOM_PPLL2;
1270 	else
1271 		BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1272 
1273 	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1274 		result = BP_RESULT_OK;
1275 
1276 	return result;
1277 }
1278 
1279 static enum bp_result enable_spread_spectrum_on_ppll_v2(
1280 	struct bios_parser *bp,
1281 	struct bp_spread_spectrum_parameters *bp_params,
1282 	bool enable)
1283 {
1284 	enum bp_result result = BP_RESULT_FAILURE;
1285 	ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
1286 
1287 	memset(&params, 0, sizeof(params));
1288 
1289 	if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
1290 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
1291 	else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
1292 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
1293 	else
1294 		BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
1295 
1296 	if ((enable == true) && (bp_params->percentage > 0)) {
1297 		params.ucEnable = ATOM_ENABLE;
1298 
1299 		params.usSpreadSpectrumPercentage =
1300 				cpu_to_le16((uint16_t)(bp_params->percentage));
1301 		params.usSpreadSpectrumStep =
1302 				cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1303 
1304 		if (bp_params->flags.EXTERNAL_SS)
1305 			params.ucSpreadSpectrumType |=
1306 					ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
1307 
1308 		if (bp_params->flags.CENTER_SPREAD)
1309 			params.ucSpreadSpectrumType |=
1310 					ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
1311 
1312 		/* Both amounts need to be left shifted first before bit
1313 		 * comparison. Otherwise, the result will always be zero here
1314 		 */
1315 		params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1316 				((bp_params->ds.feedback_amount <<
1317 						ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
1318 						ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
1319 						((bp_params->ds.nfrac_amount <<
1320 								ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
1321 								ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
1322 	} else
1323 		params.ucEnable = ATOM_DISABLE;
1324 
1325 	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1326 		result = BP_RESULT_OK;
1327 
1328 	return result;
1329 }
1330 
1331 static enum bp_result enable_spread_spectrum_on_ppll_v3(
1332 	struct bios_parser *bp,
1333 	struct bp_spread_spectrum_parameters *bp_params,
1334 	bool enable)
1335 {
1336 	enum bp_result result = BP_RESULT_FAILURE;
1337 	ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
1338 
1339 	memset(&params, 0, sizeof(params));
1340 
1341 	switch (bp_params->pll_id) {
1342 	case CLOCK_SOURCE_ID_PLL0:
1343 		/* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
1344 		 * not for SI display clock.
1345 		 */
1346 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1347 		break;
1348 	case CLOCK_SOURCE_ID_PLL1:
1349 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
1350 		break;
1351 
1352 	case CLOCK_SOURCE_ID_PLL2:
1353 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
1354 		break;
1355 
1356 	case CLOCK_SOURCE_ID_DCPLL:
1357 		params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
1358 		break;
1359 
1360 	default:
1361 		BREAK_TO_DEBUGGER();
1362 		/* Unexpected PLL value!! */
1363 		return result;
1364 	}
1365 
1366 	if (enable == true) {
1367 		params.ucEnable = ATOM_ENABLE;
1368 
1369 		params.usSpreadSpectrumAmountFrac =
1370 				cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
1371 		params.usSpreadSpectrumStep =
1372 				cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
1373 
1374 		if (bp_params->flags.EXTERNAL_SS)
1375 			params.ucSpreadSpectrumType |=
1376 					ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
1377 		if (bp_params->flags.CENTER_SPREAD)
1378 			params.ucSpreadSpectrumType |=
1379 					ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
1380 
1381 		/* Both amounts need to be left shifted first before bit
1382 		 * comparison. Otherwise, the result will always be zero here
1383 		 */
1384 		params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
1385 				((bp_params->ds.feedback_amount <<
1386 						ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
1387 						ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
1388 						((bp_params->ds.nfrac_amount <<
1389 								ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
1390 								ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
1391 	} else
1392 		params.ucEnable = ATOM_DISABLE;
1393 
1394 	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
1395 		result = BP_RESULT_OK;
1396 
1397 	return result;
1398 }
1399 
1400 /*******************************************************************************
1401  ********************************************************************************
1402  **
1403  **                  ADJUST DISPLAY PLL
1404  **
1405  ********************************************************************************
1406  *******************************************************************************/
1407 
1408 static enum bp_result adjust_display_pll_v2(
1409 	struct bios_parser *bp,
1410 	struct bp_adjust_pixel_clock_parameters *bp_params);
1411 static enum bp_result adjust_display_pll_v3(
1412 	struct bios_parser *bp,
1413 	struct bp_adjust_pixel_clock_parameters *bp_params);
1414 
1415 static void init_adjust_display_pll(struct bios_parser *bp)
1416 {
1417 	switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
1418 	case 2:
1419 		bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
1420 		break;
1421 	case 3:
1422 		bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
1423 		break;
1424 	default:
1425 		bp->cmd_tbl.adjust_display_pll = NULL;
1426 		break;
1427 	}
1428 }
1429 
1430 static enum bp_result adjust_display_pll_v2(
1431 	struct bios_parser *bp,
1432 	struct bp_adjust_pixel_clock_parameters *bp_params)
1433 {
1434 	enum bp_result result = BP_RESULT_FAILURE;
1435 	ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
1436 
1437 	/* We need to convert from KHz units into 10KHz units and then convert
1438 	 * output pixel clock back 10KHz-->KHz */
1439 	uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
1440 
1441 	params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
1442 	params.ucTransmitterID =
1443 			bp->cmd_helper->encoder_id_to_atom(
1444 					dal_graphics_object_id_get_encoder_id(
1445 							bp_params->encoder_object_id));
1446 	params.ucEncodeMode =
1447 			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1448 					bp_params->signal_type, false);
1449 	return result;
1450 }
1451 
1452 static enum bp_result adjust_display_pll_v3(
1453 	struct bios_parser *bp,
1454 	struct bp_adjust_pixel_clock_parameters *bp_params)
1455 {
1456 	enum bp_result result = BP_RESULT_FAILURE;
1457 	ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
1458 	uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
1459 
1460 	memset(&params, 0, sizeof(params));
1461 
1462 	/* We need to convert from KHz units into 10KHz units and then convert
1463 	 * output pixel clock back 10KHz-->KHz */
1464 	params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
1465 	params.sInput.ucTransmitterID =
1466 			bp->cmd_helper->encoder_id_to_atom(
1467 					dal_graphics_object_id_get_encoder_id(
1468 							bp_params->encoder_object_id));
1469 	params.sInput.ucEncodeMode =
1470 			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1471 					bp_params->signal_type, false);
1472 
1473 	if (bp_params->ss_enable == true)
1474 		params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
1475 
1476 	if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
1477 		params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
1478 
1479 	if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
1480 		/* Convert output pixel clock back 10KHz-->KHz: multiply
1481 		 * original pixel clock in KHz by ratio
1482 		 * [output pxlClk/input pxlClk] */
1483 		uint64_t pixel_clk_10_khz_out =
1484 				(uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
1485 		uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
1486 
1487 		if (pixel_clk_10_kHz_in != 0) {
1488 			bp_params->adjusted_pixel_clock =
1489 					div_u64(pixel_clk * pixel_clk_10_khz_out,
1490 							pixel_clk_10_kHz_in);
1491 		} else {
1492 			bp_params->adjusted_pixel_clock = 0;
1493 			BREAK_TO_DEBUGGER();
1494 		}
1495 
1496 		bp_params->reference_divider = params.sOutput.ucRefDiv;
1497 		bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
1498 
1499 		result = BP_RESULT_OK;
1500 	}
1501 
1502 	return result;
1503 }
1504 
1505 /*******************************************************************************
1506  ********************************************************************************
1507  **
1508  **                  DAC ENCODER CONTROL
1509  **
1510  ********************************************************************************
1511  *******************************************************************************/
1512 
1513 static enum bp_result dac1_encoder_control_v1(
1514 	struct bios_parser *bp,
1515 	bool enable,
1516 	uint32_t pixel_clock,
1517 	uint8_t dac_standard);
1518 static enum bp_result dac2_encoder_control_v1(
1519 	struct bios_parser *bp,
1520 	bool enable,
1521 	uint32_t pixel_clock,
1522 	uint8_t dac_standard);
1523 
1524 static void init_dac_encoder_control(struct bios_parser *bp)
1525 {
1526 	switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
1527 	case 1:
1528 		bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
1529 		break;
1530 	default:
1531 		bp->cmd_tbl.dac1_encoder_control = NULL;
1532 		break;
1533 	}
1534 	switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
1535 	case 1:
1536 		bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
1537 		break;
1538 	default:
1539 		bp->cmd_tbl.dac2_encoder_control = NULL;
1540 		break;
1541 	}
1542 }
1543 
1544 static void dac_encoder_control_prepare_params(
1545 	DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
1546 	bool enable,
1547 	uint32_t pixel_clock,
1548 	uint8_t dac_standard)
1549 {
1550 	params->ucDacStandard = dac_standard;
1551 	if (enable)
1552 		params->ucAction = ATOM_ENABLE;
1553 	else
1554 		params->ucAction = ATOM_DISABLE;
1555 
1556 	/* We need to convert from KHz units into 10KHz units
1557 	 * it looks as if the TvControl do not care about pixel clock
1558 	 */
1559 	params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
1560 }
1561 
1562 static enum bp_result dac1_encoder_control_v1(
1563 	struct bios_parser *bp,
1564 	bool enable,
1565 	uint32_t pixel_clock,
1566 	uint8_t dac_standard)
1567 {
1568 	enum bp_result result = BP_RESULT_FAILURE;
1569 	DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1570 
1571 	dac_encoder_control_prepare_params(
1572 		&params,
1573 		enable,
1574 		pixel_clock,
1575 		dac_standard);
1576 
1577 	if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
1578 		result = BP_RESULT_OK;
1579 
1580 	return result;
1581 }
1582 
1583 static enum bp_result dac2_encoder_control_v1(
1584 	struct bios_parser *bp,
1585 	bool enable,
1586 	uint32_t pixel_clock,
1587 	uint8_t dac_standard)
1588 {
1589 	enum bp_result result = BP_RESULT_FAILURE;
1590 	DAC_ENCODER_CONTROL_PS_ALLOCATION params;
1591 
1592 	dac_encoder_control_prepare_params(
1593 		&params,
1594 		enable,
1595 		pixel_clock,
1596 		dac_standard);
1597 
1598 	if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
1599 		result = BP_RESULT_OK;
1600 
1601 	return result;
1602 }
1603 
1604 /*******************************************************************************
1605  ********************************************************************************
1606  **
1607  **                  DAC OUTPUT CONTROL
1608  **
1609  ********************************************************************************
1610  *******************************************************************************/
1611 static enum bp_result dac1_output_control_v1(
1612 	struct bios_parser *bp,
1613 	bool enable);
1614 static enum bp_result dac2_output_control_v1(
1615 	struct bios_parser *bp,
1616 	bool enable);
1617 
1618 static void init_dac_output_control(struct bios_parser *bp)
1619 {
1620 	switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
1621 	case 1:
1622 		bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
1623 		break;
1624 	default:
1625 		bp->cmd_tbl.dac1_output_control = NULL;
1626 		break;
1627 	}
1628 	switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
1629 	case 1:
1630 		bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
1631 		break;
1632 	default:
1633 		bp->cmd_tbl.dac2_output_control = NULL;
1634 		break;
1635 	}
1636 }
1637 
1638 static enum bp_result dac1_output_control_v1(
1639 	struct bios_parser *bp, bool enable)
1640 {
1641 	enum bp_result result = BP_RESULT_FAILURE;
1642 	DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1643 
1644 	if (enable)
1645 		params.ucAction = ATOM_ENABLE;
1646 	else
1647 		params.ucAction = ATOM_DISABLE;
1648 
1649 	if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
1650 		result = BP_RESULT_OK;
1651 
1652 	return result;
1653 }
1654 
1655 static enum bp_result dac2_output_control_v1(
1656 	struct bios_parser *bp, bool enable)
1657 {
1658 	enum bp_result result = BP_RESULT_FAILURE;
1659 	DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
1660 
1661 	if (enable)
1662 		params.ucAction = ATOM_ENABLE;
1663 	else
1664 		params.ucAction = ATOM_DISABLE;
1665 
1666 	if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
1667 		result = BP_RESULT_OK;
1668 
1669 	return result;
1670 }
1671 
1672 /*******************************************************************************
1673  ********************************************************************************
1674  **
1675  **                  SET CRTC TIMING
1676  **
1677  ********************************************************************************
1678  *******************************************************************************/
1679 
1680 static enum bp_result set_crtc_using_dtd_timing_v3(
1681 	struct bios_parser *bp,
1682 	struct bp_hw_crtc_timing_parameters *bp_params);
1683 static enum bp_result set_crtc_timing_v1(
1684 	struct bios_parser *bp,
1685 	struct bp_hw_crtc_timing_parameters *bp_params);
1686 
1687 static void init_set_crtc_timing(struct bios_parser *bp)
1688 {
1689 	uint32_t dtd_version =
1690 			BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
1691 	if (dtd_version > 2)
1692 		switch (dtd_version) {
1693 		case 3:
1694 			bp->cmd_tbl.set_crtc_timing =
1695 					set_crtc_using_dtd_timing_v3;
1696 			break;
1697 		default:
1698 			bp->cmd_tbl.set_crtc_timing = NULL;
1699 			break;
1700 		}
1701 	else
1702 		switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
1703 		case 1:
1704 			bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
1705 			break;
1706 		default:
1707 			bp->cmd_tbl.set_crtc_timing = NULL;
1708 			break;
1709 		}
1710 }
1711 
1712 static enum bp_result set_crtc_timing_v1(
1713 	struct bios_parser *bp,
1714 	struct bp_hw_crtc_timing_parameters *bp_params)
1715 {
1716 	enum bp_result result = BP_RESULT_FAILURE;
1717 	SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
1718 	uint8_t atom_controller_id;
1719 
1720 	if (bp->cmd_helper->controller_id_to_atom(
1721 			bp_params->controller_id, &atom_controller_id))
1722 		params.ucCRTC = atom_controller_id;
1723 
1724 	params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
1725 	params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
1726 	params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
1727 	params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
1728 	params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
1729 	params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
1730 	params.usV_SyncStart =
1731 			cpu_to_le16((uint16_t)(bp_params->v_sync_start));
1732 	params.usV_SyncWidth =
1733 			cpu_to_le16((uint16_t)(bp_params->v_sync_width));
1734 
1735 	/* VBIOS does not expect any value except zero into this call, for
1736 	 * underscan use another entry ProgramOverscan call but when mode
1737 	 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
1738 	 * but when same ,but 60 Hz there is corruption
1739 	 * DAL1 does not allow the mode 1776x1000@60
1740 	 */
1741 	params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
1742 	params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
1743 	params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
1744 	params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
1745 
1746 	if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1747 		params.susModeMiscInfo.usAccess =
1748 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1749 
1750 	if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1751 		params.susModeMiscInfo.usAccess =
1752 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1753 
1754 	if (bp_params->flags.INTERLACE) {
1755 		params.susModeMiscInfo.usAccess =
1756 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1757 
1758 		/* original DAL code has this condition to apply tis for
1759 		 * non-TV/CV only due to complex MV testing for possible
1760 		 * impact
1761 		 * if (pACParameters->signal != SignalType_YPbPr &&
1762 		 *  pACParameters->signal != SignalType_Composite &&
1763 		 *  pACParameters->signal != SignalType_SVideo)
1764 		 */
1765 		/* HW will deduct 0.5 line from 2nd feild.
1766 		 * i.e. for 1080i, it is 2 lines for 1st field, 2.5
1767 		 * lines for the 2nd feild. we need input as 5 instead
1768 		 * of 4, but it is 4 either from Edid data
1769 		 * (spec CEA 861) or CEA timing table.
1770 		 */
1771 		params.usV_SyncStart =
1772 				cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
1773 	}
1774 
1775 	if (bp_params->flags.HORZ_COUNT_BY_TWO)
1776 		params.susModeMiscInfo.usAccess =
1777 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1778 
1779 	if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
1780 		result = BP_RESULT_OK;
1781 
1782 	return result;
1783 }
1784 
1785 static enum bp_result set_crtc_using_dtd_timing_v3(
1786 	struct bios_parser *bp,
1787 	struct bp_hw_crtc_timing_parameters *bp_params)
1788 {
1789 	enum bp_result result = BP_RESULT_FAILURE;
1790 	SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
1791 	uint8_t atom_controller_id;
1792 
1793 	if (bp->cmd_helper->controller_id_to_atom(
1794 			bp_params->controller_id, &atom_controller_id))
1795 		params.ucCRTC = atom_controller_id;
1796 
1797 	/* bios usH_Size wants h addressable size */
1798 	params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
1799 	/* bios usH_Blanking_Time wants borders included in blanking */
1800 	params.usH_Blanking_Time =
1801 			cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
1802 	/* bios usV_Size wants v addressable size */
1803 	params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
1804 	/* bios usV_Blanking_Time wants borders included in blanking */
1805 	params.usV_Blanking_Time =
1806 			cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
1807 	/* bios usHSyncOffset is the offset from the end of h addressable,
1808 	 * our horizontalSyncStart is the offset from the beginning
1809 	 * of h addressable */
1810 	params.usH_SyncOffset =
1811 			cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
1812 	params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
1813 	/* bios usHSyncOffset is the offset from the end of v addressable,
1814 	 * our verticalSyncStart is the offset from the beginning of
1815 	 * v addressable */
1816 	params.usV_SyncOffset =
1817 			cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
1818 	params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
1819 
1820 	/* we assume that overscan from original timing does not get bigger
1821 	 * than 255
1822 	 * we will program all the borders in the Set CRTC Overscan call below
1823 	 */
1824 
1825 	if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
1826 		params.susModeMiscInfo.usAccess =
1827 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
1828 
1829 	if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
1830 		params.susModeMiscInfo.usAccess =
1831 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
1832 
1833 	if (bp_params->flags.INTERLACE)	{
1834 		params.susModeMiscInfo.usAccess =
1835 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
1836 
1837 		/* original DAL code has this condition to apply this
1838 		 * for non-TV/CV only
1839 		 * due to complex MV testing for possible impact
1840 		 * if ( pACParameters->signal != SignalType_YPbPr &&
1841 		 *  pACParameters->signal != SignalType_Composite &&
1842 		 *  pACParameters->signal != SignalType_SVideo)
1843 		 */
1844 		{
1845 			/* HW will deduct 0.5 line from 2nd feild.
1846 			 * i.e. for 1080i, it is 2 lines for 1st field,
1847 			 * 2.5 lines for the 2nd feild. we need input as 5
1848 			 * instead of 4.
1849 			 * but it is 4 either from Edid data (spec CEA 861)
1850 			 * or CEA timing table.
1851 			 */
1852 			params.usV_SyncOffset =
1853 					cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
1854 
1855 		}
1856 	}
1857 
1858 	if (bp_params->flags.HORZ_COUNT_BY_TWO)
1859 		params.susModeMiscInfo.usAccess =
1860 				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
1861 
1862 	if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
1863 		result = BP_RESULT_OK;
1864 
1865 	return result;
1866 }
1867 
1868 /*******************************************************************************
1869  ********************************************************************************
1870  **
1871  **                  SELECT CRTC SOURCE
1872  **
1873  ********************************************************************************
1874  *******************************************************************************/
1875 
1876 static enum bp_result select_crtc_source_v2(
1877 	struct bios_parser *bp,
1878 	struct bp_crtc_source_select *bp_params);
1879 static enum bp_result select_crtc_source_v3(
1880 	struct bios_parser *bp,
1881 	struct bp_crtc_source_select *bp_params);
1882 
1883 static void init_select_crtc_source(struct bios_parser *bp)
1884 {
1885 	switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
1886 	case 2:
1887 		bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
1888 		break;
1889 	case 3:
1890 		bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
1891 		break;
1892 	default:
1893 		bp->cmd_tbl.select_crtc_source = NULL;
1894 		break;
1895 	}
1896 }
1897 
1898 static enum bp_result select_crtc_source_v2(
1899 	struct bios_parser *bp,
1900 	struct bp_crtc_source_select *bp_params)
1901 {
1902 	enum bp_result result = BP_RESULT_FAILURE;
1903 	SELECT_CRTC_SOURCE_PARAMETERS_V2 params;
1904 	uint8_t atom_controller_id;
1905 	uint32_t atom_engine_id;
1906 	enum signal_type s = bp_params->signal;
1907 
1908 	memset(&params, 0, sizeof(params));
1909 
1910 	/* set controller id */
1911 	if (bp->cmd_helper->controller_id_to_atom(
1912 			bp_params->controller_id, &atom_controller_id))
1913 		params.ucCRTC = atom_controller_id;
1914 	else
1915 		return BP_RESULT_FAILURE;
1916 
1917 	/* set encoder id */
1918 	if (bp->cmd_helper->engine_bp_to_atom(
1919 			bp_params->engine_id, &atom_engine_id))
1920 		params.ucEncoderID = (uint8_t)atom_engine_id;
1921 	else
1922 		return BP_RESULT_FAILURE;
1923 
1924 	if (SIGNAL_TYPE_EDP == s ||
1925 			(SIGNAL_TYPE_DISPLAY_PORT == s &&
1926 					SIGNAL_TYPE_LVDS == bp_params->sink_signal))
1927 		s = SIGNAL_TYPE_LVDS;
1928 
1929 	params.ucEncodeMode =
1930 			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
1931 					s, bp_params->enable_dp_audio);
1932 
1933 	if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
1934 		result = BP_RESULT_OK;
1935 
1936 	return result;
1937 }
1938 
1939 static enum bp_result select_crtc_source_v3(
1940 	struct bios_parser *bp,
1941 	struct bp_crtc_source_select *bp_params)
1942 {
1943 	bool result = BP_RESULT_FAILURE;
1944 	SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
1945 	uint8_t atom_controller_id;
1946 	uint32_t atom_engine_id;
1947 	enum signal_type s = bp_params->signal;
1948 
1949 	memset(&params, 0, sizeof(params));
1950 
1951 	if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
1952 			&atom_controller_id))
1953 		params.ucCRTC = atom_controller_id;
1954 	else
1955 		return result;
1956 
1957 	if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
1958 			&atom_engine_id))
1959 		params.ucEncoderID = (uint8_t)atom_engine_id;
1960 	else
1961 		return result;
1962 
1963 	if (SIGNAL_TYPE_EDP == s ||
1964 			(SIGNAL_TYPE_DISPLAY_PORT == s &&
1965 					SIGNAL_TYPE_LVDS == bp_params->sink_signal))
1966 		s = SIGNAL_TYPE_LVDS;
1967 
1968 	params.ucEncodeMode =
1969 			bp->cmd_helper->encoder_mode_bp_to_atom(
1970 					s, bp_params->enable_dp_audio);
1971 	/* Needed for VBIOS Random Spatial Dithering feature */
1972 	params.ucDstBpc = (uint8_t)(bp_params->display_output_bit_depth);
1973 
1974 	if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
1975 		result = BP_RESULT_OK;
1976 
1977 	return result;
1978 }
1979 
1980 /*******************************************************************************
1981  ********************************************************************************
1982  **
1983  **                  ENABLE CRTC
1984  **
1985  ********************************************************************************
1986  *******************************************************************************/
1987 
1988 static enum bp_result enable_crtc_v1(
1989 	struct bios_parser *bp,
1990 	enum controller_id controller_id,
1991 	bool enable);
1992 
1993 static void init_enable_crtc(struct bios_parser *bp)
1994 {
1995 	switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
1996 	case 1:
1997 		bp->cmd_tbl.enable_crtc = enable_crtc_v1;
1998 		break;
1999 	default:
2000 		bp->cmd_tbl.enable_crtc = NULL;
2001 		break;
2002 	}
2003 }
2004 
2005 static enum bp_result enable_crtc_v1(
2006 	struct bios_parser *bp,
2007 	enum controller_id controller_id,
2008 	bool enable)
2009 {
2010 	bool result = BP_RESULT_FAILURE;
2011 	ENABLE_CRTC_PARAMETERS params = {0};
2012 	uint8_t id;
2013 
2014 	if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
2015 		params.ucCRTC = id;
2016 	else
2017 		return BP_RESULT_BADINPUT;
2018 
2019 	if (enable)
2020 		params.ucEnable = ATOM_ENABLE;
2021 	else
2022 		params.ucEnable = ATOM_DISABLE;
2023 
2024 	if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
2025 		result = BP_RESULT_OK;
2026 
2027 	return result;
2028 }
2029 
2030 /*******************************************************************************
2031  ********************************************************************************
2032  **
2033  **                  ENABLE CRTC MEM REQ
2034  **
2035  ********************************************************************************
2036  *******************************************************************************/
2037 
2038 static enum bp_result enable_crtc_mem_req_v1(
2039 	struct bios_parser *bp,
2040 	enum controller_id controller_id,
2041 	bool enable);
2042 
2043 static void init_enable_crtc_mem_req(struct bios_parser *bp)
2044 {
2045 	switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
2046 	case 1:
2047 		bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
2048 		break;
2049 	default:
2050 		bp->cmd_tbl.enable_crtc_mem_req = NULL;
2051 		break;
2052 	}
2053 }
2054 
2055 static enum bp_result enable_crtc_mem_req_v1(
2056 	struct bios_parser *bp,
2057 	enum controller_id controller_id,
2058 	bool enable)
2059 {
2060 	bool result = BP_RESULT_BADINPUT;
2061 	ENABLE_CRTC_PARAMETERS params = {0};
2062 	uint8_t id;
2063 
2064 	if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
2065 		params.ucCRTC = id;
2066 
2067 		if (enable)
2068 			params.ucEnable = ATOM_ENABLE;
2069 		else
2070 			params.ucEnable = ATOM_DISABLE;
2071 
2072 		if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
2073 			result = BP_RESULT_OK;
2074 		else
2075 			result = BP_RESULT_FAILURE;
2076 	}
2077 
2078 	return result;
2079 }
2080 
2081 /*******************************************************************************
2082  ********************************************************************************
2083  **
2084  **                  DISPLAY PLL
2085  **
2086  ********************************************************************************
2087  *******************************************************************************/
2088 
2089 static enum bp_result program_clock_v5(
2090 	struct bios_parser *bp,
2091 	struct bp_pixel_clock_parameters *bp_params);
2092 static enum bp_result program_clock_v6(
2093 	struct bios_parser *bp,
2094 	struct bp_pixel_clock_parameters *bp_params);
2095 
2096 static void init_program_clock(struct bios_parser *bp)
2097 {
2098 	switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
2099 	case 5:
2100 		bp->cmd_tbl.program_clock = program_clock_v5;
2101 		break;
2102 	case 6:
2103 		bp->cmd_tbl.program_clock = program_clock_v6;
2104 		break;
2105 	default:
2106 		bp->cmd_tbl.program_clock = NULL;
2107 		break;
2108 	}
2109 }
2110 
2111 static enum bp_result program_clock_v5(
2112 	struct bios_parser *bp,
2113 	struct bp_pixel_clock_parameters *bp_params)
2114 {
2115 	enum bp_result result = BP_RESULT_FAILURE;
2116 
2117 	SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
2118 	uint32_t atom_pll_id;
2119 
2120 	memset(&params, 0, sizeof(params));
2121 	if (!bp->cmd_helper->clock_source_id_to_atom(
2122 			bp_params->pll_id, &atom_pll_id)) {
2123 		BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
2124 		return BP_RESULT_BADINPUT;
2125 	}
2126 
2127 	/* We need to convert from KHz units into 10KHz units */
2128 	params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
2129 	params.sPCLKInput.usPixelClock =
2130 			cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
2131 	params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
2132 
2133 	if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2134 		params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2135 
2136 	if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
2137 		result = BP_RESULT_OK;
2138 
2139 	return result;
2140 }
2141 
2142 static enum bp_result program_clock_v6(
2143 	struct bios_parser *bp,
2144 	struct bp_pixel_clock_parameters *bp_params)
2145 {
2146 	enum bp_result result = BP_RESULT_FAILURE;
2147 
2148 	SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
2149 	uint32_t atom_pll_id;
2150 
2151 	memset(&params, 0, sizeof(params));
2152 
2153 	if (!bp->cmd_helper->clock_source_id_to_atom(
2154 			bp_params->pll_id, &atom_pll_id)) {
2155 		BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
2156 		return BP_RESULT_BADINPUT;
2157 	}
2158 
2159 	/* We need to convert from KHz units into 10KHz units */
2160 	params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
2161 	params.sPCLKInput.ulDispEngClkFreq =
2162 			cpu_to_le32(bp_params->target_pixel_clock / 10);
2163 
2164 	if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
2165 		params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
2166 
2167 	if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
2168 		/* True display clock is returned by VBIOS if DFS bypass
2169 		 * is enabled. */
2170 		bp_params->dfs_bypass_display_clock =
2171 				(uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
2172 		result = BP_RESULT_OK;
2173 	}
2174 
2175 	return result;
2176 }
2177 
2178 /*******************************************************************************
2179  ********************************************************************************
2180  **
2181  **                  EXTERNAL ENCODER CONTROL
2182  **
2183  ********************************************************************************
2184  *******************************************************************************/
2185 
2186 static enum bp_result external_encoder_control_v3(
2187 	struct bios_parser *bp,
2188 	struct bp_external_encoder_control *cntl);
2189 
2190 static void init_external_encoder_control(
2191 	struct bios_parser *bp)
2192 {
2193 	switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
2194 	case 3:
2195 		bp->cmd_tbl.external_encoder_control =
2196 				external_encoder_control_v3;
2197 		break;
2198 	default:
2199 		bp->cmd_tbl.external_encoder_control = NULL;
2200 		break;
2201 	}
2202 }
2203 
2204 static enum bp_result external_encoder_control_v3(
2205 	struct bios_parser *bp,
2206 	struct bp_external_encoder_control *cntl)
2207 {
2208 	enum bp_result result = BP_RESULT_FAILURE;
2209 
2210 	/* we need use _PS_Alloc struct */
2211 	EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
2212 	EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
2213 	struct graphics_object_id encoder;
2214 	bool is_input_signal_dp = false;
2215 
2216 	memset(&params, 0, sizeof(params));
2217 
2218 	cntl_params = &params.sExtEncoder;
2219 
2220 	encoder = cntl->encoder_id;
2221 
2222 	/* check if encoder supports external encoder control table */
2223 	switch (dal_graphics_object_id_get_encoder_id(encoder)) {
2224 	case ENCODER_ID_EXTERNAL_NUTMEG:
2225 	case ENCODER_ID_EXTERNAL_TRAVIS:
2226 		is_input_signal_dp = true;
2227 		break;
2228 
2229 	default:
2230 		BREAK_TO_DEBUGGER();
2231 		return BP_RESULT_BADINPUT;
2232 	}
2233 
2234 	/* Fill information based on the action
2235 	 *
2236 	 * Bit[6:4]: indicate external encoder, applied to all functions.
2237 	 * =0: external encoder1, mapped to external encoder enum id1
2238 	 * =1: external encoder2, mapped to external encoder enum id2
2239 	 *
2240 	 * enum ObjectEnumId
2241 	 * {
2242 	 *  EnumId_Unknown = 0,
2243 	 *  EnumId_1,
2244 	 *  EnumId_2,
2245 	 * };
2246 	 */
2247 	cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
2248 
2249 	switch (cntl->action) {
2250 	case EXTERNAL_ENCODER_CONTROL_INIT:
2251 		/* output display connector type. Only valid in encoder
2252 		 * initialization */
2253 		cntl_params->usConnectorId =
2254 				cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
2255 		break;
2256 	case EXTERNAL_ENCODER_CONTROL_SETUP:
2257 		/* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
2258 		 * 10KHz
2259 		 * output display device pixel clock frequency in unit of 10KHz.
2260 		 * Only valid in setup and enableoutput
2261 		 */
2262 		cntl_params->usPixelClock =
2263 				cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2264 		/* Indicate display output signal type drive by external
2265 		 * encoder, only valid in setup and enableoutput */
2266 		cntl_params->ucEncoderMode =
2267 				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2268 						cntl->signal, false);
2269 
2270 		if (is_input_signal_dp) {
2271 			/* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
2272 			 * only valid in encoder setup with DP mode. */
2273 			if (LINK_RATE_HIGH == cntl->link_rate)
2274 				cntl_params->ucConfig |= 1;
2275 			/* output color depth Indicate encoder data bpc format
2276 			 * in DP mode, only valid in encoder setup in DP mode.
2277 			 */
2278 			cntl_params->ucBitPerColor =
2279 					(uint8_t)(cntl->color_depth);
2280 		}
2281 		/* Indicate how many lanes used by external encoder, only valid
2282 		 * in encoder setup and enableoutput. */
2283 		cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
2284 		break;
2285 	case EXTERNAL_ENCODER_CONTROL_ENABLE:
2286 		cntl_params->usPixelClock =
2287 				cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
2288 		cntl_params->ucEncoderMode =
2289 				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
2290 						cntl->signal, false);
2291 		cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
2292 		break;
2293 	default:
2294 		break;
2295 	}
2296 
2297 	cntl_params->ucAction = (uint8_t)cntl->action;
2298 
2299 	if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
2300 		result = BP_RESULT_OK;
2301 
2302 	return result;
2303 }
2304 
2305 /*******************************************************************************
2306  ********************************************************************************
2307  **
2308  **                  ENABLE DISPLAY POWER GATING
2309  **
2310  ********************************************************************************
2311  *******************************************************************************/
2312 
2313 static enum bp_result enable_disp_power_gating_v2_1(
2314 	struct bios_parser *bp,
2315 	enum controller_id crtc_id,
2316 	enum bp_pipe_control_action action);
2317 
2318 static void init_enable_disp_power_gating(
2319 	struct bios_parser *bp)
2320 {
2321 	switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
2322 	case 1:
2323 		bp->cmd_tbl.enable_disp_power_gating =
2324 				enable_disp_power_gating_v2_1;
2325 		break;
2326 	default:
2327 		bp->cmd_tbl.enable_disp_power_gating = NULL;
2328 		break;
2329 	}
2330 }
2331 
2332 static enum bp_result enable_disp_power_gating_v2_1(
2333 	struct bios_parser *bp,
2334 	enum controller_id crtc_id,
2335 	enum bp_pipe_control_action action)
2336 {
2337 	enum bp_result result = BP_RESULT_FAILURE;
2338 
2339 	ENABLE_DISP_POWER_GATING_PS_ALLOCATION params = {0};
2340 	uint8_t atom_crtc_id;
2341 
2342 	if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
2343 		params.ucDispPipeId = atom_crtc_id;
2344 	else
2345 		return BP_RESULT_BADINPUT;
2346 
2347 	params.ucEnable =
2348 			bp->cmd_helper->disp_power_gating_action_to_atom(action);
2349 
2350 	if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
2351 		result = BP_RESULT_OK;
2352 
2353 	return result;
2354 }
2355 
2356 /*******************************************************************************
2357  ********************************************************************************
2358  **
2359  **                  SET DCE CLOCK
2360  **
2361  ********************************************************************************
2362  *******************************************************************************/
2363 static enum bp_result set_dce_clock_v2_1(
2364 	struct bios_parser *bp,
2365 	struct bp_set_dce_clock_parameters *bp_params);
2366 
2367 static void init_set_dce_clock(struct bios_parser *bp)
2368 {
2369 	switch (BIOS_CMD_TABLE_PARA_REVISION(SetDCEClock)) {
2370 	case 1:
2371 		bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
2372 		break;
2373 	default:
2374 		bp->cmd_tbl.set_dce_clock = NULL;
2375 		break;
2376 	}
2377 }
2378 
2379 static enum bp_result set_dce_clock_v2_1(
2380 	struct bios_parser *bp,
2381 	struct bp_set_dce_clock_parameters *bp_params)
2382 {
2383 	enum bp_result result = BP_RESULT_FAILURE;
2384 
2385 	SET_DCE_CLOCK_PS_ALLOCATION_V2_1 params;
2386 	uint32_t atom_pll_id;
2387 	uint32_t atom_clock_type;
2388 	const struct command_table_helper *cmd = bp->cmd_helper;
2389 
2390 	memset(&params, 0, sizeof(params));
2391 
2392 	if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
2393 			!cmd->dc_clock_type_to_atom(bp_params->clock_type, &atom_clock_type))
2394 		return BP_RESULT_BADINPUT;
2395 
2396 	params.asParam.ucDCEClkSrc  = atom_pll_id;
2397 	params.asParam.ucDCEClkType = atom_clock_type;
2398 
2399 	if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
2400 		if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
2401 			params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
2402 
2403 		if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
2404 			params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
2405 
2406 		if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
2407 			params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
2408 
2409 		if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
2410 			params.asParam.ucDCEClkFlag |= DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
2411 	}
2412 	else
2413 		/* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
2414 		/* We need to convert from KHz units into 10KHz units */
2415 		params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
2416 
2417 	if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
2418 		/* Convert from 10KHz units back to KHz */
2419 		bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
2420 		result = BP_RESULT_OK;
2421 	}
2422 
2423 	return result;
2424 }
2425