<div dir="ltr">Hi<div><br></div><div>I've just tested out the new amd-staging-drm-next branch and noticed the following warning caused by this patch</div><div><br></div><div><div>drivers/gpu/drm/amd/amdgpu/../display/dc/bios/bios_parser2.c: In function ‘get_embedded_panel_info_v2_1’:</div><div>drivers/gpu/drm/amd/amdgpu/../display/dc/bios/bios_parser2.c:1335:3: warning: overflow in implicit constant conversion [-Woverflow]</div><div>   lvds->lcd_timing.miscinfo & ATOM_INTERLACE;</div><div>   ^~~~</div></div><div><br></div><div>Cheers</div><div><br></div><div>Mike</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, 20 Mar 2017 at 20:35 Alex Deucher <<a href="mailto:alexdeucher@gmail.com">alexdeucher@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Harry Wentland <<a href="mailto:harry.wentland@amd.com" target="_blank">harry.wentland@amd.com</a>><br>
<br>
Signed-off-by: Harry Wentland <<a href="mailto:harry.wentland@amd.com" target="_blank">harry.wentland@amd.com</a>><br>
Signed-off-by: Alex Deucher <<a href="mailto:alexander.deucher@amd.com" target="_blank">alexander.deucher@amd.com</a>><br>
---<br>
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 2085 ++++++++++++++++++++<br>
 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h |   33 +<br>
 .../display/dc/bios/bios_parser_types_internal2.h  |   74 +<br>
 .../gpu/drm/amd/display/dc/bios/command_table2.c   |  813 ++++++++<br>
 .../gpu/drm/amd/display/dc/bios/command_table2.h   |  105 +<br>
 .../amd/display/dc/bios/command_table_helper2.c    |  260 +++<br>
 .../amd/display/dc/bios/command_table_helper2.h    |   82 +<br>
 .../dc/bios/dce112/command_table_helper2_dce112.c  |  418 ++++<br>
 .../dc/bios/dce112/command_table_helper2_dce112.h  |   34 +<br>
 9 files changed, 3904 insertions(+)<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table2.c<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table2.h<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c<br>
 create mode 100644 drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h<br>
