Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   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}