cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

command_table2.c (31930B)


      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}