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