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