drm/amd/display: Add DCE12 bios parser support

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Harry Wentland 2017-03-06 14:29:52 -05:00 committed by Alex Deucher
parent b7ad57b579
commit ae79c310b1
9 changed files with 3904 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_BIOS_PARSER2_H__
#define __DAL_BIOS_PARSER2_H__
struct dc_bios *firmware_parser_create(
struct bp_init_data *init,
enum dce_version dce_version);
#endif

View File

@ -0,0 +1,74 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_BIOS_PARSER_TYPES_BIOS2_H__
#define __DAL_BIOS_PARSER_TYPES_BIOS2_H__
#include "dc_bios_types.h"
#include "bios_parser_helper.h"
/* use atomfirmware_bringup.h only. Not atombios.h anymore */
struct atom_data_revision {
uint32_t major;
uint32_t minor;
};
struct object_info_table {
struct atom_data_revision revision;
union {
struct display_object_info_table_v1_4 *v1_4;
};
};
enum spread_spectrum_id {
SS_ID_UNKNOWN = 0,
SS_ID_DP1 = 0xf1,
SS_ID_DP2 = 0xf2,
SS_ID_LVLINK_2700MHZ = 0xf3,
SS_ID_LVLINK_1620MHZ = 0xf4
};
struct bios_parser {
struct dc_bios base;
struct object_info_table object_info_tbl;
uint32_t object_info_tbl_offset;
struct atom_master_data_table_v2_1 *master_data_tbl;
const struct bios_parser_helper *bios_helper;
const struct command_table_helper *cmd_helper;
struct cmd_tbl cmd_tbl;
bool remap_device_tags;
};
/* Bios Parser from DC Bios */
#define BP_FROM_DCB(dc_bios) \
container_of(dc_bios, struct bios_parser, base)
#endif

View File

