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