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