@ -0,0 +1,813 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dm_services.h"
#include "ObjectID.h"
#include "atomfirmware.h"
#include "atomfirmwareid.h"
#include "include/bios_parser_interface.h"
#include "command_table2.h"
#include "command_table_helper2.h"
#include "bios_parser_helper.h"
#include "bios_parser_types_internal2.h"
#define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\
(((char *)(&((\
struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\
->FieldName)-(char *)0)/sizeof(uint16_t))
#define EXEC_BIOS_CMD_TABLE(fname, params)\
(cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \
GET_INDEX_INTO_MASTER_TABLE(command, fname), \
&params) == 0)
#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \
GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev)
#define BIOS_CMD_TABLE_PARA_REVISION(fname)\
bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \
GET_INDEX_INTO_MASTER_TABLE(command, fname))
static void init_dig_encoder_control(struct bios_parser *bp);
static void init_transmitter_control(struct bios_parser *bp);
static void init_set_pixel_clock(struct bios_parser *bp);
static void init_set_crtc_timing(struct bios_parser *bp);
static void init_select_crtc_source(struct bios_parser *bp);
static void init_enable_crtc(struct bios_parser *bp);
static void init_external_encoder_control(struct bios_parser *bp);
static void init_enable_disp_power_gating(struct bios_parser *bp);
static void init_set_dce_clock(struct bios_parser *bp);
static void init_get_smu_clock_info(struct bios_parser *bp);
void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp)
{
init_dig_encoder_control(bp);
init_transmitter_control(bp);
init_set_pixel_clock(bp);
init_set_crtc_timing(bp);
init_select_crtc_source(bp);
init_enable_crtc(bp);
init_external_encoder_control(bp);
init_enable_disp_power_gating(bp);
init_set_dce_clock(bp);
init_get_smu_clock_info(bp);
}
static uint32_t bios_cmd_table_para_revision(void *cgs_device,
uint32_t index)
{
uint8_t frev, crev;
if (cgs_atom_get_cmd_table_revs(cgs_device,
index,
&frev, &crev) != 0)
return 0;
return crev;
}
/******************************************************************************
******************************************************************************
**
** D I G E N C O D E R C O N T R O L
**
******************************************************************************
*****************************************************************************/
static enum bp_result encoder_control_digx_v1_5(
struct bios_parser *bp,
struct bp_encoder_control *cntl);
static void init_dig_encoder_control(struct bios_parser *bp)
{
uint32_t version =
BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol);
switch (version) {
case 5:
bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5;
break;
default:
bp->cmd_tbl.dig_encoder_control = NULL;
break;
}
}
static enum bp_result encoder_control_digx_v1_5(
struct bios_parser *bp,
struct bp_encoder_control *cntl)
{
enum bp_result result = BP_RESULT_FAILURE;
struct dig_encoder_stream_setup_parameters_v1_5 params = {0};
params.digid = (uint8_t)(cntl->engine_id);
params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action);
params.pclk_10khz = cntl->pixel_clock / 10;
params.digmode =
(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
cntl->signal,
cntl->enable_dp_audio));
params.lanenum = (uint8_t)(cntl->lanes_number);
switch (cntl->color_depth) {
case COLOR_DEPTH_888:
params.bitpercolor = PANEL_8BIT_PER_COLOR;
break;
case COLOR_DEPTH_101010:
params.bitpercolor = PANEL_10BIT_PER_COLOR;
break;
case COLOR_DEPTH_121212:
params.bitpercolor = PANEL_12BIT_PER_COLOR;
break;
case COLOR_DEPTH_161616:
params.bitpercolor = PANEL_16BIT_PER_COLOR;
break;
default:
break;
}
if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
switch (cntl->color_depth) {
case COLOR_DEPTH_101010:
params.pclk_10khz =
(params.pclk_10khz * 30) / 24;
break;
case COLOR_DEPTH_121212:
params.pclk_10khz =
(params.pclk_10khz * 36) / 24;
break;
case COLOR_DEPTH_161616:
params.pclk_10khz =
(params.pclk_10khz * 48) / 24;
break;
default:
break;
}
if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params))
result = BP_RESULT_OK;
return result;
}
/*****************************************************************************
******************************************************************************
**
** TRANSMITTER CONTROL
**
******************************************************************************
*****************************************************************************/
static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl);
static void init_transmitter_control(struct bios_parser *bp)
{
uint8_t frev;
uint8_t crev;
if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0)
BREAK_TO_DEBUGGER();
switch (crev) {
case 6:
bp->cmd_tbl.transmitter_control = transmitter_control_v1_6;
break;
default:
bp->cmd_tbl.transmitter_control = NULL;
break;
}
}
static enum bp_result transmitter_control_v1_6(
struct bios_parser *bp,
struct bp_transmitter_control *cntl)
{
enum bp_result result = BP_RESULT_FAILURE;
const struct command_table_helper *cmd = bp->cmd_helper;
struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } };
ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter);
ps.param.action = (uint8_t)cntl->action;
if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS)
ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings;
else
ps.param.mode_laneset.digmode =
cmd->signal_type_to_atom_dig_mode(cntl->signal);
ps.param.lanenum = (uint8_t)cntl->lanes_number;
ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel);
ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id);
ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id;
ps.param.symclk_10khz = cntl->pixel_clock/10;
if (cntl->action == TRANSMITTER_CONTROL_ENABLE ||
cntl->action == TRANSMITTER_CONTROL_ACTIAVATE ||
cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) {
dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE,\
"************************%s:ps.param.symclk_10khz = %d\n",\
__func__, ps.param.symclk_10khz);
}
/*color_depth not used any more, driver has deep color factor in the Phyclk*/
if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps))
result = BP_RESULT_OK;
return result;
}
/******************************************************************************
******************************************************************************
**
** SET PIXEL CLOCK
**
******************************************************************************
*****************************************************************************/
static enum bp_result set_pixel_clock_v7(
struct bios_parser *bp,
struct bp_pixel_clock_parameters *bp_params);
static void init_set_pixel_clock(struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
case 7:
bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7;
break;
default:
bp->cmd_tbl.set_pixel_clock = NULL;
break;
}
}
static enum bp_result set_pixel_clock_v7(
struct bios_parser *bp,
struct bp_pixel_clock_parameters *bp_params)
{
enum bp_result result = BP_RESULT_FAILURE;
struct set_pixel_clock_parameter_v1_7 clk;
uint8_t controller_id;
uint32_t pll_id;
memset(&clk, 0, sizeof(clk));
if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
&& bp->cmd_helper->controller_id_to_atom(bp_params->
controller_id, &controller_id)) {
/* Note: VBIOS still wants to use ucCRTC name which is now
* 1 byte in ULONG
*typedef struct _CRTC_PIXEL_CLOCK_FREQ
*{
* target the pixel clock to drive the CRTC timing.
* ULONG ulPixelClock:24;
* 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
* previous version.
* ATOM_CRTC1~6, indicate the CRTC controller to
* ULONG ucCRTC:8;
* drive the pixel clock. not used for DCPLL case.
*}CRTC_PIXEL_CLOCK_FREQ;
*union
*{
* pixel clock and CRTC id frequency
* CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
* ULONG ulDispEngClkFreq; dispclk frequency
*};
*/
clk.crtc_id = controller_id;
clk.pll_id = (uint8_t) pll_id;
clk.encoderobjid =
bp->cmd_helper->encoder_id_to_atom(
dal_graphics_object_id_get_encoder_id(
bp_params->encoder_object_id));
clk.encoder_mode = (uint8_t) bp->
cmd_helper->encoder_mode_bp_to_atom(
bp_params->signal_type, false);
/* We need to convert from KHz units into 10KHz units */
clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock *
10);
clk.deep_color_ratio =
(uint8_t) bp->cmd_helper->
transmitter_color_depth_to_atom(
bp_params->color_depth);
dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE,\
"************************%s:program display clock = %d"\
"colorDepth = %d\n", __func__,\
bp_params->target_pixel_clock, bp_params->color_depth);
if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL;
if (bp_params->flags.PROGRAM_PHY_PLL_ONLY)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL;
if (bp_params->flags.SUPPORT_YUV_420)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE;
if (bp_params->flags.SET_XTALIN_REF_SRC)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN;
if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK;
if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN;
if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk))
result = BP_RESULT_OK;
}
return result;
}
/******************************************************************************
******************************************************************************
**
** SET CRTC TIMING
**
******************************************************************************
*****************************************************************************/
static enum bp_result set_crtc_using_dtd_timing_v3(
struct bios_parser *bp,
struct bp_hw_crtc_timing_parameters *bp_params);
static void init_set_crtc_timing(struct bios_parser *bp)
{
uint32_t dtd_version =
BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming);
switch (dtd_version) {
case 3:
bp->cmd_tbl.set_crtc_timing =
set_crtc_using_dtd_timing_v3;
break;
default:
bp->cmd_tbl.set_crtc_timing = NULL;
break;
}
}
static enum bp_result set_crtc_using_dtd_timing_v3(
struct bios_parser *bp,
struct bp_hw_crtc_timing_parameters *bp_params)
{
enum bp_result result = BP_RESULT_FAILURE;
struct set_crtc_using_dtd_timing_parameters params = {0};
uint8_t atom_controller_id;
if (bp->cmd_helper->controller_id_to_atom(
bp_params->controller_id, &atom_controller_id))
params.crtc_id = atom_controller_id;
/* bios usH_Size wants h addressable size */
params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable);
/* bios usH_Blanking_Time wants borders included in blanking */
params.h_blanking_time =
cpu_to_le16((uint16_t)(bp_params->h_total -
bp_params->h_addressable));
/* bios usV_Size wants v addressable size */
params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable);
/* bios usV_Blanking_Time wants borders included in blanking */
params.v_blanking_time =
cpu_to_le16((uint16_t)(bp_params->v_total -
bp_params->v_addressable));
/* bios usHSyncOffset is the offset from the end of h addressable,
* our horizontalSyncStart is the offset from the beginning
* of h addressable
*/
params.h_syncoffset =
cpu_to_le16((uint16_t)(bp_params->h_sync_start -
bp_params->h_addressable));
params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
/* bios usHSyncOffset is the offset from the end of v addressable,
* our verticalSyncStart is the offset from the beginning of
* v addressable
*/
params.v_syncoffset =
cpu_to_le16((uint16_t)(bp_params->v_sync_start -
bp_params->v_addressable));
params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
/* we assume that overscan from original timing does not get bigger
* than 255
* we will program all the borders in the Set CRTC Overscan call below
*/
if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0)
params.modemiscinfo =
cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
ATOM_HSYNC_POLARITY);
if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0)
params.modemiscinfo =
cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
ATOM_VSYNC_POLARITY);
if (bp_params->flags.INTERLACE) {
params.modemiscinfo =
cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
ATOM_INTERLACE);
/* original DAL code has this condition to apply this
* for non-TV/CV only
* due to complex MV testing for possible impact
* if ( pACParameters->signal != SignalType_YPbPr &&
* pACParameters->signal != SignalType_Composite &&
* pACParameters->signal != SignalType_SVideo)
*/
{
/* HW will deduct 0.5 line from 2nd feild.
* i.e. for 1080i, it is 2 lines for 1st field,
* 2.5 lines for the 2nd feild. we need input as 5
* instead of 4.
* but it is 4 either from Edid data (spec CEA 861)
* or CEA timing table.
*/
params.v_syncoffset =
cpu_to_le16(le16_to_cpu(params.v_syncoffset) +
1);
}
}
if (bp_params->flags.HORZ_COUNT_BY_TWO)
params.modemiscinfo =
cpu_to_le16(le16_to_cpu(params.modemiscinfo) |
0x100); /* ATOM_DOUBLE_CLOCK_MODE */
if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params))
result = BP_RESULT_OK;
return result;
}
/******************************************************************************
******************************************************************************
**
** SELECT CRTC SOURCE
**
******************************************************************************
*****************************************************************************/
static enum bp_result select_crtc_source_v3(
struct bios_parser *bp,
struct bp_crtc_source_select *bp_params);
static void init_select_crtc_source(struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) {
case 3:
bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
break;
default:
bp->cmd_tbl.select_crtc_source = NULL;
break;
}
}
static enum bp_result select_crtc_source_v3(
struct bios_parser *bp,
struct bp_crtc_source_select *bp_params)
{
bool result = BP_RESULT_FAILURE;
struct select_crtc_source_parameters_v2_3 params;
uint8_t atom_controller_id;
uint32_t atom_engine_id;
enum signal_type s = bp_params->signal;
memset(&params, 0, sizeof(params));
if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
&atom_controller_id))
params.crtc_id = atom_controller_id;
else
return result;
if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
&atom_engine_id))
params.encoder_id = (uint8_t)atom_engine_id;
else
return result;
if (s == SIGNAL_TYPE_EDP ||
(s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal ==
SIGNAL_TYPE_LVDS))
s = SIGNAL_TYPE_LVDS;
params.encode_mode =
bp->cmd_helper->encoder_mode_bp_to_atom(
s, bp_params->enable_dp_audio);
/* Needed for VBIOS Random Spatial Dithering feature */
params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth);
if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params))
result = BP_RESULT_OK;
return result;
}
/******************************************************************************
******************************************************************************
**
** ENABLE CRTC
**
******************************************************************************
*****************************************************************************/
static enum bp_result enable_crtc_v1(
struct bios_parser *bp,
enum controller_id controller_id,
bool enable);
static void init_enable_crtc(struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) {
case 1:
bp->cmd_tbl.enable_crtc = enable_crtc_v1;
break;
default:
bp->cmd_tbl.enable_crtc = NULL;
break;
}
}
static enum bp_result enable_crtc_v1(
struct bios_parser *bp,
enum controller_id controller_id,
bool enable)
{
bool result = BP_RESULT_FAILURE;
struct enable_crtc_parameters params = {0};
uint8_t id;
if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
params.crtc_id = id;
else
return BP_RESULT_BADINPUT;
if (enable)
params.enable = ATOM_ENABLE;
else
params.enable = ATOM_DISABLE;
if (EXEC_BIOS_CMD_TABLE(enablecrtc, params))
result = BP_RESULT_OK;
return result;
}
/******************************************************************************
******************************************************************************
**
** DISPLAY PLL
**
******************************************************************************
*****************************************************************************/
/******************************************************************************
******************************************************************************
**
** EXTERNAL ENCODER CONTROL
**
******************************************************************************
*****************************************************************************/
static enum bp_result external_encoder_control_v3(
struct bios_parser *bp,
struct bp_external_encoder_control *cntl);
static void init_external_encoder_control(
struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) {
case 3:
bp->cmd_tbl.external_encoder_control =
external_encoder_control_v3;
break;
default:
bp->cmd_tbl.external_encoder_control = NULL;
break;
}
}
static enum bp_result external_encoder_control_v3(
struct bios_parser *bp,
struct bp_external_encoder_control *cntl)
{
/* TODO */
return BP_RESULT_OK;
}
/******************************************************************************
******************************************************************************
**
** ENABLE DISPLAY POWER GATING
**
******************************************************************************
*****************************************************************************/
static enum bp_result enable_disp_power_gating_v2_1(
struct bios_parser *bp,
enum controller_id crtc_id,
enum bp_pipe_control_action action);
static void init_enable_disp_power_gating(
struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) {
case 1:
bp->cmd_tbl.enable_disp_power_gating =
enable_disp_power_gating_v2_1;
break;
default:
bp->cmd_tbl.enable_disp_power_gating = NULL;
break;
}
}
static enum bp_result enable_disp_power_gating_v2_1(
struct bios_parser *bp,
enum controller_id crtc_id,
enum bp_pipe_control_action action)
{
enum bp_result result = BP_RESULT_FAILURE;
struct enable_disp_power_gating_ps_allocation ps = { { 0 } };
uint8_t atom_crtc_id;
if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
ps.param.disp_pipe_id = atom_crtc_id;
else
return BP_RESULT_BADINPUT;
ps.param.enable =
bp->cmd_helper->disp_power_gating_action_to_atom(action);
if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param))
result = BP_RESULT_OK;
return result;
}
/******************************************************************************
*******************************************************************************
**
** SET DCE CLOCK
**
*******************************************************************************
*******************************************************************************/
static enum bp_result set_dce_clock_v2_1(
struct bios_parser *bp,
struct bp_set_dce_clock_parameters *bp_params);
static void init_set_dce_clock(struct bios_parser *bp)
{
switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) {
case 1:
bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1;
break;
default:
bp->cmd_tbl.set_dce_clock = NULL;
break;
}
}
static enum bp_result set_dce_clock_v2_1(
struct bios_parser *bp,
struct bp_set_dce_clock_parameters *bp_params)
{
enum bp_result result = BP_RESULT_FAILURE;
struct set_dce_clock_ps_allocation_v2_1 params;
uint32_t atom_pll_id;
uint32_t atom_clock_type;
const struct command_table_helper *cmd = bp->cmd_helper;
memset(&params, 0, sizeof(params));
if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) ||
!cmd->dc_clock_type_to_atom(bp_params->clock_type,
&atom_clock_type))
return BP_RESULT_BADINPUT;
params.param.dceclksrc = atom_pll_id;
params.param.dceclktype = atom_clock_type;
if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) {
if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK)
params.param.dceclkflag |=
DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK;
if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK)
params.param.dceclkflag |=
DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE;
if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK)
params.param.dceclkflag |=
DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN;
if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK)
params.param.dceclkflag |=
DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA;
} else
/* only program clock frequency if display clock is used;
* VBIOS will program DPREFCLK
* We need to convert from KHz units into 10KHz units
*/
params.param.dceclk_10khz = cpu_to_le32(
bp_params->target_clock_frequency / 10);
dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE,
"************************%s:target_clock_frequency = %d"\
"clock_type = %d \n", __func__,\
bp_params->target_clock_frequency,\
bp_params->clock_type);
if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) {
/* Convert from 10KHz units back to KHz */
bp_params->target_clock_frequency = le32_to_cpu(
params.param.dceclk_10khz) * 10;
result = BP_RESULT_OK;
}
return result;
}
/******************************************************************************
******************************************************************************
**
** GET SMU CLOCK INFO
**
******************************************************************************
*****************************************************************************/
static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp);
static void init_get_smu_clock_info(struct bios_parser *bp)
{
/* TODO add switch for table vrsion */
bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1;
}
static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp)
{
struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0};
struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output;
smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ;
/* Get Specific Clock */
if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) {
memmove(&smu_output, &smu_input, sizeof(
struct atom_get_smu_clock_info_parameters_v3_1));
return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz;
}
return 0;
}

