/* * 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 *
*/
for (;;) {
header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
if (!header) return BP_RESULT_BADBIOSTABLE;
if (LAST_RECORD_TYPE == header->ucRecordType ||
!header->ucRecordSize) break;
if (ATOM_I2C_RECORD_TYPE == header->ucRecordType
&& sizeof(ATOM_I2C_RECORD) <= header->ucRecordSize) { /* get the I2C info */
record = (ATOM_I2C_RECORD *) header;
if (get_gpio_i2c_info(bp, record, info) == BP_RESULT_OK) return BP_RESULT_OK;
}
if (!firmware_info) return BP_RESULT_BADBIOSTABLE;
memset(info, 0, sizeof(*info));
/* Pixel clock pll information. We need to convert from 10KHz units into
* KHz units */
info->pll_info.crystal_frequency =
le16_to_cpu(firmware_info->usReferenceClock) * 10;
info->pll_info.min_input_pxl_clk_pll_frequency =
le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10;
info->pll_info.max_input_pxl_clk_pll_frequency =
le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10;
info->pll_info.min_output_pxl_clk_pll_frequency =
le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10;
info->pll_info.max_output_pxl_clk_pll_frequency =
le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10;
if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) /* Since there is no information on the SS, report conservative
* value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000;
if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support) /* Since there is no information on the SS,report conservative
* value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000;
/* Pixel clock pll information. We need to convert from 10KHz units into
* KHz units */
info->pll_info.crystal_frequency =
le16_to_cpu(firmwareInfo->usCoreReferenceClock) * 10;
info->pll_info.min_input_pxl_clk_pll_frequency =
le16_to_cpu(firmwareInfo->usMinPixelClockPLL_Input) * 10;
info->pll_info.max_input_pxl_clk_pll_frequency =
le16_to_cpu(firmwareInfo->usMaxPixelClockPLL_Input) * 10;
info->pll_info.min_output_pxl_clk_pll_frequency =
le32_to_cpu(firmwareInfo->ulMinPixelClockPLL_Output) * 10;
info->pll_info.max_output_pxl_clk_pll_frequency =
le32_to_cpu(firmwareInfo->ulMaxPixelClockPLL_Output) * 10;
info->default_display_engine_pll_frequency =
le32_to_cpu(firmwareInfo->ulDefaultDispEngineClkFreq) * 10;
info->external_clock_source_frequency_for_dp =
le16_to_cpu(firmwareInfo->usUniphyDPModeExtClkFreq) * 10;
info->min_allowed_bl_level = firmwareInfo->ucMinAllowedBL_Level;
/* There should be only one entry in the SS info table for Memory Clock
*/
index = 0; if (firmwareInfo->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) /* Since there is no information for external SS, report
* conservative value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000; elseif (get_ss_info_v3_1(bp,
ASIC_INTERNAL_MEMORY_SS, index, &internalSS) == BP_RESULT_OK) { if (internalSS.spread_spectrum_percentage) {
info->feature.memory_clk_ss_percentage =
internalSS.spread_spectrum_percentage; if (internalSS.type.CENTER_MODE) { /* if it is centermode, the exact SS Percentage * will be round up of half of the percentage
* reported in the SS table */
++info->feature.memory_clk_ss_percentage;
info->feature.memory_clk_ss_percentage /= 2;
}
}
}
/* There should be only one entry in the SS info table for Engine Clock
*/
index = 1; if (firmwareInfo->usFirmwareCapability.sbfAccess.EngineClockSS_Support) /* Since there is no information for external SS, report
* conservative value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000; elseif (get_ss_info_v3_1(bp,
ASIC_INTERNAL_ENGINE_SS, index, &internalSS) == BP_RESULT_OK) { if (internalSS.spread_spectrum_percentage) {
info->feature.engine_clk_ss_percentage =
internalSS.spread_spectrum_percentage; if (internalSS.type.CENTER_MODE) { /* if it is centermode, the exact SS Percentage * will be round up of half of the percentage
* reported in the SS table */
++info->feature.engine_clk_ss_percentage;
info->feature.engine_clk_ss_percentage /= 2;
}
}
}
if (!firmware_info) return BP_RESULT_BADBIOSTABLE;
memset(info, 0, sizeof(*info));
/* Pixel clock pll information. We need to convert from 10KHz units into
* KHz units */
info->pll_info.crystal_frequency =
le16_to_cpu(firmware_info->usCoreReferenceClock) * 10;
info->pll_info.min_input_pxl_clk_pll_frequency =
le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10;
info->pll_info.max_input_pxl_clk_pll_frequency =
le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10;
info->pll_info.min_output_pxl_clk_pll_frequency =
le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10;
info->pll_info.max_output_pxl_clk_pll_frequency =
le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10;
info->default_display_engine_pll_frequency =
le32_to_cpu(firmware_info->ulDefaultDispEngineClkFreq) * 10;
info->external_clock_source_frequency_for_dp =
le16_to_cpu(firmware_info->usUniphyDPModeExtClkFreq) * 10;
/* There should be only one entry in the SS info table for Memory Clock
*/
index = 0; if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support) /* Since there is no information for external SS, report
* conservative value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000; elseif (get_ss_info_v3_1(bp,
ASIC_INTERNAL_MEMORY_SS, index, &internal_ss) == BP_RESULT_OK) { if (internal_ss.spread_spectrum_percentage) {
info->feature.memory_clk_ss_percentage =
internal_ss.spread_spectrum_percentage; if (internal_ss.type.CENTER_MODE) { /* if it is centermode, the exact SS Percentage * will be round up of half of the percentage
* reported in the SS table */
++info->feature.memory_clk_ss_percentage;
info->feature.memory_clk_ss_percentage /= 2;
}
}
}
/* There should be only one entry in the SS info table for Engine Clock
*/
index = 1; if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support) /* Since there is no information for external SS, report
* conservative value 3% for bandwidth calculation */ /* unit of 0.01% */
info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000; elseif (get_ss_info_v3_1(bp,
ASIC_INTERNAL_ENGINE_SS, index, &internal_ss) == BP_RESULT_OK) { if (internal_ss.spread_spectrum_percentage) {
info->feature.engine_clk_ss_percentage =
internal_ss.spread_spectrum_percentage; if (internal_ss.type.CENTER_MODE) { /* if it is centermode, the exact SS Percentage * will be round up of half of the percentage
* reported in the SS table */
++info->feature.engine_clk_ss_percentage;
info->feature.engine_clk_ss_percentage /= 2;
}
}
}
for (i = 0; i < table_size; i++) { if (tbl[i].ucClockIndication != (uint8_t) id) continue;
if (table_index != index) {
table_index++; continue;
} /* VBIOS introduced new defines for Version 3, same values as * before, so now use these new ones for Version 3. * Shouldn't affect field VBIOS's V3 as define values are still * same. * #define SS_MODE_V3_CENTRE_SPREAD_MASK 0x01 * #define SS_MODE_V3_EXTERNAL_SS_MASK 0x02
staticenum bp_result get_ss_info_from_ss_info_table( struct bios_parser *bp,
uint32_t id, struct spread_spectrum_info *ss_info); staticenum bp_result get_ss_info_from_tbl( struct bios_parser *bp,
uint32_t id, struct spread_spectrum_info *ss_info); /** * bios_parser_get_spread_spectrum_info * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info ver 3.1, * there is only one entry for each signal /ss id. However, there is * no planning of supporting multiple spread Sprectum entry for EverGreen * @dcb: pointer to the DC BIOS * @signal: ASSignalType to be converted to info index * @index: number of entries that match the converted info index * @ss_info: sprectrum information structure, * return: Bios parser result code
*/ staticenum bp_result bios_parser_get_spread_spectrum_info( struct dc_bios *dcb, enum as_signal_type signal,
uint32_t index, struct spread_spectrum_info *ss_info)
{ struct bios_parser *bp = BP_FROM_DCB(dcb); enum bp_result result = BP_RESULT_UNSUPPORTED;
uint32_t clk_id_ss = 0;
ATOM_COMMON_TABLE_HEADER *header; struct atom_data_revision tbl_revision;
if (!ss_info) /* check for bad input */ return BP_RESULT_BADINPUT; /* signal translation */
clk_id_ss = signal_to_ss_id(signal);
if (!DATA_TABLES(ASIC_InternalSS_Info)) if (!index) return get_ss_info_from_ss_info_table(bp, clk_id_ss,
ss_info);
switch (tbl_revision.major) { case 2: switch (tbl_revision.minor) { case 1: /* there can not be more then one entry for Internal
* SS Info table version 2.1 */ if (!index) return get_ss_info_from_tbl(bp, clk_id_ss,
ss_info); break; default: break;
} break;
case 3: switch (tbl_revision.minor) { case 1: return get_ss_info_v3_1(bp, clk_id_ss, index, ss_info); default: break;
} break; default: break;
} /* there can not be more then one entry for SS Info table */ return result;
}
/** * get_ss_info_from_tbl * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or * SS_Info table from the VBIOS * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or * SS_Info. * * @bp: pointer to the BIOS parser * @id: spread sprectrum info index * @ss_info: sprectrum information structure, * return: BIOS parser result code
*/ staticenum bp_result get_ss_info_from_tbl( struct bios_parser *bp,
uint32_t id, struct spread_spectrum_info *ss_info)
{ if (!ss_info) /* check for bad input, if ss_info is not NULL */ return BP_RESULT_BADINPUT; /* for SS_Info table only support DP and LVDS */ if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS) return get_ss_info_from_ss_info_table(bp, id, ss_info); else return get_ss_info_from_internal_ss_info_tbl_V2_1(bp, id,
ss_info);
}
/** * get_ss_info_from_internal_ss_info_tbl_V2_1 * Get spread sprectrum information from the ASIC_InternalSS_Info table Ver 2.1 * from the VBIOS * There will not be multiple entry for Ver 2.1 * * @bp: pointer to the Bios parser * @id: spread sprectrum info index * @info: sprectrum information structure, * return: Bios parser result code
*/ staticenum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1( struct bios_parser *bp,
uint32_t id, struct spread_spectrum_info *info)
{ enum bp_result result = BP_RESULT_UNSUPPORTED;
ATOM_ASIC_INTERNAL_SS_INFO_V2 *header;
ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl;
uint32_t tbl_size, i;
if (!DATA_TABLES(ASIC_InternalSS_Info)) return result;
/** * get_ss_info_from_ss_info_table * Get spread sprectrum information from the SS_Info table from the VBIOS * if the pointer to info is NULL, indicate the caller what to know the number * of entries that matches the id * for, the SS_Info table, there should not be more than 1 entry match. * * @bp: pointer to the Bios parser * @id: spread sprectrum id * @ss_info: sprectrum information structure, * return: Bios parser result code
*/ staticenum bp_result get_ss_info_from_ss_info_table( struct bios_parser *bp,
uint32_t id, struct spread_spectrum_info *ss_info)
{ enum bp_result result = BP_RESULT_UNSUPPORTED;
ATOM_SPREAD_SPECTRUM_INFO *tbl;
ATOM_COMMON_TABLE_HEADER *header;
uint32_t table_size;
uint32_t i;
uint32_t id_local = SS_ID_UNKNOWN; struct atom_data_revision revision;
/* exist of the SS_Info table */ /* check for bad input, pSSinfo can not be NULL */ if (!DATA_TABLES(SS_Info) || !ss_info) return result;
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); if (!tbl) return result;
if (1 != revision.major || 2 > revision.minor) return result;
/* have to convert from Internal_SS format to SS_Info format */ switch (id) { case ASIC_INTERNAL_SS_ON_DP:
id_local = SS_ID_DP1; break; case ASIC_INTERNAL_SS_ON_LVDS:
{ struct embedded_panel_info panel_info;
/* We need to convert from 10KHz units into KHz units*/
info->lcd_timing.pixel_clk =
le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10; /* usHActive does not include borders, according to VBIOS team*/
info->lcd_timing.horizontal_addressable =
le16_to_cpu(lvds->sLCDTiming.usHActive); /* usHBlanking_Time includes borders, so we should really be subtracting
* borders duing this translation, but LVDS generally*/ /* doesn't have borders, so we should be okay leaving this as is for
* now. May need to revisit if we ever have LVDS with borders*/
info->lcd_timing.horizontal_blanking_time =
le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time); /* usVActive does not include borders, according to VBIOS team*/
info->lcd_timing.vertical_addressable =
le16_to_cpu(lvds->sLCDTiming.usVActive); /* usVBlanking_Time includes borders, so we should really be subtracting
* borders duing this translation, but LVDS generally*/ /* doesn't have borders, so we should be okay leaving this as is for
* now. May need to revisit if we ever have LVDS with borders*/
info->lcd_timing.vertical_blanking_time =
le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time);
info->lcd_timing.horizontal_sync_offset =
le16_to_cpu(lvds->sLCDTiming.usHSyncOffset);
info->lcd_timing.horizontal_sync_width =
le16_to_cpu(lvds->sLCDTiming.usHSyncWidth);
info->lcd_timing.vertical_sync_offset =
le16_to_cpu(lvds->sLCDTiming.usVSyncOffset);
info->lcd_timing.vertical_sync_width =
le16_to_cpu(lvds->sLCDTiming.usVSyncWidth);
info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder;
info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder;
info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff;
info->lcd_timing.misc_info.H_SYNC_POLARITY =
~(uint32_t)
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity;
info->lcd_timing.misc_info.V_SYNC_POLARITY =
~(uint32_t)
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity;
info->lcd_timing.misc_info.VERTICAL_CUT_OFF =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff;
info->lcd_timing.misc_info.H_REPLICATION_BY2 =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2;
info->lcd_timing.misc_info.V_REPLICATION_BY2 =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2;
info->lcd_timing.misc_info.COMPOSITE_SYNC =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync;
info->lcd_timing.misc_info.INTERLACE =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace;
info->lcd_timing.misc_info.DOUBLE_CLOCK =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock;
info->ss_id = lvds->ucSS_Id;
/* We need to convert from 10KHz units into KHz units */
info->lcd_timing.pixel_clk =
le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10; /* usHActive does not include borders, according to VBIOS team */
info->lcd_timing.horizontal_addressable =
le16_to_cpu(lvds->sLCDTiming.usHActive); /* usHBlanking_Time includes borders, so we should really be subtracting
* borders duing this translation, but LVDS generally*/ /* doesn't have borders, so we should be okay leaving this as is for
* now. May need to revisit if we ever have LVDS with borders*/
info->lcd_timing.horizontal_blanking_time =
le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time); /* usVActive does not include borders, according to VBIOS team*/
info->lcd_timing.vertical_addressable =
le16_to_cpu(lvds->sLCDTiming.usVActive); /* usVBlanking_Time includes borders, so we should really be subtracting
* borders duing this translation, but LVDS generally*/ /* doesn't have borders, so we should be okay leaving this as is for
* now. May need to revisit if we ever have LVDS with borders*/
info->lcd_timing.vertical_blanking_time =
le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time);
info->lcd_timing.horizontal_sync_offset =
le16_to_cpu(lvds->sLCDTiming.usHSyncOffset);
info->lcd_timing.horizontal_sync_width =
le16_to_cpu(lvds->sLCDTiming.usHSyncWidth);
info->lcd_timing.vertical_sync_offset =
le16_to_cpu(lvds->sLCDTiming.usVSyncOffset);
info->lcd_timing.vertical_sync_width =
le16_to_cpu(lvds->sLCDTiming.usVSyncWidth);
info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder;
info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder;
info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff;
info->lcd_timing.misc_info.H_SYNC_POLARITY =
~(uint32_t)
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity;
info->lcd_timing.misc_info.V_SYNC_POLARITY =
~(uint32_t)
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity;
info->lcd_timing.misc_info.VERTICAL_CUT_OFF =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff;
info->lcd_timing.misc_info.H_REPLICATION_BY2 =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2;
info->lcd_timing.misc_info.V_REPLICATION_BY2 =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2;
info->lcd_timing.misc_info.COMPOSITE_SYNC =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync;
info->lcd_timing.misc_info.INTERLACE =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace;
info->lcd_timing.misc_info.DOUBLE_CLOCK =
lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock;
info->ss_id = lvds->ucSS_Id;
/* Drr panel support can be reported by VBIOS*/ if (LCDPANEL_CAP_V13_DRR_SUPPORTED
& lvds->ucLCDPanel_SpecialHandlingCap)
info->drr_enabled = 1;
/* Get supported refresh rate*/ if (info->drr_enabled == 1) {
uint8_t min_rr =
lvds->sRefreshRateSupport.ucMinRefreshRateForDRR;
uint8_t rr = lvds->sRefreshRateSupport.ucSupportedRefreshRate;
/** * get_encoder_cap_record - Get encoder cap record for the object * * @bp: pointer to the BIOS parser * @object: ATOM object * return: atom encoder cap record * note: search all records to find the ATOM_ENCODER_CAP_RECORD_V2 record
*/ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( struct bios_parser *bp,
ATOM_OBJECT *object)
{
ATOM_COMMON_RECORD_HEADER *header;
uint32_t offset;
/** * bios_parser_get_ss_entry_number * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table from * the VBIOS that match the SSid (to be converted from signal) * * @dcb: pointer to the DC BIOS * @signal: ASSignalType to be converted to SSid * return: number of SS Entry that match the signal
*/ static uint32_t bios_parser_get_ss_entry_number( struct dc_bios *dcb, enum as_signal_type signal)
{ struct bios_parser *bp = BP_FROM_DCB(dcb);
uint32_t ss_id = 0;
ATOM_COMMON_TABLE_HEADER *header; struct atom_data_revision revision;
ss_id = signal_to_ss_id(signal);
if (!DATA_TABLES(ASIC_InternalSS_Info)) return get_ss_entry_number_from_ss_info_tbl(bp, ss_id);
switch (revision.major) { case 2: switch (revision.minor) { case 1: return get_ss_entry_number(bp, ss_id); default: break;
} break; case 3: switch (revision.minor) { case 1: return
get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
bp, ss_id); default: break;
} break; default: break;
}
return 0;
}
/** * get_ss_entry_number_from_ss_info_tbl * Get Number of spread spectrum entry from the SS_Info table from the VBIOS. * * @bp: pointer to the BIOS parser * @id: spread spectrum id * return: number of SS Entry that match the id * note: There can only be one entry for each id for SS_Info Table
*/ static uint32_t get_ss_entry_number_from_ss_info_tbl( struct bios_parser *bp,
uint32_t id)
{
ATOM_SPREAD_SPECTRUM_INFO *tbl;
ATOM_COMMON_TABLE_HEADER *header;
uint32_t table_size;
uint32_t i;
uint32_t number = 0;
uint32_t id_local = SS_ID_UNKNOWN; struct atom_data_revision revision;
/* SS_Info table exist */ if (!DATA_TABLES(SS_Info)) return number;
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO,
DATA_TABLES(SS_Info)); if (!tbl) return number;
if (1 != revision.major || 2 > revision.minor) return number;
/* have to convert from Internal_SS format to SS_Info format */ switch (id) { case ASIC_INTERNAL_SS_ON_DP:
id_local = SS_ID_DP1; break; case ASIC_INTERNAL_SS_ON_LVDS: { struct embedded_panel_info panel_info;
for (i = 0; i < table_size; i++) if (id_local == (uint32_t)tbl->asSS_Info[i].ucSS_Id) {
number = 1; break;
}
return number;
}
/** * get_ss_entry_number * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or * SS_Info table from the VBIOS * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or * SS_Info. * * @bp: pointer to the BIOS parser * @id: spread sprectrum info index * return: Bios parser result code
*/ static uint32_t get_ss_entry_number(struct bios_parser *bp, uint32_t id)
{ if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS) return get_ss_entry_number_from_ss_info_tbl(bp, id);
/** * get_ss_entry_number_from_internal_ss_info_tbl_v2_1 * Get NUmber of spread sprectrum entry from the ASIC_InternalSS_Info table * Ver 2.1 from the VBIOS * There will not be multiple entry for Ver 2.1 * * @bp: pointer to the BIOS parser * @id: spread sprectrum info index * return: number of SS Entry that match the id
*/ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1( struct bios_parser *bp,
uint32_t id)
{
ATOM_ASIC_INTERNAL_SS_INFO_V2 *header_include;
ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl;
uint32_t size;
uint32_t i;
tbl = (ATOM_ASIC_SS_ASSIGNMENT_V2 *)
&header_include->asSpreadSpectrum[0]; for (i = 0; i < size; i++) if (tbl[i].ucClockIndication == (uint8_t)id) return 1;
return 0;
}
/** * get_ss_entry_number_from_internal_ss_info_tbl_V3_1 * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table of * the VBIOS that matches id * * @bp: pointer to the BIOS parser * @id: spread sprectrum id * return: number of SS Entry that match the id
*/ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1( struct bios_parser *bp,
uint32_t id)
{
uint32_t number = 0;
ATOM_ASIC_INTERNAL_SS_INFO_V3 *header_include;
ATOM_ASIC_SS_ASSIGNMENT_V3 *tbl;
uint32_t size;
uint32_t i;
if (!DATA_TABLES(ASIC_InternalSS_Info)) return number;
for (i = 0; i < size; i++) if (tbl[i].ucClockIndication == (uint8_t)id)
number++;
return number;
}
/** * bios_parser_get_gpio_pin_info * Get GpioPin information of input gpio id * * @dcb: pointer to the DC BIOS * @gpio_id: GPIO ID * @info: GpioPin information structure * return: Bios parser result code * note: * to get the GPIO PIN INFO, we need: * 1. get the GPIO_ID from other object table, see GetHPDInfo() * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, to get the registerA * offset/mask
*/ staticenum bp_result bios_parser_get_gpio_pin_info( struct dc_bios *dcb,
uint32_t gpio_id, struct gpio_pin_info *info)
{ struct bios_parser *bp = BP_FROM_DCB(dcb);
ATOM_GPIO_PIN_LUT *header;
uint32_t count = 0;
uint32_t i = 0;
if (!DATA_TABLES(GPIO_Pin_LUT)) return BP_RESULT_BADBIOSTABLE;
for (i = 0; i < tbl->ucNumberOfObjects; i++) if (dal_graphics_object_id_is_equal(id,
object_id_from_bios_object_id(
le16_to_cpu(tbl->asObjects[i].usObjectID)))) return &tbl->asObjects[i];
/** * bios_parser_set_scratch_critical_state - update critical state * bit in VBIOS scratch register * @dcb: pointer to the DC BIOS * @state: set or reset state
*/ staticvoid bios_parser_set_scratch_critical_state( struct dc_bios *dcb, bool state)
{
bios_set_scratch_critical_state(dcb, state);
}
/* * get_integrated_info_v8 * * @brief * Get V8 integrated BIOS information * * @param * bios_parser *bp - [in]BIOS parser handler to get master data table * integrated_info *info - [out] store and output integrated info * * return: * enum bp_result - BP_RESULT_OK if information is available, * BP_RESULT_BADBIOSTABLE otherwise.
*/ staticenum bp_result get_integrated_info_v8( struct bios_parser *bp, struct integrated_info *info)
{
ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *info_v8;
uint32_t i;
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.