/* * 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 *
*/
/******************************************************************************* ******************************************************************************** ** ** D I G E N C O D E R C O N T R O L ** ********************************************************************************
*******************************************************************************/ staticenum bp_result encoder_control_digx_v3( struct bios_parser *bp, struct bp_encoder_control *cntl);
if (cntl != NULL) switch (cntl->engine_id) { case ENGINE_ID_DIGA: if (cmd_tbl->encoder_control_dig1 != NULL)
result =
cmd_tbl->encoder_control_dig1(bp, cntl); break; case ENGINE_ID_DIGB: if (cmd_tbl->encoder_control_dig2 != NULL)
result =
cmd_tbl->encoder_control_dig2(bp, cntl); break;
/* We need to convert from KHz units into 10KHz units */
params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
params.ucEncoderMode =
(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
cntl->signal,
cntl->enable_dp_audio);
params.ucLaneNum = (uint8_t)(cntl->lanes_number);
switch (cntl->color_depth) { case COLOR_DEPTH_888:
params.ucBitPerColor = PANEL_8BIT_PER_COLOR; break; case COLOR_DEPTH_101010:
params.ucBitPerColor = PANEL_10BIT_PER_COLOR; break; case COLOR_DEPTH_121212:
params.ucBitPerColor = PANEL_12BIT_PER_COLOR; break; case COLOR_DEPTH_161616:
params.ucBitPerColor = PANEL_16BIT_PER_COLOR; break; default: break;
}
if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
result = BP_RESULT_OK;
/* We need to convert from KHz units into 10KHz units */
params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
params.ucEncoderMode =
(uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
cntl->signal,
cntl->enable_dp_audio));
params.ucLaneNum = (uint8_t)(cntl->lanes_number);
switch (cntl->color_depth) { case COLOR_DEPTH_888:
params.ucBitPerColor = PANEL_8BIT_PER_COLOR; break; case COLOR_DEPTH_101010:
params.ucBitPerColor = PANEL_10BIT_PER_COLOR; break; case COLOR_DEPTH_121212:
params.ucBitPerColor = PANEL_12BIT_PER_COLOR; break; case COLOR_DEPTH_161616:
params.ucBitPerColor = PANEL_16BIT_PER_COLOR; break; default: break;
}
if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
result = BP_RESULT_OK;
switch (cntl->transmitter) { case TRANSMITTER_UNIPHY_A: case TRANSMITTER_UNIPHY_B: case TRANSMITTER_UNIPHY_C: case TRANSMITTER_UNIPHY_D: case TRANSMITTER_UNIPHY_E: case TRANSMITTER_UNIPHY_F: case TRANSMITTER_TRAVIS_LCD: break; default: return BP_RESULT_BADINPUT;
}
switch (cntl->action) { case TRANSMITTER_CONTROL_INIT: if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
(CONNECTOR_ID_DUAL_LINK_DVID == connector_id)) /* on INIT this bit should be set according to the * physical connector * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* connector object id */
params.usInitInfo =
cpu_to_le16((uint8_t)cntl->connector_obj_id.id); break; case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: /* voltage swing and pre-emphsis */
params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings; break; default: /* if dual-link */ if (LANE_COUNT_FOUR < cntl->lanes_number) { /* on ENABLE/DISABLE this bit should be set according to * actual timing (number of lanes) * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* link rate, half for dual link * We need to convert from KHz units into 20KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
} else /* link rate, half for dual link * We need to convert from KHz units into 10KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 10)); break;
}
/* 00 - coherent mode * 01 - incoherent mode
*/
params.acConfig.fCoherentMode = cntl->coherent;
if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_F == cntl->transmitter)) /* Bit2: Transmitter Link selection * =0 when bit0=0, single link A/C/E, when bit0=1, * master link A/C/E * =1 when bit0=0, single link B/D/F, when bit0=1, * master link B/D/F
*/
params.acConfig.ucLinkSel = 1;
if (ENGINE_ID_DIGB == cntl->engine_id) /* Bit3: Transmitter data source selection * =0 DIGA is data source. * =1 DIGB is data source. * This bit is only useful when ucAction= ATOM_ENABLE
*/
params.acConfig.ucEncoderSel = 1;
if (CONNECTOR_ID_DISPLAY_PORT == connector_id ||
CONNECTOR_ID_USBC == connector_id) /* Bit4: DP connector flag * =0 connector is none-DP connector * =1 connector is DP connector
*/
params.acConfig.fDPConnector = 1;
switch (cntl->transmitter) { case TRANSMITTER_UNIPHY_A: case TRANSMITTER_UNIPHY_B: case TRANSMITTER_UNIPHY_C: case TRANSMITTER_UNIPHY_D: case TRANSMITTER_UNIPHY_E: case TRANSMITTER_UNIPHY_F: case TRANSMITTER_TRAVIS_LCD: break; default: return BP_RESULT_BADINPUT;
}
if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id)) return BP_RESULT_BADINPUT;
/* fill information based on the action */ switch (cntl->action) { case TRANSMITTER_CONTROL_INIT: if (dual_link_conn) { /* on INIT this bit should be set according to the * phisycal connector * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
}
/* connector object id */
params.usInitInfo =
cpu_to_le16((uint8_t)(cntl->connector_obj_id.id)); break; case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: /* votage swing and pre-emphsis */
params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings; break; default: if (dual_link_conn && cntl->multi_path) /* on ENABLE/DISABLE this bit should be set according to * actual timing (number of lanes) * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* if dual-link */ if (LANE_COUNT_FOUR < cntl->lanes_number) { /* on ENABLE/DISABLE this bit should be set according to * actual timing (number of lanes) * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* link rate, half for dual link * We need to convert from KHz units into 20KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
} else { /* link rate, half for dual link * We need to convert from KHz units into 10KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
} break;
}
/* 00 - coherent mode * 01 - incoherent mode
*/
params.acConfig.fCoherentMode = cntl->coherent;
if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_F == cntl->transmitter)) /* Bit2: Transmitter Link selection * =0 when bit0=0, single link A/C/E, when bit0=1, * master link A/C/E * =1 when bit0=0, single link B/D/F, when bit0=1, * master link B/D/F
*/
params.acConfig.ucLinkSel = 1;
if (ENGINE_ID_DIGB == cntl->engine_id) /* Bit3: Transmitter data source selection * =0 DIGA is data source. * =1 DIGB is data source. * This bit is only useful when ucAction= ATOM_ENABLE
*/
params.acConfig.ucEncoderSel = 1;
switch (cntl->transmitter) { case TRANSMITTER_UNIPHY_A: case TRANSMITTER_UNIPHY_B: case TRANSMITTER_UNIPHY_C: case TRANSMITTER_UNIPHY_D: case TRANSMITTER_UNIPHY_E: case TRANSMITTER_UNIPHY_F: case TRANSMITTER_TRAVIS_LCD: break; default: return BP_RESULT_BADINPUT;
}
if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id)) return BP_RESULT_BADINPUT;
switch (cntl->action) { case TRANSMITTER_CONTROL_INIT:
{ if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
(CONNECTOR_ID_DUAL_LINK_DVID == conn_id)) /* on INIT this bit should be set according to the * phisycal connector * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* connector object id */
params.usInitInfo =
cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
} break; case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS: /* votage swing and pre-emphsis */
params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings); break; default: if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
(CONNECTOR_ID_DUAL_LINK_DVID == conn_id)) /* on ENABLE/DISABLE this bit should be set according to * actual timing (number of lanes) * Bit0: dual link connector flag * =0 connector is single link connector * =1 connector is dual link connector
*/
params.acConfig.fDualLinkConnector = 1;
/* if dual-link */ if (LANE_COUNT_FOUR < cntl->lanes_number) /* link rate, half for dual link * We need to convert from KHz units into 20KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 20)); else { /* link rate, half for dual link * We need to convert from KHz units into 10KHz units
*/
params.usPixelClock =
cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
} break;
}
/* 00 - coherent mode * 01 - incoherent mode
*/
params.acConfig.fCoherentMode = cntl->coherent;
if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_D == cntl->transmitter)
|| (TRANSMITTER_UNIPHY_F == cntl->transmitter)) /* Bit2: Transmitter Link selection * =0 when bit0=0, single link A/C/E, when bit0=1, * master link A/C/E * =1 when bit0=0, single link B/D/F, when bit0=1, * master link B/D/F
*/
params.acConfig.ucLinkSel = 1;
if (ENGINE_ID_DIGB == cntl->engine_id) /* Bit3: Transmitter data source selection * =0 DIGA is data source. * =1 DIGB is data source. * This bit is only useful when ucAction= ATOM_ENABLE
*/
params.acConfig.ucEncoderSel = 1;
/* We need to convert from 100Hz units into 10KHz units */
allocation.sPCLKInput.usPixelClock =
cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
if (CONTROLLER_ID_D1 != bp_params->controller_id)
params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
result = BP_RESULT_OK;
return result;
}
#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5 /* video bios did not define this: */ typedefstruct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput; /* Caller doesn't need to init this portion */
ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
} SET_PIXEL_CLOCK_PS_ALLOCATION_V5; #endif
#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6 /* video bios did not define this: */ typedefstruct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput; /* Caller doesn't need to init this portion */
ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
} SET_PIXEL_CLOCK_PS_ALLOCATION_V6; #endif
/* We need to convert from 100Hz units into 10KHz units */
clk.sPCLKInput.usPixelClock =
cpu_to_le16((uint16_t)(bp_params->target_pixel_clock_100hz / 100));
if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
clk.sPCLKInput.ucMiscInfo |=
PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
clk.sPCLKInput.ucMiscInfo |=
PIXEL_CLOCK_MISC_REF_DIV_SRC;
/* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp * =1:30bpp, =2:32bpp * driver choose program it itself, i.e. here we program it * to 888 by default.
*/ if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) switch (bp_params->color_depth) { case TRANSMITTER_COLOR_DEPTH_30: /* yes this is correct, the atom define is wrong */
clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP; break; case TRANSMITTER_COLOR_DEPTH_36: /* yes this is correct, the atom define is wrong */
clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; break; default: break;
}
if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
result = BP_RESULT_OK;
}
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.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
clk.sPCLKInput.ucRefDiv =
(uint8_t) bp_params->reference_divider;
clk.sPCLKInput.usFbDiv =
cpu_to_le16((uint16_t) bp_params->feedback_divider);
clk.sPCLKInput.ulFbDivDecFrac =
cpu_to_le32(bp_params->fractional_feedback_divider);
clk.sPCLKInput.ucPostDiv =
(uint8_t) bp_params->pixel_clock_post_divider;
clk.sPCLKInput.ucTransmitterID =
bp->cmd_helper->encoder_id_to_atom(
dal_graphics_object_id_get_encoder_id(
bp_params->encoder_object_id));
clk.sPCLKInput.ucEncoderMode =
(uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
bp_params->signal_type, false);
/* We need to convert from 100 Hz units into 10KHz units */
clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
cpu_to_le32(bp_params->target_pixel_clock_100hz / 100);
if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
clk.sPCLKInput.ucMiscInfo |=
PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
}
if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
clk.sPCLKInput.ucMiscInfo |=
PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
}
/* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: * 24bpp =1:30bpp, =2:32bpp * driver choose program it itself, i.e. here we pass required * target rate that includes deep color.
*/ if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) switch (bp_params->color_depth) { case TRANSMITTER_COLOR_DEPTH_30:
clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6; break; case TRANSMITTER_COLOR_DEPTH_36:
clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6; break; case TRANSMITTER_COLOR_DEPTH_48:
clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; break; default: break;
}
if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
result = BP_RESULT_OK;
}
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.ucCRTC = controller_id;
clk.ucPpll = (uint8_t) pll_id;
clk.ucTransmitterID = bp->cmd_helper->encoder_id_to_atom(dal_graphics_object_id_get_encoder_id(bp_params->encoder_object_id));
clk.ucEncoderMode = (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(bp_params->signal_type, false);
if (bp_params->flags.EXTERNAL_SS)
params.ucSpreadSpectrumType |=
ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
if (bp_params->flags.CENTER_SPREAD)
params.ucSpreadSpectrumType |=
ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
/* Both amounts need to be left shifted first before bit * comparison. Otherwise, the result will always be zero here
*/
params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
((bp_params->ds.feedback_amount <<
ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
((bp_params->ds.nfrac_amount <<
ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
} else
params.ucEnable = ATOM_DISABLE;
if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
result = BP_RESULT_OK;
switch (bp_params->pll_id) { case CLOCK_SOURCE_ID_PLL0: /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only, * not for SI display clock.
*/
params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL; break; case CLOCK_SOURCE_ID_PLL1:
params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL; break;
case CLOCK_SOURCE_ID_PLL2:
params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL; break;
case CLOCK_SOURCE_ID_DCPLL:
params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL; break;
if (bp_params->flags.EXTERNAL_SS)
params.ucSpreadSpectrumType |=
ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD; if (bp_params->flags.CENTER_SPREAD)
params.ucSpreadSpectrumType |=
ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
/* Both amounts need to be left shifted first before bit * comparison. Otherwise, the result will always be zero here
*/
params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
((bp_params->ds.feedback_amount <<
ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
((bp_params->ds.nfrac_amount <<
ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
} else
params.ucEnable = ATOM_DISABLE;
if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
result = BP_RESULT_OK;
/* We need to convert from KHz units into 10KHz units and then convert
* output pixel clock back 10KHz-->KHz */
uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
/* We need to convert from KHz units into 10KHz units and then convert
* output pixel clock back 10KHz-->KHz */
params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
params.sInput.ucTransmitterID =
bp->cmd_helper->encoder_id_to_atom(
dal_graphics_object_id_get_encoder_id(
bp_params->encoder_object_id));
params.sInput.ucEncodeMode =
(uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
bp_params->signal_type, false);
if (bp_params->ss_enable == true)
params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) { /* Convert output pixel clock back 10KHz-->KHz: multiply * original pixel clock in KHz by ratio
* [output pxlClk/input pxlClk] */
uint64_t pixel_clk_10_khz_out =
(uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
/* We need to convert from KHz units into 10KHz units * it looks as if the TvControl do not care about pixel clock
*/
params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
}
/* VBIOS does not expect any value except zero into this call, for * underscan use another entry ProgramOverscan call but when mode * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok, * but when same ,but 60 Hz there is corruption * DAL1 does not allow the mode 1776x1000@60
*/
params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
if (bp_params->flags.INTERLACE) {
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
/* original DAL code has this condition to apply tis 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.usV_SyncStart =
cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
}
if (bp_params->flags.HORZ_COUNT_BY_TWO)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
result = BP_RESULT_OK;
if (bp->cmd_helper->controller_id_to_atom(
bp_params->controller_id, &atom_controller_id))
params.ucCRTC = atom_controller_id;
/* bios usH_Size wants h addressable size */
params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable); /* bios usH_Blanking_Time wants borders included in blanking */
params.usH_Blanking_Time =
cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable)); /* bios usV_Size wants v addressable size */
params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable); /* bios usV_Blanking_Time wants borders included in blanking */
params.usV_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.usH_SyncOffset =
cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
params.usH_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.usV_SyncOffset =
cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
params.usV_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 (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
if (bp_params->flags.INTERLACE) {
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | 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.
*/
le16_add_cpu(¶ms.usV_SyncOffset, 1);
}
}
if (bp_params->flags.HORZ_COUNT_BY_TWO)
params.susModeMiscInfo.usAccess =
cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
result = BP_RESULT_OK;
/* We need to convert from KHz units into 10KHz units */
params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
params.sPCLKInput.usPixelClock =
cpu_to_le16((uint16_t) (bp_params->target_pixel_clock_100hz / 100));
params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.