View File

@ -0,0 +1,105 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_COMMAND_TABLE2_H__
#define __DAL_COMMAND_TABLE2_H__
struct bios_parser;
struct bp_encoder_control;
struct cmd_tbl {
enum bp_result (*dig_encoder_control)(
struct bios_parser *bp,
struct bp_encoder_control *control);
enum bp_result (*encoder_control_dig1)(
struct bios_parser *bp,
struct bp_encoder_control *control);
enum bp_result (*encoder_control_dig2)(
struct bios_parser *bp,
struct bp_encoder_control *control);
enum bp_result (*transmitter_control)(
struct bios_parser *bp,
struct bp_transmitter_control *control);
enum bp_result (*set_pixel_clock)(
struct bios_parser *bp,
struct bp_pixel_clock_parameters *bp_params);
enum bp_result (*enable_spread_spectrum_on_ppll)(
struct bios_parser *bp,
struct bp_spread_spectrum_parameters *bp_params,
bool enable);
enum bp_result (*adjust_display_pll)(
struct bios_parser *bp,
struct bp_adjust_pixel_clock_parameters *bp_params);
enum bp_result (*dac1_encoder_control)(
struct bios_parser *bp,
bool enable,
uint32_t pixel_clock,
uint8_t dac_standard);
enum bp_result (*dac2_encoder_control)(
struct bios_parser *bp,
bool enable,
uint32_t pixel_clock,
uint8_t dac_standard);
enum bp_result (*dac1_output_control)(
struct bios_parser *bp,
bool enable);
enum bp_result (*dac2_output_control)(
struct bios_parser *bp,
bool enable);
enum bp_result (*set_crtc_timing)(
struct bios_parser *bp,
struct bp_hw_crtc_timing_parameters *bp_params);
enum bp_result (*select_crtc_source)(
struct bios_parser *bp,
struct bp_crtc_source_select *bp_params);
enum bp_result (*enable_crtc)(
struct bios_parser *bp,
enum controller_id controller_id,
bool enable);
enum bp_result (*enable_crtc_mem_req)(
struct bios_parser *bp,
enum controller_id controller_id,
bool enable);
enum bp_result (*program_clock)(
struct bios_parser *bp,
struct bp_pixel_clock_parameters *bp_params);
enum bp_result (*external_encoder_control)(
struct bios_parser *bp,
struct bp_external_encoder_control *cntl);
enum bp_result (*enable_disp_power_gating)(
struct bios_parser *bp,
enum controller_id crtc_id,
enum bp_pipe_control_action action);
enum bp_result (*set_dce_clock)(
struct bios_parser *bp,
struct bp_set_dce_clock_parameters *bp_params);
unsigned int (*get_smu_clock_info)(
struct bios_parser *bp);
};
void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp);
#endif