<br>
diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c<br>
new file mode 100644<br>
index 0000000..f6e77da<br>
--- /dev/null<br>
+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c<br>
@@ -0,0 +1,2085 @@<br>
+/*<br>
+ * Copyright 2012-15 Advanced Micro Devices, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be included in<br>
+ * all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
+ * OTHER DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ * Authors: AMD<br>
+ *<br>
+ */<br>
+<br>
+#include "dm_services.h"<br>
+<br>
+#define _BIOS_PARSER_2_<br>
+<br>
+#include "ObjectID.h"<br>
+#include "atomfirmware.h"<br>
+#include "atomfirmwareid.h"<br>
+<br>
+#include "dc_bios_types.h"<br>
+#include "include/grph_object_ctrl_defs.h"<br>
+#include "include/bios_parser_interface.h"<br>
+#include "include/i2caux_interface.h"<br>
+#include "include/logger_interface.h"<br>
+<br>
+#include "command_table2.h"<br>
+<br>
+#include "bios_parser_helper.h"<br>
+#include "command_table_helper2.h"<br>
+#include "bios_parser2.h"<br>
+#include "bios_parser_types_internal2.h"<br>
+#include "bios_parser_interface.h"<br>
+<br>
+#define LAST_RECORD_TYPE 0xff<br>
+<br>
+<br>
+struct i2c_id_config_access {<br>
+       uint8_t bfI2C_LineMux:4;<br>
+       uint8_t bfHW_EngineID:3;<br>
+       uint8_t bfHW_Capable:1;<br>
+       uint8_t ucAccess;<br>
+};<br>
+<br>
+static enum object_type object_type_from_bios_object_id(<br>
+       uint32_t bios_object_id);<br>
+<br>
+static enum object_enum_id enum_id_from_bios_object_id(uint32_t bios_object_id);<br>
+<br>
+static struct graphics_object_id object_id_from_bios_object_id(<br>
+       uint32_t bios_object_id);<br>
+<br>
+static uint32_t id_from_bios_object_id(enum object_type type,<br>
+       uint32_t bios_object_id);<br>
+<br>
+static uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id);<br>
+<br>
+static enum encoder_id encoder_id_from_bios_object_id(uint32_t bios_object_id);<br>
+<br>
+static enum connector_id connector_id_from_bios_object_id(<br>
+                                               uint32_t bios_object_id);<br>
+<br>
+static enum generic_id generic_id_from_bios_object_id(uint32_t bios_object_id);<br>
+<br>
+static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,<br>
+       struct atom_i2c_record *record,<br>
+       struct graphics_object_i2c_info *info);<br>
+<br>
+static enum bp_result bios_parser_get_firmware_info(<br>
+       struct dc_bios *dcb,<br>
+       struct firmware_info *info);<br>
+<br>
+static enum bp_result bios_parser_get_encoder_cap_info(<br>
+       struct dc_bios *dcb,<br>
+       struct graphics_object_id object_id,<br>
+       struct bp_encoder_cap_info *info);<br>
+<br>
+static enum bp_result get_firmware_info_v3_1(<br>
+       struct bios_parser *bp,<br>
+       struct firmware_info *info);<br>
+<br>
+static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,<br>
+               struct atom_display_object_path_v2 *object);<br>
+<br>
+static struct atom_encoder_caps_record *get_encoder_cap_record(<br>
+       struct bios_parser *bp,<br>
+       struct atom_display_object_path_v2 *object);<br>
+<br>
+#define BIOS_IMAGE_SIZE_OFFSET 2<br>
+#define BIOS_IMAGE_SIZE_UNIT 512<br>
+<br>
+#define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)<br>
+<br>
+<br>
+static void destruct(struct bios_parser *bp)<br>
+{<br>
+       if (bp->base.bios_local_image)<br>
+               dm_free(bp->base.bios_local_image);<br>
+<br>
+       if (bp->base.integrated_info)<br>
+               dm_free(bp->base.integrated_info);<br>
+}<br>
+<br>
+static void firmware_parser_destroy(struct dc_bios **dcb)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(*dcb);<br>
+<br>
+       if (!bp) {<br>
+               BREAK_TO_DEBUGGER();<br>
+               return;<br>
+       }<br>
+<br>
+       destruct(bp);<br>
+<br>
+       dm_free(bp);<br>
+       *dcb = NULL;<br>
+}<br>
+<br>
+static void get_atom_data_table_revision(<br>
+       struct atom_common_table_header *atom_data_tbl,<br>
+       struct atom_data_revision *tbl_revision)<br>
+{<br>
+       if (!tbl_revision)<br>
+               return;<br>
+<br>
+       /* initialize the revision to 0 which is invalid revision */<br>
+       tbl_revision->major = 0;<br>
+       tbl_revision->minor = 0;<br>
+<br>
+       if (!atom_data_tbl)<br>
+               return;<br>
+<br>
+       tbl_revision->major =<br>
+                       (uint32_t) atom_data_tbl->format_revision & 0x3f;<br>
+       tbl_revision->minor =<br>
+                       (uint32_t) atom_data_tbl->content_revision & 0x3f;<br>
+}<br>
+<br>
+static struct graphics_object_id object_id_from_bios_object_id(<br>
+       uint32_t bios_object_id)<br>
+{<br>
+       enum object_type type;<br>
+       enum object_enum_id enum_id;<br>
+       struct graphics_object_id go_id = { 0 };<br>
+<br>
+       type = object_type_from_bios_object_id(bios_object_id);<br>
+<br>
+       if (type == OBJECT_TYPE_UNKNOWN)<br>
+               return go_id;<br>
+<br>
+       enum_id = enum_id_from_bios_object_id(bios_object_id);<br>
+<br>
+       if (enum_id == ENUM_ID_UNKNOWN)<br>
+               return go_id;<br>
+<br>
+       go_id = dal_graphics_object_id_init(<br>
+                       id_from_bios_object_id(type, bios_object_id),<br>
+                                                               enum_id, type);<br>
+<br>
+       return go_id;<br>
+}<br>
+<br>
+static enum object_type object_type_from_bios_object_id(uint32_t bios_object_id)<br>
+{<br>
+       uint32_t bios_object_type = (bios_object_id & OBJECT_TYPE_MASK)<br>
+                               >> OBJECT_TYPE_SHIFT;<br>
+       enum object_type object_type;<br>
+<br>
+       switch (bios_object_type) {<br>
+       case GRAPH_OBJECT_TYPE_GPU:<br>
+               object_type = OBJECT_TYPE_GPU;<br>
+               break;<br>
+       case GRAPH_OBJECT_TYPE_ENCODER:<br>
+               object_type = OBJECT_TYPE_ENCODER;<br>
+               break;<br>
+       case GRAPH_OBJECT_TYPE_CONNECTOR:<br>
+               object_type = OBJECT_TYPE_CONNECTOR;<br>
+               break;<br>
+       case GRAPH_OBJECT_TYPE_ROUTER:<br>
+               object_type = OBJECT_TYPE_ROUTER;<br>
+               break;<br>
+       case GRAPH_OBJECT_TYPE_GENERIC:<br>
+               object_type = OBJECT_TYPE_GENERIC;<br>
+               break;<br>
+       default:<br>
+               object_type = OBJECT_TYPE_UNKNOWN;<br>
+               break;<br>
+       }<br>
+<br>
+       return object_type;<br>
+}<br>
+<br>
+static enum object_enum_id enum_id_from_bios_object_id(uint32_t bios_object_id)<br>
+{<br>
+       uint32_t bios_enum_id =<br>
+                       (bios_object_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT;<br>
+       enum object_enum_id id;<br>
+<br>
+       switch (bios_enum_id) {<br>
+       case GRAPH_OBJECT_ENUM_ID1:<br>
+               id = ENUM_ID_1;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID2:<br>
+               id = ENUM_ID_2;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID3:<br>
+               id = ENUM_ID_3;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID4:<br>
+               id = ENUM_ID_4;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID5:<br>
+               id = ENUM_ID_5;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID6:<br>
+               id = ENUM_ID_6;<br>
+               break;<br>
+       case GRAPH_OBJECT_ENUM_ID7:<br>
+               id = ENUM_ID_7;<br>
+               break;<br>
+       default:<br>
+               id = ENUM_ID_UNKNOWN;<br>
+               break;<br>
+       }<br>
+<br>
+       return id;<br>
+}<br>
+<br>
+static uint32_t id_from_bios_object_id(enum object_type type,<br>
+       uint32_t bios_object_id)<br>
+{<br>
+       switch (type) {<br>
+       case OBJECT_TYPE_GPU:<br>
+               return gpu_id_from_bios_object_id(bios_object_id);<br>
+       case OBJECT_TYPE_ENCODER:<br>
+               return (uint32_t)encoder_id_from_bios_object_id(bios_object_id);<br>
+       case OBJECT_TYPE_CONNECTOR:<br>
+               return (uint32_t)connector_id_from_bios_object_id(<br>
+                               bios_object_id);<br>
+       case OBJECT_TYPE_GENERIC:<br>
+               return generic_id_from_bios_object_id(bios_object_id);<br>
+       default:<br>
+               return 0;<br>
+       }<br>
+}<br>
+<br>
+uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id)<br>
+{<br>
+       return (bios_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;<br>
+}<br>
+<br>
+static enum encoder_id encoder_id_from_bios_object_id(uint32_t bios_object_id)<br>
+{<br>
+       uint32_t bios_encoder_id = gpu_id_from_bios_object_id(bios_object_id);<br>
+       enum encoder_id id;<br>
+<br>
+       switch (bios_encoder_id) {<br>
+       case ENCODER_OBJECT_ID_INTERNAL_LVDS:<br>
+               id = ENCODER_ID_INTERNAL_LVDS;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS1:<br>
+               id = ENCODER_ID_INTERNAL_TMDS1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_TMDS2:<br>
+               id = ENCODER_ID_INTERNAL_TMDS2;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_DAC1:<br>
+               id = ENCODER_ID_INTERNAL_DAC1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_DAC2:<br>
+               id = ENCODER_ID_INTERNAL_DAC2;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_LVTM1:<br>
+               id = ENCODER_ID_INTERNAL_LVTM1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_HDMI_INTERNAL:<br>
+               id = ENCODER_ID_INTERNAL_HDMI;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:<br>
+               id = ENCODER_ID_INTERNAL_KLDSCP_TMDS1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:<br>
+               id = ENCODER_ID_INTERNAL_KLDSCP_DAC1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:<br>
+               id = ENCODER_ID_INTERNAL_KLDSCP_DAC2;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_MVPU_FPGA:<br>
+               id = ENCODER_ID_EXTERNAL_MVPU_FPGA;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_DDI:<br>
+               id = ENCODER_ID_INTERNAL_DDI;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:<br>
+               id = ENCODER_ID_INTERNAL_UNIPHY;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:<br>
+               id = ENCODER_ID_INTERNAL_KLDSCP_LVTMA;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:<br>
+               id = ENCODER_ID_INTERNAL_UNIPHY1;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:<br>
+               id = ENCODER_ID_INTERNAL_UNIPHY2;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_ALMOND: /* ENCODER_OBJECT_ID_NUTMEG */<br>
+               id = ENCODER_ID_EXTERNAL_NUTMEG;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_TRAVIS:<br>
+               id = ENCODER_ID_EXTERNAL_TRAVIS;<br>
+               break;<br>
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:<br>
+               id = ENCODER_ID_INTERNAL_UNIPHY3;<br>
+               break;<br>
+       default:<br>
+               id = ENCODER_ID_UNKNOWN;<br>
+               ASSERT(0);<br>
+               break;<br>
+       }<br>
+<br>
+       return id;<br>
+}<br>
+<br>
+static enum connector_id connector_id_from_bios_object_id(<br>
+       uint32_t bios_object_id)<br>
+{<br>
+       uint32_t bios_connector_id = gpu_id_from_bios_object_id(bios_object_id);<br>
+<br>
+       enum connector_id id;<br>
+<br>
+       switch (bios_connector_id) {<br>
+       case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I:<br>
+               id = CONNECTOR_ID_SINGLE_LINK_DVII;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I:<br>
+               id = CONNECTOR_ID_DUAL_LINK_DVII;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D:<br>
+               id = CONNECTOR_ID_SINGLE_LINK_DVID;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D:<br>
+               id = CONNECTOR_ID_DUAL_LINK_DVID;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_VGA:<br>
+               id = CONNECTOR_ID_VGA;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_HDMI_TYPE_A:<br>
+               id = CONNECTOR_ID_HDMI_TYPE_A;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_LVDS:<br>
+               id = CONNECTOR_ID_LVDS;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_PCIE_CONNECTOR:<br>
+               id = CONNECTOR_ID_PCIE;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_HARDCODE_DVI:<br>
+               id = CONNECTOR_ID_HARDCODE_DVI;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_DISPLAYPORT:<br>
+               id = CONNECTOR_ID_DISPLAY_PORT;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_eDP:<br>
+               id = CONNECTOR_ID_EDP;<br>
+               break;<br>
+       case CONNECTOR_OBJECT_ID_MXM:<br>
+               id = CONNECTOR_ID_MXM;<br>
+               break;<br>
+       default:<br>
+               id = CONNECTOR_ID_UNKNOWN;<br>
+               break;<br>
+       }<br>
+<br>
+       return id;<br>
+}<br>
+<br>
+enum generic_id generic_id_from_bios_object_id(uint32_t bios_object_id)<br>
+{<br>
+       uint32_t bios_generic_id = gpu_id_from_bios_object_id(bios_object_id);<br>
+<br>
+       enum generic_id id;<br>
+<br>
+       switch (bios_generic_id) {<br>
+       case GENERIC_OBJECT_ID_MXM_OPM:<br>
+               id = GENERIC_ID_MXM_OPM;<br>
+               break;<br>
+       case GENERIC_OBJECT_ID_GLSYNC:<br>
+               id = GENERIC_ID_GLSYNC;<br>
+               break;<br>
+       case GENERIC_OBJECT_ID_STEREO_PIN:<br>
+               id = GENERIC_ID_STEREO;<br>
+               break;<br>
+       default:<br>
+               id = GENERIC_ID_UNKNOWN;<br>
+               break;<br>
+       }<br>
+<br>
+       return id;<br>
+}<br>
+<br>
+static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       unsigned int count = 0;<br>
+       unsigned int i;<br>
+<br>
+       for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {<br>
+               if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0<br>
+                               &&<br>
+               bp->object_info_tbl.v1_4->display_path[i].display_objid != 0)<br>
+                       count++;<br>
+       }<br>
+       return count;<br>
+}<br>
+<br>
+static struct graphics_object_id bios_parser_get_encoder_id(<br>
+       struct dc_bios *dcb,<br>
+       uint32_t i)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct graphics_object_id object_id = dal_graphics_object_id_init(<br>
+               0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);<br>
+<br>
+       if (bp->object_info_tbl.v1_4->number_of_path > i)<br>
+               object_id = object_id_from_bios_object_id(<br>
+               bp->object_info_tbl.v1_4->display_path[i].encoderobjid);<br>
+<br>
+       return object_id;<br>
+}<br>
+<br>
+static struct graphics_object_id bios_parser_get_connector_id(<br>
+       struct dc_bios *dcb,<br>
+       uint8_t i)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct graphics_object_id object_id = dal_graphics_object_id_init(<br>
+               0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);<br>
+       struct object_info_table *tbl = &bp->object_info_tbl;<br>
+       struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;<br>
+<br>
+       if (v1_4->number_of_path > i) {<br>
+               /* If display_objid is generic object id,  the encoderObj<br>
+                * /extencoderobjId should be 0<br>
+                */<br>
+               if (v1_4->display_path[i].encoderobjid != 0 &&<br>
+                               v1_4->display_path[i].display_objid != 0)<br>
+                       object_id = object_id_from_bios_object_id(<br>
+                                       v1_4->display_path[i].display_objid);<br>
+       }<br>
+<br>
+       return object_id;<br>
+}<br>
+<br>
+<br>
+/*  TODO:  GetNumberOfSrc*/<br>
+<br>
+static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb,<br>
+       struct graphics_object_id id)<br>
+{<br>
+       /* connector has 1 Dest, encoder has 0 Dest */<br>
+       switch (id.type) {<br>
+       case OBJECT_TYPE_ENCODER:<br>
+               return 0;<br>
+       case OBJECT_TYPE_CONNECTOR:<br>
+               return 1;<br>
+       default:<br>
+               return 0;<br>
+       }<br>
+}<br>
+<br>
+/*  removed getSrcObjList, getDestObjList*/<br>
+<br>
+<br>
+static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,<br>
+       struct graphics_object_id object_id, uint32_t index,<br>
+       struct graphics_object_id *src_object_id)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       unsigned int i;<br>
+       enum bp_result  bp_result = BP_RESULT_BADINPUT;<br>
+       struct graphics_object_id obj_id = {0};<br>
+       struct object_info_table *tbl = &bp->object_info_tbl;<br>
+<br>
+       if (!src_object_id)<br>
+               return bp_result;<br>
+<br>
+       switch (object_id.type) {<br>
+       /* Encoder's Source is GPU.  BIOS does not provide GPU, since all<br>
+        * displaypaths point to same GPU (0x1100).  Hardcode GPU object type<br>
+        */<br>
+       case OBJECT_TYPE_ENCODER:<br>
+               /* TODO: since num of src must be less than 2.<br>
+                * If found in for loop, should break.<br>
+                * DAL2 implementation may be changed too<br>
+                */<br>
+               for (i = 0; i < tbl->v1_4->number_of_path; i++) {<br>
+                       obj_id = object_id_from_bios_object_id(<br>
+                       tbl->v1_4->display_path[i].encoderobjid);<br>
+                       if (object_id.type == obj_id.type &&<br>
+                                       <a href="http://object_id.id" rel="noreferrer" target="_blank">object_id.id</a> == <a href="http://obj_id.id" rel="noreferrer" target="_blank">obj_id.id</a> &&<br>
+                                               object_id.enum_id ==<br>
+                                                       obj_id.enum_id) {<br>
+                               *src_object_id =<br>
+                               object_id_from_bios_object_id(0x1100);<br>
+                               /* break; */<br>
+                       }<br>
+               }<br>
+               bp_result = BP_RESULT_OK;<br>
+               break;<br>
+       case OBJECT_TYPE_CONNECTOR:<br>
+               for (i = 0; i < tbl->v1_4->number_of_path; i++) {<br>
+                       obj_id = object_id_from_bios_object_id(<br>
+                               tbl->v1_4->display_path[i].display_objid);<br>
+<br>
+                       if (object_id.type == obj_id.type &&<br>
+                               <a href="http://object_id.id" rel="noreferrer" target="_blank">object_id.id</a> == <a href="http://obj_id.id" rel="noreferrer" target="_blank">obj_id.id</a> &&<br>
+                                       object_id.enum_id == obj_id.enum_id) {<br>
+                               *src_object_id =<br>
+                               object_id_from_bios_object_id(<br>
+                               tbl->v1_4->display_path[i].encoderobjid);<br>
+                               /* break; */<br>
+                       }<br>
+               }<br>
+               bp_result = BP_RESULT_OK;<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+<br>
+       return bp_result;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb,<br>
+       struct graphics_object_id object_id, uint32_t index,<br>
+       struct graphics_object_id *dest_object_id)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       unsigned int i;<br>
+       enum bp_result  bp_result = BP_RESULT_BADINPUT;<br>
+       struct graphics_object_id obj_id = {0};<br>
+       struct object_info_table *tbl = &bp->object_info_tbl;<br>
+<br>
+       if (!dest_object_id)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       switch (object_id.type) {<br>
+       case OBJECT_TYPE_ENCODER:<br>
+               /* TODO: since num of src must be less than 2.<br>
+                * If found in for loop, should break.<br>
+                * DAL2 implementation may be changed too<br>
+                */<br>
+               for (i = 0; i < tbl->v1_4->number_of_path; i++) {<br>
+                       obj_id = object_id_from_bios_object_id(<br>
+                               tbl->v1_4->display_path[i].encoderobjid);<br>
+                       if (object_id.type == obj_id.type &&<br>
+                                       <a href="http://object_id.id" rel="noreferrer" target="_blank">object_id.id</a> == <a href="http://obj_id.id" rel="noreferrer" target="_blank">obj_id.id</a> &&<br>
+                                               object_id.enum_id ==<br>
+                                                       obj_id.enum_id) {<br>
+                               *dest_object_id =<br>
+                                       object_id_from_bios_object_id(<br>
+                               tbl->v1_4->display_path[i].display_objid);<br>
+                               /* break; */<br>
+                       }<br>
+               }<br>
+               bp_result = BP_RESULT_OK;<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+<br>
+       return bp_result;<br>
+}<br>
+<br>
+<br>
+/* from graphics_object_id, find display path which includes the object_id */<br>
+static struct atom_display_object_path_v2 *get_bios_object(<br>
+       struct bios_parser *bp,<br>
+       struct graphics_object_id id)<br>
+{<br>
+       unsigned int i;<br>
+       struct graphics_object_id obj_id = {0};<br>
+<br>
+       switch (id.type) {<br>
+       case OBJECT_TYPE_ENCODER:<br>
+               for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {<br>
+                       obj_id = object_id_from_bios_object_id(<br>
+                       bp->object_info_tbl.v1_4->display_path[i].encoderobjid);<br>
+                       if (id.type == obj_id.type &&<br>
+                                       <a href="http://id.id" rel="noreferrer" target="_blank">id.id</a> == <a href="http://obj_id.id" rel="noreferrer" target="_blank">obj_id.id</a> &&<br>
+                                               id.enum_id == obj_id.enum_id)<br>
+                               return<br>
+                               &bp->object_info_tbl.v1_4->display_path[i];<br>
+               }<br>
+       case OBJECT_TYPE_CONNECTOR:<br>
+       case OBJECT_TYPE_GENERIC:<br>
+               /* Both Generic and Connector Object ID<br>
+                * will be stored on display_objid<br>
+               */<br>
+               for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {<br>
+                       obj_id = object_id_from_bios_object_id(<br>
+                       bp->object_info_tbl.v1_4->display_path[i].display_objid<br>
+                       );<br>
+                       if (id.type == obj_id.type &&<br>
+                                       <a href="http://id.id" rel="noreferrer" target="_blank">id.id</a> == <a href="http://obj_id.id" rel="noreferrer" target="_blank">obj_id.id</a> &&<br>
+                                               id.enum_id == obj_id.enum_id)<br>
+                               return<br>
+                               &bp->object_info_tbl.v1_4->display_path[i];<br>
+               }<br>
+       default:<br>
+               return NULL;<br>
+       }<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,<br>
+       struct graphics_object_id id,<br>
+       struct graphics_object_i2c_info *info)<br>
+{<br>
+       uint32_t offset;<br>
+       struct atom_display_object_path_v2 *object;<br>
+       struct atom_common_record_header *header;<br>
+       struct atom_i2c_record *record;<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       object = get_bios_object(bp, id);<br>
+<br>
+       if (!object)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       offset = object->disp_recordoffset + bp->object_info_tbl_offset;<br>
+<br>
+       for (;;) {<br>
+               header = GET_IMAGE(struct atom_common_record_header, offset);<br>
+<br>
+               if (!header)<br>
+                       return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+               if (header->record_type == LAST_RECORD_TYPE ||<br>
+                       !header->record_size)<br>
+                       break;<br>
+<br>
+               if (header->record_type == ATOM_I2C_RECORD_TYPE<br>
+                       && sizeof(struct atom_i2c_record) <=<br>
+                                                       header->record_size) {<br>
+                       /* get the I2C info */<br>
+                       record = (struct atom_i2c_record *) header;<br>
+<br>
+                       if (get_gpio_i2c_info(bp, record, info) ==<br>
+                                                               BP_RESULT_OK)<br>
+                               return BP_RESULT_OK;<br>
+               }<br>
+<br>
+               offset += header->record_size;<br>
+       }<br>
+<br>
+       return BP_RESULT_NORECORD;<br>
+}<br>
+<br>
+static enum bp_result get_gpio_i2c_info(<br>
+       struct bios_parser *bp,<br>
+       struct atom_i2c_record *record,<br>
+       struct graphics_object_i2c_info *info)<br>
+{<br>
+       struct atom_gpio_pin_lut_v2_1 *header;<br>
+       uint32_t count = 0;<br>
+       unsigned int table_index = 0;<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       /* get the GPIO_I2C info */<br>
+       if (!DATA_TABLES(gpio_pin_lut))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,<br>
+                                       DATA_TABLES(gpio_pin_lut));<br>
+       if (!header)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       if (sizeof(struct atom_common_table_header) +<br>
+                       sizeof(struct atom_gpio_pin_assignment) ><br>
+                       le16_to_cpu(header->table_header.structuresize))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       /* TODO: is version change? */<br>
+       if (header->table_header.content_revision != 1)<br>
+               return BP_RESULT_UNSUPPORTED;<br>
+<br>
+       /* get data count */<br>
+       count = (le16_to_cpu(header->table_header.structuresize)<br>
+                       - sizeof(struct atom_common_table_header))<br>
+                               / sizeof(struct atom_gpio_pin_assignment);<br>
+<br>
+       table_index = record->i2c_id  & I2C_HW_LANE_MUX;<br>
+<br>
+       if (count < table_index) {<br>
+               bool find_valid = false;<br>
+<br>
+               for (table_index = 0; table_index < count; table_index++) {<br>
+                       if (((record->i2c_id & I2C_HW_CAP) == (<br>
+                       header->gpio_pin[table_index].gpio_id &<br>
+                                                       I2C_HW_CAP)) &&<br>
+                       ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==<br>
+                       (header->gpio_pin[table_index].gpio_id &<br>
+                                               I2C_HW_ENGINE_ID_MASK)) &&<br>
+                       ((record->i2c_id & I2C_HW_LANE_MUX) ==<br>
+                       (header->gpio_pin[table_index].gpio_id &<br>
+                                                       I2C_HW_LANE_MUX))) {<br>
+                               /* still valid */<br>
+                               find_valid = true;<br>
+                               break;<br>
+                       }<br>
+               }<br>
+               /* If we don't find the entry that we are looking for then<br>
+                *  we will return BP_Result_BadBiosTable.<br>
+                */<br>
+               if (find_valid == false)<br>
+                       return BP_RESULT_BADBIOSTABLE;<br>
+       }<br>
+<br>
+       /* get the GPIO_I2C_INFO */<br>
+       info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;<br>
+       info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;<br>
+       info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;<br>
+       info->i2c_slave_address = record->i2c_slave_addr;<br>
+<br>
+       /* TODO: check how to get register offset for en, Y, etc. */<br>
+       info->gpio_info.clk_a_register_index =<br>
+                       le16_to_cpu(<br>
+                       header->gpio_pin[table_index].data_a_reg_index);<br>
+       info->gpio_info.clk_a_shift =<br>
+                       header->gpio_pin[table_index].gpio_bitshift;<br>
+<br>
+       return BP_RESULT_OK;<br>
+}<br>
+<br>
+static enum bp_result get_voltage_ddc_info_v4(<br>
+       uint8_t *i2c_line,<br>
+       uint32_t index,<br>
+       struct atom_common_table_header *header,<br>
+       uint8_t *address)<br>
+{<br>
+       enum bp_result result = BP_RESULT_NORECORD;<br>
+       struct atom_voltage_objects_info_v4_1 *info =<br>
+               (struct atom_voltage_objects_info_v4_1 *) address;<br>
+<br>
+       uint8_t *voltage_current_object =<br>
+               (uint8_t *) (&(info->voltage_object[0]));<br>
+<br>
+       while ((address + le16_to_cpu(header->structuresize)) ><br>
+                                               voltage_current_object) {<br>
+               struct atom_i2c_voltage_object_v4 *object =<br>
+                       (struct atom_i2c_voltage_object_v4 *)<br>
+                                               voltage_current_object;<br>
+<br>
+               if (object->header.voltage_mode ==<br>
+                       ATOM_INIT_VOLTAGE_REGULATOR) {<br>
+                       if (object->header.voltage_type == index) {<br>
+                               *i2c_line = object->i2c_id ^ 0x90;<br>
+                               result = BP_RESULT_OK;<br>
+                               break;<br>
+                       }<br>
+               }<br>
+<br>
+               voltage_current_object +=<br>
+                               le16_to_cpu(object->header.object_size);<br>
+       }<br>
+       return result;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_thermal_ddc_info(<br>
+       struct dc_bios *dcb,<br>
+       uint32_t i2c_channel_id,<br>
+       struct graphics_object_i2c_info *info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct i2c_id_config_access *config;<br>
+       struct atom_i2c_record record;<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       config = (struct i2c_id_config_access *) &i2c_channel_id;<br>
+<br>
+       record.i2c_id = config->bfHW_Capable;<br>
+       record.i2c_id |= config->bfI2C_LineMux;<br>
+       record.i2c_id |= config->bfHW_EngineID;<br>
+<br>
+       return get_gpio_i2c_info(bp, &record, info);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios *dcb,<br>
+       uint32_t index,<br>
+       struct graphics_object_i2c_info *info)<br>
+{<br>
+       uint8_t i2c_line = 0;<br>
+       enum bp_result result = BP_RESULT_NORECORD;<br>
+       uint8_t *voltage_info_address;<br>
+       struct atom_common_table_header *header;<br>
+       struct atom_data_revision revision = {0};<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!DATA_TABLES(voltageobject_info))<br>
+               return result;<br>
+<br>
+       voltage_info_address = get_image(&bp->base,<br>
+                       DATA_TABLES(voltageobject_info),<br>
+                       sizeof(struct atom_common_table_header));<br>
+<br>
+       header = (struct atom_common_table_header *) voltage_info_address;<br>
+<br>
+       get_atom_data_table_revision(header, &revision);<br>
+<br>
+       switch (revision.major) {<br>
+       case 4:<br>
+               if (revision.minor != 1)<br>
+                       break;<br>
+               result = get_voltage_ddc_info_v4(&i2c_line, index, header,<br>
+                       voltage_info_address);<br>
+               break;<br>
+       }<br>
+<br>
+       if (result == BP_RESULT_OK)<br>
+               result = bios_parser_get_thermal_ddc_info(dcb,<br>
+                       i2c_line, info);<br>
+<br>
+       return result;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_hpd_info(<br>
+       struct dc_bios *dcb,<br>
+       struct graphics_object_id id,<br>
+       struct graphics_object_hpd_info *info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct atom_display_object_path_v2 *object;<br>
+       struct atom_hpd_int_record *record = NULL;<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       object = get_bios_object(bp, id);<br>
+<br>
+       if (!object)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       record = get_hpd_record(bp, object);<br>
+<br>
+       if (record != NULL) {<br>
+               info->hpd_int_gpio_uid = record->pin_id;<br>
+               info->hpd_active = record->plugin_pin_state;<br>
+               return BP_RESULT_OK;<br>
+       }<br>
+<br>
+       return BP_RESULT_NORECORD;<br>
+}<br>
+<br>
+static struct atom_hpd_int_record *get_hpd_record(<br>
+       struct bios_parser *bp,<br>
+       struct atom_display_object_path_v2 *object)<br>
+{<br>
+       struct atom_common_record_header *header;<br>
+       uint32_t offset;<br>
+<br>
+       if (!object) {<br>
+               BREAK_TO_DEBUGGER(); /* Invalid object */<br>
+               return NULL;<br>
+       }<br>
+<br>
+       offset = le16_to_cpu(object->disp_recordoffset)<br>
+                       + bp->object_info_tbl_offset;<br>
+<br>
+       for (;;) {<br>
+               header = GET_IMAGE(struct atom_common_record_header, offset);<br>
+<br>
+               if (!header)<br>
+                       return NULL;<br>
+<br>
+               if (header->record_type == LAST_RECORD_TYPE ||<br>
+                       !header->record_size)<br>
+                       break;<br>
+<br>
+               if (header->record_type == ATOM_HPD_INT_RECORD_TYPE<br>
+                       && sizeof(struct atom_hpd_int_record) <=<br>
+                                                       header->record_size)<br>
+                       return (struct atom_hpd_int_record *) header;<br>
+<br>
+               offset += header->record_size;<br>
+       }<br>
+<br>
+       return NULL;<br>
+}<br>
+<br>
+/**<br>
+ * bios_parser_get_gpio_pin_info<br>
+ * Get GpioPin information of input gpio id<br>
+ *<br>
+ * @param gpio_id, GPIO ID<br>
+ * @param info, GpioPin information structure<br>
+ * @return Bios parser result code<br>
+ * @note<br>
+ *  to get the GPIO PIN INFO, we need:<br>
+ *  1. get the GPIO_ID from other object table, see GetHPDInfo()<br>
+ *  2. in DATA_TABLE.GPIO_Pin_LUT, search all records,<br>
+ *     to get the registerA  offset/mask<br>
+ */<br>
+static enum bp_result bios_parser_get_gpio_pin_info(<br>
+       struct dc_bios *dcb,<br>
+       uint32_t gpio_id,<br>
+       struct gpio_pin_info *info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct atom_gpio_pin_lut_v2_1 *header;<br>
+       uint32_t count = 0;<br>
+       uint32_t i = 0;<br>
+<br>
+       if (!DATA_TABLES(gpio_pin_lut))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,<br>
+                                               DATA_TABLES(gpio_pin_lut));<br>
+       if (!header)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       if (sizeof(struct atom_common_table_header) +<br>
+                       sizeof(struct atom_gpio_pin_lut_v2_1)<br>
+                       > le16_to_cpu(header->table_header.structuresize))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       if (header->table_header.content_revision != 1)<br>
+               return BP_RESULT_UNSUPPORTED;<br>
+<br>
+       /* Temporary hard code gpio pin info */<br>
+#if defined(FOR_SIMNOW_BOOT)<br>
+       {<br>
+               struct  atom_gpio_pin_assignment  gpio_pin[8] = {<br>
+                               {0x5db5, 0, 0, 1, 0},<br>
+                               {0x5db5, 8, 8, 2, 0},<br>
+                               {0x5db5, 0x10, 0x10, 3, 0},<br>
+                               {0x5db5, 0x18, 0x14, 4, 0},<br>
+                               {0x5db5, 0x1A, 0x18, 5, 0},<br>
+                               {0x5db5, 0x1C, 0x1C, 6, 0},<br>
+               };<br>
+<br>
+               count = 6;<br>
+               memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));<br>
+       }<br>
+#else<br>
+       count = (le16_to_cpu(header->table_header.structuresize)<br>
+                       - sizeof(struct atom_common_table_header))<br>
+                               / sizeof(struct atom_gpio_pin_assignment);<br>
+#endif<br>
+       for (i = 0; i < count; ++i) {<br>
+               if (header->gpio_pin[i].gpio_id != gpio_id)<br>
+                       continue;<br>
+<br>
+               info->offset =<br>
+                       (uint32_t) le16_to_cpu(<br>
+                                       header->gpio_pin[i].data_a_reg_index);<br>
+               info->offset_y = info->offset + 2;<br>
+               info->offset_en = info->offset + 1;<br>
+               info->offset_mask = info->offset - 1;<br>
+<br>
+               info->mask = (uint32_t) (1 <<<br>
+                       header->gpio_pin[i].gpio_bitshift);<br>
+               info->mask_y = info->mask + 2;<br>
+               info->mask_en = info->mask + 1;<br>
+               info->mask_mask = info->mask - 1;<br>
+<br>
+               return BP_RESULT_OK;<br>
+       }<br>
+<br>
+       return BP_RESULT_NORECORD;<br>
+}<br>
+<br>
+static struct device_id device_type_from_device_id(uint16_t device_id)<br>
+{<br>
+<br>
+       struct device_id result_device_id;<br>
+<br>
+       switch (device_id) {<br>
+       case ATOM_DISPLAY_LCD1_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_LCD;<br>
+               result_device_id.enum_id = 1;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP1_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 1;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP2_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 2;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP3_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 3;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP4_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 4;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP5_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 5;<br>
+               break;<br>
+<br>
+       case ATOM_DISPLAY_DFP6_SUPPORT:<br>
+               result_device_id.device_type = DEVICE_TYPE_DFP;<br>
+               result_device_id.enum_id = 6;<br>
+               break;<br>
+<br>
+       default:<br>
+               BREAK_TO_DEBUGGER(); /* Invalid device Id */<br>
+               result_device_id.device_type = DEVICE_TYPE_UNKNOWN;<br>
+               result_device_id.enum_id = 0;<br>
+       }<br>
+       return result_device_id;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_device_tag(<br>
+       struct dc_bios *dcb,<br>
+       struct graphics_object_id connector_object_id,<br>
+       uint32_t device_tag_index,<br>
+       struct connector_device_tag_info *info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct atom_display_object_path_v2 *object;<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       /* getBiosObject will return MXM object */<br>
+       object = get_bios_object(bp, connector_object_id);<br>
+<br>
+       if (!object) {<br>
+               BREAK_TO_DEBUGGER(); /* Invalid object id */<br>
+               return BP_RESULT_BADINPUT;<br>
+       }<br>
+<br>
+       info->acpi_device = 0; /* BIOS no longer provides this */<br>
+       info->dev_id = device_type_from_device_id(object->device_tag);<br>
+<br>
+       return BP_RESULT_OK;<br>
+}<br>
+<br>
+static enum bp_result get_ss_info_v4_1(<br>
+       struct bios_parser *bp,<br>
+       uint32_t id,<br>
+       uint32_t index,<br>
+       struct spread_spectrum_info *ss_info)<br>
+{<br>
+       enum bp_result result = BP_RESULT_OK;<br>
+       struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;<br>
+       struct atom_smu_info_v3_1 *smu_tbl = NULL;<br>
+<br>
+       if (!ss_info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       if (!DATA_TABLES(dce_info))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       if (!DATA_TABLES(smu_info))<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       disp_cntl_tbl =  GET_IMAGE(struct atom_display_controller_info_v4_1,<br>
+                                                       DATA_TABLES(dce_info));<br>
+       if (!disp_cntl_tbl)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       smu_tbl =  GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));<br>
+       if (!smu_tbl)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+<br>
+       ss_info->type.STEP_AND_DELAY_INFO = false;<br>
+       ss_info->spread_percentage_divider = 1000;<br>
+       /* BIOS no longer uses target clock.  Always enable for now */<br>
+       ss_info->target_clock_range = 0xffffffff;<br>
+<br>
+       switch (id) {<br>
+       case AS_SIGNAL_TYPE_DVI:<br>
+               ss_info->spread_spectrum_percentage =<br>
+                               disp_cntl_tbl->dvi_ss_percentage;<br>
+               ss_info->spread_spectrum_range =<br>
+                               disp_cntl_tbl->dvi_ss_rate_10hz * 10;<br>
+               if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)<br>
+                       ss_info->type.CENTER_MODE = true;<br>
+               break;<br>
+       case AS_SIGNAL_TYPE_HDMI:<br>
+               ss_info->spread_spectrum_percentage =<br>
+                               disp_cntl_tbl->hdmi_ss_percentage;<br>
+               ss_info->spread_spectrum_range =<br>
+                               disp_cntl_tbl->hdmi_ss_rate_10hz * 10;<br>
+               if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)<br>
+                       ss_info->type.CENTER_MODE = true;<br>
+               break;<br>
+       /* TODO LVDS not support anymore? */<br>
+       case AS_SIGNAL_TYPE_DISPLAY_PORT:<br>
+               ss_info->spread_spectrum_percentage =<br>
+                               disp_cntl_tbl->dp_ss_percentage;<br>
+               ss_info->spread_spectrum_range =<br>
+                               disp_cntl_tbl->dp_ss_rate_10hz * 10;<br>
+               if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)<br>
+                       ss_info->type.CENTER_MODE = true;<br>
+               break;<br>
+       case AS_SIGNAL_TYPE_GPU_PLL:<br>
+               ss_info->spread_spectrum_percentage =<br>
+                               smu_tbl->gpuclk_ss_percentage;<br>
+               ss_info->spread_spectrum_range =<br>
+                               smu_tbl->gpuclk_ss_rate_10hz * 10;<br>
+               if (smu_tbl->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)<br>
+                       ss_info->type.CENTER_MODE = true;<br>
+               break;<br>
+       default:<br>
+               result = BP_RESULT_UNSUPPORTED;<br>
+       }<br>
+<br>
+       return result;<br>
+}<br>
+<br>
+/**<br>
+ * bios_parser_get_spread_spectrum_info<br>
+ * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or<br>
+ * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info<br>
+ * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info<br>
+ * ver 3.1,<br>
+ * there is only one entry for each signal /ss id.  However, there is<br>
+ * no planning of supporting multiple spread Sprectum entry for EverGreen<br>
+ * @param [in] this<br>
+ * @param [in] signal, ASSignalType to be converted to info index<br>
+ * @param [in] index, number of entries that match the converted info index<br>
+ * @param [out] ss_info, sprectrum information structure,<br>
+ * @return Bios parser result code<br>
+ */<br>
+static enum bp_result bios_parser_get_spread_spectrum_info(<br>
+       struct dc_bios *dcb,<br>
+       enum as_signal_type signal,<br>
+       uint32_t index,<br>
+       struct spread_spectrum_info *ss_info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       enum bp_result result = BP_RESULT_UNSUPPORTED;<br>
+       struct atom_common_table_header *header;<br>
+       struct atom_data_revision tbl_revision;<br>
+<br>
+       if (!ss_info) /* check for bad input */<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       if (!DATA_TABLES(dce_info))<br>
+               return BP_RESULT_UNSUPPORTED;<br>
+<br>
+       header = GET_IMAGE(struct atom_common_table_header,<br>
+                                               DATA_TABLES(dce_info));<br>
+       get_atom_data_table_revision(header, &tbl_revision);<br>
+<br>
+       switch (tbl_revision.major) {<br>
+       case 4:<br>
+               switch (tbl_revision.minor) {<br>
+               case 1:<br>
+                       return get_ss_info_v4_1(bp, signal, index, ss_info);<br>
+               default:<br>
+                       break;<br>
+               }<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+       /* there can not be more then one entry for SS Info table */<br>
+       return result;<br>
+}<br>
+<br>
+static enum bp_result get_embedded_panel_info_v2_1(<br>
+       struct bios_parser *bp,<br>
+       struct embedded_panel_info *info)<br>
+{<br>
+       struct lcd_info_v2_1 *lvds;<br>
+<br>
+       if (!info)<br>
+               return BP_RESULT_BADINPUT;<br>
+<br>
+       if (!DATA_TABLES(lcd_info))<br>
+               return BP_RESULT_UNSUPPORTED;<br>
+<br>
+       lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));<br>
+<br>
+       if (!lvds)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       /* TODO: previous vv1_3, should v2_1 */<br>
+       if (!((lvds->table_header.format_revision == 2)<br>
+                       && (lvds->table_header.content_revision >= 1)))<br>
+               return BP_RESULT_UNSUPPORTED;<br>
+<br>
+       memset(info, 0, sizeof(struct embedded_panel_info));<br>
+<br>
+       /* We need to convert from 10KHz units into KHz units */<br>
+       info->lcd_timing.pixel_clk =<br>
+                       le16_to_cpu(lvds->lcd_timing.pixclk) * 10;<br>
+       /* usHActive does not include borders, according to VBIOS team */<br>
+       info->lcd_timing.horizontal_addressable =<br>
+                       le16_to_cpu(lvds->lcd_timing.h_active);<br>
+       /* usHBlanking_Time includes borders, so we should really be<br>
+        * subtractingborders duing this translation, but LVDS generally<br>
+        * doesn't have borders, so we should be okay leaving this as is for<br>
+        * now.  May need to revisit if we ever have LVDS with borders<br>
+        */<br>
+       info->lcd_timing.horizontal_blanking_time =<br>
+               le16_to_cpu(lvds->lcd_timing.h_blanking_time);<br>
+       /* usVActive does not include borders, according to VBIOS team*/<br>
+       info->lcd_timing.vertical_addressable =<br>
+               le16_to_cpu(lvds->lcd_timing.v_active);<br>
+       /* usVBlanking_Time includes borders, so we should really be<br>
+        * subtracting borders duing this translation, but LVDS generally<br>
+        * doesn't have borders, so we should be okay leaving this as is for<br>
+        * now. May need to revisit if we ever have LVDS with borders<br>
+        */<br>
+       info->lcd_timing.vertical_blanking_time =<br>
+               le16_to_cpu(lvds->lcd_timing.v_blanking_time);<br>
+       info->lcd_timing.horizontal_sync_offset =<br>
+               le16_to_cpu(lvds->lcd_timing.h_sync_offset);<br>
+       info->lcd_timing.horizontal_sync_width =<br>
+               le16_to_cpu(lvds->lcd_timing.h_sync_width);<br>
+       info->lcd_timing.vertical_sync_offset =<br>
+               le16_to_cpu(lvds->lcd_timing.v_sync_offset);<br>
+       info->lcd_timing.vertical_sync_width =<br>
+               le16_to_cpu(lvds->lcd_timing.v_syncwidth);<br>
+       info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;<br>
+       info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;<br>
+<br>
+       /* not provided by VBIOS */<br>
+       info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;<br>
+<br>
+       info->lcd_timing.misc_info.H_SYNC_POLARITY =<br>
+               ~(uint32_t)<br>
+               (lvds->lcd_timing.miscinfo & ATOM_HSYNC_POLARITY);<br>
+       info->lcd_timing.misc_info.V_SYNC_POLARITY =<br>
+               ~(uint32_t)<br>
+               (lvds->lcd_timing.miscinfo & ATOM_VSYNC_POLARITY);<br>
+<br>
+       /* not provided by VBIOS */<br>
+       info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;<br>
+<br>
+       info->lcd_timing.misc_info.H_REPLICATION_BY2 =<br>
+               lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2;<br>
+       info->lcd_timing.misc_info.V_REPLICATION_BY2 =<br>
+               lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2;<br>
+       info->lcd_timing.misc_info.COMPOSITE_SYNC =<br>
+               lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC;<br>
+       info->lcd_timing.misc_info.INTERLACE =<br>
+               lvds->lcd_timing.miscinfo & ATOM_INTERLACE;<br>
+<br>
+       /* not provided by VBIOS*/<br>
+       info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;<br>
+       /* not provided by VBIOS*/<br>
+       info->ss_id = 0;<br>
+<br>
+       info->realtek_eDPToLVDS =<br>
+                       (lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID ? 1:0);<br>
+<br>
+       return BP_RESULT_OK;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_get_embedded_panel_info(<br>
+       struct dc_bios *dcb,<br>
+       struct embedded_panel_info *info)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+       struct atom_common_table_header *header;<br>
+       struct atom_data_revision tbl_revision;<br>
+<br>
+       if (!DATA_TABLES(lcd_info))<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       header = GET_IMAGE(struct atom_common_table_header,<br>
+                                       DATA_TABLES(lcd_info));<br>
+<br>
+       if (!header)<br>
+               return BP_RESULT_BADBIOSTABLE;<br>
+<br>
+       get_atom_data_table_revision(header, &tbl_revision);<br>
+<br>
+<br>
+       switch (tbl_revision.major) {<br>
+       case 2:<br>
+               switch (tbl_revision.minor) {<br>
+               case 1:<br>
+                       return get_embedded_panel_info_v2_1(bp, info);<br>
+               default:<br>
+                       break;<br>
+               }<br>
+       default:<br>
+               break;<br>
+       }<br>
+<br>
+       return BP_RESULT_FAILURE;<br>
+}<br>
+<br>
+static uint32_t get_support_mask_for_device_id(struct device_id device_id)<br>
+{<br>
+       enum dal_device_type device_type = device_id.device_type;<br>
+       uint32_t enum_id = device_id.enum_id;<br>
+<br>
+       switch (device_type) {<br>
+       case DEVICE_TYPE_LCD:<br>
+               switch (enum_id) {<br>
+               case 1:<br>
+                       return ATOM_DISPLAY_LCD1_SUPPORT;<br>
+               default:<br>
+                       break;<br>
+               }<br>
+               break;<br>
+       case DEVICE_TYPE_DFP:<br>
+               switch (enum_id) {<br>
+               case 1:<br>
+                       return ATOM_DISPLAY_DFP1_SUPPORT;<br>
+               case 2:<br>
+                       return ATOM_DISPLAY_DFP2_SUPPORT;<br>
+               case 3:<br>
+                       return ATOM_DISPLAY_DFP3_SUPPORT;<br>
+               case 4:<br>
+                       return ATOM_DISPLAY_DFP4_SUPPORT;<br>
+               case 5:<br>
+                       return ATOM_DISPLAY_DFP5_SUPPORT;<br>
+               case 6:<br>
+                       return ATOM_DISPLAY_DFP6_SUPPORT;<br>
+               default:<br>
+                       break;<br>
+               }<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       };<br>
+<br>
+       /* Unidentified device ID, return empty support mask. */<br>
+       return 0;<br>
+}<br>
+<br>
+static bool bios_parser_is_device_id_supported(<br>
+       struct dc_bios *dcb,<br>
+       struct device_id id)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       uint32_t mask = get_support_mask_for_device_id(id);<br>
+<br>
+       return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &<br>
+                                                               mask) != 0;<br>
+}<br>
+<br>
+static void bios_parser_post_init(<br>
+       struct dc_bios *dcb)<br>
+{<br>
+       /* TODO for OPM module. Need implement later */<br>
+}<br>
+<br>
+static uint32_t bios_parser_get_ss_entry_number(<br>
+       struct dc_bios *dcb,<br>
+       enum as_signal_type signal)<br>
+{<br>
+       /* TODO: DAL2 atomfirmware implementation does not need this.<br>
+        * why DAL3 need this?<br>
+        */<br>
+       return 1;<br>
+}<br>
+<br>
+static enum bp_result bios_parser_transmitter_control(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_transmitter_control *cntl)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.transmitter_control)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.transmitter_control(bp, cntl);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_encoder_control(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_encoder_control *cntl)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.dig_encoder_control)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.dig_encoder_control(bp, cntl);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_set_pixel_clock(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_pixel_clock_parameters *bp_params)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.set_pixel_clock)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.set_pixel_clock(bp, bp_params);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_set_dce_clock(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_set_dce_clock_parameters *bp_params)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.set_dce_clock)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.set_dce_clock(bp, bp_params);<br>
+}<br>
+<br>
+static unsigned int bios_parser_get_smu_clock_info(<br>
+       struct dc_bios *dcb)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.get_smu_clock_info)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.get_smu_clock_info(bp);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_program_crtc_timing(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_hw_crtc_timing_parameters *bp_params)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.set_crtc_timing)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.set_crtc_timing(bp, bp_params);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_enable_crtc(<br>
+       struct dc_bios *dcb,<br>
+       enum controller_id id,<br>
+       bool enable)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.enable_crtc)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.enable_crtc(bp, id, enable);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_crtc_source_select(<br>
+       struct dc_bios *dcb,<br>
+       struct bp_crtc_source_select *bp_params)<br>
+{<br>
+       struct bios_parser *bp = BP_FROM_DCB(dcb);<br>
+<br>
+       if (!bp->cmd_tbl.select_crtc_source)<br>
+               return BP_RESULT_FAILURE;<br>
+<br>
+       return bp->cmd_tbl.select_crtc_source(bp, bp_params);<br>
+}<br>
+<br>
+static enum bp_result bios_parser_enable_di</blockquote></div>