cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

command_table.c (74636B)


      1/*
      2 * Copyright 2012-15 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "dm_services.h"
     27#include "amdgpu.h"
     28#include "atom.h"
     29
     30#include "include/bios_parser_interface.h"
     31
     32#include "command_table.h"
     33#include "command_table_helper.h"
     34#include "bios_parser_helper.h"
     35#include "bios_parser_types_internal.h"
     36
     37#define EXEC_BIOS_CMD_TABLE(command, params)\
     38	(amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
     39		GetIndexIntoMasterTable(COMMAND, command), \
     40		(uint32_t *)&params) == 0)
     41
     42#define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
     43	amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
     44		GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
     45
     46#define BIOS_CMD_TABLE_PARA_REVISION(command)\
     47	bios_cmd_table_para_revision(bp->base.ctx->driver_context, \
     48		GetIndexIntoMasterTable(COMMAND, command))
     49
     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	else
     94		return 0;
     95}
     96
     97/*******************************************************************************
     98 ********************************************************************************
     99 **
    100 **                  D I G E N C O D E R C O N T R O L
    101 **
    102 ********************************************************************************
    103 *******************************************************************************/
    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	else
    158		cmd_tbl->encoder_control_dig1 = NULL;
    159
    160	if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
    161		cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
    162	else
    163		cmd_tbl->encoder_control_dig2 = NULL;
    164
    165	cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
    166}
    167
    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	else
    235		params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
    236
    237	params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
    238
    239	/* We need to convert from KHz units into 10KHz units */
    240	params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
    241	params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
    242	params.ucEncoderMode =
    243			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
    244					cntl->signal,
    245					cntl->enable_dp_audio);
    246	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
    247
    248	switch (cntl->color_depth) {
    249	case COLOR_DEPTH_888:
    250		params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
    251		break;
    252	case COLOR_DEPTH_101010:
    253		params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
    254		break;
    255	case COLOR_DEPTH_121212:
    256		params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
    257		break;
    258	case COLOR_DEPTH_161616:
    259		params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
    260		break;
    261	default:
    262		break;
    263	}
    264
    265	if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
    266		result = BP_RESULT_OK;
    267
    268	return result;
    269}
    270
    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	else
    281		params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
    282
    283	params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
    284
    285	/* We need to convert from KHz units into 10KHz units */
    286	params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
    287	params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
    288	params.ucEncoderMode =
    289			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
    290					cntl->signal,
    291					cntl->enable_dp_audio));
    292	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
    293
    294	switch (cntl->color_depth) {
    295	case COLOR_DEPTH_888:
    296		params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
    297		break;
    298	case COLOR_DEPTH_101010:
    299		params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
    300		break;
    301	case COLOR_DEPTH_121212:
    302		params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
    303		break;
    304	case COLOR_DEPTH_161616:
    305		params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
    306		break;
    307	default:
    308		break;
    309	}
    310
    311	if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
    312		result = BP_RESULT_OK;
    313
    314	return result;
    315}
    316
    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 CONTROL
    379 **
    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;
    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 the
    459			 * physical connector
    460			 * Bit0: dual link connector flag
    461			 * =0 connector is single link connector
    462			 * =1 connector is dual link connector
    463			 */
    464			params.acConfig.fDualLinkConnector = 1;
    465
    466		/* connector object id */
    467		params.usInitInfo =
    468				cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
    469		break;
    470	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
    471		/* voltage swing and pre-emphsis */
    472		params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
    473		params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
    474		break;
    475	default:
    476		/* if dual-link */
    477		if (LANE_COUNT_FOUR < cntl->lanes_number) {
    478			/* on ENABLE/DISABLE this bit should be set according to
    479			 * actual timing (number of lanes)
    480			 * Bit0: dual link connector flag
    481			 * =0 connector is single link connector
    482			 * =1 connector is dual link connector
    483			 */
    484			params.acConfig.fDualLinkConnector = 1;
    485
    486			/* link rate, half for dual link
    487			 * We need to convert from KHz units into 20KHz units
    488			 */
    489			params.usPixelClock =
    490					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
    491		} else
    492			/* link rate, half for dual link
    493			 * We need to convert from KHz units into 10KHz units
    494			 */
    495			params.usPixelClock =
    496					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
    497		break;
    498	}
    499
    500	/* 00 - coherent mode
    501	 * 01 - incoherent mode
    502	 */
    503
    504	params.acConfig.fCoherentMode = cntl->coherent;
    505
    506	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
    507			|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
    508			|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
    509		/* Bit2: Transmitter Link selection
    510		 * =0 when bit0=0, single link A/C/E, when bit0=1,
    511		 * master link A/C/E
    512		 * =1 when bit0=0, single link B/D/F, when bit0=1,
    513		 * master link B/D/F
    514		 */
    515		params.acConfig.ucLinkSel = 1;
    516
    517	if (ENGINE_ID_DIGB == cntl->engine_id)
    518		/* Bit3: Transmitter data source selection
    519		 * =0 DIGA is data source.
    520		 * =1 DIGB is data source.
    521		 * This bit is only useful when ucAction= ATOM_ENABLE
    522		 */
    523		params.acConfig.ucEncoderSel = 1;
    524
    525	if (CONNECTOR_ID_DISPLAY_PORT == connector_id
    526		|| CONNECTOR_ID_USBC == connector_id)
    527		/* Bit4: DP connector flag
    528		 * =0 connector is none-DP connector
    529		 * =1 connector is DP connector
    530		 */
    531		params.acConfig.fDPConnector = 1;
    532
    533	/* Bit[7:6]: Transmitter selection
    534	 * =0 UNIPHY_ENCODER: UNIPHYA/B
    535	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
    536	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
    537	 * =3 reserved
    538	 */
    539	params.acConfig.ucTransmitterSel =
    540			(uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
    541					cntl->transmitter);
    542
    543	params.ucAction = (uint8_t)cntl->action;
    544
    545	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
    546		result = BP_RESULT_OK;
    547
    548	return result;
    549}
    550
    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 the
    587			 * phisycal connector
    588			 * Bit0: dual link connector flag
    589			 * =0 connector is single link connector
    590			 * =1 connector is dual link connector
    591			 */
    592			params.acConfig.fDualLinkConnector = 1;
    593		}
    594
    595		/* connector object id */
    596		params.usInitInfo =
    597				cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
    598		break;
    599	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
    600		/* votage swing and pre-emphsis */
    601		params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
    602		params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
    603		break;
    604	default:
    605		if (dual_link_conn && cntl->multi_path)
    606			/* on ENABLE/DISABLE this bit should be set according to
    607			 * actual timing (number of lanes)
    608			 * Bit0: dual link connector flag
    609			 * =0 connector is single link connector
    610			 * =1 connector is dual link connector
    611			 */
    612			params.acConfig.fDualLinkConnector = 1;
    613
    614		/* if dual-link */
    615		if (LANE_COUNT_FOUR < cntl->lanes_number) {
    616			/* on ENABLE/DISABLE this bit should be set according to
    617			 * actual timing (number of lanes)
    618			 * Bit0: dual link connector flag
    619			 * =0 connector is single link connector
    620			 * =1 connector is dual link connector
    621			 */
    622			params.acConfig.fDualLinkConnector = 1;
    623
    624			/* link rate, half for dual link
    625			 * We need to convert from KHz units into 20KHz units
    626			 */
    627			params.usPixelClock =
    628					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
    629		} else {
    630			/* link rate, half for dual link
    631			 * We need to convert from KHz units into 10KHz units
    632			 */
    633			params.usPixelClock =
    634					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
    635		}
    636		break;
    637	}
    638
    639	/* 00 - coherent mode
    640	 * 01 - incoherent mode
    641	 */
    642
    643	params.acConfig.fCoherentMode = cntl->coherent;
    644
    645	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
    646		|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
    647		|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
    648		/* Bit2: Transmitter Link selection
    649		 * =0 when bit0=0, single link A/C/E, when bit0=1,
    650		 * master link A/C/E
    651		 * =1 when bit0=0, single link B/D/F, when bit0=1,
    652		 * master link B/D/F
    653		 */
    654		params.acConfig.ucLinkSel = 1;
    655
    656	if (ENGINE_ID_DIGB == cntl->engine_id)
    657		/* Bit3: Transmitter data source selection
    658		 * =0 DIGA is data source.
    659		 * =1 DIGB is data source.
    660		 * This bit is only useful when ucAction= ATOM_ENABLE
    661		 */
    662		params.acConfig.ucEncoderSel = 1;
    663
    664	/* Bit[7:6]: Transmitter selection
    665	 * =0 UNIPHY_ENCODER: UNIPHYA/B
    666	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
    667	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
    668	 * =3 reserved
    669	 */
    670	params.acConfig.ucTransmitterSel =
    671			(uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
    672
    673	params.ucLaneNum = (uint8_t)cntl->lanes_number;
    674
    675	params.acConfig.ucRefClkSource = (uint8_t)pll_id;
    676
    677	params.ucAction = (uint8_t)cntl->action;
    678
    679	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
    680		result = BP_RESULT_OK;
    681
    682	return result;
    683}
    684
    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 the
    720			 * phisycal connector
    721			 * Bit0: dual link connector flag
    722			 * =0 connector is single link connector
    723			 * =1 connector is dual link connector
    724			 */
    725			params.acConfig.fDualLinkConnector = 1;
    726
    727		/* connector object id */
    728		params.usInitInfo =
    729				cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
    730	}
    731	break;
    732	case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
    733		/* votage swing and pre-emphsis */
    734		params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
    735		params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
    736		break;
    737	default:
    738		if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
    739				(CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
    740			/* on ENABLE/DISABLE this bit should be set according to
    741			 * actual timing (number of lanes)
    742			 * Bit0: dual link connector flag
    743			 * =0 connector is single link connector
    744			 * =1 connector is dual link connector
    745			 */
    746			params.acConfig.fDualLinkConnector = 1;
    747
    748		/* if dual-link */
    749		if (LANE_COUNT_FOUR < cntl->lanes_number)
    750			/* link rate, half for dual link
    751			 * We need to convert from KHz units into 20KHz units
    752			 */
    753			params.usPixelClock =
    754					cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
    755		else {
    756			/* link rate, half for dual link
    757			 * We need to convert from KHz units into 10KHz units
    758			 */
    759			params.usPixelClock =
    760					cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
    761		}
    762		break;
    763	}
    764
    765	/* 00 - coherent mode
    766	 * 01 - incoherent mode
    767	 */
    768
    769	params.acConfig.fCoherentMode = cntl->coherent;
    770
    771	if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
    772		|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
    773		|| (TRANSMITTER_UNIPHY_F == cntl->transmitter))
    774		/* Bit2: Transmitter Link selection
    775		 * =0 when bit0=0, single link A/C/E, when bit0=1,
    776		 * master link A/C/E
    777		 * =1 when bit0=0, single link B/D/F, when bit0=1,
    778		 * master link B/D/F
    779		 */
    780		params.acConfig.ucLinkSel = 1;
    781
    782	if (ENGINE_ID_DIGB == cntl->engine_id)
    783		/* Bit3: Transmitter data source selection
    784		 * =0 DIGA is data source.
    785		 * =1 DIGB is data source.
    786		 * This bit is only useful when ucAction= ATOM_ENABLE
    787		 */
    788		params.acConfig.ucEncoderSel = 1;
    789
    790	/* Bit[7:6]: Transmitter selection
    791	 * =0 UNIPHY_ENCODER: UNIPHYA/B
    792	 * =1 UNIPHY1_ENCODER: UNIPHYC/D
    793	 * =2 UNIPHY2_ENCODER: UNIPHYE/F
    794	 * =3 reserved
    795	 */
    796	params.acConfig.ucTransmitterSel =
    797		(uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
    798	params.ucLaneNum = (uint8_t)(cntl->lanes_number);
    799	params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
    800	params.ucAction = (uint8_t)(cntl->action);
    801
    802	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
    803		result = BP_RESULT_OK;
    804
    805	return result;
    806}
    807
    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/10
    837	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
    838	 * DVI single link mode: usPixelClock = pixel clock
    839	 * DVI dual link mode: usPixelClock = pixel clock
    840	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
    841	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
    842	 * LVDS mode: usPixelClock = pixel clock
    843	 */
    844	if  (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
    845		switch (cntl->color_depth) {
    846		case COLOR_DEPTH_101010:
    847			params.usSymClock =
    848				cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24);
    849			break;
    850		case COLOR_DEPTH_121212:
    851			params.usSymClock =
    852				cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24);
    853			break;
    854		case COLOR_DEPTH_161616:
    855			params.usSymClock =
    856				cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24);
    857			break;
    858		default:
    859			break;
    860		}
    861	}
    862
    863	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
    864		result = BP_RESULT_OK;
    865
    866	return result;
    867}
    868
    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	else
    884		params.ucDigMode = cmd->signal_type_to_atom_dig_mode(cntl->signal);
    885
    886	params.ucLaneNum = (uint8_t)cntl->lanes_number;
    887	params.ucHPDSel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
    888	params.ucDigEncoderSel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
    889	params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
    890	params.ulSymClock = cntl->pixel_clock/10;
    891
    892	/*
    893	 * In SI/TN case, caller have to set usPixelClock as following:
    894	 * DP mode: usPixelClock = DP_LINK_CLOCK/10
    895	 * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
    896	 * DVI single link mode: usPixelClock = pixel clock
    897	 * DVI dual link mode: usPixelClock = pixel clock
    898	 * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
    899	 * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
    900	 * LVDS mode: usPixelClock = pixel clock
    901	 */
    902	switch (cntl->signal) {
    903	case SIGNAL_TYPE_HDMI_TYPE_A:
    904		switch (cntl->color_depth) {
    905		case COLOR_DEPTH_101010:
    906			params.ulSymClock =
    907				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 30) / 24);
    908			break;
    909		case COLOR_DEPTH_121212:
    910			params.ulSymClock =
    911				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 36) / 24);
    912			break;
    913		case COLOR_DEPTH_161616:
    914			params.ulSymClock =
    915				cpu_to_le16((le16_to_cpu(params.ulSymClock) * 48) / 24);
    916			break;
    917		default:
    918			break;
    919		}
    920		break;
    921		default:
    922			break;
    923	}
    924
    925	if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
    926		result = BP_RESULT_OK;
    927	return result;
    928}
    929
    930/*******************************************************************************
    931 ********************************************************************************
    932 **
    933 **                  SET PIXEL CLOCK
    934 **
    935 ********************************************************************************
    936 *******************************************************************************/
    937
    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	else
    989		return BP_RESULT_BADINPUT;
    990
    991	allocation.sPCLKInput.usRefDiv =
    992			cpu_to_le16((uint16_t)bp_params->reference_divider);
    993	allocation.sPCLKInput.usFbDiv =
    994			cpu_to_le16((uint16_t)bp_params->feedback_divider);
    995	allocation.sPCLKInput.ucFracFbDiv =
    996			(uint8_t)bp_params->fractional_feedback_divider;
    997	allocation.sPCLKInput.ucPostDiv =
    998			(uint8_t)bp_params->pixel_clock_post_divider;
    999
   1000	/* We need to convert from 100Hz units into 10KHz units */
   1001	allocation.sPCLKInput.usPixelClock =
   1002			cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
   1003
   1004	params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
   1005	params->ucTransmitterId =
   1006			bp->cmd_helper->encoder_id_to_atom(
   1007					dal_graphics_object_id_get_encoder_id(
   1008							bp_params->encoder_object_id));
   1009	params->ucEncoderMode =
   1010			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
   1011					bp_params->signal_type, false));
   1012
   1013	if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
   1014		params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
   1015
   1016	if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
   1017		params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
   1018
   1019	if (CONTROLLER_ID_D1 != bp_params->controller_id)
   1020		params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
   1021
   1022	if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
   1023		result = BP_RESULT_OK;
   1024
   1025	return result;
   1026}
   1027
   1028#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
   1029/* video bios did not define this: */
   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#endif
   1036
   1037#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
   1038/* 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#endif
   1045
   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: 24bpp
   1091		 * =1:30bpp, =2:32bpp
   1092		 * driver choose program it itself, i.e. here we program it
   1093		 * to 888 by default.
   1094		 */
   1095		if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A)
   1096			switch (bp_params->color_depth) {
   1097			case TRANSMITTER_COLOR_DEPTH_30:
   1098				/* yes this is correct, the atom define is wrong */
   1099				clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
   1100				break;
   1101			case TRANSMITTER_COLOR_DEPTH_36:
   1102				/* yes this is correct, the atom define is wrong */
   1103				clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
   1104				break;
   1105			default:
   1106				break;
   1107			}
   1108
   1109		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
   1110			result = BP_RESULT_OK;
   1111	}
   1112
   1113	return result;
   1114}
   1115
   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 now
   1131		 * 1 byte in ULONG
   1132		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
   1133		 *{
   1134		 * target the pixel clock to drive the CRTC timing.
   1135		 * ULONG ulPixelClock:24;
   1136		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
   1137		 * previous version.
   1138		 * ATOM_CRTC1~6, indicate the CRTC controller to
   1139		 * ULONG ucCRTC:8;
   1140		 * drive the pixel clock. not used for DCPLL case.
   1141		 *}CRTC_PIXEL_CLOCK_FREQ;
   1142		 *union
   1143		 *{
   1144		 * pixel clock and CRTC id frequency
   1145		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
   1146		 * ULONG ulDispEngClkFreq; dispclk frequency
   1147		 *};
   1148		 */
   1149		clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
   1150		clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
   1151		clk.sPCLKInput.ucRefDiv =
   1152				(uint8_t) bp_params->reference_divider;
   1153		clk.sPCLKInput.usFbDiv =
   1154				cpu_to_le16((uint16_t) bp_params->feedback_divider);
   1155		clk.sPCLKInput.ulFbDivDecFrac =
   1156				cpu_to_le32(bp_params->fractional_feedback_divider);
   1157		clk.sPCLKInput.ucPostDiv =
   1158				(uint8_t) bp_params->pixel_clock_post_divider;
   1159		clk.sPCLKInput.ucTransmitterID =
   1160				bp->cmd_helper->encoder_id_to_atom(
   1161						dal_graphics_object_id_get_encoder_id(
   1162								bp_params->encoder_object_id));
   1163		clk.sPCLKInput.ucEncoderMode =
   1164				(uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
   1165						bp_params->signal_type, false);
   1166
   1167		/* We need to convert from 100 Hz units into 10KHz units */
   1168		clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
   1169				cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
   1170
   1171		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
   1172			clk.sPCLKInput.ucMiscInfo |=
   1173					PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
   1174		}
   1175
   1176		if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
   1177			clk.sPCLKInput.ucMiscInfo |=
   1178					PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
   1179		}
   1180
   1181		/* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
   1182		 * 24bpp =1:30bpp, =2:32bpp
   1183		 * driver choose program it itself, i.e. here we pass required
   1184		 * target rate that includes deep color.
   1185		 */
   1186		if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A)
   1187			switch (bp_params->color_depth) {
   1188			case TRANSMITTER_COLOR_DEPTH_30:
   1189				clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
   1190				break;
   1191			case TRANSMITTER_COLOR_DEPTH_36:
   1192				clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
   1193				break;
   1194			case TRANSMITTER_COLOR_DEPTH_48:
   1195				clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
   1196				break;
   1197			default:
   1198				break;
   1199			}
   1200
   1201		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
   1202			result = BP_RESULT_OK;
   1203	}
   1204
   1205	return result;
   1206}
   1207
   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 now
   1222		 * 1 byte in ULONG
   1223		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
   1224		 *{
   1225		 * target the pixel clock to drive the CRTC timing.
   1226		 * ULONG ulPixelClock:24;
   1227		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
   1228		 * previous version.
   1229		 * ATOM_CRTC1~6, indicate the CRTC controller to
   1230		 * ULONG ucCRTC:8;
   1231		 * drive the pixel clock. not used for DCPLL case.
   1232		 *}CRTC_PIXEL_CLOCK_FREQ;
   1233		 *union
   1234		 *{
   1235		 * pixel clock and CRTC id frequency
   1236		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
   1237		 * ULONG ulDispEngClkFreq; dispclk frequency
   1238		 *};
   1239		 */
   1240		clk.ucCRTC = controller_id;
   1241		clk.ucPpll = (uint8_t) pll_id;
   1242		clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
   1243		clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
   1244
   1245		clk.ulPixelClock = cpu_to_le32(bp_params->target_pixel_clock_100hz);
   1246
   1247		clk.ucDeepColorRatio = (uint8_t) bp->cmd_helper->transmitter_color_depth_to_atom(bp_params->color_depth);
   1248
   1249		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
   1250			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
   1251
   1252		if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
   1253			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC;
   1254
   1255		if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
   1256			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
   1257
   1258		if (bp_params->flags.SUPPORT_YUV_420)
   1259			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
   1260
   1261		if (bp_params->flags.SET_XTALIN_REF_SRC)
   1262			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
   1263
   1264		if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
   1265			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
   1266
   1267		if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
   1268			clk.ucMiscInfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
   1269
   1270		if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
   1271			result = BP_RESULT_OK;
   1272	}
   1273	return result;
   1274}
   1275
   1276/*******************************************************************************
   1277 ********************************************************************************
   1278 **
   1279 **                  ENABLE PIXEL CLOCK SS
   1280 **
   1281 ********************************************************************************
   1282 *******************************************************************************/
   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	else
   1332		params.ucEnable = ATOM_DISABLE;
   1333
   1334	params.usSpreadSpectrumPercentage =
   1335			cpu_to_le16((uint16_t)bp_params->percentage);
   1336	params.ucSpreadSpectrumStep =
   1337			(uint8_t)bp_params->ver1.step;
   1338	params.ucSpreadSpectrumDelay =
   1339			(uint8_t)bp_params->ver1.delay;
   1340	/* convert back to unit of 10KHz */
   1341	params.ucSpreadSpectrumRange =
   1342			(uint8_t)(bp_params->ver1.range / 10000);
   1343
   1344	if (bp_params->flags.EXTERNAL_SS)
   1345		params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
   1346
   1347	if (bp_params->flags.CENTER_SPREAD)
   1348		params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
   1349
   1350	if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
   1351		params.ucPpll = ATOM_PPLL1;
   1352	else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
   1353		params.ucPpll = ATOM_PPLL2;
   1354	else
   1355		BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
   1356
   1357	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
   1358		result = BP_RESULT_OK;
   1359
   1360	return result;
   1361}
   1362
   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	else
   1378		BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
   1379
   1380	if ((enable == true) && (bp_params->percentage > 0)) {
   1381		params.ucEnable = ATOM_ENABLE;
   1382
   1383		params.usSpreadSpectrumPercentage =
   1384				cpu_to_le16((uint16_t)(bp_params->percentage));
   1385		params.usSpreadSpectrumStep =
   1386				cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
   1387
   1388		if (bp_params->flags.EXTERNAL_SS)
   1389			params.ucSpreadSpectrumType |=
   1390					ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
   1391
   1392		if (bp_params->flags.CENTER_SPREAD)
   1393			params.ucSpreadSpectrumType |=
   1394					ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
   1395
   1396		/* Both amounts need to be left shifted first before bit
   1397		 * comparison. Otherwise, the result will always be zero here
   1398		 */
   1399		params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
   1400				((bp_params->ds.feedback_amount <<
   1401						ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
   1402						ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
   1403						((bp_params->ds.nfrac_amount <<
   1404								ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
   1405								ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
   1406	} else
   1407		params.ucEnable = ATOM_DISABLE;
   1408
   1409	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
   1410		result = BP_RESULT_OK;
   1411
   1412	return result;
   1413}
   1414
   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 bit
   1466		 * comparison. Otherwise, the result will always be zero here
   1467		 */
   1468		params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
   1469				((bp_params->ds.feedback_amount <<
   1470						ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
   1471						ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
   1472						((bp_params->ds.nfrac_amount <<
   1473								ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
   1474								ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
   1475	} else
   1476		params.ucEnable = ATOM_DISABLE;
   1477
   1478	if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
   1479		result = BP_RESULT_OK;
   1480
   1481	return result;
   1482}
   1483
   1484/*******************************************************************************
   1485 ********************************************************************************
   1486 **
   1487 **                  ADJUST DISPLAY PLL
   1488 **
   1489 ********************************************************************************
   1490 *******************************************************************************/
   1491
   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 convert
   1524	 * output pixel clock back 10KHz-->KHz */
   1525	uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
   1526
   1527	params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
   1528	params.ucTransmitterID =
   1529			bp->cmd_helper->encoder_id_to_atom(
   1530					dal_graphics_object_id_get_encoder_id(
   1531							bp_params->encoder_object_id));
   1532	params.ucEncodeMode =
   1533			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
   1534					bp_params->signal_type, false);
   1535
   1536	if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
   1537		/* Convert output pixel clock back 10KHz-->KHz: multiply
   1538		 * original pixel clock in KHz by ratio
   1539		 * [output pxlClk/input pxlClk] */
   1540		uint64_t pixel_clk_10_khz_out =
   1541				(uint64_t)le16_to_cpu(params.usPixelClock);
   1542		uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
   1543
   1544		if (pixel_clock_10KHz_in != 0) {
   1545			bp_params->adjusted_pixel_clock =
   1546					div_u64(pixel_clk * pixel_clk_10_khz_out,
   1547							pixel_clock_10KHz_in);
   1548		} else {
   1549			bp_params->adjusted_pixel_clock = 0;
   1550			BREAK_TO_DEBUGGER();
   1551		}
   1552
   1553		result = BP_RESULT_OK;
   1554	}
   1555
   1556	return result;
   1557}
   1558
   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 convert
   1570	 * output pixel clock back 10KHz-->KHz */
   1571	params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
   1572	params.sInput.ucTransmitterID =
   1573			bp->cmd_helper->encoder_id_to_atom(
   1574					dal_graphics_object_id_get_encoder_id(
   1575							bp_params->encoder_object_id));
   1576	params.sInput.ucEncodeMode =
   1577			(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
   1578					bp_params->signal_type, false);
   1579
   1580	if (bp_params->ss_enable == true)
   1581		params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
   1582
   1583	if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
   1584		params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
   1585
   1586	if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
   1587		/* Convert output pixel clock back 10KHz-->KHz: multiply
   1588		 * original pixel clock in KHz by ratio
   1589		 * [output pxlClk/input pxlClk] */
   1590		uint64_t pixel_clk_10_khz_out =
   1591				(uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
   1592		uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
   1593
   1594		if (pixel_clk_10_kHz_in != 0) {
   1595			bp_params->adjusted_pixel_clock =
   1596					div_u64(pixel_clk * pixel_clk_10_khz_out,
   1597							pixel_clk_10_kHz_in);
   1598		} else {
   1599			bp_params->adjusted_pixel_clock = 0;
   1600			BREAK_TO_DEBUGGER();
   1601		}
   1602
   1603		bp_params->reference_divider = params.sOutput.ucRefDiv;
   1604		bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
   1605
   1606		result = BP_RESULT_OK;
   1607	}
   1608
   1609	return result;
   1610}
   1611
   1612/*******************************************************************************
   1613 ********************************************************************************
   1614 **
   1615 **                  DAC ENCODER CONTROL
   1616 **
   1617 ********************************************************************************
   1618 *******************************************************************************/
   1619
   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	else
   1661		params->ucAction = ATOM_DISABLE;
   1662
   1663	/* We need to convert from KHz units into 10KHz units
   1664	 * it looks as if the TvControl do not care about pixel clock
   1665	 */
   1666	params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
   1667}
   1668
   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 CONTROL
   1715 **
   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	else
   1754		params.ucAction = ATOM_DISABLE;
   1755
   1756	if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
   1757		result = BP_RESULT_OK;
   1758
   1759	return result;
   1760}
   1761
   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	else
   1771		params.ucAction = ATOM_DISABLE;
   1772
   1773	if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
   1774		result = BP_RESULT_OK;
   1775
   1776	return result;
   1777}
   1778
   1779/*******************************************************************************
   1780 ********************************************************************************
   1781 **
   1782 **                  SET CRTC TIMING
   1783 **
   1784 ********************************************************************************
   1785 *******************************************************************************/
   1786
   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	else
   1811		switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
   1812		case 1:
   1813			bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
   1814			break;
   1815		default:
   1816			dm_output_to_console("Don't have set_crtc_timing for v%d\n",
   1817				 BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing));
   1818			bp->cmd_tbl.set_crtc_timing = NULL;
   1819			break;
   1820		}
   1821}
   1822
   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, for
   1847	 * underscan use another entry ProgramOverscan call but when mode
   1848	 * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
   1849	 * but when same ,but 60 Hz there is corruption
   1850	 * DAL1 does not allow the mode 1776x1000@60
   1851	 */
   1852	params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
   1853	params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
   1854	params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
   1855	params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
   1856
   1857	if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
   1858		params.susModeMiscInfo.usAccess =
   1859				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
   1860
   1861	if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
   1862		params.susModeMiscInfo.usAccess =
   1863				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
   1864
   1865	if (bp_params->flags.INTERLACE) {
   1866		params.susModeMiscInfo.usAccess =
   1867				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
   1868
   1869		/* original DAL code has this condition to apply tis for
   1870		 * non-TV/CV only due to complex MV testing for possible
   1871		 * impact
   1872		 * if (pACParameters->signal != SignalType_YPbPr &&
   1873		 *  pACParameters->signal != SignalType_Composite &&
   1874		 *  pACParameters->signal != SignalType_SVideo)
   1875		 */
   1876		/* HW will deduct 0.5 line from 2nd feild.
   1877		 * i.e. for 1080i, it is 2 lines for 1st field, 2.5
   1878		 * lines for the 2nd feild. we need input as 5 instead
   1879		 * of 4, but it is 4 either from Edid data
   1880		 * (spec CEA 861) or CEA timing table.
   1881		 */
   1882		params.usV_SyncStart =
   1883				cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
   1884	}
   1885
   1886	if (bp_params->flags.HORZ_COUNT_BY_TWO)
   1887		params.susModeMiscInfo.usAccess =
   1888				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
   1889
   1890	if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
   1891		result = BP_RESULT_OK;
   1892
   1893	return result;
   1894}
   1895
   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 beginning
   1920	 * of h addressable */
   1921	params.usH_SyncOffset =
   1922			cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
   1923	params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
   1924	/* bios usHSyncOffset is the offset from the end of v addressable,
   1925	 * our verticalSyncStart is the offset from the beginning of
   1926	 * v addressable */
   1927	params.usV_SyncOffset =
   1928			cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
   1929	params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
   1930
   1931	/* we assume that overscan from original timing does not get bigger
   1932	 * than 255
   1933	 * we will program all the borders in the Set CRTC Overscan call below
   1934	 */
   1935
   1936	if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
   1937		params.susModeMiscInfo.usAccess =
   1938				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
   1939
   1940	if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
   1941		params.susModeMiscInfo.usAccess =
   1942				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
   1943
   1944	if (bp_params->flags.INTERLACE)	{
   1945		params.susModeMiscInfo.usAccess =
   1946				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
   1947
   1948		/* original DAL code has this condition to apply this
   1949		 * for non-TV/CV only
   1950		 * due to complex MV testing for possible impact
   1951		 * if ( pACParameters->signal != SignalType_YPbPr &&
   1952		 *  pACParameters->signal != SignalType_Composite &&
   1953		 *  pACParameters->signal != SignalType_SVideo)
   1954		 */
   1955		{
   1956			/* HW will deduct 0.5 line from 2nd feild.
   1957			 * i.e. for 1080i, it is 2 lines for 1st field,
   1958			 * 2.5 lines for the 2nd feild. we need input as 5
   1959			 * instead of 4.
   1960			 * but it is 4 either from Edid data (spec CEA 861)
   1961			 * or CEA timing table.
   1962			 */
   1963			le16_add_cpu(&params.usV_SyncOffset, 1);
   1964		}
   1965	}
   1966
   1967	if (bp_params->flags.HORZ_COUNT_BY_TWO)
   1968		params.susModeMiscInfo.usAccess =
   1969				cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
   1970
   1971	if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
   1972		result = BP_RESULT_OK;
   1973
   1974	return result;
   1975}
   1976
   1977/*******************************************************************************
   1978 ********************************************************************************
   1979 **
   1980 **                  ENABLE CRTC
   1981 **
   1982 ********************************************************************************
   1983 *******************************************************************************/
   1984
   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	else
   2016		return BP_RESULT_BADINPUT;
   2017
   2018	if (enable)
   2019		params.ucEnable = ATOM_ENABLE;
   2020	else
   2021		params.ucEnable = ATOM_DISABLE;
   2022
   2023	if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
   2024		result = BP_RESULT_OK;
   2025
   2026	return result;
   2027}
   2028
   2029/*******************************************************************************
   2030 ********************************************************************************
   2031 **
   2032 **                  ENABLE CRTC MEM REQ
   2033 **
   2034 ********************************************************************************
   2035 *******************************************************************************/
   2036
   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		else
   2069			params.ucEnable = ATOM_DISABLE;
   2070
   2071		if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
   2072			result = BP_RESULT_OK;
   2073		else
   2074			result = BP_RESULT_FAILURE;
   2075	}
   2076
   2077	return result;
   2078}
   2079
   2080/*******************************************************************************
   2081 ********************************************************************************
   2082 **
   2083 **                  DISPLAY PLL
   2084 **
   2085 ********************************************************************************
   2086 *******************************************************************************/
   2087
   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 bypass
   2173		 * is enabled. */
   2174		bp_params->dfs_bypass_display_clock =
   2175				(uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
   2176		result = BP_RESULT_OK;
   2177	}
   2178
   2179	return result;
   2180}
   2181
   2182/*******************************************************************************
   2183 ********************************************************************************
   2184 **
   2185 **                  EXTERNAL ENCODER CONTROL
   2186 **
   2187 ********************************************************************************
   2188 *******************************************************************************/
   2189
   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 action
   2239	 *
   2240	 * Bit[6:4]: indicate external encoder, applied to all functions.
   2241	 * =0: external encoder1, mapped to external encoder enum id1
   2242	 * =1: external encoder2, mapped to external encoder enum id2
   2243	 *
   2244	 * enum ObjectEnumId
   2245	 * {
   2246	 *  EnumId_Unknown = 0,
   2247	 *  EnumId_1,
   2248	 *  EnumId_2,
   2249	 * };
   2250	 */
   2251	cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
   2252
   2253	switch (cntl->action) {
   2254	case EXTERNAL_ENCODER_CONTROL_INIT:
   2255		/* output display connector type. Only valid in encoder
   2256		 * initialization */
   2257		cntl_params->usConnectorId =
   2258				cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
   2259		break;
   2260	case EXTERNAL_ENCODER_CONTROL_SETUP:
   2261		/* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
   2262		 * 10KHz
   2263		 * output display device pixel clock frequency in unit of 10KHz.
   2264		 * Only valid in setup and enableoutput
   2265		 */
   2266		cntl_params->usPixelClock =
   2267				cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
   2268		/* Indicate display output signal type drive by external
   2269		 * encoder, only valid in setup and enableoutput */
   2270		cntl_params->ucEncoderMode =
   2271				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
   2272						cntl->signal, false);
   2273
   2274		if (is_input_signal_dp) {
   2275			/* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
   2276			 * only valid in encoder setup with DP mode. */
   2277			if (LINK_RATE_HIGH == cntl->link_rate)
   2278				cntl_params->ucConfig |= 1;
   2279			/* output color depth Indicate encoder data bpc format
   2280			 * in DP mode, only valid in encoder setup in DP mode.
   2281			 */
   2282			cntl_params->ucBitPerColor =
   2283					(uint8_t)(cntl->color_depth);
   2284		}
   2285		/* Indicate how many lanes used by external encoder, only valid
   2286		 * in encoder setup and enableoutput. */
   2287		cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
   2288		break;
   2289	case EXTERNAL_ENCODER_CONTROL_ENABLE:
   2290		cntl_params->usPixelClock =
   2291				cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
   2292		cntl_params->ucEncoderMode =
   2293				(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
   2294						cntl->signal, false);
   2295		cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
   2296		break;
   2297	default:
   2298		break;
   2299	}
   2300
   2301	cntl_params->ucAction = (uint8_t)cntl->action;
   2302
   2303	if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
   2304		result = BP_RESULT_OK;
   2305
   2306	return result;
   2307}
   2308
   2309/*******************************************************************************
   2310 ********************************************************************************
   2311 **
   2312 **                  ENABLE DISPLAY POWER GATING
   2313 **
   2314 ********************************************************************************
   2315 *******************************************************************************/
   2316
   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	else
   2351		return BP_RESULT_BADINPUT;
   2352
   2353	params.ucEnable =
   2354			bp->cmd_helper->disp_power_gating_action_to_atom(action);
   2355
   2356	if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
   2357		result = BP_RESULT_OK;
   2358
   2359	return result;
   2360}
   2361
   2362/*******************************************************************************
   2363 ********************************************************************************
   2364 **
   2365 **                  SET DCE CLOCK
   2366 **
   2367 ********************************************************************************
   2368 *******************************************************************************/
   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	else
   2421		/* only program clock frequency if display clock is used; VBIOS will program DPREFCLK */
   2422		/* We need to convert from KHz units into 10KHz units */
   2423		params.asParam.ulDCEClkFreq = cpu_to_le32(bp_params->target_clock_frequency / 10);
   2424
   2425	if (EXEC_BIOS_CMD_TABLE(SetDCEClock, params)) {
   2426		/* Convert from 10KHz units back to KHz */
   2427		bp_params->target_clock_frequency = le32_to_cpu(params.asParam.ulDCEClkFreq) * 10;
   2428		result = BP_RESULT_OK;
   2429	}
   2430
   2431	return result;
   2432}