View File

@ -0,0 +1,260 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dm_services.h"
#include "ObjectID.h"
#include "atomfirmware.h"
#include "atomfirmwareid.h"
#include "include/bios_parser_types.h"
#include "command_table_helper2.h"
bool dal_bios_parser_init_cmd_tbl_helper2(
const struct command_table_helper **h,
enum dce_version dce)
{
switch (dce) {
case DCE_VERSION_8_0:
*h = dal_cmd_tbl_helper_dce80_get_table();
return true;
case DCE_VERSION_10_0:
*h = dal_cmd_tbl_helper_dce110_get_table();
return true;
case DCE_VERSION_11_0:
*h = dal_cmd_tbl_helper_dce110_get_table();
return true;
case DCE_VERSION_11_2:
*h = dal_cmd_tbl_helper_dce112_get_table2();
return true;
#if defined(CONFIG_DRM_AMD_DC_DCE12_0)
case DCE_VERSION_12_0:
*h = dal_cmd_tbl_helper_dce112_get_table2();
return true;
#endif
default:
/* Unsupported DCE */
BREAK_TO_DEBUGGER();
return false;
}
}
/* real implementations */
bool dal_cmd_table_helper_controller_id_to_atom2(
enum controller_id id,
uint8_t *atom_id)
{
if (atom_id == NULL) {
BREAK_TO_DEBUGGER();
return false;
}
switch (id) {
case CONTROLLER_ID_D0:
*atom_id = ATOM_CRTC1;
return true;
case CONTROLLER_ID_D1:
*atom_id = ATOM_CRTC2;
return true;
case CONTROLLER_ID_D2:
*atom_id = ATOM_CRTC3;
return true;
case CONTROLLER_ID_D3:
*atom_id = ATOM_CRTC4;
return true;
case CONTROLLER_ID_D4:
*atom_id = ATOM_CRTC5;
return true;
case CONTROLLER_ID_D5:
*atom_id = ATOM_CRTC6;
return true;
/* TODO :case CONTROLLER_ID_UNDERLAY0:
*atom_id = ATOM_UNDERLAY_PIPE0;
return true;
*/
case CONTROLLER_ID_UNDEFINED:
*atom_id = ATOM_CRTC_INVALID;
return true;
default:
/* Wrong controller id */
BREAK_TO_DEBUGGER();
return false;
}
}
/**
* translate_transmitter_bp_to_atom
*
* @brief
* Translate the Transmitter to the corresponding ATOM BIOS value
*
* @param
* input transmitter
* output digitalTransmitter
* // =00: Digital Transmitter1 ( UNIPHY linkAB )
* // =01: Digital Transmitter2 ( UNIPHY linkCD )
* // =02: Digital Transmitter3 ( UNIPHY linkEF )
*/
uint8_t dal_cmd_table_helper_transmitter_bp_to_atom2(
enum transmitter t)
{
switch (t) {
case TRANSMITTER_UNIPHY_A:
case TRANSMITTER_UNIPHY_B:
case TRANSMITTER_TRAVIS_LCD:
return 0;
case TRANSMITTER_UNIPHY_C:
case TRANSMITTER_UNIPHY_D:
return 1;
case TRANSMITTER_UNIPHY_E:
case TRANSMITTER_UNIPHY_F:
return 2;
default:
/* Invalid Transmitter Type! */
BREAK_TO_DEBUGGER();
return 0;
}
}
uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom2(
enum signal_type s,
bool enable_dp_audio)
{
switch (s) {
case SIGNAL_TYPE_DVI_SINGLE_LINK:
case SIGNAL_TYPE_DVI_DUAL_LINK:
return ATOM_ENCODER_MODE_DVI;
case SIGNAL_TYPE_HDMI_TYPE_A:
return ATOM_ENCODER_MODE_HDMI;
case SIGNAL_TYPE_LVDS:
return ATOM_ENCODER_MODE_LVDS;
case SIGNAL_TYPE_EDP:
case SIGNAL_TYPE_DISPLAY_PORT_MST:
case SIGNAL_TYPE_DISPLAY_PORT:
case SIGNAL_TYPE_VIRTUAL:
if (enable_dp_audio)
return ATOM_ENCODER_MODE_DP_AUDIO;
else
return ATOM_ENCODER_MODE_DP;
case SIGNAL_TYPE_RGB:
return ATOM_ENCODER_MODE_CRT;
default:
return ATOM_ENCODER_MODE_CRT;
}
}
bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src2(
enum clock_source_id id,
uint32_t *ref_clk_src_id)
{
if (ref_clk_src_id == NULL) {
BREAK_TO_DEBUGGER();
return false;
}
switch (id) {
case CLOCK_SOURCE_ID_PLL1:
*ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL;
return true;
case CLOCK_SOURCE_ID_PLL2:
*ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL;
return true;
/*TODO:case CLOCK_SOURCE_ID_DCPLL:
*ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL;
return true;
*/
case CLOCK_SOURCE_ID_EXTERNAL:
*ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK;
return true;
case CLOCK_SOURCE_ID_UNDEFINED:
*ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID;
return true;
default:
/* Unsupported clock source id */
BREAK_TO_DEBUGGER();
return false;
}
}
uint8_t dal_cmd_table_helper_encoder_id_to_atom2(
enum encoder_id id)
{
switch (id) {
case ENCODER_ID_INTERNAL_LVDS:
return ENCODER_OBJECT_ID_INTERNAL_LVDS;
case ENCODER_ID_INTERNAL_TMDS1:
return ENCODER_OBJECT_ID_INTERNAL_TMDS1;
case ENCODER_ID_INTERNAL_TMDS2:
return ENCODER_OBJECT_ID_INTERNAL_TMDS2;
case ENCODER_ID_INTERNAL_DAC1:
return ENCODER_OBJECT_ID_INTERNAL_DAC1;
case ENCODER_ID_INTERNAL_DAC2:
return ENCODER_OBJECT_ID_INTERNAL_DAC2;
case ENCODER_ID_INTERNAL_LVTM1:
return ENCODER_OBJECT_ID_INTERNAL_LVTM1;
case ENCODER_ID_INTERNAL_HDMI:
return ENCODER_OBJECT_ID_HDMI_INTERNAL;
case ENCODER_ID_EXTERNAL_TRAVIS:
return ENCODER_OBJECT_ID_TRAVIS;
case ENCODER_ID_EXTERNAL_NUTMEG:
return ENCODER_OBJECT_ID_NUTMEG;
case ENCODER_ID_INTERNAL_KLDSCP_TMDS1:
return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
case ENCODER_ID_EXTERNAL_MVPU_FPGA:
return ENCODER_OBJECT_ID_MVPU_FPGA;
case ENCODER_ID_INTERNAL_DDI:
return ENCODER_OBJECT_ID_INTERNAL_DDI;
case ENCODER_ID_INTERNAL_UNIPHY:
return ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
case ENCODER_ID_INTERNAL_KLDSCP_LVTMA:
return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
case ENCODER_ID_INTERNAL_UNIPHY1:
return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
case ENCODER_ID_INTERNAL_UNIPHY2:
return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
case ENCODER_ID_INTERNAL_UNIPHY3:
return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3;
case ENCODER_ID_INTERNAL_WIRELESS:
return ENCODER_OBJECT_ID_INTERNAL_VCE;
case ENCODER_ID_INTERNAL_VIRTUAL:
return ENCODER_OBJECT_ID_NONE;
case ENCODER_ID_UNKNOWN:
return ENCODER_OBJECT_ID_NONE;
default:
/* Invalid encoder id */
BREAK_TO_DEBUGGER();
return ENCODER_OBJECT_ID_NONE;
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_COMMAND_TABLE_HELPER2_H__
#define __DAL_COMMAND_TABLE_HELPER2_H__
#include "dce80/command_table_helper_dce80.h"
#include "dce110/command_table_helper_dce110.h"
#include "dce112/command_table_helper2_dce112.h"
struct command_table_helper {
bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
uint8_t (*encoder_action_to_atom)(
enum bp_encoder_control_action action);
uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
bool enable_dp_audio);
bool (*engine_bp_to_atom)(enum engine_id engine_id,
uint32_t *atom_engine_id);
bool (*clock_source_id_to_atom)(enum clock_source_id id,
uint32_t *atom_pll_id);
bool (*clock_source_id_to_ref_clk_src)(
enum clock_source_id id,
uint32_t *ref_clk_src_id);
uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
uint8_t (*encoder_id_to_atom)(enum encoder_id id);
uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
enum clock_source_id id);
uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
uint8_t (*phy_id_to_atom)(enum transmitter t);
uint8_t (*disp_power_gating_action_to_atom)(
enum bp_pipe_control_action action);
bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id,
uint32_t *atom_clock_type);
uint8_t (*transmitter_color_depth_to_atom)(
enum transmitter_color_depth id);
};
bool dal_bios_parser_init_cmd_tbl_helper2(const struct command_table_helper **h,
enum dce_version dce);
bool dal_cmd_table_helper_controller_id_to_atom2(
enum controller_id id,
uint8_t *atom_id);
uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom2(
enum signal_type s,
bool enable_dp_audio);
bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src2(
enum clock_source_id id,
uint32_t *ref_clk_src_id);
uint8_t dal_cmd_table_helper_transmitter_bp_to_atom2(
enum transmitter t);
uint8_t dal_cmd_table_helper_encoder_id_to_atom2(
enum encoder_id id);
#endif

