brintos

brintos / linux-shallow public Read only

0
0
Text · 31.3 KiB · 7d18f37 Raw
1049 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 28#include "ObjectID.h"29 30#include "atomfirmware.h"31#include "atom.h"32#include "include/bios_parser_interface.h"33 34#include "command_table2.h"35#include "command_table_helper2.h"36#include "bios_parser_helper.h"37#include "bios_parser_types_internal2.h"38#include "amdgpu.h"39 40#include "dc_dmub_srv.h"41#include "dc.h"42 43#define DC_LOGGER \44	bp->base.ctx->logger45 46#define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\47	(offsetof(struct atom_master_list_of_##MasterOrData##_functions_v2_1, FieldName) / sizeof(uint16_t))48 49#define EXEC_BIOS_CMD_TABLE(fname, params)\50	(amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \51		GET_INDEX_INTO_MASTER_TABLE(command, fname), \52		(uint32_t *)&params, sizeof(params)) == 0)53 54#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\55	amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \56		GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)57 58#define BIOS_CMD_TABLE_PARA_REVISION(fname)\59	bios_cmd_table_para_revision(bp->base.ctx->driver_context, \60			GET_INDEX_INTO_MASTER_TABLE(command, fname))61 62 63 64static uint32_t bios_cmd_table_para_revision(void *dev,65					     uint32_t index)66{67	struct amdgpu_device *adev = dev;68	uint8_t frev, crev;69 70	if (amdgpu_atom_parse_cmd_header(adev->mode_info.atom_context,71					index,72					&frev, &crev))73		return crev;74	else75		return 0;76}77 78/******************************************************************************79 ******************************************************************************80 **81 **                  D I G E N C O D E R C O N T R O L82 **83 ******************************************************************************84 *****************************************************************************/85 86static enum bp_result encoder_control_digx_v1_5(87	struct bios_parser *bp,88	struct bp_encoder_control *cntl);89 90static enum bp_result encoder_control_fallback(91	struct bios_parser *bp,92	struct bp_encoder_control *cntl);93 94static void init_dig_encoder_control(struct bios_parser *bp)95{96	uint32_t version =97		BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);98 99	switch (version) {100	case 5:101		bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;102		break;103	default:104		dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);105		bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;106		break;107	}108}109 110static void encoder_control_dmcub(111		struct dc_dmub_srv *dmcub,112		struct dig_encoder_stream_setup_parameters_v1_5 *dig)113{114	union dmub_rb_cmd cmd;115 116	memset(&cmd, 0, sizeof(cmd));117 118	cmd.digx_encoder_control.header.type = DMUB_CMD__VBIOS;119	cmd.digx_encoder_control.header.sub_type =120		DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL;121	cmd.digx_encoder_control.header.payload_bytes =122		sizeof(cmd.digx_encoder_control) -123		sizeof(cmd.digx_encoder_control.header);124	cmd.digx_encoder_control.encoder_control.dig.stream_param = *dig;125 126	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);127}128 129static enum bp_result encoder_control_digx_v1_5(130	struct bios_parser *bp,131	struct bp_encoder_control *cntl)132{133	enum bp_result result = BP_RESULT_FAILURE;134	struct dig_encoder_stream_setup_parameters_v1_5 params = {0};135 136	params.digid = (uint8_t)(cntl->engine_id);137	params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);138 139	params.pclk_10khz = cntl->pixel_clock / 10;140	params.digmode =141			(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(142					cntl->signal,143					cntl->enable_dp_audio));144	params.lanenum = (uint8_t)(cntl->lanes_number);145 146	switch (cntl->color_depth) {147	case COLOR_DEPTH_888:148		params.bitpercolor = PANEL_8BIT_PER_COLOR;149		break;150	case COLOR_DEPTH_101010:151		params.bitpercolor = PANEL_10BIT_PER_COLOR;152		break;153	case COLOR_DEPTH_121212:154		params.bitpercolor = PANEL_12BIT_PER_COLOR;155		break;156	case COLOR_DEPTH_161616:157		params.bitpercolor = PANEL_16BIT_PER_COLOR;158		break;159	default:160		break;161	}162 163	if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)164		switch (cntl->color_depth) {165		case COLOR_DEPTH_101010:166			params.pclk_10khz =167				(params.pclk_10khz * 30) / 24;168			break;169		case COLOR_DEPTH_121212:170			params.pclk_10khz =171				(params.pclk_10khz * 36) / 24;172			break;173		case COLOR_DEPTH_161616:174			params.pclk_10khz =175				(params.pclk_10khz * 48) / 24;176			break;177		default:178			break;179		}180 181	if (bp->base.ctx->dc->ctx->dmub_srv &&182	    bp->base.ctx->dc->debug.dmub_command_table) {183		encoder_control_dmcub(bp->base.ctx->dmub_srv, &params);184		return BP_RESULT_OK;185	}186 187	if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))188		result = BP_RESULT_OK;189 190	return result;191}192 193static enum bp_result encoder_control_fallback(194	struct bios_parser *bp,195	struct bp_encoder_control *cntl)196{197	if (bp->base.ctx->dc->ctx->dmub_srv &&198	    bp->base.ctx->dc->debug.dmub_command_table) {199		return encoder_control_digx_v1_5(bp, cntl);200	}201 202	return BP_RESULT_FAILURE;203}204 205/*****************************************************************************206 ******************************************************************************207 **208 **                  TRANSMITTER CONTROL209 **210 ******************************************************************************211 *****************************************************************************/212 213static enum bp_result transmitter_control_v1_6(214	struct bios_parser *bp,215	struct bp_transmitter_control *cntl);216 217static enum bp_result transmitter_control_v1_7(218	struct bios_parser *bp,219	struct bp_transmitter_control *cntl);220 221static enum bp_result transmitter_control_fallback(222	struct bios_parser *bp,223	struct bp_transmitter_control *cntl);224 225static void init_transmitter_control(struct bios_parser *bp)226{227	uint8_t frev;228	uint8_t crev = 0;229 230	if (!BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) && (bp->base.ctx->dc->ctx->dce_version <= DCN_VERSION_2_0))231		BREAK_TO_DEBUGGER();232 233	switch (crev) {234	case 6:235		bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;236		break;237	case 7:238		bp->cmd_tbl.transmitter_control = transmitter_control_v1_7;239		break;240	default:241		dm_output_to_console("Don't have transmitter_control for v%d\n", crev);242		bp->cmd_tbl.transmitter_control = transmitter_control_fallback;243		break;244	}245}246 247static void transmitter_control_dmcub(248		struct dc_dmub_srv *dmcub,249		struct dig_transmitter_control_parameters_v1_6 *dig)250{251	union dmub_rb_cmd cmd;252 253	memset(&cmd, 0, sizeof(cmd));254 255	cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;256	cmd.dig1_transmitter_control.header.sub_type =257		DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;258	cmd.dig1_transmitter_control.header.payload_bytes =259		sizeof(cmd.dig1_transmitter_control) -260		sizeof(cmd.dig1_transmitter_control.header);261	cmd.dig1_transmitter_control.transmitter_control.dig = *dig;262 263	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);264}265 266static enum bp_result transmitter_control_v1_6(267	struct bios_parser *bp,268	struct bp_transmitter_control *cntl)269{270	enum bp_result result = BP_RESULT_FAILURE;271	const struct command_table_helper *cmd = bp->cmd_helper;272	struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };273 274	ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);275	ps.param.action = (uint8_t)cntl->action;276 277	if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)278		ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;279	else280		ps.param.mode_laneset.digmode =281				cmd->signal_type_to_atom_dig_mode(cntl->signal);282 283	ps.param.lanenum = (uint8_t)cntl->lanes_number;284	ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);285	ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);286	ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;287	ps.param.symclk_10khz = cntl->pixel_clock/10;288 289 290	if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||291		cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||292		cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {293		DC_LOG_BIOS("%s:ps.param.symclk_10khz = %d\n",\294		__func__, ps.param.symclk_10khz);295	}296 297	if (bp->base.ctx->dc->ctx->dmub_srv &&298	    bp->base.ctx->dc->debug.dmub_command_table) {299		transmitter_control_dmcub(bp->base.ctx->dmub_srv, &ps.param);300		return BP_RESULT_OK;301	}302 303/*color_depth not used any more, driver has deep color factor in the Phyclk*/304	if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))305		result = BP_RESULT_OK;306	return result;307}308 309static void transmitter_control_dmcub_v1_7(310		struct dc_dmub_srv *dmcub,311		struct dmub_dig_transmitter_control_data_v1_7 *dig)312{313	union dmub_rb_cmd cmd;314 315	memset(&cmd, 0, sizeof(cmd));316 317	cmd.dig1_transmitter_control.header.type = DMUB_CMD__VBIOS;318	cmd.dig1_transmitter_control.header.sub_type =319		DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL;320	cmd.dig1_transmitter_control.header.payload_bytes =321		sizeof(cmd.dig1_transmitter_control) -322		sizeof(cmd.dig1_transmitter_control.header);323	cmd.dig1_transmitter_control.transmitter_control.dig_v1_7 = *dig;324 325	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);326}327 328static enum bp_result transmitter_control_v1_7(329	struct bios_parser *bp,330	struct bp_transmitter_control *cntl)331{332	enum bp_result result = BP_RESULT_FAILURE;333	const struct command_table_helper *cmd = bp->cmd_helper;334	struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7 = {0};335 336	uint8_t hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_0;337 338	if (dc_is_dp_signal(cntl->signal))339		hpo_instance = (uint8_t)cntl->hpo_engine_id - ENGINE_ID_HPO_DP_0;340 341	dig_v1_7.phyid = cmd->phy_id_to_atom(cntl->transmitter);342	dig_v1_7.action = (uint8_t)cntl->action;343 344	if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)345		dig_v1_7.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;346	else347		dig_v1_7.mode_laneset.digmode =348				cmd->signal_type_to_atom_dig_mode(cntl->signal);349 350	dig_v1_7.lanenum = (uint8_t)cntl->lanes_number;351	dig_v1_7.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);352	dig_v1_7.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);353	dig_v1_7.connobj_id = (uint8_t)cntl->connector_obj_id.id;354	dig_v1_7.HPO_instance = hpo_instance;355	dig_v1_7.symclk_units.symclk_10khz = cntl->pixel_clock/10;356 357	if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||358		cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||359		cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {360			DC_LOG_BIOS("%s:dig_v1_7.symclk_units.symclk_10khz = %d\n",361			__func__, dig_v1_7.symclk_units.symclk_10khz);362	}363 364	if (bp->base.ctx->dc->ctx->dmub_srv &&365		bp->base.ctx->dc->debug.dmub_command_table) {366		transmitter_control_dmcub_v1_7(bp->base.ctx->dmub_srv, &dig_v1_7);367		return BP_RESULT_OK;368	}369 370/*color_depth not used any more, driver has deep color factor in the Phyclk*/371	if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, dig_v1_7))372		result = BP_RESULT_OK;373	return result;374}375 376static enum bp_result transmitter_control_fallback(377	struct bios_parser *bp,378	struct bp_transmitter_control *cntl)379{380	if (bp->base.ctx->dc->ctx->dmub_srv &&381	    bp->base.ctx->dc->debug.dmub_command_table) {382		return transmitter_control_v1_7(bp, cntl);383	}384 385	return BP_RESULT_FAILURE;386}387 388/******************************************************************************389 ******************************************************************************390 **391 **                  SET PIXEL CLOCK392 **393 ******************************************************************************394 *****************************************************************************/395 396static enum bp_result set_pixel_clock_v7(397	struct bios_parser *bp,398	struct bp_pixel_clock_parameters *bp_params);399 400static enum bp_result set_pixel_clock_fallback(401	struct bios_parser *bp,402	struct bp_pixel_clock_parameters *bp_params);403 404static void init_set_pixel_clock(struct bios_parser *bp)405{406	switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {407	case 7:408		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;409		break;410	default:411		dm_output_to_console("Don't have set_pixel_clock for v%d\n",412			 BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));413		bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;414		break;415	}416}417 418static void set_pixel_clock_dmcub(419		struct dc_dmub_srv *dmcub,420		struct set_pixel_clock_parameter_v1_7 *clk)421{422	union dmub_rb_cmd cmd;423 424	memset(&cmd, 0, sizeof(cmd));425 426	cmd.set_pixel_clock.header.type = DMUB_CMD__VBIOS;427	cmd.set_pixel_clock.header.sub_type = DMUB_CMD__VBIOS_SET_PIXEL_CLOCK;428	cmd.set_pixel_clock.header.payload_bytes =429		sizeof(cmd.set_pixel_clock) -430		sizeof(cmd.set_pixel_clock.header);431	cmd.set_pixel_clock.pixel_clock.clk = *clk;432 433	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);434}435 436static enum bp_result set_pixel_clock_v7(437	struct bios_parser *bp,438	struct bp_pixel_clock_parameters *bp_params)439{440	enum bp_result result = BP_RESULT_FAILURE;441	struct set_pixel_clock_parameter_v1_7 clk;442	uint8_t controller_id;443	uint32_t pll_id;444 445	memset(&clk, 0, sizeof(clk));446 447	if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)448			&& bp->cmd_helper->controller_id_to_atom(bp_params->449					controller_id, &controller_id)) {450		/* Note: VBIOS still wants to use ucCRTC name which is now451		 * 1 byte in ULONG452		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ453		 *{454		 * target the pixel clock to drive the CRTC timing.455		 * ULONG ulPixelClock:24;456		 * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to457		 * previous version.458		 * ATOM_CRTC1~6, indicate the CRTC controller to459		 * ULONG ucCRTC:8;460		 * drive the pixel clock. not used for DCPLL case.461		 *}CRTC_PIXEL_CLOCK_FREQ;462		 *union463		 *{464		 * pixel clock and CRTC id frequency465		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;466		 * ULONG ulDispEngClkFreq; dispclk frequency467		 *};468		 */469		clk.crtc_id = controller_id;470		clk.pll_id = (uint8_t) pll_id;471		clk.encoderobjid =472			bp->cmd_helper->encoder_id_to_atom(473				dal_graphics_object_id_get_encoder_id(474					bp_params->encoder_object_id));475 476		clk.encoder_mode = (uint8_t) bp->477			cmd_helper->encoder_mode_bp_to_atom(478				bp_params->signal_type, false);479 480		clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock_100hz);481 482		clk.deep_color_ratio =483			(uint8_t) bp->cmd_helper->484				transmitter_color_depth_to_atom(485					bp_params->color_depth);486 487		DC_LOG_BIOS("%s:program display clock = %d, tg = %d, pll = %d, "\488				"colorDepth = %d\n", __func__,489				bp_params->target_pixel_clock_100hz, (int)controller_id,490				pll_id, bp_params->color_depth);491 492		if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)493			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;494 495		if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)496			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;497 498		if (bp_params->flags.SUPPORT_YUV_420)499			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;500 501		if (bp_params->flags.SET_XTALIN_REF_SRC)502			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;503 504		if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)505			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;506 507		if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)508			clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;509 510		if (bp->base.ctx->dc->ctx->dmub_srv &&511		    bp->base.ctx->dc->debug.dmub_command_table) {512			set_pixel_clock_dmcub(bp->base.ctx->dmub_srv, &clk);513			return BP_RESULT_OK;514		}515 516		if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))517			result = BP_RESULT_OK;518	}519	return result;520}521 522static enum bp_result set_pixel_clock_fallback(523	struct bios_parser *bp,524	struct bp_pixel_clock_parameters *bp_params)525{526	if (bp->base.ctx->dc->ctx->dmub_srv &&527	    bp->base.ctx->dc->debug.dmub_command_table) {528		return set_pixel_clock_v7(bp, bp_params);529	}530 531	return BP_RESULT_FAILURE;532}533 534/******************************************************************************535 ******************************************************************************536 **537 **                  SET CRTC TIMING538 **539 ******************************************************************************540 *****************************************************************************/541 542static enum bp_result set_crtc_using_dtd_timing_v3(543	struct bios_parser *bp,544	struct bp_hw_crtc_timing_parameters *bp_params);545 546static void init_set_crtc_timing(struct bios_parser *bp)547{548	uint32_t dtd_version =549			BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);550 551	switch (dtd_version) {552	case 3:553		bp->cmd_tbl.set_crtc_timing =554			set_crtc_using_dtd_timing_v3;555		break;556	default:557		dm_output_to_console("Don't have set_crtc_timing for v%d\n", dtd_version);558		bp->cmd_tbl.set_crtc_timing = NULL;559		break;560	}561}562 563static enum bp_result set_crtc_using_dtd_timing_v3(564	struct bios_parser *bp,565	struct bp_hw_crtc_timing_parameters *bp_params)566{567	enum bp_result result = BP_RESULT_FAILURE;568	struct set_crtc_using_dtd_timing_parameters params = {0};569	uint8_t atom_controller_id;570 571	if (bp->cmd_helper->controller_id_to_atom(572			bp_params->controller_id, &atom_controller_id))573		params.crtc_id = atom_controller_id;574 575	/* bios usH_Size wants h addressable size */576	params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);577	/* bios usH_Blanking_Time wants borders included in blanking */578	params.h_blanking_time =579			cpu_to_le16((uint16_t)(bp_params->h_total -580					bp_params->h_addressable));581	/* bios usV_Size wants v addressable size */582	params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);583	/* bios usV_Blanking_Time wants borders included in blanking */584	params.v_blanking_time =585			cpu_to_le16((uint16_t)(bp_params->v_total -586					bp_params->v_addressable));587	/* bios usHSyncOffset is the offset from the end of h addressable,588	 * our horizontalSyncStart is the offset from the beginning589	 * of h addressable590	 */591	params.h_syncoffset =592			cpu_to_le16((uint16_t)(bp_params->h_sync_start -593					bp_params->h_addressable));594	params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);595	/* bios usHSyncOffset is the offset from the end of v addressable,596	 * our verticalSyncStart is the offset from the beginning of597	 * v addressable598	 */599	params.v_syncoffset =600			cpu_to_le16((uint16_t)(bp_params->v_sync_start -601					bp_params->v_addressable));602	params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);603 604	/* we assume that overscan from original timing does not get bigger605	 * than 255606	 * we will program all the borders in the Set CRTC Overscan call below607	 */608 609	if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)610		params.modemiscinfo =611				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |612						ATOM_HSYNC_POLARITY);613 614	if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)615		params.modemiscinfo =616				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |617						ATOM_VSYNC_POLARITY);618 619	if (bp_params->flags.INTERLACE)	{620		params.modemiscinfo =621				cpu_to_le16(le16_to_cpu(params.modemiscinfo) |622						ATOM_INTERLACE);623 624		/* original DAL code has this condition to apply this625		 * for non-TV/CV only626		 * due to complex MV testing for possible impact627		 * if ( pACParameters->signal != SignalType_YPbPr &&628		 *  pACParameters->signal != SignalType_Composite &&629		 *  pACParameters->signal != SignalType_SVideo)630		 */631		{632			/* HW will deduct 0.5 line from 2nd feild.633			 * i.e. for 1080i, it is 2 lines for 1st field,634			 * 2.5 lines for the 2nd feild. we need input as 5635			 * instead of 4.636			 * but it is 4 either from Edid data (spec CEA 861)637			 * or CEA timing table.638			 */639			le16_add_cpu(&params.v_syncoffset, 1);640		}641	}642 643	if (bp_params->flags.HORZ_COUNT_BY_TWO)644		params.modemiscinfo =645			cpu_to_le16(le16_to_cpu(params.modemiscinfo) |646					0x100); /* ATOM_DOUBLE_CLOCK_MODE */647 648	if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))649		result = BP_RESULT_OK;650 651	return result;652}653 654/******************************************************************************655 ******************************************************************************656 **657 **                  ENABLE CRTC658 **659 ******************************************************************************660 *****************************************************************************/661 662static enum bp_result enable_crtc_v1(663	struct bios_parser *bp,664	enum controller_id controller_id,665	bool enable);666 667static void init_enable_crtc(struct bios_parser *bp)668{669	switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {670	case 1:671		bp->cmd_tbl.enable_crtc = enable_crtc_v1;672		break;673	default:674		dm_output_to_console("Don't have enable_crtc for v%d\n",675			 BIOS_CMD_TABLE_PARA_REVISION(enablecrtc));676		bp->cmd_tbl.enable_crtc = NULL;677		break;678	}679}680 681static enum bp_result enable_crtc_v1(682	struct bios_parser *bp,683	enum controller_id controller_id,684	bool enable)685{686	bool result = BP_RESULT_FAILURE;687	struct enable_crtc_parameters params = {0};688	uint8_t id;689 690	if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))691		params.crtc_id = id;692	else693		return BP_RESULT_BADINPUT;694 695	if (enable)696		params.enable = ATOM_ENABLE;697	else698		params.enable = ATOM_DISABLE;699 700	if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))701		result = BP_RESULT_OK;702 703	return result;704}705 706/******************************************************************************707 ******************************************************************************708 **709 **                  DISPLAY PLL710 **711 ******************************************************************************712 *****************************************************************************/713 714 715 716/******************************************************************************717 ******************************************************************************718 **719 **                  EXTERNAL ENCODER CONTROL720 **721 ******************************************************************************722 *****************************************************************************/723 724static enum bp_result external_encoder_control_v3(725	struct bios_parser *bp,726	struct bp_external_encoder_control *cntl);727 728static void init_external_encoder_control(729	struct bios_parser *bp)730{731	switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {732	case 3:733		bp->cmd_tbl.external_encoder_control =734				external_encoder_control_v3;735		break;736	default:737		bp->cmd_tbl.external_encoder_control = NULL;738		break;739	}740}741 742static enum bp_result external_encoder_control_v3(743	struct bios_parser *bp,744	struct bp_external_encoder_control *cntl)745{746	/* TODO */747	return BP_RESULT_OK;748}749 750/******************************************************************************751 ******************************************************************************752 **753 **                  ENABLE DISPLAY POWER GATING754 **755 ******************************************************************************756 *****************************************************************************/757 758static enum bp_result enable_disp_power_gating_v2_1(759	struct bios_parser *bp,760	enum controller_id crtc_id,761	enum bp_pipe_control_action action);762 763static enum bp_result enable_disp_power_gating_fallback(764	struct bios_parser *bp,765	enum controller_id crtc_id,766	enum bp_pipe_control_action action);767 768static void init_enable_disp_power_gating(769	struct bios_parser *bp)770{771	switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {772	case 1:773		bp->cmd_tbl.enable_disp_power_gating =774				enable_disp_power_gating_v2_1;775		break;776	default:777		dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",778			 BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));779		bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;780		break;781	}782}783 784static void enable_disp_power_gating_dmcub(785	struct dc_dmub_srv *dmcub,786	struct enable_disp_power_gating_parameters_v2_1 *pwr)787{788	union dmub_rb_cmd cmd;789 790	memset(&cmd, 0, sizeof(cmd));791 792	cmd.enable_disp_power_gating.header.type = DMUB_CMD__VBIOS;793	cmd.enable_disp_power_gating.header.sub_type =794		DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;795	cmd.enable_disp_power_gating.header.payload_bytes =796		sizeof(cmd.enable_disp_power_gating) -797		sizeof(cmd.enable_disp_power_gating.header);798	cmd.enable_disp_power_gating.power_gating.pwr = *pwr;799 800	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);801}802 803static enum bp_result enable_disp_power_gating_v2_1(804	struct bios_parser *bp,805	enum controller_id crtc_id,806	enum bp_pipe_control_action action)807{808	enum bp_result result = BP_RESULT_FAILURE;809 810 811	struct enable_disp_power_gating_ps_allocation ps = { { 0 } };812	uint8_t atom_crtc_id;813 814	if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))815		ps.param.disp_pipe_id = atom_crtc_id;816	else817		return BP_RESULT_BADINPUT;818 819	ps.param.enable =820		bp->cmd_helper->disp_power_gating_action_to_atom(action);821 822	if (bp->base.ctx->dc->ctx->dmub_srv &&823	    bp->base.ctx->dc->debug.dmub_command_table) {824		enable_disp_power_gating_dmcub(bp->base.ctx->dmub_srv,825					       &ps.param);826		return BP_RESULT_OK;827	}828 829	if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))830		result = BP_RESULT_OK;831 832	return result;833}834 835static enum bp_result enable_disp_power_gating_fallback(836	struct bios_parser *bp,837	enum controller_id crtc_id,838	enum bp_pipe_control_action action)839{840	if (bp->base.ctx->dc->ctx->dmub_srv &&841	    bp->base.ctx->dc->debug.dmub_command_table) {842		return enable_disp_power_gating_v2_1(bp, crtc_id, action);843	}844 845	return BP_RESULT_FAILURE;846}847 848/******************************************************************************849*******************************************************************************850 **851 **                  SET DCE CLOCK852 **853*******************************************************************************854*******************************************************************************/855 856static enum bp_result set_dce_clock_v2_1(857	struct bios_parser *bp,858	struct bp_set_dce_clock_parameters *bp_params);859 860static void init_set_dce_clock(struct bios_parser *bp)861{862	switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {863	case 1:864		bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;865		break;866	default:867		dm_output_to_console("Don't have set_dce_clock for v%d\n",868			 BIOS_CMD_TABLE_PARA_REVISION(setdceclock));869		bp->cmd_tbl.set_dce_clock = NULL;870		break;871	}872}873 874static enum bp_result set_dce_clock_v2_1(875	struct bios_parser *bp,876	struct bp_set_dce_clock_parameters *bp_params)877{878	enum bp_result result = BP_RESULT_FAILURE;879 880	struct set_dce_clock_ps_allocation_v2_1 params;881	uint32_t atom_pll_id;882	uint32_t atom_clock_type;883	const struct command_table_helper *cmd = bp->cmd_helper;884 885	memset(&params, 0, sizeof(params));886 887	if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||888			!cmd->dc_clock_type_to_atom(bp_params->clock_type,889					&atom_clock_type))890		return BP_RESULT_BADINPUT;891 892	params.param.dceclksrc  = atom_pll_id;893	params.param.dceclktype = atom_clock_type;894 895	if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {896		if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)897			params.param.dceclkflag |=898					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;899 900		if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)901			params.param.dceclkflag |=902					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;903 904		if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)905			params.param.dceclkflag |=906					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;907 908		if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)909			params.param.dceclkflag |=910					DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;911	} else912		/* only program clock frequency if display clock is used;913		 * VBIOS will program DPREFCLK914		 * We need to convert from KHz units into 10KHz units915		 */916		params.param.dceclk_10khz = cpu_to_le32(917				bp_params->target_clock_frequency / 10);918	DC_LOG_BIOS("%s:target_clock_frequency = %d"\919			"clock_type = %d \n", __func__,\920			bp_params->target_clock_frequency,\921			bp_params->clock_type);922 923	if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {924		/* Convert from 10KHz units back to KHz */925		bp_params->target_clock_frequency = le32_to_cpu(926				params.param.dceclk_10khz) * 10;927		result = BP_RESULT_OK;928	}929 930	return result;931}932 933 934/******************************************************************************935 ******************************************************************************936 **937 **                  GET SMU CLOCK INFO938 **939 ******************************************************************************940 *****************************************************************************/941 942static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id);943 944static void init_get_smu_clock_info(struct bios_parser *bp)945{946	/* TODO add switch for table vrsion */947	bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;948 949}950 951static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp, uint8_t id)952{953	struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};954	struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;955 956	smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;957	smu_input.syspll_id = id;958 959	/* Get Specific Clock */960	if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {961		memmove(&smu_output, &smu_input, sizeof(962			struct atom_get_smu_clock_info_parameters_v3_1));963		return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;964	}965 966	return 0;967}968 969/******************************************************************************970 ******************************************************************************971 **972 **                  LVTMA CONTROL973 **974 ******************************************************************************975 *****************************************************************************/976 977static enum bp_result enable_lvtma_control(978	struct bios_parser *bp,979	uint8_t uc_pwr_on,980	uint8_t pwrseq_instance,981	uint8_t bypass_panel_control_wait);982 983static void init_enable_lvtma_control(struct bios_parser *bp)984{985	/* TODO add switch for table vrsion */986	bp->cmd_tbl.enable_lvtma_control = enable_lvtma_control;987 988}989 990static void enable_lvtma_control_dmcub(991	struct dc_dmub_srv *dmcub,992	uint8_t uc_pwr_on,993	uint8_t pwrseq_instance,994	uint8_t bypass_panel_control_wait)995{996 997	union dmub_rb_cmd cmd;998 999	memset(&cmd, 0, sizeof(cmd));1000 1001	cmd.lvtma_control.header.type = DMUB_CMD__VBIOS;1002	cmd.lvtma_control.header.sub_type =1003			DMUB_CMD__VBIOS_LVTMA_CONTROL;1004	cmd.lvtma_control.data.uc_pwr_action =1005			uc_pwr_on;1006	cmd.lvtma_control.data.pwrseq_inst =1007			pwrseq_instance;1008	cmd.lvtma_control.data.bypass_panel_control_wait =1009			bypass_panel_control_wait;1010	dc_wake_and_execute_dmub_cmd(dmcub->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);1011}1012 1013static enum bp_result enable_lvtma_control(1014	struct bios_parser *bp,1015	uint8_t uc_pwr_on,1016	uint8_t pwrseq_instance,1017	uint8_t bypass_panel_control_wait)1018{1019	enum bp_result result = BP_RESULT_FAILURE;1020 1021	if (bp->base.ctx->dc->ctx->dmub_srv &&1022	    bp->base.ctx->dc->debug.dmub_command_table) {1023		enable_lvtma_control_dmcub(bp->base.ctx->dmub_srv,1024				uc_pwr_on,1025				pwrseq_instance,1026				bypass_panel_control_wait);1027		return BP_RESULT_OK;1028	}1029	return result;1030}1031 1032void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)1033{1034	init_dig_encoder_control(bp);1035	init_transmitter_control(bp);1036	init_set_pixel_clock(bp);1037 1038	init_set_crtc_timing(bp);1039 1040	init_enable_crtc(bp);1041 1042	init_external_encoder_control(bp);1043	init_enable_disp_power_gating(bp);1044	init_set_dce_clock(bp);1045	init_get_smu_clock_info(bp);1046 1047	init_enable_lvtma_control(bp);1048}1049