brintos

brintos / linux-shallow public Read only

0
0
Text · 72.9 KiB · 2bcae06 Raw
2433 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *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 50static void init_dig_encoder_control(struct bios_parser *bp);51static void init_transmitter_control(struct bios_parser *bp);52static void init_set_pixel_clock(struct bios_parser *bp);53static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);54static void init_adjust_display_pll(struct bios_parser *bp);55static void init_dac_encoder_control(struct bios_parser *bp);56static void init_dac_output_control(struct bios_parser *bp);57static void init_set_crtc_timing(struct bios_parser *bp);58static void init_enable_crtc(struct bios_parser *bp);59static void init_enable_crtc_mem_req(struct bios_parser *bp);60static void init_external_encoder_control(struct bios_parser *bp);61static void init_enable_disp_power_gating(struct bios_parser *bp);62static void init_program_clock(struct bios_parser *bp);63static void init_set_dce_clock(struct bios_parser *bp);64 65void 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 83static 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	else94		return 0;95}96 97/*******************************************************************************98 ********************************************************************************99 **100 **                  D I G E N C O D E R C O N T R O L101 **102 ********************************************************************************103 *******************************************************************************/104static enum bp_result encoder_control_digx_v3(105	struct bios_parser *bp,106	struct bp_encoder_control *cntl);107 108static enum bp_result encoder_control_digx_v4(109	struct bios_parser *bp,110	struct bp_encoder_control *cntl);111 112static enum bp_result encoder_control_digx_v5(113	struct bios_parser *bp,114	struct bp_encoder_control *cntl);115 116static void init_encoder_control_dig_v1(struct bios_parser *bp);117 118static 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 141static enum bp_result encoder_control_dig_v1(142	struct bios_parser *bp,143	struct bp_encoder_control *cntl);144static enum bp_result encoder_control_dig1_v1(145	struct bios_parser *bp,146	struct bp_encoder_control *cntl);147static enum bp_result encoder_control_dig2_v1(148	struct bios_parser *bp,149	struct bp_encoder_control *cntl);150 151static 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	else158		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	else163		cmd_tbl->encoder_control_dig2 = NULL;164 165	cmd_tbl->dig_encoder_control = encoder_control_dig_v1;166}167 168static 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 195static 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 210static 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 225static 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	else235		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 271static 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	else281		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 317static 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 CONTROL379 **380 ********************************************************************************381 *******************************************************************************/382 383static enum bp_result transmitter_control_v2(384	struct bios_parser *bp,385	struct bp_transmitter_control *cntl);386static enum bp_result transmitter_control_v3(387	struct bios_parser *bp,388	struct bp_transmitter_control *cntl);389static enum bp_result transmitter_control_v4(390	struct bios_parser *bp,391	struct bp_transmitter_control *cntl);392static enum bp_result transmitter_control_v1_5(393	struct bios_parser *bp,394	struct bp_transmitter_control *cntl);395static enum bp_result transmitter_control_v1_6(396	struct bios_parser *bp,397	struct bp_transmitter_control *cntl);398 399static void init_transmitter_control(struct bios_parser *bp)400{401	uint8_t frev;402	uint8_t crev = 0;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 430static 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 the459			 * physical connector460			 * Bit0: dual link connector flag461			 * =0 connector is single link connector462			 * =1 connector is dual link connector463			 */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 to479			 * actual timing (number of lanes)480			 * Bit0: dual link connector flag481			 * =0 connector is single link connector482			 * =1 connector is dual link connector483			 */484			params.acConfig.fDualLinkConnector = 1;485 486			/* link rate, half for dual link487			 * We need to convert from KHz units into 20KHz units488			 */489			params.usPixelClock =490					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));491		} else492			/* link rate, half for dual link493			 * We need to convert from KHz units into 10KHz units494			 */495			params.usPixelClock =496					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));497		break;498	}499 500	/* 00 - coherent mode501	 * 01 - incoherent mode502	 */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 selection510		 * =0 when bit0=0, single link A/C/E, when bit0=1,511		 * master link A/C/E512		 * =1 when bit0=0, single link B/D/F, when bit0=1,513		 * master link B/D/F514		 */515		params.acConfig.ucLinkSel = 1;516 517	if (ENGINE_ID_DIGB == cntl->engine_id)518		/* Bit3: Transmitter data source selection519		 * =0 DIGA is data source.520		 * =1 DIGB is data source.521		 * This bit is only useful when ucAction= ATOM_ENABLE522		 */523		params.acConfig.ucEncoderSel = 1;524 525	if (CONNECTOR_ID_DISPLAY_PORT == connector_id ||526	    CONNECTOR_ID_USBC == connector_id)527		/* Bit4: DP connector flag528		 * =0 connector is none-DP connector529		 * =1 connector is DP connector530		 */531		params.acConfig.fDPConnector = 1;532 533	/* Bit[7:6]: Transmitter selection534	 * =0 UNIPHY_ENCODER: UNIPHYA/B535	 * =1 UNIPHY1_ENCODER: UNIPHYC/D536	 * =2 UNIPHY2_ENCODER: UNIPHYE/F537	 * =3 reserved538	 */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 551static 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 the587			 * phisycal connector588			 * Bit0: dual link connector flag589			 * =0 connector is single link connector590			 * =1 connector is dual link connector591			 */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 to607			 * actual timing (number of lanes)608			 * Bit0: dual link connector flag609			 * =0 connector is single link connector610			 * =1 connector is dual link connector611			 */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 to617			 * actual timing (number of lanes)618			 * Bit0: dual link connector flag619			 * =0 connector is single link connector620			 * =1 connector is dual link connector621			 */622			params.acConfig.fDualLinkConnector = 1;623 624			/* link rate, half for dual link625			 * We need to convert from KHz units into 20KHz units626			 */627			params.usPixelClock =628					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));629		} else {630			/* link rate, half for dual link631			 * We need to convert from KHz units into 10KHz units632			 */633			params.usPixelClock =634					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));635		}636		break;637	}638 639	/* 00 - coherent mode640	 * 01 - incoherent mode641	 */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 selection649		 * =0 when bit0=0, single link A/C/E, when bit0=1,650		 * master link A/C/E651		 * =1 when bit0=0, single link B/D/F, when bit0=1,652		 * master link B/D/F653		 */654		params.acConfig.ucLinkSel = 1;655 656	if (ENGINE_ID_DIGB == cntl->engine_id)657		/* Bit3: Transmitter data source selection658		 * =0 DIGA is data source.659		 * =1 DIGB is data source.660		 * This bit is only useful when ucAction= ATOM_ENABLE661		 */662		params.acConfig.ucEncoderSel = 1;663 664	/* Bit[7:6]: Transmitter selection665	 * =0 UNIPHY_ENCODER: UNIPHYA/B666	 * =1 UNIPHY1_ENCODER: UNIPHYC/D667	 * =2 UNIPHY2_ENCODER: UNIPHYE/F668	 * =3 reserved669	 */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 685static 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 the720			 * phisycal connector721			 * Bit0: dual link connector flag722			 * =0 connector is single link connector723			 * =1 connector is dual link connector724			 */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 to741			 * actual timing (number of lanes)742			 * Bit0: dual link connector flag743			 * =0 connector is single link connector744			 * =1 connector is dual link connector745			 */746			params.acConfig.fDualLinkConnector = 1;747 748		/* if dual-link */749		if (LANE_COUNT_FOUR < cntl->lanes_number)750			/* link rate, half for dual link751			 * We need to convert from KHz units into 20KHz units752			 */753			params.usPixelClock =754					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));755		else {756			/* link rate, half for dual link757			 * We need to convert from KHz units into 10KHz units758			 */759			params.usPixelClock =760					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));761		}762		break;763	}764 765	/* 00 - coherent mode766	 * 01 - incoherent mode767	 */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 selection775		 * =0 when bit0=0, single link A/C/E, when bit0=1,776		 * master link A/C/E777		 * =1 when bit0=0, single link B/D/F, when bit0=1,778		 * master link B/D/F779		 */780		params.acConfig.ucLinkSel = 1;781 782	if (ENGINE_ID_DIGB == cntl->engine_id)783		/* Bit3: Transmitter data source selection784		 * =0 DIGA is data source.785		 * =1 DIGB is data source.786		 * This bit is only useful when ucAction= ATOM_ENABLE787		 */788		params.acConfig.ucEncoderSel = 1;789 790	/* Bit[7:6]: Transmitter selection791	 * =0 UNIPHY_ENCODER: UNIPHYA/B792	 * =1 UNIPHY1_ENCODER: UNIPHYC/D793	 * =2 UNIPHY2_ENCODER: UNIPHYE/F794	 * =3 reserved795	 */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 808static 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/10837	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)838	 * DVI single link mode: usPixelClock = pixel clock839	 * DVI dual link mode: usPixelClock = pixel clock840	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio841	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)842	 * LVDS mode: usPixelClock = pixel clock843	 */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 869static 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	else884		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/10895	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)896	 * DVI single link mode: usPixelClock = pixel clock897	 * DVI dual link mode: usPixelClock = pixel clock898	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio899	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)900	 * LVDS mode: usPixelClock = pixel clock901	 */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 CLOCK934 **935 ********************************************************************************936 *******************************************************************************/937 938static enum bp_result set_pixel_clock_v3(939	struct bios_parser *bp,940	struct bp_pixel_clock_parameters *bp_params);941static enum bp_result set_pixel_clock_v5(942	struct bios_parser *bp,943	struct bp_pixel_clock_parameters *bp_params);944static enum bp_result set_pixel_clock_v6(945	struct bios_parser *bp,946	struct bp_pixel_clock_parameters *bp_params);947static enum bp_result set_pixel_clock_v7(948	struct bios_parser *bp,949	struct bp_pixel_clock_parameters *bp_params);950 951static 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 974static 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	else989		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_V51029/* video bios did not define this: */1030typedef 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#endif1036 1037#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V61038/* video bios did not define this: */1039typedef 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#endif1045 1046static 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: 24bpp1091		 * =1:30bpp, =2:32bpp1092		 * driver choose program it itself, i.e. here we program it1093		 * 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 1116static 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 now1131		 * 1 byte in ULONG1132		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ1133		 *{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 to1137		 * previous version.1138		 * ATOM_CRTC1~6, indicate the CRTC controller to1139		 * ULONG ucCRTC:8;1140		 * drive the pixel clock. not used for DCPLL case.1141		 *}CRTC_PIXEL_CLOCK_FREQ;1142		 *union1143		 *{1144		 * pixel clock and CRTC id frequency1145		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;1146		 * ULONG ulDispEngClkFreq; dispclk frequency1147		 *};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:32bpp1183		 * driver choose program it itself, i.e. here we pass required1184		 * 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 1208static 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 now1222		 * 1 byte in ULONG1223		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ1224		 *{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 to1228		 * previous version.1229		 * ATOM_CRTC1~6, indicate the CRTC controller to1230		 * ULONG ucCRTC:8;1231		 * drive the pixel clock. not used for DCPLL case.1232		 *}CRTC_PIXEL_CLOCK_FREQ;1233		 *union1234		 *{1235		 * pixel clock and CRTC id frequency1236		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;1237		 * ULONG ulDispEngClkFreq; dispclk frequency1238		 *};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 SS1280 **1281 ********************************************************************************1282 *******************************************************************************/1283static 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);1287static 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);1291static 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 1296static 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 1319static 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	else1332		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	else1355		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 1363static 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	else1378		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 bit1397		 * comparison. Otherwise, the result will always be zero here1398		 */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	} else1407		params.ucEnable = ATOM_DISABLE;1408 1409	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))1410		result = BP_RESULT_OK;1411 1412	return result;1413}1414 1415static 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 bit1466		 * comparison. Otherwise, the result will always be zero here1467		 */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	} else1476		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 PLL1488 **1489 ********************************************************************************1490 *******************************************************************************/1491 1492static enum bp_result adjust_display_pll_v2(1493	struct bios_parser *bp,1494	struct bp_adjust_pixel_clock_parameters *bp_params);1495static enum bp_result adjust_display_pll_v3(1496	struct bios_parser *bp,1497	struct bp_adjust_pixel_clock_parameters *bp_params);1498 1499static 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 1516static 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 convert1524	 * 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: multiply1538		 * original pixel clock in KHz by ratio1539		 * [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 1559static 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 convert1570	 * 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: multiply1588		 * original pixel clock in KHz by ratio1589		 * [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 CONTROL1616 **1617 ********************************************************************************1618 *******************************************************************************/1619 1620static 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);1625static 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 1631static 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 1651static 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	else1661		params->ucAction = ATOM_DISABLE;1662 1663	/* We need to convert from KHz units into 10KHz units1664	 * it looks as if the TvControl do not care about pixel clock1665	 */1666	params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));1667}1668 1669static 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 1690static 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 CONTROL1715 **1716 ********************************************************************************1717 *******************************************************************************/1718static enum bp_result dac1_output_control_v1(1719	struct bios_parser *bp,1720	bool enable);1721static enum bp_result dac2_output_control_v1(1722	struct bios_parser *bp,1723	bool enable);1724 1725static 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 1745static 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	else1754		params.ucAction = ATOM_DISABLE;1755 1756	if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))1757		result = BP_RESULT_OK;1758 1759	return result;1760}1761 1762static 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	else1771		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 TIMING1783 **1784 ********************************************************************************1785 *******************************************************************************/1786 1787static enum bp_result set_crtc_using_dtd_timing_v3(1788	struct bios_parser *bp,1789	struct bp_hw_crtc_timing_parameters *bp_params);1790static enum bp_result set_crtc_timing_v1(1791	struct bios_parser *bp,1792	struct bp_hw_crtc_timing_parameters *bp_params);1793 1794static 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	else1811		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 1823static 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, for1847	 * underscan use another entry ProgramOverscan call but when mode1848	 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,1849	 * but when same ,but 60 Hz there is corruption1850	 * DAL1 does not allow the mode 1776x1000@601851	 */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 for1870		 * non-TV/CV only due to complex MV testing for possible1871		 * impact1872		 * 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.51878		 * lines for the 2nd feild. we need input as 5 instead1879		 * of 4, but it is 4 either from Edid data1880		 * (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 1896static 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 beginning1920	 * 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 of1926	 * 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 bigger1932	 * than 2551933	 * we will program all the borders in the Set CRTC Overscan call below1934	 */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 this1949		 * for non-TV/CV only1950		 * due to complex MV testing for possible impact1951		 * 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 51959			 * 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 CRTC1981 **1982 ********************************************************************************1983 *******************************************************************************/1984 1985static enum bp_result enable_crtc_v1(1986	struct bios_parser *bp,1987	enum controller_id controller_id,1988	bool enable);1989 1990static 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 2004static 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	else2016		return BP_RESULT_BADINPUT;2017 2018	if (enable)2019		params.ucEnable = ATOM_ENABLE;2020	else2021		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 REQ2033 **2034 ********************************************************************************2035 *******************************************************************************/2036 2037static enum bp_result enable_crtc_mem_req_v1(2038	struct bios_parser *bp,2039	enum controller_id controller_id,2040	bool enable);2041 2042static 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 2054static 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		else2069			params.ucEnable = ATOM_DISABLE;2070 2071		if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))2072			result = BP_RESULT_OK;2073		else2074			result = BP_RESULT_FAILURE;2075	}2076 2077	return result;2078}2079 2080/*******************************************************************************2081 ********************************************************************************2082 **2083 **                  DISPLAY PLL2084 **2085 ********************************************************************************2086 *******************************************************************************/2087 2088static enum bp_result program_clock_v5(2089	struct bios_parser *bp,2090	struct bp_pixel_clock_parameters *bp_params);2091static enum bp_result program_clock_v6(2092	struct bios_parser *bp,2093	struct bp_pixel_clock_parameters *bp_params);2094 2095static 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 2112static 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 2143static 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 bypass2173		 * 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 CONTROL2186 **2187 ********************************************************************************2188 *******************************************************************************/2189 2190static enum bp_result external_encoder_control_v3(2191	struct bios_parser *bp,2192	struct bp_external_encoder_control *cntl);2193 2194static 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 2208static 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 action2239	 *2240	 * Bit[6:4]: indicate external encoder, applied to all functions.2241	 * =0: external encoder1, mapped to external encoder enum id12242	 * =1: external encoder2, mapped to external encoder enum id22243	 *2244	 * enum ObjectEnumId2245	 * {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 encoder2256		 * 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 in2262		 * 10KHz2263		 * output display device pixel clock frequency in unit of 10KHz.2264		 * Only valid in setup and enableoutput2265		 */2266		cntl_params->usPixelClock =2267				cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));2268		/* Indicate display output signal type drive by external2269		 * 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 format2280			 * 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 valid2286		 * 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 GATING2313 **2314 ********************************************************************************2315 *******************************************************************************/2316 2317static 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 2322static 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 2338static 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	else2351		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 CLOCK2366 **2367 ********************************************************************************2368 *******************************************************************************/2369static enum bp_result set_dce_clock_v2_1(2370	struct bios_parser *bp,2371	struct bp_set_dce_clock_parameters *bp_params);2372 2373static 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 2387static 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	else2421		/* 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