View File

@ -0,0 +1,418 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#include "dm_services.h"
#include "atom.h"
#include "include/bios_parser_types.h"
#include "../command_table_helper2.h"
static uint8_t phy_id_to_atom(enum transmitter t)
{
uint8_t atom_phy_id;
switch (t) {
case TRANSMITTER_UNIPHY_A:
atom_phy_id = ATOM_PHY_ID_UNIPHYA;
break;
case TRANSMITTER_UNIPHY_B:
atom_phy_id = ATOM_PHY_ID_UNIPHYB;
break;
case TRANSMITTER_UNIPHY_C:
atom_phy_id = ATOM_PHY_ID_UNIPHYC;
break;
case TRANSMITTER_UNIPHY_D:
atom_phy_id = ATOM_PHY_ID_UNIPHYD;
break;
case TRANSMITTER_UNIPHY_E:
atom_phy_id = ATOM_PHY_ID_UNIPHYE;
break;
case TRANSMITTER_UNIPHY_F:
atom_phy_id = ATOM_PHY_ID_UNIPHYF;
break;
case TRANSMITTER_UNIPHY_G:
atom_phy_id = ATOM_PHY_ID_UNIPHYG;
break;
default:
atom_phy_id = ATOM_PHY_ID_UNIPHYA;
break;
}
return atom_phy_id;
}
static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
{
uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
switch (s) {
case SIGNAL_TYPE_DISPLAY_PORT:
case SIGNAL_TYPE_EDP:
atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
break;
case SIGNAL_TYPE_DVI_SINGLE_LINK:
case SIGNAL_TYPE_DVI_DUAL_LINK:
atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
break;
case SIGNAL_TYPE_HDMI_TYPE_A:
atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
break;
case SIGNAL_TYPE_DISPLAY_PORT_MST:
atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
break;
default:
atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
break;
}
return atom_dig_mode;
}
static uint8_t clock_source_id_to_atom_phy_clk_src_id(
enum clock_source_id id)
{
uint8_t atom_phy_clk_src_id = 0;
switch (id) {
case CLOCK_SOURCE_ID_PLL0:
atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
break;
case CLOCK_SOURCE_ID_PLL1:
atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
break;
case CLOCK_SOURCE_ID_PLL2:
atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
break;
case CLOCK_SOURCE_ID_EXTERNAL:
atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
break;
default:
atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
break;
}
return atom_phy_clk_src_id >> 2;
}
static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
{
uint8_t atom_hpd_sel = 0;
switch (id) {
case HPD_SOURCEID1:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD1_SEL;
break;
case HPD_SOURCEID2:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD2_SEL;
break;
case HPD_SOURCEID3:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD3_SEL;
break;
case HPD_SOURCEID4:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD4_SEL;
break;
case HPD_SOURCEID5:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD5_SEL;
break;
case HPD_SOURCEID6:
atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD6_SEL;
break;
case HPD_SOURCEID_UNKNOWN:
default:
atom_hpd_sel = 0;
break;
}
return atom_hpd_sel;
}
static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
{
uint8_t atom_dig_encoder_sel = 0;
switch (id) {
case ENGINE_ID_DIGA:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL;
break;
case ENGINE_ID_DIGB:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGB_SEL;
break;
case ENGINE_ID_DIGC:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGC_SEL;
break;
case ENGINE_ID_DIGD:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGD_SEL;
break;
case ENGINE_ID_DIGE:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGE_SEL;
break;
case ENGINE_ID_DIGF:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGF_SEL;
break;
case ENGINE_ID_DIGG:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGG_SEL;
break;
case ENGINE_ID_UNKNOWN:
/* No DIG_FRONT is associated to DIG_BACKEND */
atom_dig_encoder_sel = 0;
break;
default:
atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL;
break;
}
return 0;
}
static bool clock_source_id_to_atom(
enum clock_source_id id,
uint32_t *atom_pll_id)
{
bool result = true;
if (atom_pll_id != NULL)
switch (id) {
case CLOCK_SOURCE_COMBO_PHY_PLL0:
*atom_pll_id = ATOM_COMBOPHY_PLL0;
break;
case CLOCK_SOURCE_COMBO_PHY_PLL1:
*atom_pll_id = ATOM_COMBOPHY_PLL1;
break;
case CLOCK_SOURCE_COMBO_PHY_PLL2:
*atom_pll_id = ATOM_COMBOPHY_PLL2;
break;
case CLOCK_SOURCE_COMBO_PHY_PLL3:
*atom_pll_id = ATOM_COMBOPHY_PLL3;
break;
case CLOCK_SOURCE_COMBO_PHY_PLL4:
*atom_pll_id = ATOM_COMBOPHY_PLL4;
break;
case CLOCK_SOURCE_COMBO_PHY_PLL5:
*atom_pll_id = ATOM_COMBOPHY_PLL5;
break;
case CLOCK_SOURCE_COMBO_DISPLAY_PLL0:
*atom_pll_id = ATOM_PPLL0;
break;
case CLOCK_SOURCE_ID_DFS:
*atom_pll_id = ATOM_GCK_DFS;
break;
case CLOCK_SOURCE_ID_VCE:
*atom_pll_id = ATOM_DP_DTO;
break;
case CLOCK_SOURCE_ID_DP_DTO:
*atom_pll_id = ATOM_DP_DTO;
break;
case CLOCK_SOURCE_ID_UNDEFINED:
/* Should not happen */
*atom_pll_id = ATOM_PPLL_INVALID;
result = false;
break;
default:
result = false;
break;
}
return result;
}
static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
{
bool result = false;
if (atom_engine_id != NULL)
switch (id) {
case ENGINE_ID_DIGA:
*atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGB:
*atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGC:
*atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGD:
*atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGE:
*atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGF:
*atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DIGG:
*atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
result = true;
break;
case ENGINE_ID_DACA:
*atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
result = true;
break;
default:
break;
}
return result;
}
static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
{
uint8_t atom_action = 0;
switch (action) {
case ENCODER_CONTROL_ENABLE:
atom_action = ATOM_ENABLE;
break;
case ENCODER_CONTROL_DISABLE:
atom_action = ATOM_DISABLE;
break;
case ENCODER_CONTROL_SETUP:
atom_action = ATOM_ENCODER_CMD_STREAM_SETUP;
break;
case ENCODER_CONTROL_INIT:
atom_action = ATOM_ENCODER_INIT;
break;
default:
BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
break;
}
return atom_action;
}
static uint8_t disp_power_gating_action_to_atom(
enum bp_pipe_control_action action)
{
uint8_t atom_pipe_action = 0;
switch (action) {
case ASIC_PIPE_DISABLE:
atom_pipe_action = ATOM_DISABLE;
break;
case ASIC_PIPE_ENABLE:
atom_pipe_action = ATOM_ENABLE;
break;
case ASIC_PIPE_INIT:
atom_pipe_action = ATOM_INIT;
break;
default:
ASSERT_CRITICAL(false); /* Unhandle action in driver! */
break;
}
return atom_pipe_action;
}
static bool dc_clock_type_to_atom(
enum bp_dce_clock_type id,
uint32_t *atom_clock_type)
{
bool retCode = true;
if (atom_clock_type != NULL) {
switch (id) {
case DCECLOCK_TYPE_DISPLAY_CLOCK:
*atom_clock_type = DCE_CLOCK_TYPE_DISPCLK;
break;
case DCECLOCK_TYPE_DPREFCLK:
*atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK;
break;
default:
ASSERT_CRITICAL(false); /* Unhandle action in driver! */
break;
}
}
return retCode;
}
static uint8_t transmitter_color_depth_to_atom(enum transmitter_color_depth id)
{
uint8_t atomColorDepth = 0;
switch (id) {
case TRANSMITTER_COLOR_DEPTH_24:
atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
break;
case TRANSMITTER_COLOR_DEPTH_30:
atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
break;
case TRANSMITTER_COLOR_DEPTH_36:
atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
break;
case TRANSMITTER_COLOR_DEPTH_48:
atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
break;
default:
ASSERT_CRITICAL(false); /* Unhandle action in driver! */
break;
}
return atomColorDepth;
}
/* function table */
static const struct command_table_helper command_table_helper_funcs = {
.controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom2,
.encoder_action_to_atom = encoder_action_to_atom,
.engine_bp_to_atom = engine_bp_to_atom,
.clock_source_id_to_atom = clock_source_id_to_atom,
.clock_source_id_to_atom_phy_clk_src_id =
clock_source_id_to_atom_phy_clk_src_id,
.signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
.hpd_sel_to_atom = hpd_sel_to_atom,
.dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
.phy_id_to_atom = phy_id_to_atom,
.disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
.clock_source_id_to_ref_clk_src = NULL,
.transmitter_bp_to_atom = NULL,
.encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom2,
.encoder_mode_bp_to_atom =
dal_cmd_table_helper_encoder_mode_bp_to_atom2,
.dc_clock_type_to_atom = dc_clock_type_to_atom,
.transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
};
/*
* dal_cmd_tbl_helper_dce110_get_table
*
* @brief
* Initialize command table helper functions
*
* @param
* const struct command_table_helper **h - [out] struct of functions
*
*/
const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2()
{
return &command_table_helper_funcs;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: AMD
*
*/
#ifndef __DAL_COMMAND_TABLE_HELPER2_DCE112_H__
#define __DAL_COMMAND_TABLE_HELPER2_DCE112_H__
struct command_table_helper;
/* Initialize command table helper functions */
const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void);
#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */