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