Linux Audio

Check our new training course

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