File Index
Files and directories
Sign in
FILE

command_table2.c

File preview with syntax highlighting.

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