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