Hi I've just tested out the new amd-staging-drm-next branch and noticed the following warning caused by this patch drivers/gpu/drm/amd/amdgpu/../display/dc/bios/bios_parser2.c: In function â??get_embedded_panel_info_v2_1â??: drivers/gpu/drm/amd/amdgpu/../display/dc/bios/bios_parser2.c:1335:3: warning: overflow in implicit constant conversion [-Woverflow] lvds->lcd_timing.miscinfo & ATOM_INTERLACE; ^~~~ Cheers Mike On Mon, 20 Mar 2017 at 20:35 Alex Deucher <alexdeucher at gmail.com> wrote: > From: Harry Wentland <harry.wentland at amd.com> > > Signed-off-by: Harry Wentland <harry.wentland at amd.com> > Signed-off-by: Alex Deucher <alexander.deucher at amd.com> > --- > drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 2085 > ++++++++++++++++++++ > drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h | 33 + > .../display/dc/bios/bios_parser_types_internal2.h | 74 + > .../gpu/drm/amd/display/dc/bios/command_table2.c | 813 ++++++++ > .../gpu/drm/amd/display/dc/bios/command_table2.h | 105 + > .../amd/display/dc/bios/command_table_helper2.c | 260 +++ > .../amd/display/dc/bios/command_table_helper2.h | 82 + > .../dc/bios/dce112/command_table_helper2_dce112.c | 418 ++++ > .../dc/bios/dce112/command_table_helper2_dce112.h | 34 + > 9 files changed, 3904 insertions(+) > create mode 100644 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c > create mode 100644 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h > create mode 100644 > drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h > create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table2.c > create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table2.h > create mode 100644 > drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c > create mode 100644 > drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h > create mode 100644 > drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c > create mode 100644 > drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h > > diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c > b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c > new file mode 100644 > index 0000000..f6e77da > --- /dev/null > +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c > @@ -0,0 +1,2085 @@ > +/* > + * 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" > + > +#define _BIOS_PARSER_2_ > + > +#include "ObjectID.h" > +#include "atomfirmware.h" > +#include "atomfirmwareid.h" > + > +#include "dc_bios_types.h" > +#include "include/grph_object_ctrl_defs.h" > +#include "include/bios_parser_interface.h" > +#include "include/i2caux_interface.h" > +#include "include/logger_interface.h" > + > +#include "command_table2.h" > + > +#include "bios_parser_helper.h" > +#include "command_table_helper2.h" > +#include "bios_parser2.h" > +#include "bios_parser_types_internal2.h" > +#include "bios_parser_interface.h" > + > +#define LAST_RECORD_TYPE 0xff > + > + > +struct i2c_id_config_access { > + uint8_t bfI2C_LineMux:4; > + uint8_t bfHW_EngineID:3; > + uint8_t bfHW_Capable:1; > + uint8_t ucAccess; > +}; > + > +static enum object_type object_type_from_bios_object_id( > + uint32_t bios_object_id); > + > +static enum object_enum_id enum_id_from_bios_object_id(uint32_t > bios_object_id); > + > +static struct graphics_object_id object_id_from_bios_object_id( > + uint32_t bios_object_id); > + > +static uint32_t id_from_bios_object_id(enum object_type type, > + uint32_t bios_object_id); > + > +static uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id); > + > +static enum encoder_id encoder_id_from_bios_object_id(uint32_t > bios_object_id); > + > +static enum connector_id connector_id_from_bios_object_id( > + uint32_t bios_object_id); > + > +static enum generic_id generic_id_from_bios_object_id(uint32_t > bios_object_id); > + > +static enum bp_result get_gpio_i2c_info(struct bios_parser *bp, > + struct atom_i2c_record *record, > + struct graphics_object_i2c_info *info); > + > +static enum bp_result bios_parser_get_firmware_info( > + struct dc_bios *dcb, > + struct firmware_info *info); > + > +static enum bp_result bios_parser_get_encoder_cap_info( > + struct dc_bios *dcb, > + struct graphics_object_id object_id, > + struct bp_encoder_cap_info *info); > + > +static enum bp_result get_firmware_info_v3_1( > + struct bios_parser *bp, > + struct firmware_info *info); > + > +static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp, > + struct atom_display_object_path_v2 *object); > + > +static struct atom_encoder_caps_record *get_encoder_cap_record( > + struct bios_parser *bp, > + struct atom_display_object_path_v2 *object); > + > +#define BIOS_IMAGE_SIZE_OFFSET 2 > +#define BIOS_IMAGE_SIZE_UNIT 512 > + > +#define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table) > + > + > +static void destruct(struct bios_parser *bp) > +{ > + if (bp->base.bios_local_image) > + dm_free(bp->base.bios_local_image); > + > + if (bp->base.integrated_info) > + dm_free(bp->base.integrated_info); > +} > + > +static void firmware_parser_destroy(struct dc_bios **dcb) > +{ > + struct bios_parser *bp = BP_FROM_DCB(*dcb); > + > + if (!bp) { > + BREAK_TO_DEBUGGER(); > + return; > + } > + > + destruct(bp); > + > + dm_free(bp); > + *dcb = NULL; > +} > + > +static void get_atom_data_table_revision( > + struct atom_common_table_header *atom_data_tbl, > + struct atom_data_revision *tbl_revision) > +{ > + if (!tbl_revision) > + return; > + > + /* initialize the revision to 0 which is invalid revision */ > + tbl_revision->major = 0; > + tbl_revision->minor = 0; > + > + if (!atom_data_tbl) > + return; > + > + tbl_revision->major = > + (uint32_t) atom_data_tbl->format_revision & 0x3f; > + tbl_revision->minor = > + (uint32_t) atom_data_tbl->content_revision & 0x3f; > +} > + > +static struct graphics_object_id object_id_from_bios_object_id( > + uint32_t bios_object_id) > +{ > + enum object_type type; > + enum object_enum_id enum_id; > + struct graphics_object_id go_id = { 0 }; > + > + type = object_type_from_bios_object_id(bios_object_id); > + > + if (type == OBJECT_TYPE_UNKNOWN) > + return go_id; > + > + enum_id = enum_id_from_bios_object_id(bios_object_id); > + > + if (enum_id == ENUM_ID_UNKNOWN) > + return go_id; > + > + go_id = dal_graphics_object_id_init( > + id_from_bios_object_id(type, bios_object_id), > + enum_id, > type); > + > + return go_id; > +} > + > +static enum object_type object_type_from_bios_object_id(uint32_t > bios_object_id) > +{ > + uint32_t bios_object_type = (bios_object_id & OBJECT_TYPE_MASK) > + >> OBJECT_TYPE_SHIFT; > + enum object_type object_type; > + > + switch (bios_object_type) { > + case GRAPH_OBJECT_TYPE_GPU: > + object_type = OBJECT_TYPE_GPU; > + break; > + case GRAPH_OBJECT_TYPE_ENCODER: > + object_type = OBJECT_TYPE_ENCODER; > + break; > + case GRAPH_OBJECT_TYPE_CONNECTOR: > + object_type = OBJECT_TYPE_CONNECTOR; > + break; > + case GRAPH_OBJECT_TYPE_ROUTER: > + object_type = OBJECT_TYPE_ROUTER; > + break; > + case GRAPH_OBJECT_TYPE_GENERIC: > + object_type = OBJECT_TYPE_GENERIC; > + break; > + default: > + object_type = OBJECT_TYPE_UNKNOWN; > + break; > + } > + > + return object_type; > +} > + > +static enum object_enum_id enum_id_from_bios_object_id(uint32_t > bios_object_id) > +{ > + uint32_t bios_enum_id = > + (bios_object_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT; > + enum object_enum_id id; > + > + switch (bios_enum_id) { > + case GRAPH_OBJECT_ENUM_ID1: > + id = ENUM_ID_1; > + break; > + case GRAPH_OBJECT_ENUM_ID2: > + id = ENUM_ID_2; > + break; > + case GRAPH_OBJECT_ENUM_ID3: > + id = ENUM_ID_3; > + break; > + case GRAPH_OBJECT_ENUM_ID4: > + id = ENUM_ID_4; > + break; > + case GRAPH_OBJECT_ENUM_ID5: > + id = ENUM_ID_5; > + break; > + case GRAPH_OBJECT_ENUM_ID6: > + id = ENUM_ID_6; > + break; > + case GRAPH_OBJECT_ENUM_ID7: > + id = ENUM_ID_7; > + break; > + default: > + id = ENUM_ID_UNKNOWN; > + break; > + } > + > + return id; > +} > + > +static uint32_t id_from_bios_object_id(enum object_type type, > + uint32_t bios_object_id) > +{ > + switch (type) { > + case OBJECT_TYPE_GPU: > + return gpu_id_from_bios_object_id(bios_object_id); > + case OBJECT_TYPE_ENCODER: > + return > (uint32_t)encoder_id_from_bios_object_id(bios_object_id); > + case OBJECT_TYPE_CONNECTOR: > + return (uint32_t)connector_id_from_bios_object_id( > + bios_object_id); > + case OBJECT_TYPE_GENERIC: > + return generic_id_from_bios_object_id(bios_object_id); > + default: > + return 0; > + } > +} > + > +uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id) > +{ > + return (bios_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; > +} > + > +static enum encoder_id encoder_id_from_bios_object_id(uint32_t > bios_object_id) > +{ > + uint32_t bios_encoder_id = > gpu_id_from_bios_object_id(bios_object_id); > + enum encoder_id id; > + > + switch (bios_encoder_id) { > + case ENCODER_OBJECT_ID_INTERNAL_LVDS: > + id = ENCODER_ID_INTERNAL_LVDS; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: > + id = ENCODER_ID_INTERNAL_TMDS1; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_TMDS2: > + id = ENCODER_ID_INTERNAL_TMDS2; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_DAC1: > + id = ENCODER_ID_INTERNAL_DAC1; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_DAC2: > + id = ENCODER_ID_INTERNAL_DAC2; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: > + id = ENCODER_ID_INTERNAL_LVTM1; > + break; > + case ENCODER_OBJECT_ID_HDMI_INTERNAL: > + id = ENCODER_ID_INTERNAL_HDMI; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: > + id = ENCODER_ID_INTERNAL_KLDSCP_TMDS1; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: > + id = ENCODER_ID_INTERNAL_KLDSCP_DAC1; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: > + id = ENCODER_ID_INTERNAL_KLDSCP_DAC2; > + break; > + case ENCODER_OBJECT_ID_MVPU_FPGA: > + id = ENCODER_ID_EXTERNAL_MVPU_FPGA; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_DDI: > + id = ENCODER_ID_INTERNAL_DDI; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: > + id = ENCODER_ID_INTERNAL_UNIPHY; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: > + id = ENCODER_ID_INTERNAL_KLDSCP_LVTMA; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: > + id = ENCODER_ID_INTERNAL_UNIPHY1; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: > + id = ENCODER_ID_INTERNAL_UNIPHY2; > + break; > + case ENCODER_OBJECT_ID_ALMOND: /* ENCODER_OBJECT_ID_NUTMEG */ > + id = ENCODER_ID_EXTERNAL_NUTMEG; > + break; > + case ENCODER_OBJECT_ID_TRAVIS: > + id = ENCODER_ID_EXTERNAL_TRAVIS; > + break; > + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: > + id = ENCODER_ID_INTERNAL_UNIPHY3; > + break; > + default: > + id = ENCODER_ID_UNKNOWN; > + ASSERT(0); > + break; > + } > + > + return id; > +} > + > +static enum connector_id connector_id_from_bios_object_id( > + uint32_t bios_object_id) > +{ > + uint32_t bios_connector_id = > gpu_id_from_bios_object_id(bios_object_id); > + > + enum connector_id id; > + > + switch (bios_connector_id) { > + case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I: > + id = CONNECTOR_ID_SINGLE_LINK_DVII; > + break; > + case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I: > + id = CONNECTOR_ID_DUAL_LINK_DVII; > + break; > + case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D: > + id = CONNECTOR_ID_SINGLE_LINK_DVID; > + break; > + case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D: > + id = CONNECTOR_ID_DUAL_LINK_DVID; > + break; > + case CONNECTOR_OBJECT_ID_VGA: > + id = CONNECTOR_ID_VGA; > + break; > + case CONNECTOR_OBJECT_ID_HDMI_TYPE_A: > + id = CONNECTOR_ID_HDMI_TYPE_A; > + break; > + case CONNECTOR_OBJECT_ID_LVDS: > + id = CONNECTOR_ID_LVDS; > + break; > + case CONNECTOR_OBJECT_ID_PCIE_CONNECTOR: > + id = CONNECTOR_ID_PCIE; > + break; > + case CONNECTOR_OBJECT_ID_HARDCODE_DVI: > + id = CONNECTOR_ID_HARDCODE_DVI; > + break; > + case CONNECTOR_OBJECT_ID_DISPLAYPORT: > + id = CONNECTOR_ID_DISPLAY_PORT; > + break; > + case CONNECTOR_OBJECT_ID_eDP: > + id = CONNECTOR_ID_EDP; > + break; > + case CONNECTOR_OBJECT_ID_MXM: > + id = CONNECTOR_ID_MXM; > + break; > + default: > + id = CONNECTOR_ID_UNKNOWN; > + break; > + } > + > + return id; > +} > + > +enum generic_id generic_id_from_bios_object_id(uint32_t bios_object_id) > +{ > + uint32_t bios_generic_id = > gpu_id_from_bios_object_id(bios_object_id); > + > + enum generic_id id; > + > + switch (bios_generic_id) { > + case GENERIC_OBJECT_ID_MXM_OPM: > + id = GENERIC_ID_MXM_OPM; > + break; > + case GENERIC_OBJECT_ID_GLSYNC: > + id = GENERIC_ID_GLSYNC; > + break; > + case GENERIC_OBJECT_ID_STEREO_PIN: > + id = GENERIC_ID_STEREO; > + break; > + default: > + id = GENERIC_ID_UNKNOWN; > + break; > + } > + > + return id; > +} > + > +static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + unsigned int count = 0; > + unsigned int i; > + > + for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) { > + if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid > != 0 > + && > + bp->object_info_tbl.v1_4->display_path[i].display_objid != > 0) > + count++; > + } > + return count; > +} > + > +static struct graphics_object_id bios_parser_get_encoder_id( > + struct dc_bios *dcb, > + uint32_t i) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct graphics_object_id object_id = dal_graphics_object_id_init( > + 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); > + > + if (bp->object_info_tbl.v1_4->number_of_path > i) > + object_id = object_id_from_bios_object_id( > + bp->object_info_tbl.v1_4->display_path[i].encoderobjid); > + > + return object_id; > +} > + > +static struct graphics_object_id bios_parser_get_connector_id( > + struct dc_bios *dcb, > + uint8_t i) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct graphics_object_id object_id = dal_graphics_object_id_init( > + 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN); > + struct object_info_table *tbl = &bp->object_info_tbl; > + struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4; > + > + if (v1_4->number_of_path > i) { > + /* If display_objid is generic object id, the encoderObj > + * /extencoderobjId should be 0 > + */ > + if (v1_4->display_path[i].encoderobjid != 0 && > + v1_4->display_path[i].display_objid != 0) > + object_id = object_id_from_bios_object_id( > + > v1_4->display_path[i].display_objid); > + } > + > + return object_id; > +} > + > + > +/* TODO: GetNumberOfSrc*/ > + > +static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb, > + struct graphics_object_id id) > +{ > + /* connector has 1 Dest, encoder has 0 Dest */ > + switch (id.type) { > + case OBJECT_TYPE_ENCODER: > + return 0; > + case OBJECT_TYPE_CONNECTOR: > + return 1; > + default: > + return 0; > + } > +} > + > +/* removed getSrcObjList, getDestObjList*/ > + > + > +static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb, > + struct graphics_object_id object_id, uint32_t index, > + struct graphics_object_id *src_object_id) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + unsigned int i; > + enum bp_result bp_result = BP_RESULT_BADINPUT; > + struct graphics_object_id obj_id = {0}; > + struct object_info_table *tbl = &bp->object_info_tbl; > + > + if (!src_object_id) > + return bp_result; > + > + switch (object_id.type) { > + /* Encoder's Source is GPU. BIOS does not provide GPU, since all > + * displaypaths point to same GPU (0x1100). Hardcode GPU object > type > + */ > + case OBJECT_TYPE_ENCODER: > + /* TODO: since num of src must be less than 2. > + * If found in for loop, should break. > + * DAL2 implementation may be changed too > + */ > + for (i = 0; i < tbl->v1_4->number_of_path; i++) { > + obj_id = object_id_from_bios_object_id( > + tbl->v1_4->display_path[i].encoderobjid); > + if (object_id.type == obj_id.type && > + object_id.id == obj_id.id && > + object_id.enum_id == > + obj_id.enum_id) { > + *src_object_id = > + object_id_from_bios_object_id(0x1100); > + /* break; */ > + } > + } > + bp_result = BP_RESULT_OK; > + break; > + case OBJECT_TYPE_CONNECTOR: > + for (i = 0; i < tbl->v1_4->number_of_path; i++) { > + obj_id = object_id_from_bios_object_id( > + tbl->v1_4->display_path[i].display_objid); > + > + if (object_id.type == obj_id.type && > + object_id.id == obj_id.id && > + object_id.enum_id == > obj_id.enum_id) { > + *src_object_id = > + object_id_from_bios_object_id( > + tbl->v1_4->display_path[i].encoderobjid); > + /* break; */ > + } > + } > + bp_result = BP_RESULT_OK; > + break; > + default: > + break; > + } > + > + return bp_result; > +} > + > +static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb, > + struct graphics_object_id object_id, uint32_t index, > + struct graphics_object_id *dest_object_id) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + unsigned int i; > + enum bp_result bp_result = BP_RESULT_BADINPUT; > + struct graphics_object_id obj_id = {0}; > + struct object_info_table *tbl = &bp->object_info_tbl; > + > + if (!dest_object_id) > + return BP_RESULT_BADINPUT; > + > + switch (object_id.type) { > + case OBJECT_TYPE_ENCODER: > + /* TODO: since num of src must be less than 2. > + * If found in for loop, should break. > + * DAL2 implementation may be changed too > + */ > + for (i = 0; i < tbl->v1_4->number_of_path; i++) { > + obj_id = object_id_from_bios_object_id( > + tbl->v1_4->display_path[i].encoderobjid); > + if (object_id.type == obj_id.type && > + object_id.id == obj_id.id && > + object_id.enum_id == > + obj_id.enum_id) { > + *dest_object_id = > + object_id_from_bios_object_id( > + tbl->v1_4->display_path[i].display_objid); > + /* break; */ > + } > + } > + bp_result = BP_RESULT_OK; > + break; > + default: > + break; > + } > + > + return bp_result; > +} > + > + > +/* from graphics_object_id, find display path which includes the > object_id */ > +static struct atom_display_object_path_v2 *get_bios_object( > + struct bios_parser *bp, > + struct graphics_object_id id) > +{ > + unsigned int i; > + struct graphics_object_id obj_id = {0}; > + > + switch (id.type) { > + case OBJECT_TYPE_ENCODER: > + for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; > i++) { > + obj_id = object_id_from_bios_object_id( > + > bp->object_info_tbl.v1_4->display_path[i].encoderobjid); > + if (id.type == obj_id.type && > + id.id == obj_id.id && > + id.enum_id == > obj_id.enum_id) > + return > + &bp->object_info_tbl.v1_4->display_path[i]; > + } > + case OBJECT_TYPE_CONNECTOR: > + case OBJECT_TYPE_GENERIC: > + /* Both Generic and Connector Object ID > + * will be stored on display_objid > + */ > + for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; > i++) { > + obj_id = object_id_from_bios_object_id( > + > bp->object_info_tbl.v1_4->display_path[i].display_objid > + ); > + if (id.type == obj_id.type && > + id.id == obj_id.id && > + id.enum_id == > obj_id.enum_id) > + return > + &bp->object_info_tbl.v1_4->display_path[i]; > + } > + default: > + return NULL; > + } > +} > + > +static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, > + struct graphics_object_id id, > + struct graphics_object_i2c_info *info) > +{ > + uint32_t offset; > + struct atom_display_object_path_v2 *object; > + struct atom_common_record_header *header; > + struct atom_i2c_record *record; > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + object = get_bios_object(bp, id); > + > + if (!object) > + return BP_RESULT_BADINPUT; > + > + offset = object->disp_recordoffset + bp->object_info_tbl_offset; > + > + for (;;) { > + header = GET_IMAGE(struct atom_common_record_header, > offset); > + > + if (!header) > + return BP_RESULT_BADBIOSTABLE; > + > + if (header->record_type == LAST_RECORD_TYPE || > + !header->record_size) > + break; > + > + if (header->record_type == ATOM_I2C_RECORD_TYPE > + && sizeof(struct atom_i2c_record) <= > + > header->record_size) { > + /* get the I2C info */ > + record = (struct atom_i2c_record *) header; > + > + if (get_gpio_i2c_info(bp, record, info) == > + > BP_RESULT_OK) > + return BP_RESULT_OK; > + } > + > + offset += header->record_size; > + } > + > + return BP_RESULT_NORECORD; > +} > + > +static enum bp_result get_gpio_i2c_info( > + struct bios_parser *bp, > + struct atom_i2c_record *record, > + struct graphics_object_i2c_info *info) > +{ > + struct atom_gpio_pin_lut_v2_1 *header; > + uint32_t count = 0; > + unsigned int table_index = 0; > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + /* get the GPIO_I2C info */ > + if (!DATA_TABLES(gpio_pin_lut)) > + return BP_RESULT_BADBIOSTABLE; > + > + header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, > + DATA_TABLES(gpio_pin_lut)); > + if (!header) > + return BP_RESULT_BADBIOSTABLE; > + > + if (sizeof(struct atom_common_table_header) + > + sizeof(struct atom_gpio_pin_assignment) > > + le16_to_cpu(header->table_header.structuresize)) > + return BP_RESULT_BADBIOSTABLE; > + > + /* TODO: is version change? */ > + if (header->table_header.content_revision != 1) > + return BP_RESULT_UNSUPPORTED; > + > + /* get data count */ > + count = (le16_to_cpu(header->table_header.structuresize) > + - sizeof(struct atom_common_table_header)) > + / sizeof(struct atom_gpio_pin_assignment); > + > + table_index = record->i2c_id & I2C_HW_LANE_MUX; > + > + if (count < table_index) { > + bool find_valid = false; > + > + for (table_index = 0; table_index < count; table_index++) { > + if (((record->i2c_id & I2C_HW_CAP) == ( > + header->gpio_pin[table_index].gpio_id & > + I2C_HW_CAP)) && > + ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) == > + (header->gpio_pin[table_index].gpio_id & > + I2C_HW_ENGINE_ID_MASK)) && > + ((record->i2c_id & I2C_HW_LANE_MUX) == > + (header->gpio_pin[table_index].gpio_id & > + I2C_HW_LANE_MUX))) > { > + /* still valid */ > + find_valid = true; > + break; > + } > + } > + /* If we don't find the entry that we are looking for then > + * we will return BP_Result_BadBiosTable. > + */ > + if (find_valid == false) > + return BP_RESULT_BADBIOSTABLE; > + } > + > + /* get the GPIO_I2C_INFO */ > + info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false; > + info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX; > + info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> > 4; > + info->i2c_slave_address = record->i2c_slave_addr; > + > + /* TODO: check how to get register offset for en, Y, etc. */ > + info->gpio_info.clk_a_register_index = > + le16_to_cpu( > + header->gpio_pin[table_index].data_a_reg_index); > + info->gpio_info.clk_a_shift = > + header->gpio_pin[table_index].gpio_bitshift; > + > + return BP_RESULT_OK; > +} > + > +static enum bp_result get_voltage_ddc_info_v4( > + uint8_t *i2c_line, > + uint32_t index, > + struct atom_common_table_header *header, > + uint8_t *address) > +{ > + enum bp_result result = BP_RESULT_NORECORD; > + struct atom_voltage_objects_info_v4_1 *info = > + (struct atom_voltage_objects_info_v4_1 *) address; > + > + uint8_t *voltage_current_object = > + (uint8_t *) (&(info->voltage_object[0])); > + > + while ((address + le16_to_cpu(header->structuresize)) > > + voltage_current_object) { > + struct atom_i2c_voltage_object_v4 *object = > + (struct atom_i2c_voltage_object_v4 *) > + voltage_current_object; > + > + if (object->header.voltage_mode == > + ATOM_INIT_VOLTAGE_REGULATOR) { > + if (object->header.voltage_type == index) { > + *i2c_line = object->i2c_id ^ 0x90; > + result = BP_RESULT_OK; > + break; > + } > + } > + > + voltage_current_object += > + le16_to_cpu(object->header.object_size); > + } > + return result; > +} > + > +static enum bp_result bios_parser_get_thermal_ddc_info( > + struct dc_bios *dcb, > + uint32_t i2c_channel_id, > + struct graphics_object_i2c_info *info) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct i2c_id_config_access *config; > + struct atom_i2c_record record; > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + config = (struct i2c_id_config_access *) &i2c_channel_id; > + > + record.i2c_id = config->bfHW_Capable; > + record.i2c_id |= config->bfI2C_LineMux; > + record.i2c_id |= config->bfHW_EngineID; > + > + return get_gpio_i2c_info(bp, &record, info); > +} > + > +static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios > *dcb, > + uint32_t index, > + struct graphics_object_i2c_info *info) > +{ > + uint8_t i2c_line = 0; > + enum bp_result result = BP_RESULT_NORECORD; > + uint8_t *voltage_info_address; > + struct atom_common_table_header *header; > + struct atom_data_revision revision = {0}; > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!DATA_TABLES(voltageobject_info)) > + return result; > + > + voltage_info_address = get_image(&bp->base, > + DATA_TABLES(voltageobject_info), > + sizeof(struct atom_common_table_header)); > + > + header = (struct atom_common_table_header *) voltage_info_address; > + > + get_atom_data_table_revision(header, &revision); > + > + switch (revision.major) { > + case 4: > + if (revision.minor != 1) > + break; > + result = get_voltage_ddc_info_v4(&i2c_line, index, header, > + voltage_info_address); > + break; > + } > + > + if (result == BP_RESULT_OK) > + result = bios_parser_get_thermal_ddc_info(dcb, > + i2c_line, info); > + > + return result; > +} > + > +static enum bp_result bios_parser_get_hpd_info( > + struct dc_bios *dcb, > + struct graphics_object_id id, > + struct graphics_object_hpd_info *info) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct atom_display_object_path_v2 *object; > + struct atom_hpd_int_record *record = NULL; > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + object = get_bios_object(bp, id); > + > + if (!object) > + return BP_RESULT_BADINPUT; > + > + record = get_hpd_record(bp, object); > + > + if (record != NULL) { > + info->hpd_int_gpio_uid = record->pin_id; > + info->hpd_active = record->plugin_pin_state; > + return BP_RESULT_OK; > + } > + > + return BP_RESULT_NORECORD; > +} > + > +static struct atom_hpd_int_record *get_hpd_record( > + struct bios_parser *bp, > + struct atom_display_object_path_v2 *object) > +{ > + struct atom_common_record_header *header; > + uint32_t offset; > + > + if (!object) { > + BREAK_TO_DEBUGGER(); /* Invalid object */ > + return NULL; > + } > + > + offset = le16_to_cpu(object->disp_recordoffset) > + + bp->object_info_tbl_offset; > + > + for (;;) { > + header = GET_IMAGE(struct atom_common_record_header, > offset); > + > + if (!header) > + return NULL; > + > + if (header->record_type == LAST_RECORD_TYPE || > + !header->record_size) > + break; > + > + if (header->record_type == ATOM_HPD_INT_RECORD_TYPE > + && sizeof(struct atom_hpd_int_record) <= > + > header->record_size) > + return (struct atom_hpd_int_record *) header; > + > + offset += header->record_size; > + } > + > + return NULL; > +} > + > +/** > + * bios_parser_get_gpio_pin_info > + * Get GpioPin information of input gpio id > + * > + * @param gpio_id, GPIO ID > + * @param 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 > + */ > +static enum 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); > + struct atom_gpio_pin_lut_v2_1 *header; > + uint32_t count = 0; > + uint32_t i = 0; > + > + if (!DATA_TABLES(gpio_pin_lut)) > + return BP_RESULT_BADBIOSTABLE; > + > + header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1, > + DATA_TABLES(gpio_pin_lut)); > + if (!header) > + return BP_RESULT_BADBIOSTABLE; > + > + if (sizeof(struct atom_common_table_header) + > + sizeof(struct atom_gpio_pin_lut_v2_1) > + > le16_to_cpu(header->table_header.structuresize)) > + return BP_RESULT_BADBIOSTABLE; > + > + if (header->table_header.content_revision != 1) > + return BP_RESULT_UNSUPPORTED; > + > + /* Temporary hard code gpio pin info */ > +#if defined(FOR_SIMNOW_BOOT) > + { > + struct atom_gpio_pin_assignment gpio_pin[8] = { > + {0x5db5, 0, 0, 1, 0}, > + {0x5db5, 8, 8, 2, 0}, > + {0x5db5, 0x10, 0x10, 3, 0}, > + {0x5db5, 0x18, 0x14, 4, 0}, > + {0x5db5, 0x1A, 0x18, 5, 0}, > + {0x5db5, 0x1C, 0x1C, 6, 0}, > + }; > + > + count = 6; > + memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin)); > + } > +#else > + count = (le16_to_cpu(header->table_header.structuresize) > + - sizeof(struct atom_common_table_header)) > + / sizeof(struct atom_gpio_pin_assignment); > +#endif > + for (i = 0; i < count; ++i) { > + if (header->gpio_pin[i].gpio_id != gpio_id) > + continue; > + > + info->offset = > + (uint32_t) le16_to_cpu( > + > header->gpio_pin[i].data_a_reg_index); > + info->offset_y = info->offset + 2; > + info->offset_en = info->offset + 1; > + info->offset_mask = info->offset - 1; > + > + info->mask = (uint32_t) (1 << > + header->gpio_pin[i].gpio_bitshift); > + info->mask_y = info->mask + 2; > + info->mask_en = info->mask + 1; > + info->mask_mask = info->mask - 1; > + > + return BP_RESULT_OK; > + } > + > + return BP_RESULT_NORECORD; > +} > + > +static struct device_id device_type_from_device_id(uint16_t device_id) > +{ > + > + struct device_id result_device_id; > + > + switch (device_id) { > + case ATOM_DISPLAY_LCD1_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_LCD; > + result_device_id.enum_id = 1; > + break; > + > + case ATOM_DISPLAY_DFP1_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 1; > + break; > + > + case ATOM_DISPLAY_DFP2_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 2; > + break; > + > + case ATOM_DISPLAY_DFP3_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 3; > + break; > + > + case ATOM_DISPLAY_DFP4_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 4; > + break; > + > + case ATOM_DISPLAY_DFP5_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 5; > + break; > + > + case ATOM_DISPLAY_DFP6_SUPPORT: > + result_device_id.device_type = DEVICE_TYPE_DFP; > + result_device_id.enum_id = 6; > + break; > + > + default: > + BREAK_TO_DEBUGGER(); /* Invalid device Id */ > + result_device_id.device_type = DEVICE_TYPE_UNKNOWN; > + result_device_id.enum_id = 0; > + } > + return result_device_id; > +} > + > +static enum bp_result bios_parser_get_device_tag( > + struct dc_bios *dcb, > + struct graphics_object_id connector_object_id, > + uint32_t device_tag_index, > + struct connector_device_tag_info *info) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct atom_display_object_path_v2 *object; > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + /* getBiosObject will return MXM object */ > + object = get_bios_object(bp, connector_object_id); > + > + if (!object) { > + BREAK_TO_DEBUGGER(); /* Invalid object id */ > + return BP_RESULT_BADINPUT; > + } > + > + info->acpi_device = 0; /* BIOS no longer provides this */ > + info->dev_id = device_type_from_device_id(object->device_tag); > + > + return BP_RESULT_OK; > +} > + > +static enum bp_result get_ss_info_v4_1( > + struct bios_parser *bp, > + uint32_t id, > + uint32_t index, > + struct spread_spectrum_info *ss_info) > +{ > + enum bp_result result = BP_RESULT_OK; > + struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL; > + struct atom_smu_info_v3_1 *smu_tbl = NULL; > + > + if (!ss_info) > + return BP_RESULT_BADINPUT; > + > + if (!DATA_TABLES(dce_info)) > + return BP_RESULT_BADBIOSTABLE; > + > + if (!DATA_TABLES(smu_info)) > + return BP_RESULT_BADBIOSTABLE; > + > + disp_cntl_tbl = GET_IMAGE(struct > atom_display_controller_info_v4_1, > + > DATA_TABLES(dce_info)); > + if (!disp_cntl_tbl) > + return BP_RESULT_BADBIOSTABLE; > + > + smu_tbl = GET_IMAGE(struct atom_smu_info_v3_1, > DATA_TABLES(smu_info)); > + if (!smu_tbl) > + return BP_RESULT_BADBIOSTABLE; > + > + > + ss_info->type.STEP_AND_DELAY_INFO = false; > + ss_info->spread_percentage_divider = 1000; > + /* BIOS no longer uses target clock. Always enable for now */ > + ss_info->target_clock_range = 0xffffffff; > + > + switch (id) { > + case AS_SIGNAL_TYPE_DVI: > + ss_info->spread_spectrum_percentage = > + disp_cntl_tbl->dvi_ss_percentage; > + ss_info->spread_spectrum_range = > + disp_cntl_tbl->dvi_ss_rate_10hz * 10; > + if (disp_cntl_tbl->dvi_ss_mode & > ATOM_SS_CENTRE_SPREAD_MODE) > + ss_info->type.CENTER_MODE = true; > + break; > + case AS_SIGNAL_TYPE_HDMI: > + ss_info->spread_spectrum_percentage = > + disp_cntl_tbl->hdmi_ss_percentage; > + ss_info->spread_spectrum_range = > + disp_cntl_tbl->hdmi_ss_rate_10hz * 10; > + if (disp_cntl_tbl->hdmi_ss_mode & > ATOM_SS_CENTRE_SPREAD_MODE) > + ss_info->type.CENTER_MODE = true; > + break; > + /* TODO LVDS not support anymore? */ > + case AS_SIGNAL_TYPE_DISPLAY_PORT: > + ss_info->spread_spectrum_percentage = > + disp_cntl_tbl->dp_ss_percentage; > + ss_info->spread_spectrum_range = > + disp_cntl_tbl->dp_ss_rate_10hz * 10; > + if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) > + ss_info->type.CENTER_MODE = true; > + break; > + case AS_SIGNAL_TYPE_GPU_PLL: > + ss_info->spread_spectrum_percentage = > + smu_tbl->gpuclk_ss_percentage; > + ss_info->spread_spectrum_range = > + smu_tbl->gpuclk_ss_rate_10hz * 10; > + if (smu_tbl->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE) > + ss_info->type.CENTER_MODE = true; > + break; > + default: > + result = BP_RESULT_UNSUPPORTED; > + } > + > + return result; > +} > + > +/** > + * 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 > + * @param [in] this > + * @param [in] signal, ASSignalType to be converted to info index > + * @param [in] index, number of entries that match the converted info > index > + * @param [out] ss_info, sprectrum information structure, > + * @return Bios parser result code > + */ > +static enum 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; > + struct atom_common_table_header *header; > + struct atom_data_revision tbl_revision; > + > + if (!ss_info) /* check for bad input */ > + return BP_RESULT_BADINPUT; > + > + if (!DATA_TABLES(dce_info)) > + return BP_RESULT_UNSUPPORTED; > + > + header = GET_IMAGE(struct atom_common_table_header, > + DATA_TABLES(dce_info)); > + get_atom_data_table_revision(header, &tbl_revision); > + > + switch (tbl_revision.major) { > + case 4: > + switch (tbl_revision.minor) { > + case 1: > + return get_ss_info_v4_1(bp, signal, index, > ss_info); > + default: > + break; > + } > + break; > + default: > + break; > + } > + /* there can not be more then one entry for SS Info table */ > + return result; > +} > + > +static enum bp_result get_embedded_panel_info_v2_1( > + struct bios_parser *bp, > + struct embedded_panel_info *info) > +{ > + struct lcd_info_v2_1 *lvds; > + > + if (!info) > + return BP_RESULT_BADINPUT; > + > + if (!DATA_TABLES(lcd_info)) > + return BP_RESULT_UNSUPPORTED; > + > + lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info)); > + > + if (!lvds) > + return BP_RESULT_BADBIOSTABLE; > + > + /* TODO: previous vv1_3, should v2_1 */ > + if (!((lvds->table_header.format_revision == 2) > + && (lvds->table_header.content_revision >= 1))) > + return BP_RESULT_UNSUPPORTED; > + > + memset(info, 0, sizeof(struct embedded_panel_info)); > + > + /* We need to convert from 10KHz units into KHz units */ > + info->lcd_timing.pixel_clk = > + le16_to_cpu(lvds->lcd_timing.pixclk) * 10; > + /* usHActive does not include borders, according to VBIOS team */ > + info->lcd_timing.horizontal_addressable = > + le16_to_cpu(lvds->lcd_timing.h_active); > + /* usHBlanking_Time includes borders, so we should really be > + * subtractingborders 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->lcd_timing.h_blanking_time); > + /* usVActive does not include borders, according to VBIOS team*/ > + info->lcd_timing.vertical_addressable = > + le16_to_cpu(lvds->lcd_timing.v_active); > + /* 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->lcd_timing.v_blanking_time); > + info->lcd_timing.horizontal_sync_offset = > + le16_to_cpu(lvds->lcd_timing.h_sync_offset); > + info->lcd_timing.horizontal_sync_width = > + le16_to_cpu(lvds->lcd_timing.h_sync_width); > + info->lcd_timing.vertical_sync_offset = > + le16_to_cpu(lvds->lcd_timing.v_sync_offset); > + info->lcd_timing.vertical_sync_width = > + le16_to_cpu(lvds->lcd_timing.v_syncwidth); > + info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border; > + info->lcd_timing.vertical_border = lvds->lcd_timing.v_border; > + > + /* not provided by VBIOS */ > + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; > + > + info->lcd_timing.misc_info.H_SYNC_POLARITY = > + ~(uint32_t) > + (lvds->lcd_timing.miscinfo & ATOM_HSYNC_POLARITY); > + info->lcd_timing.misc_info.V_SYNC_POLARITY = > + ~(uint32_t) > + (lvds->lcd_timing.miscinfo & ATOM_VSYNC_POLARITY); > + > + /* not provided by VBIOS */ > + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; > + > + info->lcd_timing.misc_info.H_REPLICATION_BY2 = > + lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2; > + info->lcd_timing.misc_info.V_REPLICATION_BY2 = > + lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2; > + info->lcd_timing.misc_info.COMPOSITE_SYNC = > + lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC; > + info->lcd_timing.misc_info.INTERLACE = > + lvds->lcd_timing.miscinfo & ATOM_INTERLACE; > + > + /* not provided by VBIOS*/ > + info->lcd_timing.misc_info.DOUBLE_CLOCK = 0; > + /* not provided by VBIOS*/ > + info->ss_id = 0; > + > + info->realtek_eDPToLVDS = > + (lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0); > + > + return BP_RESULT_OK; > +} > + > +static enum bp_result bios_parser_get_embedded_panel_info( > + struct dc_bios *dcb, > + struct embedded_panel_info *info) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + struct atom_common_table_header *header; > + struct atom_data_revision tbl_revision; > + > + if (!DATA_TABLES(lcd_info)) > + return BP_RESULT_FAILURE; > + > + header = GET_IMAGE(struct atom_common_table_header, > + DATA_TABLES(lcd_info)); > + > + if (!header) > + return BP_RESULT_BADBIOSTABLE; > + > + get_atom_data_table_revision(header, &tbl_revision); > + > + > + switch (tbl_revision.major) { > + case 2: > + switch (tbl_revision.minor) { > + case 1: > + return get_embedded_panel_info_v2_1(bp, info); > + default: > + break; > + } > + default: > + break; > + } > + > + return BP_RESULT_FAILURE; > +} > + > +static uint32_t get_support_mask_for_device_id(struct device_id device_id) > +{ > + enum dal_device_type device_type = device_id.device_type; > + uint32_t enum_id = device_id.enum_id; > + > + switch (device_type) { > + case DEVICE_TYPE_LCD: > + switch (enum_id) { > + case 1: > + return ATOM_DISPLAY_LCD1_SUPPORT; > + default: > + break; > + } > + break; > + case DEVICE_TYPE_DFP: > + switch (enum_id) { > + case 1: > + return ATOM_DISPLAY_DFP1_SUPPORT; > + case 2: > + return ATOM_DISPLAY_DFP2_SUPPORT; > + case 3: > + return ATOM_DISPLAY_DFP3_SUPPORT; > + case 4: > + return ATOM_DISPLAY_DFP4_SUPPORT; > + case 5: > + return ATOM_DISPLAY_DFP5_SUPPORT; > + case 6: > + return ATOM_DISPLAY_DFP6_SUPPORT; > + default: > + break; > + } > + break; > + default: > + break; > + }; > + > + /* Unidentified device ID, return empty support mask. */ > + return 0; > +} > + > +static bool bios_parser_is_device_id_supported( > + struct dc_bios *dcb, > + struct device_id id) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + uint32_t mask = get_support_mask_for_device_id(id); > + > + return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) & > + mask) != 0; > +} > + > +static void bios_parser_post_init( > + struct dc_bios *dcb) > +{ > + /* TODO for OPM module. Need implement later */ > +} > + > +static uint32_t bios_parser_get_ss_entry_number( > + struct dc_bios *dcb, > + enum as_signal_type signal) > +{ > + /* TODO: DAL2 atomfirmware implementation does not need this. > + * why DAL3 need this? > + */ > + return 1; > +} > + > +static enum bp_result bios_parser_transmitter_control( > + struct dc_bios *dcb, > + struct bp_transmitter_control *cntl) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.transmitter_control) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.transmitter_control(bp, cntl); > +} > + > +static enum bp_result bios_parser_encoder_control( > + struct dc_bios *dcb, > + struct bp_encoder_control *cntl) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.dig_encoder_control) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.dig_encoder_control(bp, cntl); > +} > + > +static enum bp_result bios_parser_set_pixel_clock( > + struct dc_bios *dcb, > + struct bp_pixel_clock_parameters *bp_params) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.set_pixel_clock) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.set_pixel_clock(bp, bp_params); > +} > + > +static enum bp_result bios_parser_set_dce_clock( > + struct dc_bios *dcb, > + struct bp_set_dce_clock_parameters *bp_params) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.set_dce_clock) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.set_dce_clock(bp, bp_params); > +} > + > +static unsigned int bios_parser_get_smu_clock_info( > + struct dc_bios *dcb) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.get_smu_clock_info) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.get_smu_clock_info(bp); > +} > + > +static enum bp_result bios_parser_program_crtc_timing( > + struct dc_bios *dcb, > + struct bp_hw_crtc_timing_parameters *bp_params) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.set_crtc_timing) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.set_crtc_timing(bp, bp_params); > +} > + > +static enum bp_result bios_parser_enable_crtc( > + struct dc_bios *dcb, > + enum controller_id id, > + bool enable) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.enable_crtc) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.enable_crtc(bp, id, enable); > +} > + > +static enum bp_result bios_parser_crtc_source_select( > + struct dc_bios *dcb, > + struct bp_crtc_source_select *bp_params) > +{ > + struct bios_parser *bp = BP_FROM_DCB(dcb); > + > + if (!bp->cmd_tbl.select_crtc_source) > + return BP_RESULT_FAILURE; > + > + return bp->cmd_tbl.select_crtc_source(bp, bp_params); > +} > + > +static enum bp_result bios_parser_enable_di -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20170803/c008b2a9/attachment-0001.html>