Linux Audio

Check our new training course

Loading...
v6.9.4
   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, 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	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}
v6.13.7
   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, 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	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 = 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	else
 280		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	else
 347		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 CLOCK
 392 **
 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 now
 451		 * 1 byte in ULONG
 452		 *typedef struct _CRTC_PIXEL_CLOCK_FREQ
 453		 *{
 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 to
 457		 * previous version.
 458		 * ATOM_CRTC1~6, indicate the CRTC controller to
 459		 * ULONG ucCRTC:8;
 460		 * drive the pixel clock. not used for DCPLL case.
 461		 *}CRTC_PIXEL_CLOCK_FREQ;
 462		 *union
 463		 *{
 464		 * pixel clock and CRTC id frequency
 465		 * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
 466		 * ULONG ulDispEngClkFreq; dispclk frequency
 467		 *};
 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 TIMING
 538 **
 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 beginning
 589	 * of h addressable
 590	 */
 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 of
 597	 * v addressable
 598	 */
 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 bigger
 605	 * than 255
 606	 * we will program all the borders in the Set CRTC Overscan call below
 607	 */
 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 this
 625		 * for non-TV/CV only
 626		 * due to complex MV testing for possible impact
 627		 * 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 5
 635			 * 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 CRTC
 658 **
 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	else
 693		return BP_RESULT_BADINPUT;
 694
 695	if (enable)
 696		params.enable = ATOM_ENABLE;
 697	else
 698		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 PLL
 710 **
 711 ******************************************************************************
 712 *****************************************************************************/
 713
 714
 715
 716/******************************************************************************
 717 ******************************************************************************
 718 **
 719 **                  EXTERNAL ENCODER CONTROL
 720 **
 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 GATING
 754 **
 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	else
 817		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 CLOCK
 852 **
 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	} else
 912		/* only program clock frequency if display clock is used;
 913		 * VBIOS will program DPREFCLK
 914		 * We need to convert from KHz units into 10KHz units
 915		 */
 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 INFO
 938 **
 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 CONTROL
 973 **
 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}